// $Id$
// Version: $Name$
//
-// Copyright (C) 2001, 2002, 2003, 2005, 2006 by the deal.II authors
+// Copyright (C) 2001, 2002, 2003, 2005, 2006, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
const unsigned int n_components,
const double initial_time)
:
- Function<dim>(n_components, initial_time),
- h(1),
- ht(dim),
- formula(Euler)
+ Function<dim>(n_components, initial_time),
+ h(1),
+ ht(dim),
+ formula(Euler)
{
set_h(hh);
set_formula();
template <int dim>
Tensor<1,dim>
AutoDerivativeFunction<dim>::gradient (const Point<dim> &p,
- const unsigned int comp) const
+ const unsigned int comp) const
{
Tensor<1,dim> grad;
switch (formula)
{
case UpwindEuler:
{
- Point<dim> q1;
- for (unsigned int i=0; i<dim; ++i)
- {
- q1=p-ht[i];
- grad[i]=(this->value(p, comp)-this->value(q1, comp))/h;
- }
- break;
+ Point<dim> q1;
+ for (unsigned int i=0; i<dim; ++i)
+ {
+ q1=p-ht[i];
+ grad[i]=(this->value(p, comp)-this->value(q1, comp))/h;
+ }
+ break;
}
case Euler:
{
- Point<dim> q1, q2;
- for (unsigned int i=0; i<dim; ++i)
- {
- q1=p+ht[i];
- q2=p-ht[i];
- grad[i]=(this->value(q1, comp)-this->value(q2, comp))/(2*h);
- }
- break;
+ Point<dim> q1, q2;
+ for (unsigned int i=0; i<dim; ++i)
+ {
+ q1=p+ht[i];
+ q2=p-ht[i];
+ grad[i]=(this->value(q1, comp)-this->value(q2, comp))/(2*h);
+ }
+ break;
}
case FourthOrder:
{
- Point<dim> q1, q2, q3, q4;
- for (unsigned int i=0; i<dim; ++i)
- {
- q2=p+ht[i];
- q1=q2+ht[i];
- q3=p-ht[i];
- q4=q3-ht[i];
- grad[i]=(- this->value(q1, comp)
- +8*this->value(q2, comp)
- -8*this->value(q3, comp)
- + this->value(q4, comp))/(12*h);
-
- }
- break;
+ Point<dim> q1, q2, q3, q4;
+ for (unsigned int i=0; i<dim; ++i)
+ {
+ q2=p+ht[i];
+ q1=q2+ht[i];
+ q3=p-ht[i];
+ q4=q3-ht[i];
+ grad[i]=(- this->value(q1, comp)
+ +8*this->value(q2, comp)
+ -8*this->value(q3, comp)
+ + this->value(q4, comp))/(12*h);
+
+ }
+ break;
}
default:
- Assert(false, ExcInvalidFormula());
+ Assert(false, ExcInvalidFormula());
}
return grad;
}
std::vector<Tensor<1,dim> > &gradients) const
{
Assert (gradients.size() == this->n_components,
- ExcDimensionMismatch(gradients.size(), this->n_components));
-
+ ExcDimensionMismatch(gradients.size(), this->n_components));
+
switch (formula)
{
case UpwindEuler:
{
- Point<dim> q1;
- Vector<double> v(this->n_components), v1(this->n_components);
- const double h_inv=1./h;
- for (unsigned int i=0; i<dim; ++i)
- {
- q1=p-ht[i];
- this->vector_value(p, v);
- this->vector_value(q1, v1);
-
- for (unsigned int comp=0; comp<this->n_components; ++comp)
- gradients[comp][i]=(v(comp)-v1(comp))*h_inv;
- }
- break;
+ Point<dim> q1;
+ Vector<double> v(this->n_components), v1(this->n_components);
+ const double h_inv=1./h;
+ for (unsigned int i=0; i<dim; ++i)
+ {
+ q1=p-ht[i];
+ this->vector_value(p, v);
+ this->vector_value(q1, v1);
+
+ for (unsigned int comp=0; comp<this->n_components; ++comp)
+ gradients[comp][i]=(v(comp)-v1(comp))*h_inv;
+ }
+ break;
}
case Euler:
{
- Point<dim> q1, q2;
- Vector<double> v1(this->n_components), v2(this->n_components);
- const double h_inv_2=1./(2*h);
- for (unsigned int i=0; i<dim; ++i)
- {
- q1=p+ht[i];
- q2=p-ht[i];
- this->vector_value(q1, v1);
- this->vector_value(q2, v2);
-
- for (unsigned int comp=0; comp<this->n_components; ++comp)
- gradients[comp][i]=(v1(comp)-v2(comp))*h_inv_2;
- }
- break;
+ Point<dim> q1, q2;
+ Vector<double> v1(this->n_components), v2(this->n_components);
+ const double h_inv_2=1./(2*h);
+ for (unsigned int i=0; i<dim; ++i)
+ {
+ q1=p+ht[i];
+ q2=p-ht[i];
+ this->vector_value(q1, v1);
+ this->vector_value(q2, v2);
+
+ for (unsigned int comp=0; comp<this->n_components; ++comp)
+ gradients[comp][i]=(v1(comp)-v2(comp))*h_inv_2;
+ }
+ break;
}
case FourthOrder:
{
- Point<dim> q1, q2, q3, q4;
- Vector<double>
- v1(this->n_components), v2(this->n_components),
- v3(this->n_components), v4(this->n_components);
- const double h_inv_12=1./(12*h);
- for (unsigned int i=0; i<dim; ++i)
- {
- q2=p+ht[i];
- q1=q2+ht[i];
- q3=p-ht[i];
- q4=q3-ht[i];
- this->vector_value(q1, v1);
- this->vector_value(q2, v2);
- this->vector_value(q3, v3);
- this->vector_value(q4, v4);
-
- for (unsigned int comp=0; comp<this->n_components; ++comp)
- gradients[comp][i]=(-v1(comp)+8*v2(comp)-8*v3(comp)+v4(comp))*h_inv_12;
- }
- break;
+ Point<dim> q1, q2, q3, q4;
+ Vector<double>
+ v1(this->n_components), v2(this->n_components),
+ v3(this->n_components), v4(this->n_components);
+ const double h_inv_12=1./(12*h);
+ for (unsigned int i=0; i<dim; ++i)
+ {
+ q2=p+ht[i];
+ q1=q2+ht[i];
+ q3=p-ht[i];
+ q4=q3-ht[i];
+ this->vector_value(q1, v1);
+ this->vector_value(q2, v2);
+ this->vector_value(q3, v3);
+ this->vector_value(q4, v4);
+
+ for (unsigned int comp=0; comp<this->n_components; ++comp)
+ gradients[comp][i]=(-v1(comp)+8*v2(comp)-8*v3(comp)+v4(comp))*h_inv_12;
+ }
+ break;
}
default:
- Assert(false, ExcInvalidFormula());
+ Assert(false, ExcInvalidFormula());
}
}
const unsigned int comp) const
{
Assert (gradients.size() == points.size(),
- ExcDimensionMismatch(gradients.size(), points.size()));
+ ExcDimensionMismatch(gradients.size(), points.size()));
switch (formula)
{
case UpwindEuler:
{
- Point<dim> q1;
- for (unsigned p=0; p<points.size(); ++p)
- for (unsigned int i=0; i<dim; ++i)
- {
- q1=points[p]-ht[i];
- gradients[p][i]=(this->value(points[p], comp)-this->value(q1, comp))/h;
- }
- break;
+ Point<dim> q1;
+ for (unsigned p=0; p<points.size(); ++p)
+ for (unsigned int i=0; i<dim; ++i)
+ {
+ q1=points[p]-ht[i];
+ gradients[p][i]=(this->value(points[p], comp)-this->value(q1, comp))/h;
+ }
+ break;
}
case Euler:
{
- Point<dim> q1, q2;
- for (unsigned p=0; p<points.size(); ++p)
- for (unsigned int i=0; i<dim; ++i)
- {
- q1=points[p]+ht[i];
- q2=points[p]-ht[i];
- gradients[p][i]=(this->value(q1, comp)-this->value(q2, comp))/(2*h);
- }
- break;
+ Point<dim> q1, q2;
+ for (unsigned p=0; p<points.size(); ++p)
+ for (unsigned int i=0; i<dim; ++i)
+ {
+ q1=points[p]+ht[i];
+ q2=points[p]-ht[i];
+ gradients[p][i]=(this->value(q1, comp)-this->value(q2, comp))/(2*h);
+ }
+ break;
}
case FourthOrder:
{
- Point<dim> q1, q2, q3, q4;
- for (unsigned p=0; p<points.size(); ++p)
- for (unsigned int i=0; i<dim; ++i)
- {
- q2=points[p]+ht[i];
- q1=q2+ht[i];
- q3=points[p]-ht[i];
- q4=q3-ht[i];
- gradients[p][i]=(- this->value(q1, comp)
- +8*this->value(q2, comp)
- -8*this->value(q3, comp)
- + this->value(q4, comp))/(12*h);
- }
- break;
+ Point<dim> q1, q2, q3, q4;
+ for (unsigned p=0; p<points.size(); ++p)
+ for (unsigned int i=0; i<dim; ++i)
+ {
+ q2=points[p]+ht[i];
+ q1=q2+ht[i];
+ q3=points[p]-ht[i];
+ q4=q3-ht[i];
+ gradients[p][i]=(- this->value(q1, comp)
+ +8*this->value(q2, comp)
+ -8*this->value(q3, comp)
+ + this->value(q4, comp))/(12*h);
+ }
+ break;
}
default:
- Assert(false, ExcInvalidFormula());
+ Assert(false, ExcInvalidFormula());
}
}
template <int dim>
-void
+void
AutoDerivativeFunction<dim>::
vector_gradient_list (const std::vector<Point<dim> > &points,
- std::vector<std::vector<Tensor<1,dim> > > &gradients) const
+ std::vector<std::vector<Tensor<1,dim> > > &gradients) const
{
Assert (gradients.size() == points.size(),
- ExcDimensionMismatch(gradients.size(), points.size()));
+ ExcDimensionMismatch(gradients.size(), points.size()));
for (unsigned p=0; p<points.size(); ++p)
Assert (gradients[p].size() == this->n_components,
- ExcDimensionMismatch(gradients.size(), this->n_components));
-
+ ExcDimensionMismatch(gradients.size(), this->n_components));
+
switch (formula)
{
case UpwindEuler:
{
- Point<dim> q1;
- for (unsigned p=0; p<points.size(); ++p)
- for (unsigned int i=0; i<dim; ++i)
- {
- q1=points[p]-ht[i];
- for (unsigned int comp=0; comp<this->n_components; ++comp)
- gradients[p][comp][i]=(this->value(points[p], comp)-this->value(q1, comp))/h;
- }
- break;
+ Point<dim> q1;
+ for (unsigned p=0; p<points.size(); ++p)
+ for (unsigned int i=0; i<dim; ++i)
+ {
+ q1=points[p]-ht[i];
+ for (unsigned int comp=0; comp<this->n_components; ++comp)
+ gradients[p][comp][i]=(this->value(points[p], comp)-this->value(q1, comp))/h;
+ }
+ break;
}
case Euler:
{
- Point<dim> q1, q2;
- for (unsigned p=0; p<points.size(); ++p)
- for (unsigned int i=0; i<dim; ++i)
- {
- q1=points[p]+ht[i];
- q2=points[p]-ht[i];
- for (unsigned int comp=0; comp<this->n_components; ++comp)
- gradients[p][comp][i]=(this->value(q1, comp) -
+ Point<dim> q1, q2;
+ for (unsigned p=0; p<points.size(); ++p)
+ for (unsigned int i=0; i<dim; ++i)
+ {
+ q1=points[p]+ht[i];
+ q2=points[p]-ht[i];
+ for (unsigned int comp=0; comp<this->n_components; ++comp)
+ gradients[p][comp][i]=(this->value(q1, comp) -
this->value(q2, comp))/(2*h);
- }
- break;
+ }
+ break;
}
case FourthOrder:
{
- Point<dim> q1, q2, q3, q4;
- for (unsigned p=0; p<points.size(); ++p)
- for (unsigned int i=0; i<dim; ++i)
- {
- q2=points[p]+ht[i];
- q1=q2+ht[i];
- q3=points[p]-ht[i];
- q4=q3-ht[i];
- for (unsigned int comp=0; comp<this->n_components; ++comp)
- gradients[p][comp][i]=(- this->value(q1, comp)
- +8*this->value(q2, comp)
- -8*this->value(q3, comp)
- + this->value(q4, comp))/(12*h);
- }
- break;
+ Point<dim> q1, q2, q3, q4;
+ for (unsigned p=0; p<points.size(); ++p)
+ for (unsigned int i=0; i<dim; ++i)
+ {
+ q2=points[p]+ht[i];
+ q1=q2+ht[i];
+ q3=points[p]-ht[i];
+ q4=q3-ht[i];
+ for (unsigned int comp=0; comp<this->n_components; ++comp)
+ gradients[p][comp][i]=(- this->value(q1, comp)
+ +8*this->value(q2, comp)
+ -8*this->value(q3, comp)
+ + this->value(q4, comp))/(12*h);
+ }
+ break;
}
-
+
default:
- Assert(false, ExcInvalidFormula());
+ Assert(false, ExcInvalidFormula());
}
}
case 3:
case 4: return FourthOrder;
default:
- Assert(false, ExcNotImplemented());
+ Assert(false, ExcNotImplemented());
}
return Euler;
}
// $Id$
// Version: $Name$
//
-// Copyright (C) 2009, 2010, 2011 by the deal.II authors
+// Copyright (C) 2009, 2010, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
// $Id$
// Version: $Name$
//
-// Copyright (C) 2009, 2010, 2011 by the deal.II authors
+// Copyright (C) 2009, 2010, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
// $Id$
// Version: $Name$
//
-// Copyright (C) 2004, 2005, 2006, 2007 by the deal.II authors
+// Copyright (C) 2004, 2005, 2006, 2007, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
ConditionalOStream::ConditionalOStream(std::ostream &stream,
const bool active)
:
- output_stream (stream),
- active_flag(active)
+ output_stream (stream),
+ active_flag(active)
{}
// $Id$
// Version: $Name$
//
-// Copyright (C) 2006, 2007, 2010 by the deal.II authors
+// Copyright (C) 2006, 2007, 2010, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
#ifdef DEAL_II_HAVE_ISFINITE
return std::isfinite (x);
#else
- // Check against infinities. Note
- // that if x is a NaN, then both
- // comparisons will be false
+ // Check against infinities. Note
+ // that if x is a NaN, then both
+ // comparisons will be false
return ((x >= -std::numeric_limits<double>::max())
- &&
- (x <= std::numeric_limits<double>::max()));
+ &&
+ (x <= std::numeric_limits<double>::max()));
#endif
}
bool is_finite (const std::complex<double> &x)
{
- // Check complex numbers for infinity
- // by testing real and imaginary part
+ // Check complex numbers for infinity
+ // by testing real and imaginary part
return ( is_finite (x.real())
&&
is_finite (x.imag()) );
bool is_finite (const std::complex<float> &x)
{
- // Check complex numbers for infinity
- // by testing real and imaginary part
+ // Check complex numbers for infinity
+ // by testing real and imaginary part
return ( is_finite (x.real())
&&
is_finite (x.imag()) );
bool is_finite (const std::complex<long double> &x)
{
- // Same for std::complex<long double>
+ // Same for std::complex<long double>
return ( is_finite (x.real())
&&
is_finite (x.imag()) );
// $Id$
// Version: $Name$
//
-// Copyright (C) 1999, 2000, 2001, 2002, 2003, 2005, 2006, 2007, 2011 by the deal.II authors
+// Copyright (C) 1999, 2000, 2001, 2002, 2003, 2005, 2006, 2007, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
void ConvergenceTable::evaluate_convergence_rates(const std::string &data_column_key,
- const std::string &reference_column_key,
- const RateMode rate_mode)
+ const std::string &reference_column_key,
+ const RateMode rate_mode)
{
Assert(columns.count(data_column_key),
- ExcColumnNotExistent(data_column_key));
+ ExcColumnNotExistent(data_column_key));
Assert(columns.count(reference_column_key),
- ExcColumnNotExistent(reference_column_key));
+ ExcColumnNotExistent(reference_column_key));
if (rate_mode==none)
return;
- // reset the auto fill mode flag since we
- // are going to fill columns from the top
- // that don't yet exist
+ // reset the auto fill mode flag since we
+ // are going to fill columns from the top
+ // that don't yet exist
set_auto_fill_mode (false);
std::vector<internal::TableEntry> &entries=columns[data_column_key].entries;
switch (rate_mode)
{
case none:
- break;
+ break;
case reduction_rate:
- rate_key+="red.rate";
- Assert(columns.count(rate_key)==0, ExcRateColumnAlreadyExists(rate_key));
- // no value available for the
- // first row
- add_value(rate_key, std::string("-"));
- for (unsigned int i=1; i<n; ++i)
- add_value(rate_key, values[i-1]/values[i] *
- ref_values[i]/ref_values[i-1]);
- break;
+ rate_key+="red.rate";
+ Assert(columns.count(rate_key)==0, ExcRateColumnAlreadyExists(rate_key));
+ // no value available for the
+ // first row
+ add_value(rate_key, std::string("-"));
+ for (unsigned int i=1; i<n; ++i)
+ add_value(rate_key, values[i-1]/values[i] *
+ ref_values[i]/ref_values[i-1]);
+ break;
case reduction_rate_log2:
- rate_key+="red.rate";
- Assert(columns.count(rate_key)==0, ExcRateColumnAlreadyExists(rate_key));
- // no value available for the
- // first row
- add_value(rate_key, std::string("-"));
- for (unsigned int i=1; i<n; ++i)
- add_value(rate_key, 2*std::log(std::fabs(values[i-1]/values[i])) /
- std::log(std::fabs(ref_values[i]/ref_values[i-1])));
- break;
+ rate_key+="red.rate";
+ Assert(columns.count(rate_key)==0, ExcRateColumnAlreadyExists(rate_key));
+ // no value available for the
+ // first row
+ add_value(rate_key, std::string("-"));
+ for (unsigned int i=1; i<n; ++i)
+ add_value(rate_key, 2*std::log(std::fabs(values[i-1]/values[i])) /
+ std::log(std::fabs(ref_values[i]/ref_values[i-1])));
+ break;
default:
- Assert(false, ExcNotImplemented());
+ Assert(false, ExcNotImplemented());
}
Assert(columns.count(rate_key), ExcInternalError());
{
Assert(columns.count(data_column_key), ExcColumnNotExistent(data_column_key));
- // reset the auto fill mode flag since we
- // are going to fill columns from the top
- // that don't yet exist
+ // reset the auto fill mode flag since we
+ // are going to fill columns from the top
+ // that don't yet exist
set_auto_fill_mode (false);
std::vector<internal::TableEntry> &entries = columns[data_column_key].entries;
switch (rate_mode)
{
case none:
- break;
+ break;
case reduction_rate:
- rate_key+="red.rate";
- Assert(columns.count(rate_key)==0, ExcRateColumnAlreadyExists(rate_key));
- // no value available for the
- // first row
- add_value(rate_key, std::string("-"));
- for (unsigned int i=1; i<n; ++i)
- add_value(rate_key, values[i-1]/values[i]);
- break;
+ rate_key+="red.rate";
+ Assert(columns.count(rate_key)==0, ExcRateColumnAlreadyExists(rate_key));
+ // no value available for the
+ // first row
+ add_value(rate_key, std::string("-"));
+ for (unsigned int i=1; i<n; ++i)
+ add_value(rate_key, values[i-1]/values[i]);
+ break;
case reduction_rate_log2:
- rate_key+="red.rate.log2";
- Assert(columns.count(rate_key)==0, ExcRateColumnAlreadyExists(rate_key));
- // no value availble for the
- // first row
- add_value(rate_key, std::string("-"));
- for (unsigned int i=1; i<n; ++i)
- add_value(rate_key, std::log(std::fabs(values[i-1]/values[i]))/std::log(2.0));
- break;
+ rate_key+="red.rate.log2";
+ Assert(columns.count(rate_key)==0, ExcRateColumnAlreadyExists(rate_key));
+ // no value availble for the
+ // first row
+ add_value(rate_key, std::string("-"));
+ for (unsigned int i=1; i<n; ++i)
+ add_value(rate_key, std::log(std::fabs(values[i-1]/values[i]))/std::log(2.0));
+ break;
default:
- ExcNotImplemented();
+ ExcNotImplemented();
}
Assert(columns.count(rate_key), ExcInternalError());
columns[rate_key].flag=1;
set_precision(rate_key, 2);
- // set the superkey equal to the key
+ // set the superkey equal to the key
std::string superkey=data_column_key;
- // and set the tex caption of the supercolumn
- // to the tex caption of the data_column.
+ // and set the tex caption of the supercolumn
+ // to the tex caption of the data_column.
if (!supercolumns.count(superkey))
{
add_column_to_supercolumn(data_column_key, superkey);
// $Id$
// Version: $Name$
//
-// Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 by the deal.II authors
+// Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
namespace
{
DeclException2 (ExcUnexpectedInput,
- std::string, std::string,
- << "Unexpected input: expected line\n <"
- << arg1
- << ">\nbut got\n <"
- << arg2 << ">");
+ std::string, std::string,
+ << "Unexpected input: expected line\n <"
+ << arg1
+ << ">\nbut got\n <"
+ << arg2 << ">");
}
namespace
{
- // the functions in this namespace are
- // taken from the libb64 project, see
- // http://sourceforge.net/projects/libb64
- //
- // libb64 has been placed in the public
- // domain
+ // the functions in this namespace are
+ // taken from the libb64 project, see
+ // http://sourceforge.net/projects/libb64
+ //
+ // libb64 has been placed in the public
+ // domain
namespace base64
{
typedef enum
{
- step_A, step_B, step_C
+ step_A, step_B, step_C
} base64_encodestep;
typedef struct
{
- base64_encodestep step;
- char result;
+ base64_encodestep step;
+ char result;
} base64_encodestate;
void base64_init_encodestate(base64_encodestate* state_in)
char base64_encode_value(char value_in)
{
static const char* encoding
- = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+ = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
if (value_in > 63) return '=';
return encoding[(int)value_in];
}
int base64_encode_block(const char* plaintext_in,
- int length_in,
- char* code_out,
- base64_encodestate *state_in)
+ int length_in,
+ char* code_out,
+ base64_encodestate *state_in)
{
const char* plainchar = plaintext_in;
const char* const plaintextend = plaintext_in + length_in;
result = state_in->result;
switch (state_in->step)
- {
- while (1)
- {
- case step_A:
- if (plainchar == plaintextend)
- {
- state_in->result = result;
- state_in->step = step_A;
- return codechar - code_out;
- }
- fragment = *plainchar++;
- result = (fragment & 0x0fc) >> 2;
- *codechar++ = base64_encode_value(result);
- result = (fragment & 0x003) << 4;
- case step_B:
- if (plainchar == plaintextend)
- {
- state_in->result = result;
- state_in->step = step_B;
- return codechar - code_out;
- }
- fragment = *plainchar++;
- result |= (fragment & 0x0f0) >> 4;
- *codechar++ = base64_encode_value(result);
- result = (fragment & 0x00f) << 2;
- case step_C:
- if (plainchar == plaintextend)
- {
- state_in->result = result;
- state_in->step = step_C;
- return codechar - code_out;
- }
- fragment = *plainchar++;
- result |= (fragment & 0x0c0) >> 6;
- *codechar++ = base64_encode_value(result);
- result = (fragment & 0x03f) >> 0;
- *codechar++ = base64_encode_value(result);
- }
- }
- /* control should not reach here */
+ {
+ while (1)
+ {
+ case step_A:
+ if (plainchar == plaintextend)
+ {
+ state_in->result = result;
+ state_in->step = step_A;
+ return codechar - code_out;
+ }
+ fragment = *plainchar++;
+ result = (fragment & 0x0fc) >> 2;
+ *codechar++ = base64_encode_value(result);
+ result = (fragment & 0x003) << 4;
+ case step_B:
+ if (plainchar == plaintextend)
+ {
+ state_in->result = result;
+ state_in->step = step_B;
+ return codechar - code_out;
+ }
+ fragment = *plainchar++;
+ result |= (fragment & 0x0f0) >> 4;
+ *codechar++ = base64_encode_value(result);
+ result = (fragment & 0x00f) << 2;
+ case step_C:
+ if (plainchar == plaintextend)
+ {
+ state_in->result = result;
+ state_in->step = step_C;
+ return codechar - code_out;
+ }
+ fragment = *plainchar++;
+ result |= (fragment & 0x0c0) >> 6;
+ *codechar++ = base64_encode_value(result);
+ result = (fragment & 0x03f) >> 0;
+ *codechar++ = base64_encode_value(result);
+ }
+ }
+ /* control should not reach here */
return codechar - code_out;
}
char* codechar = code_out;
switch (state_in->step)
- {
- case step_B:
- *codechar++ = base64_encode_value(state_in->result);
- *codechar++ = '=';
- *codechar++ = '=';
- break;
- case step_C:
- *codechar++ = base64_encode_value(state_in->result);
- *codechar++ = '=';
- break;
- case step_A:
- break;
- }
+ {
+ case step_B:
+ *codechar++ = base64_encode_value(state_in->result);
+ *codechar++ = '=';
+ *codechar++ = '=';
+ break;
+ case step_C:
+ *codechar++ = base64_encode_value(state_in->result);
+ *codechar++ = '=';
+ break;
+ case step_A:
+ break;
+ }
*codechar++ = '\0';
return codechar - code_out;
}
- /**
- * Do a base64 encoding of the given data.
- *
- * The function allocates memory as
- * necessary and returns a pointer to
- * it. The calling function must release
- * this memory again.
- */
+ /**
+ * Do a base64 encoding of the given data.
+ *
+ * The function allocates memory as
+ * necessary and returns a pointer to
+ * it. The calling function must release
+ * this memory again.
+ */
char *
encode_block (const char *data,
- const int data_size)
+ const int data_size)
{
base64::base64_encodestate state;
base64::base64_init_encodestate(&state);
const int encoded_length_data
= base64::base64_encode_block (data, data_size,
- encoded_data, &state);
+ encoded_data, &state);
base64::base64_encode_blockend (encoded_data + encoded_length_data,
- &state);
+ &state);
return encoded_data;
}
#ifdef HAVE_LIBZ
- /**
- * Do a zlib compression followed
- * by a base64 encoding of the
- * given data. The result is then
- * written to the given stream.
- */
+ /**
+ * Do a zlib compression followed
+ * by a base64 encoding of the
+ * given data. The result is then
+ * written to the given stream.
+ */
template <typename T>
void write_compressed_block (const std::vector<T> &data,
- std::ostream &output_stream)
+ std::ostream &output_stream)
{
if (data.size() != 0)
{
- // allocate a buffer for compressing
- // data and do so
- uLongf compressed_data_length
- = compressBound (data.size() * sizeof(T));
- char *compressed_data = new char[compressed_data_length];
- int err = compress2 ((Bytef *) compressed_data,
- &compressed_data_length,
- (const Bytef *) &data[0],
- data.size() * sizeof(T),
- Z_BEST_COMPRESSION);
- Assert (err == Z_OK, ExcInternalError());
-
- // now encode the compression header
- const uint32_t compression_header[4]
- = { 1, /* number of blocks */
- (uint32_t)(data.size() * sizeof(T)), /* size of block */
- (uint32_t)(data.size() * sizeof(T)), /* size of last block */
- (uint32_t)compressed_data_length }; /* list of compressed sizes of blocks */
-
- char *encoded_header = encode_block ((char*)&compression_header[0],
- 4 * sizeof(compression_header[0]));
- output_stream << encoded_header;
- delete[] encoded_header;
-
- // next do the compressed
- // data encoding in base64
- char *encoded_data = encode_block (compressed_data,
- compressed_data_length);
- delete[] compressed_data;
-
- output_stream << encoded_data;
- delete[] encoded_data;
+ // allocate a buffer for compressing
+ // data and do so
+ uLongf compressed_data_length
+ = compressBound (data.size() * sizeof(T));
+ char *compressed_data = new char[compressed_data_length];
+ int err = compress2 ((Bytef *) compressed_data,
+ &compressed_data_length,
+ (const Bytef *) &data[0],
+ data.size() * sizeof(T),
+ Z_BEST_COMPRESSION);
+ Assert (err == Z_OK, ExcInternalError());
+
+ // now encode the compression header
+ const uint32_t compression_header[4]
+ = { 1, /* number of blocks */
+ (uint32_t)(data.size() * sizeof(T)), /* size of block */
+ (uint32_t)(data.size() * sizeof(T)), /* size of last block */
+ (uint32_t)compressed_data_length }; /* list of compressed sizes of blocks */
+
+ char *encoded_header = encode_block ((char*)&compression_header[0],
+ 4 * sizeof(compression_header[0]));
+ output_stream << encoded_header;
+ delete[] encoded_header;
+
+ // next do the compressed
+ // data encoding in base64
+ char *encoded_data = encode_block (compressed_data,
+ compressed_data_length);
+ delete[] compressed_data;
+
+ output_stream << encoded_data;
+ delete[] encoded_data;
}
}
#endif
static const char* gmv_cell_type[4] =
{
- "", "line 2", "quad 4", "hex 8"
+ "", "line 2", "quad 4", "hex 8"
};
static const char* ucd_cell_type[4] =
{
- "", "line", "quad", "hex"
+ "", "line", "quad", "hex"
};
static const char* tecplot_cell_type[4] =
{
- "", "lineseg", "quadrilateral", "brick"
+ "", "lineseg", "quadrilateral", "brick"
};
#ifdef DEAL_II_HAVE_TECPLOT
static unsigned int tecplot_binary_cell_type[4] =
{
- 0, 0, 1, 3
+ 0, 0, 1, 3
};
#endif
static unsigned int vtk_cell_type[4] =
{
- 0, 3, 9, 12
+ 0, 3, 9, 12
};
//----------------------------------------------------------------------//
{
if (patch->points_are_available)
{
- unsigned int point_no=0;
- // note: switch without break !
- switch (dim)
- {
- case 3:
- Assert (zstep<n_subdivisions+1, ExcIndexRange(zstep,0,n_subdivisions+1));
- point_no+=(n_subdivisions+1)*(n_subdivisions+1)*zstep;
- case 2:
- Assert (ystep<n_subdivisions+1, ExcIndexRange(ystep,0,n_subdivisions+1));
- point_no+=(n_subdivisions+1)*ystep;
- case 1:
- Assert (xstep<n_subdivisions+1, ExcIndexRange(xstep,0,n_subdivisions+1));
- point_no+=xstep;
-
- // break here for dim<=3
- break;
-
- default:
- Assert (false, ExcNotImplemented());
- }
- for (unsigned int d=0; d<spacedim; ++d)
- node[d]=patch->data(patch->data.size(0)-spacedim+d,point_no);
+ unsigned int point_no=0;
+ // note: switch without break !
+ switch (dim)
+ {
+ case 3:
+ Assert (zstep<n_subdivisions+1, ExcIndexRange(zstep,0,n_subdivisions+1));
+ point_no+=(n_subdivisions+1)*(n_subdivisions+1)*zstep;
+ case 2:
+ Assert (ystep<n_subdivisions+1, ExcIndexRange(ystep,0,n_subdivisions+1));
+ point_no+=(n_subdivisions+1)*ystep;
+ case 1:
+ Assert (xstep<n_subdivisions+1, ExcIndexRange(xstep,0,n_subdivisions+1));
+ point_no+=xstep;
+
+ // break here for dim<=3
+ break;
+
+ default:
+ Assert (false, ExcNotImplemented());
+ }
+ for (unsigned int d=0; d<spacedim; ++d)
+ node[d]=patch->data(patch->data.size(0)-spacedim+d,point_no);
}
else
{
- // perform a dim-linear interpolation
- const double stepsize=1./n_subdivisions,
- xfrac=xstep*stepsize;
-
- node = (patch->vertices[1] * xfrac) + (patch->vertices[0] * (1-xfrac));
- if (dim>1)
- {
- const double yfrac=ystep*stepsize;
- node*= 1-yfrac;
- node += ((patch->vertices[3] * xfrac) + (patch->vertices[2] * (1-xfrac))) * yfrac;
- if (dim>2)
- {
- const double zfrac=zstep*stepsize;
- node *= (1-zfrac);
- node += (((patch->vertices[5] * xfrac) + (patch->vertices[4] * (1-xfrac)))
- * (1-yfrac) +
- ((patch->vertices[7] * xfrac) + (patch->vertices[6] * (1-xfrac)))
- * yfrac) * zfrac;
- }
- }
+ // perform a dim-linear interpolation
+ const double stepsize=1./n_subdivisions,
+ xfrac=xstep*stepsize;
+
+ node = (patch->vertices[1] * xfrac) + (patch->vertices[0] * (1-xfrac));
+ if (dim>1)
+ {
+ const double yfrac=ystep*stepsize;
+ node*= 1-yfrac;
+ node += ((patch->vertices[3] * xfrac) + (patch->vertices[2] * (1-xfrac))) * yfrac;
+ if (dim>2)
+ {
+ const double zfrac=zstep*stepsize;
+ node *= (1-zfrac);
+ node += (((patch->vertices[5] * xfrac) + (patch->vertices[4] * (1-xfrac)))
+ * (1-yfrac) +
+ ((patch->vertices[7] * xfrac) + (patch->vertices[6] * (1-xfrac)))
+ * yfrac) * zfrac;
+ }
+ }
}
}
static
void
compute_sizes(const std::vector<DataOutBase::Patch<dim, spacedim> >& patches,
- unsigned int& n_nodes,
- unsigned int& n_cells)
+ unsigned int& n_nodes,
+ unsigned int& n_cells)
{
n_nodes = 0;
n_cells = 0;
for (typename std::vector<DataOutBase::Patch<dim,spacedim> >::const_iterator patch=patches.begin();
- patch!=patches.end(); ++patch)
+ patch!=patches.end(); ++patch)
{
- n_nodes += Utilities::fixed_power<dim>(patch->n_subdivisions+1);
- n_cells += Utilities::fixed_power<dim>(patch->n_subdivisions);
+ n_nodes += Utilities::fixed_power<dim>(patch->n_subdivisions+1);
+ n_cells += Utilities::fixed_power<dim>(patch->n_subdivisions);
}
}
- /**
- * Class for writing basic
- * entities in @ref
- * SoftwareOpenDX format,
- * depending on the flags.
- */
+ /**
+ * Class for writing basic
+ * entities in @ref
+ * SoftwareOpenDX format,
+ * depending on the flags.
+ */
class DXStream
{
public:
- /**
- * Constructor, storing
- * persistent values for
- * later use.
- */
+ /**
+ * Constructor, storing
+ * persistent values for
+ * later use.
+ */
DXStream (std::ostream& stream,
- const DataOutBase::DXFlags flags);
+ const DataOutBase::DXFlags flags);
- /**
- * Output operator for points.
- */
+ /**
+ * Output operator for points.
+ */
template <int dim>
void write_point (const unsigned int index,
- const Point<dim>&);
+ const Point<dim>&);
- /**
- * Do whatever is necessary to
- * terminate the list of points.
- */
+ /**
+ * Do whatever is necessary to
+ * terminate the list of points.
+ */
void flush_points ();
- /**
- * Write dim-dimensional cell
- * with first vertex at
- * number start and further
- * vertices offset by the
- * specified values. Values
- * not needed are ignored.
- *
- * The order of vertices for
- * these cells in different
- * dimensions is
- * <ol>
- * <li> [0,1]
- * <li> [0,2,1,3]
- * <li> [0,4,2,6,1,5,3,7]
- * </ol>
- */
+ /**
+ * Write dim-dimensional cell
+ * with first vertex at
+ * number start and further
+ * vertices offset by the
+ * specified values. Values
+ * not needed are ignored.
+ *
+ * The order of vertices for
+ * these cells in different
+ * dimensions is
+ * <ol>
+ * <li> [0,1]
+ * <li> [0,2,1,3]
+ * <li> [0,4,2,6,1,5,3,7]
+ * </ol>
+ */
template <int dim>
void write_cell (const unsigned int index,
- const unsigned int start,
- const unsigned int x_offset,
- const unsigned int y_offset,
- const unsigned int z_offset);
-
- /**
- * Do whatever is necessary to
- * terminate the list of cells.
- */
+ const unsigned int start,
+ const unsigned int x_offset,
+ const unsigned int y_offset,
+ const unsigned int z_offset);
+
+ /**
+ * Do whatever is necessary to
+ * terminate the list of cells.
+ */
void flush_cells ();
- /**
- * Write a complete set of
- * data for a single node.
- *
- * The index given as first
- * argument indicates the
- * number of a data set, as
- * some output formats require
- * this number to be printed.
- */
+ /**
+ * Write a complete set of
+ * data for a single node.
+ *
+ * The index given as first
+ * argument indicates the
+ * number of a data set, as
+ * some output formats require
+ * this number to be printed.
+ */
template<typename data>
void write_dataset (const unsigned int index,
- const std::vector<data>& values);
+ const std::vector<data>& values);
- /**
- * Forwarding of output stream
- */
+ /**
+ * Forwarding of output stream
+ */
template <typename T>
std::ostream& operator<< (const T&);
private:
- /**
- * The ostream to use. Since
- * the life span of these
- * objects is small, we use a
- * very simple storage
- * technique.
- */
+ /**
+ * The ostream to use. Since
+ * the life span of these
+ * objects is small, we use a
+ * very simple storage
+ * technique.
+ */
std::ostream& stream;
- /**
- * The flags controlling the output
- */
+ /**
+ * The flags controlling the output
+ */
const DataOutBase::DXFlags flags;
};
- /**
- * Class for writing basic
- * entities in @ref SoftwareGMV
- * format, depending on the
- * flags.
- */
+ /**
+ * Class for writing basic
+ * entities in @ref SoftwareGMV
+ * format, depending on the
+ * flags.
+ */
class GmvStream
{
public:
- /**
- * Constructor, storing
- * persistent values for
- * later use.
- */
+ /**
+ * Constructor, storing
+ * persistent values for
+ * later use.
+ */
GmvStream (std::ostream& stream,
- const DataOutBase::GmvFlags flags);
+ const DataOutBase::GmvFlags flags);
- /**
- * Output operator for points.
- */
+ /**
+ * Output operator for points.
+ */
template <int dim>
void write_point (const unsigned int index,
- const Point<dim>&);
+ const Point<dim>&);
- /**
- * Do whatever is necessary to
- * terminate the list of points.
- */
+ /**
+ * Do whatever is necessary to
+ * terminate the list of points.
+ */
void flush_points ();
- /**
- * Write dim-dimensional cell
- * with first vertex at
- * number start and further
- * vertices offset by the
- * specified values. Values
- * not needed are ignored.
- *
- * The order of vertices for
- * these cells in different
- * dimensions is
- * <ol>
- * <li> [0,1]
- * <li> [0,1,3,2]
- * <li> [0,1,3,2,4,5,7,6]
- * </ol>
- */
+ /**
+ * Write dim-dimensional cell
+ * with first vertex at
+ * number start and further
+ * vertices offset by the
+ * specified values. Values
+ * not needed are ignored.
+ *
+ * The order of vertices for
+ * these cells in different
+ * dimensions is
+ * <ol>
+ * <li> [0,1]
+ * <li> [0,1,3,2]
+ * <li> [0,1,3,2,4,5,7,6]
+ * </ol>
+ */
template <int dim>
void write_cell(const unsigned int index,
- const unsigned int start,
- const unsigned int x_offset,
- const unsigned int y_offset,
- const unsigned int z_offset);
-
- /**
- * Do whatever is necessary to
- * terminate the list of cells.
- */
+ const unsigned int start,
+ const unsigned int x_offset,
+ const unsigned int y_offset,
+ const unsigned int z_offset);
+
+ /**
+ * Do whatever is necessary to
+ * terminate the list of cells.
+ */
void flush_cells ();
- /**
- * Forwarding of output stream
- */
+ /**
+ * Forwarding of output stream
+ */
template <typename T>
std::ostream& operator<< (const T&);
- /**
- * Since GMV reads the x, y
- * and z coordinates in
- * separate fields, we enable
- * write() to output only a
- * single selected component
- * at once and do this dim
- * times for the whole set of
- * nodes. This integer can be
- * used to select the
- * component written.
- */
+ /**
+ * Since GMV reads the x, y
+ * and z coordinates in
+ * separate fields, we enable
+ * write() to output only a
+ * single selected component
+ * at once and do this dim
+ * times for the whole set of
+ * nodes. This integer can be
+ * used to select the
+ * component written.
+ */
unsigned int selected_component;
private:
- /**
- * The ostream to use. Since
- * the life span of these
- * objects is small, we use a
- * very simple storage
- * technique.
- */
+ /**
+ * The ostream to use. Since
+ * the life span of these
+ * objects is small, we use a
+ * very simple storage
+ * technique.
+ */
std::ostream& stream;
- /**
- * The flags controlling the output
- */
+ /**
+ * The flags controlling the output
+ */
const DataOutBase::GmvFlags flags;
};
- /**
- * Class for writing basic
- * entities in @ref
- * SoftwareTecplot format,
- * depending on the flags.
- */
+ /**
+ * Class for writing basic
+ * entities in @ref
+ * SoftwareTecplot format,
+ * depending on the flags.
+ */
class TecplotStream
{
public:
- /**
- * Constructor, storing
- * persistent values for
- * later use.
- */
+ /**
+ * Constructor, storing
+ * persistent values for
+ * later use.
+ */
TecplotStream (std::ostream& stream, const DataOutBase::TecplotFlags flags);
- /**
- * Output operator for points.
- */
+ /**
+ * Output operator for points.
+ */
template <int dim>
void write_point (const unsigned int index,
- const Point<dim>&);
+ const Point<dim>&);
- /**
- * Do whatever is necessary to
- * terminate the list of points.
- */
+ /**
+ * Do whatever is necessary to
+ * terminate the list of points.
+ */
void flush_points ();
- /**
- * Write dim-dimensional cell
- * with first vertex at
- * number start and further
- * vertices offset by the
- * specified values. Values
- * not needed are ignored.
- *
- * The order of vertices for
- * these cells in different
- * dimensions is
- * <ol>
- * <li> [0,1]
- * <li> [0,1,3,2]
- * <li> [0,1,3,2,4,5,7,6]
- * </ol>
- */
+ /**
+ * Write dim-dimensional cell
+ * with first vertex at
+ * number start and further
+ * vertices offset by the
+ * specified values. Values
+ * not needed are ignored.
+ *
+ * The order of vertices for
+ * these cells in different
+ * dimensions is
+ * <ol>
+ * <li> [0,1]
+ * <li> [0,1,3,2]
+ * <li> [0,1,3,2,4,5,7,6]
+ * </ol>
+ */
template <int dim>
void write_cell(const unsigned int index,
- const unsigned int start,
- const unsigned int x_offset,
- const unsigned int y_offset,
- const unsigned int z_offset);
-
- /**
- * Do whatever is necessary to
- * terminate the list of cells.
- */
+ const unsigned int start,
+ const unsigned int x_offset,
+ const unsigned int y_offset,
+ const unsigned int z_offset);
+
+ /**
+ * Do whatever is necessary to
+ * terminate the list of cells.
+ */
void flush_cells ();
- /**
- * Forwarding of output stream
- */
+ /**
+ * Forwarding of output stream
+ */
template <typename T>
std::ostream& operator<< (const T&);
- /**
- * Since TECPLOT reads the x, y
- * and z coordinates in
- * separate fields, we enable
- * write() to output only a
- * single selected component
- * at once and do this dim
- * times for the whole set of
- * nodes. This integer can be
- * used to select the
- * component written.
- */
+ /**
+ * Since TECPLOT reads the x, y
+ * and z coordinates in
+ * separate fields, we enable
+ * write() to output only a
+ * single selected component
+ * at once and do this dim
+ * times for the whole set of
+ * nodes. This integer can be
+ * used to select the
+ * component written.
+ */
unsigned int selected_component;
private:
- /**
- * The ostream to use. Since
- * the life span of these
- * objects is small, we use a
- * very simple storage
- * technique.
- */
+ /**
+ * The ostream to use. Since
+ * the life span of these
+ * objects is small, we use a
+ * very simple storage
+ * technique.
+ */
std::ostream& stream;
- /**
- * The flags controlling the output
- */
+ /**
+ * The flags controlling the output
+ */
const DataOutBase::TecplotFlags flags;
};
- /**
- * Class for writing basic
- * entities in UCD format for
- * @ref SoftwareAVS, depending on
- * the flags.
- */
+ /**
+ * Class for writing basic
+ * entities in UCD format for
+ * @ref SoftwareAVS, depending on
+ * the flags.
+ */
class UcdStream
{
public:
- /**
- * Constructor, storing
- * persistent values for
- * later use.
- */
+ /**
+ * Constructor, storing
+ * persistent values for
+ * later use.
+ */
UcdStream (std::ostream& stream,
- const DataOutBase::UcdFlags flags);
+ const DataOutBase::UcdFlags flags);
- /**
- * Output operator for points.
- */
+ /**
+ * Output operator for points.
+ */
template <int dim>
void write_point (const unsigned int index,
- const Point<dim>&);
+ const Point<dim>&);
- /**
- * Do whatever is necessary to
- * terminate the list of points.
- */
+ /**
+ * Do whatever is necessary to
+ * terminate the list of points.
+ */
void flush_points ();
- /**
- * Write dim-dimensional cell
- * with first vertex at
- * number start and further
- * vertices offset by the
- * specified values. Values
- * not needed are ignored.
- *
- * The additional offset 1 is
- * added inside this
- * function.
- *
- * The order of vertices for
- * these cells in different
- * dimensions is
- * <ol>
- * <li> [0,1]
- * <li> [0,1,3,2]
- * <li> [0,1,5,4,2,3,7,6]
- * </ol>
- */
+ /**
+ * Write dim-dimensional cell
+ * with first vertex at
+ * number start and further
+ * vertices offset by the
+ * specified values. Values
+ * not needed are ignored.
+ *
+ * The additional offset 1 is
+ * added inside this
+ * function.
+ *
+ * The order of vertices for
+ * these cells in different
+ * dimensions is
+ * <ol>
+ * <li> [0,1]
+ * <li> [0,1,3,2]
+ * <li> [0,1,5,4,2,3,7,6]
+ * </ol>
+ */
template <int dim>
void write_cell(const unsigned int index,
- const unsigned int start,
- const unsigned int x_offset,
- const unsigned int y_offset,
- const unsigned int z_offset);
-
- /**
- * Do whatever is necessary to
- * terminate the list of cells.
- */
+ const unsigned int start,
+ const unsigned int x_offset,
+ const unsigned int y_offset,
+ const unsigned int z_offset);
+
+ /**
+ * Do whatever is necessary to
+ * terminate the list of cells.
+ */
void flush_cells ();
- /**
- * Write a complete set of
- * data for a single node.
- *
- * The index given as first
- * argument indicates the
- * number of a data set, as
- * some output formats require
- * this number to be printed.
- */
+ /**
+ * Write a complete set of
+ * data for a single node.
+ *
+ * The index given as first
+ * argument indicates the
+ * number of a data set, as
+ * some output formats require
+ * this number to be printed.
+ */
template<typename data>
void write_dataset (const unsigned int index,
- const std::vector<data> &values);
+ const std::vector<data> &values);
- /**
- * Forwarding of output stream
- */
+ /**
+ * Forwarding of output stream
+ */
template <typename T>
std::ostream& operator<< (const T&);
private:
- /**
- * The ostream to use. Since
- * the life span of these
- * objects is small, we use a
- * very simple storage
- * technique.
- */
+ /**
+ * The ostream to use. Since
+ * the life span of these
+ * objects is small, we use a
+ * very simple storage
+ * technique.
+ */
std::ostream& stream;
- /**
- * The flags controlling the output
- */
+ /**
+ * The flags controlling the output
+ */
const DataOutBase::UcdFlags flags;
};
- /**
- * Class for writing basic
- * entities in @ref SoftwareVTK
- * format, depending on the
- * flags.
- */
+ /**
+ * Class for writing basic
+ * entities in @ref SoftwareVTK
+ * format, depending on the
+ * flags.
+ */
class VtkStream
{
public:
- /**
- * Constructor, storing
- * persistent values for
- * later use.
- */
+ /**
+ * Constructor, storing
+ * persistent values for
+ * later use.
+ */
VtkStream (std::ostream& stream,
- const DataOutBase::VtkFlags flags);
+ const DataOutBase::VtkFlags flags);
- /**
- * Output operator for points.
- */
+ /**
+ * Output operator for points.
+ */
template <int dim>
void write_point (const unsigned int index,
- const Point<dim>&);
+ const Point<dim>&);
- /**
- * Do whatever is necessary to
- * terminate the list of points.
- */
+ /**
+ * Do whatever is necessary to
+ * terminate the list of points.
+ */
void flush_points ();
- /**
- * Write dim-dimensional cell
- * with first vertex at
- * number start and further
- * vertices offset by the
- * specified values. Values
- * not needed are ignored.
- *
- * The order of vertices for
- * these cells in different
- * dimensions is
- * <ol>
- * <li> [0,1]
- * <li> []
- * <li> []
- * </ol>
- */
+ /**
+ * Write dim-dimensional cell
+ * with first vertex at
+ * number start and further
+ * vertices offset by the
+ * specified values. Values
+ * not needed are ignored.
+ *
+ * The order of vertices for
+ * these cells in different
+ * dimensions is
+ * <ol>
+ * <li> [0,1]
+ * <li> []
+ * <li> []
+ * </ol>
+ */
template <int dim>
void write_cell(const unsigned int index,
- const unsigned int start,
- const unsigned int x_offset,
- const unsigned int y_offset,
- const unsigned int z_offset);
-
- /**
- * Do whatever is necessary to
- * terminate the list of cells.
- */
+ const unsigned int start,
+ const unsigned int x_offset,
+ const unsigned int y_offset,
+ const unsigned int z_offset);
+
+ /**
+ * Do whatever is necessary to
+ * terminate the list of cells.
+ */
void flush_cells ();
- /**
- * Forwarding of output stream
- */
+ /**
+ * Forwarding of output stream
+ */
template <typename T>
std::ostream& operator<< (const T&);
private:
- /**
- * The ostream to use. Since
- * the life span of these
- * objects is small, we use a
- * very simple storage
- * technique.
- */
+ /**
+ * The ostream to use. Since
+ * the life span of these
+ * objects is small, we use a
+ * very simple storage
+ * technique.
+ */
std::ostream& stream;
- /**
- * The flags controlling the output
- */
+ /**
+ * The flags controlling the output
+ */
const DataOutBase::VtkFlags flags;
};
class VtuStream
{
public:
- /**
- * Constructor, storing
- * persistent values for
- * later use.
- */
+ /**
+ * Constructor, storing
+ * persistent values for
+ * later use.
+ */
VtuStream (std::ostream& stream,
- const DataOutBase::VtkFlags flags);
+ const DataOutBase::VtkFlags flags);
- /**
- * Output operator for points.
- */
+ /**
+ * Output operator for points.
+ */
template <int dim>
void write_point (const unsigned int index,
- const Point<dim>&);
+ const Point<dim>&);
- /**
- * Do whatever is necessary to
- * terminate the list of points.
- */
+ /**
+ * Do whatever is necessary to
+ * terminate the list of points.
+ */
void flush_points ();
- /**
- * Write dim-dimensional cell
- * with first vertex at
- * number start and further
- * vertices offset by the
- * specified values. Values
- * not needed are ignored.
- *
- * The order of vertices for
- * these cells in different
- * dimensions is
- * <ol>
- * <li> [0,1]
- * <li> []
- * <li> []
- * </ol>
- */
+ /**
+ * Write dim-dimensional cell
+ * with first vertex at
+ * number start and further
+ * vertices offset by the
+ * specified values. Values
+ * not needed are ignored.
+ *
+ * The order of vertices for
+ * these cells in different
+ * dimensions is
+ * <ol>
+ * <li> [0,1]
+ * <li> []
+ * <li> []
+ * </ol>
+ */
template <int dim>
void write_cell(const unsigned int index,
- const unsigned int start,
- const unsigned int x_offset,
- const unsigned int y_offset,
- const unsigned int z_offset);
-
- /**
- * Do whatever is necessary to
- * terminate the list of cells.
- */
+ const unsigned int start,
+ const unsigned int x_offset,
+ const unsigned int y_offset,
+ const unsigned int z_offset);
+
+ /**
+ * Do whatever is necessary to
+ * terminate the list of cells.
+ */
void flush_cells ();
- /**
- * Forwarding of output stream
- */
+ /**
+ * Forwarding of output stream
+ */
template <typename T>
std::ostream& operator<< (const T&);
- /**
- * Forwarding of output stream.
- *
- * If libz was found during
- * configuration, this operator
- * compresses and encodes the
- * entire data
- * block. Otherwise, it simply
- * writes it element by
- * element.
- */
+ /**
+ * Forwarding of output stream.
+ *
+ * If libz was found during
+ * configuration, this operator
+ * compresses and encodes the
+ * entire data
+ * block. Otherwise, it simply
+ * writes it element by
+ * element.
+ */
template <typename T>
std::ostream& operator<< (const std::vector<T>&);
private:
- /**
- * The ostream to use. Since
- * the life span of these
- * objects is small, we use a
- * very simple storage
- * technique.
- */
+ /**
+ * The ostream to use. Since
+ * the life span of these
+ * objects is small, we use a
+ * very simple storage
+ * technique.
+ */
std::ostream& stream;
- /**
- * The flags controlling the output
- */
+ /**
+ * The flags controlling the output
+ */
const DataOutBase::VtkFlags flags;
- /**
- * A list of vertices and
- * cells, to be used in case we
- * want to compress the data.
- *
- * The data types of these
- * arrays needs to match what
- * we print in the XML-preamble
- * to the respective parts of
- * VTU files (e.g. Float64 and
- * Int32)
- */
+ /**
+ * A list of vertices and
+ * cells, to be used in case we
+ * want to compress the data.
+ *
+ * The data types of these
+ * arrays needs to match what
+ * we print in the XML-preamble
+ * to the respective parts of
+ * VTU files (e.g. Float64 and
+ * Int32)
+ */
std::vector<double> vertices;
std::vector<int32_t> cells;
};
//----------------------------------------------------------------------//
DXStream::DXStream(std::ostream& out,
- const DataOutBase::DXFlags f)
- :
- stream(out), flags(f)
+ const DataOutBase::DXFlags f)
+ :
+ stream(out), flags(f)
{}
template<int dim>
void
DXStream::write_point (const unsigned int,
- const Point<dim>& p)
+ const Point<dim>& p)
{
if (flags.coordinates_binary)
{
- float data[dim];
- for (unsigned int d=0; d<dim; ++d)
- data[d] = p(d);
- stream.write(reinterpret_cast<const char*>(data),
- dim * sizeof(*data));
+ float data[dim];
+ for (unsigned int d=0; d<dim; ++d)
+ data[d] = p(d);
+ stream.write(reinterpret_cast<const char*>(data),
+ dim * sizeof(*data));
}
else
{
- for (unsigned int d=0; d<dim; ++d)
- stream << p(d) << '\t';
- stream << '\n';
+ for (unsigned int d=0; d<dim; ++d)
+ stream << p(d) << '\t';
+ stream << '\n';
}
}
nodes[GeometryInfo<dim>::dx_to_deal[1]] = start+d1;
if (dim>=2)
{
- // Add shifted line in y direction
- nodes[GeometryInfo<dim>::dx_to_deal[2]] = start+d2;
- nodes[GeometryInfo<dim>::dx_to_deal[3]] = start+d2+d1;
- if (dim>=3)
- {
- // Add shifted quad in z direction
- nodes[GeometryInfo<dim>::dx_to_deal[4]] = start+d3;
- nodes[GeometryInfo<dim>::dx_to_deal[5]] = start+d3+d1;
- nodes[GeometryInfo<dim>::dx_to_deal[6]] = start+d3+d2;
- nodes[GeometryInfo<dim>::dx_to_deal[7]] = start+d3+d2+d1;
- }
+ // Add shifted line in y direction
+ nodes[GeometryInfo<dim>::dx_to_deal[2]] = start+d2;
+ nodes[GeometryInfo<dim>::dx_to_deal[3]] = start+d2+d1;
+ if (dim>=3)
+ {
+ // Add shifted quad in z direction
+ nodes[GeometryInfo<dim>::dx_to_deal[4]] = start+d3;
+ nodes[GeometryInfo<dim>::dx_to_deal[5]] = start+d3+d1;
+ nodes[GeometryInfo<dim>::dx_to_deal[6]] = start+d3+d2;
+ nodes[GeometryInfo<dim>::dx_to_deal[7]] = start+d3+d2+d1;
+ }
}
if (flags.int_binary)
stream.write(reinterpret_cast<const char*>(nodes),
- (1<<dim) * sizeof(*nodes));
+ (1<<dim) * sizeof(*nodes));
else
{
- const unsigned int final = (1<<dim) - 1;
- for (unsigned int i=0;i<final ;++i)
- stream << nodes[i] << '\t';
- stream << nodes[final] << '\n';
+ const unsigned int final = (1<<dim) - 1;
+ for (unsigned int i=0;i<final ;++i)
+ stream << nodes[i] << '\t';
+ stream << nodes[final] << '\n';
}
}
inline
void
DXStream::write_dataset(const unsigned int /*index*/,
- const std::vector<data> &values)
+ const std::vector<data> &values)
{
if (flags.data_binary)
{
- stream.write(reinterpret_cast<const char*>(&values[0]),
- values.size()*sizeof(data));
+ stream.write(reinterpret_cast<const char*>(&values[0]),
+ values.size()*sizeof(data));
}
else
{
- for (unsigned int i=0;i<values.size();++i)
- stream << '\t' << values[i];
- stream << '\n';
+ for (unsigned int i=0;i<values.size();++i)
+ stream << '\t' << values[i];
+ stream << '\n';
}
}
//----------------------------------------------------------------------//
GmvStream::GmvStream (std::ostream& out,
- const DataOutBase::GmvFlags f)
- :
- selected_component(numbers::invalid_unsigned_int),
- stream(out), flags(f)
+ const DataOutBase::GmvFlags f)
+ :
+ selected_component(numbers::invalid_unsigned_int),
+ stream(out), flags(f)
{}
template<int dim>
void
GmvStream::write_point (const unsigned int,
- const Point<dim>& p)
+ const Point<dim>& p)
{
Assert(selected_component != numbers::invalid_unsigned_int,
- ExcNotInitialized());
+ ExcNotInitialized());
stream << p(selected_component) << ' ';
}
unsigned int d2,
unsigned int d3)
{
- // Vertices are numbered starting
- // with one.
+ // Vertices are numbered starting
+ // with one.
const unsigned int start=s+1;
stream << gmv_cell_type[dim] << '\n';
stream << start << '\t'
- << start+d1;
+ << start+d1;
if (dim>=2)
{
- stream << '\t' << start+d2+d1
- << '\t' << start+d2;
- if (dim>=3)
- {
- stream << '\t' << start+d3
- << '\t' << start+d3+d1
- << '\t' << start+d3+d2+d1
- << '\t' << start+d3+d2;
- }
+ stream << '\t' << start+d2+d1
+ << '\t' << start+d2;
+ if (dim>=3)
+ {
+ stream << '\t' << start+d3
+ << '\t' << start+d3+d1
+ << '\t' << start+d3+d2+d1
+ << '\t' << start+d3+d2;
+ }
}
stream << '\n';
}
//----------------------------------------------------------------------//
TecplotStream::TecplotStream(std::ostream& out, const DataOutBase::TecplotFlags f)
- :
- selected_component(numbers::invalid_unsigned_int),
- stream(out), flags(f)
+ :
+ selected_component(numbers::invalid_unsigned_int),
+ stream(out), flags(f)
{}
template<int dim>
void
TecplotStream::write_point (const unsigned int,
- const Point<dim>& p)
+ const Point<dim>& p)
{
Assert(selected_component != numbers::invalid_unsigned_int,
- ExcNotInitialized());
+ ExcNotInitialized());
stream << p(selected_component) << '\n';
}
const unsigned int start = s+1;
stream << start << '\t'
- << start+d1;
+ << start+d1;
if (dim>=2)
{
- stream << '\t' << start+d2+d1
- << '\t' << start+d2;
- if (dim>=3)
- {
- stream << '\t' << start+d3
- << '\t' << start+d3+d1
- << '\t' << start+d3+d2+d1
- << '\t' << start+d3+d2;
- }
+ stream << '\t' << start+d2+d1
+ << '\t' << start+d2;
+ if (dim>=3)
+ {
+ stream << '\t' << start+d3
+ << '\t' << start+d3+d1
+ << '\t' << start+d3+d2+d1
+ << '\t' << start+d3+d2;
+ }
}
stream << '\n';
}
//----------------------------------------------------------------------//
UcdStream::UcdStream(std::ostream& out, const DataOutBase::UcdFlags f)
- :
- stream(out), flags(f)
+ :
+ stream(out), flags(f)
{}
template<int dim>
void
UcdStream::write_point (const unsigned int index,
- const Point<dim>& p)
+ const Point<dim>& p)
{
stream << index+1
- << " ";
- // write out coordinates
+ << " ";
+ // write out coordinates
for (unsigned int i=0; i<dim; ++i)
stream << p(i) << ' ';
- // fill with zeroes
+ // fill with zeroes
for (unsigned int i=dim; i<3; ++i)
stream << "0 ";
stream << '\n';
nodes[GeometryInfo<dim>::ucd_to_deal[1]] = start+d1;
if (dim>=2)
{
- // Add shifted line in y direction
- nodes[GeometryInfo<dim>::ucd_to_deal[2]] = start+d2;
- nodes[GeometryInfo<dim>::ucd_to_deal[3]] = start+d2+d1;
- if (dim>=3)
- {
- // Add shifted quad in z direction
- nodes[GeometryInfo<dim>::ucd_to_deal[4]] = start+d3;
- nodes[GeometryInfo<dim>::ucd_to_deal[5]] = start+d3+d1;
- nodes[GeometryInfo<dim>::ucd_to_deal[6]] = start+d3+d2;
- nodes[GeometryInfo<dim>::ucd_to_deal[7]] = start+d3+d2+d1;
- }
+ // Add shifted line in y direction
+ nodes[GeometryInfo<dim>::ucd_to_deal[2]] = start+d2;
+ nodes[GeometryInfo<dim>::ucd_to_deal[3]] = start+d2+d1;
+ if (dim>=3)
+ {
+ // Add shifted quad in z direction
+ nodes[GeometryInfo<dim>::ucd_to_deal[4]] = start+d3;
+ nodes[GeometryInfo<dim>::ucd_to_deal[5]] = start+d3+d1;
+ nodes[GeometryInfo<dim>::ucd_to_deal[6]] = start+d3+d2;
+ nodes[GeometryInfo<dim>::ucd_to_deal[7]] = start+d3+d2+d1;
+ }
}
- // Write out all cells and remember
- // that all indices must be shifted
- // by one.
+ // Write out all cells and remember
+ // that all indices must be shifted
+ // by one.
stream << index+1 << "\t0 " << ucd_cell_type[dim];
const unsigned int final = (1<<dim);
for (unsigned int i=0;i<final ;++i)
inline
void
UcdStream::write_dataset(const unsigned int index,
- const std::vector<data> &values)
+ const std::vector<data> &values)
{
stream << index+1;
for (unsigned int i=0;i<values.size();++i)
//----------------------------------------------------------------------//
VtkStream::VtkStream(std::ostream& out, const DataOutBase::VtkFlags f)
- :
- stream(out), flags(f)
+ :
+ stream(out), flags(f)
{}
template<int dim>
void
VtkStream::write_point (const unsigned int,
- const Point<dim>& p)
+ const Point<dim>& p)
{
- // write out coordinates
+ // write out coordinates
stream << p;
- // fill with zeroes
+ // fill with zeroes
for (unsigned int i=dim; i<3; ++i)
stream << " 0";
stream << '\n';
unsigned int d3)
{
stream << GeometryInfo<dim>::vertices_per_cell << '\t'
- << start << '\t'
- << start+d1;
+ << start << '\t'
+ << start+d1;
if (dim>=2)
{
- stream << '\t' << start+d2+d1
- << '\t' << start+d2;
- if (dim>=3)
- {
- stream << '\t' << start+d3
- << '\t' << start+d3+d1
- << '\t' << start+d3+d2+d1
- << '\t' << start+d3+d2;
- }
+ stream << '\t' << start+d2+d1
+ << '\t' << start+d2;
+ if (dim>=3)
+ {
+ stream << '\t' << start+d3
+ << '\t' << start+d3+d1
+ << '\t' << start+d3+d2+d1
+ << '\t' << start+d3+d2;
+ }
}
stream << '\n';
}
VtuStream::VtuStream(std::ostream& out, const DataOutBase::VtkFlags f)
- :
- stream(out), flags(f)
+ :
+ stream(out), flags(f)
{}
template<int dim>
void
VtuStream::write_point (const unsigned int,
- const Point<dim>& p)
+ const Point<dim>& p)
{
#if !defined(HAVE_LIBZ)
- // write out coordinates
+ // write out coordinates
stream << p;
- // fill with zeroes
+ // fill with zeroes
for (unsigned int i=dim; i<3; ++i)
stream << " 0";
stream << '\n';
#else
- // if we want to compress, then
- // first collect all the data in
- // an array
+ // if we want to compress, then
+ // first collect all the data in
+ // an array
for (unsigned int i=0; i<dim; ++i)
vertices.push_back(p[i]);
for (unsigned int i=dim; i<3; ++i)
VtuStream::flush_points ()
{
#ifdef HAVE_LIBZ
- // compress the data we have in
- // memory and write them to the
- // stream. then release the data
+ // compress the data we have in
+ // memory and write them to the
+ // stream. then release the data
*this << vertices << '\n';
vertices.clear ();
#endif
{
#if !defined(HAVE_LIBZ)
stream << start << '\t'
- << start+d1;
+ << start+d1;
if (dim>=2)
{
- stream << '\t' << start+d2+d1
- << '\t' << start+d2;
- if (dim>=3)
- {
- stream << '\t' << start+d3
- << '\t' << start+d3+d1
- << '\t' << start+d3+d2+d1
- << '\t' << start+d3+d2;
- }
+ stream << '\t' << start+d2+d1
+ << '\t' << start+d2;
+ if (dim>=3)
+ {
+ stream << '\t' << start+d3
+ << '\t' << start+d3+d1
+ << '\t' << start+d3+d2+d1
+ << '\t' << start+d3+d2;
+ }
}
stream << '\n';
#else
cells.push_back (start+d1);
if (dim>=2)
{
- cells.push_back (start+d2+d1);
- cells.push_back (start+d2);
- if (dim>=3)
- {
- cells.push_back (start+d3);
- cells.push_back (start+d3+d1);
- cells.push_back (start+d3+d2+d1);
- cells.push_back (start+d3+d2);
- }
+ cells.push_back (start+d2+d1);
+ cells.push_back (start+d2);
+ if (dim>=3)
+ {
+ cells.push_back (start+d3);
+ cells.push_back (start+d3+d1);
+ cells.push_back (start+d3+d2+d1);
+ cells.push_back (start+d3+d2);
+ }
}
#endif
}
VtuStream::flush_cells ()
{
#ifdef HAVE_LIBZ
- // compress the data we have in
- // memory and write them to the
- // stream. then release the data
+ // compress the data we have in
+ // memory and write them to the
+ // stream. then release the data
*this << cells << '\n';
cells.clear ();
#endif
VtuStream::operator<< (const std::vector<T> &data)
{
#ifdef HAVE_LIBZ
- // compress the data we have in
- // memory and write them to the
- // stream. then release the data
+ // compress the data we have in
+ // memory and write them to the
+ // stream. then release the data
write_compressed_block (data, stream);
#else
for (unsigned int i=0; i<data.size(); ++i)
template <int dim, int spacedim>
DataOutBase::Patch<dim,spacedim>::Patch ()
:
- patch_index(no_neighbor),
- n_subdivisions (1),
- points_are_available(false)
- // all the other data has a
- // constructor of its own, except
- // for the "neighbors" field, which
- // we set to invalid values.
+ patch_index(no_neighbor),
+ n_subdivisions (1),
+ points_are_available(false)
+ // all the other data has a
+ // constructor of its own, except
+ // for the "neighbors" field, which
+ // we set to invalid values.
{
for (unsigned int i=0;i<GeometryInfo<dim>::faces_per_cell;++i)
neighbors[i] = no_neighbor;
for (unsigned int i=0; i<data.n_rows(); ++i)
for (unsigned int j=0; j<data.n_cols(); ++j)
if (data[i][j] != patch.data[i][j])
- return false;
+ return false;
return true;
}
DataOutBase::Patch<dim,spacedim>::memory_consumption () const
{
return (sizeof(vertices) / sizeof(vertices[0]) *
- MemoryConsumption::memory_consumption(vertices[0])
- +
- MemoryConsumption::memory_consumption(n_subdivisions)
- +
- MemoryConsumption::memory_consumption(data)
- +
- MemoryConsumption::memory_consumption(points_are_available));
+ MemoryConsumption::memory_consumption(vertices[0])
+ +
+ MemoryConsumption::memory_consumption(n_subdivisions)
+ +
+ MemoryConsumption::memory_consumption(data)
+ +
+ MemoryConsumption::memory_consumption(points_are_available));
}
DataOutBase::UcdFlags::UcdFlags (const bool write_preamble)
:
- write_preamble (write_preamble)
+ write_preamble (write_preamble)
{}
DataOutBase::PovrayFlags::PovrayFlags (const bool smooth,
- const bool bicubic_patch,
- const bool external_data)
+ const bool bicubic_patch,
+ const bool external_data)
:
- smooth (smooth),
- bicubic_patch(bicubic_patch),
- external_data(external_data)
+ smooth (smooth),
+ bicubic_patch(bicubic_patch),
+ external_data(external_data)
{}
DataOutBase::DXFlags::DXFlags (const bool write_neighbors,
- const bool int_binary,
- const bool coordinates_binary,
- const bool data_binary)
+ const bool int_binary,
+ const bool coordinates_binary,
+ const bool data_binary)
:
- write_neighbors(write_neighbors),
- int_binary(int_binary),
- coordinates_binary(coordinates_binary),
- data_binary(data_binary),
- data_double(false)
+ write_neighbors(write_neighbors),
+ int_binary(int_binary),
+ coordinates_binary(coordinates_binary),
+ data_binary(data_binary),
+ data_double(false)
{}
prm.declare_entry ("Integer format", "ascii",
Patterns::Selection("ascii|32|64"),
"Output format of integer numbers, which is "
- "either a text representation (ascii) or binary integer "
- "values of 32 or 64 bits length");
+ "either a text representation (ascii) or binary integer "
+ "values of 32 or 64 bits length");
prm.declare_entry ("Coordinates format", "ascii",
Patterns::Selection("ascii|32|64"),
"Output format of vertex coordinates, which is "
- "either a text representation (ascii) or binary "
- "floating point values of 32 or 64 bits length");
+ "either a text representation (ascii) or binary "
+ "floating point values of 32 or 64 bits length");
prm.declare_entry ("Data format", "ascii",
Patterns::Selection("ascii|32|64"),
"Output format of data values, which is "
- "either a text representation (ascii) or binary "
- "floating point values of 32 or 64 bits length");
+ "either a text representation (ascii) or binary "
+ "floating point values of 32 or 64 bits length");
}
std::size_t
DataOutBase::DXFlags::memory_consumption () const
{
- // only simple data elements, so
- // use sizeof operator
+ // only simple data elements, so
+ // use sizeof operator
return sizeof (*this);
}
std::size_t
DataOutBase::UcdFlags::memory_consumption () const
{
- // only simple data elements, so
- // use sizeof operator
+ // only simple data elements, so
+ // use sizeof operator
return sizeof (*this);
}
DataOutBase::GnuplotFlags::GnuplotFlags ()
- :
- dummy (0)
+ :
+ dummy (0)
{}
size_t
DataOutBase::GnuplotFlags::memory_consumption () const
{
- // only simple data elements, so
- // use sizeof operator
+ // only simple data elements, so
+ // use sizeof operator
return sizeof (*this);
}
void DataOutBase::PovrayFlags::declare_parameters (ParameterHandler &prm)
{
prm.declare_entry ("Use smooth triangles", "false",
- Patterns::Bool(),
+ Patterns::Bool(),
"A flag indicating whether POVRAY should use smoothed "
"triangles instead of the usual ones");
prm.declare_entry ("Use bicubic patches", "false",
- Patterns::Bool(),
+ Patterns::Bool(),
"Whether POVRAY should use bicubic patches");
prm.declare_entry ("Include external file", "true",
- Patterns::Bool (),
+ Patterns::Bool (),
"Whether camera and lightling information should "
"be put into an external file \"data.inc\" or into "
"the POVRAY input file");
std::size_t
DataOutBase::PovrayFlags::memory_consumption () const
{
- // only simple data elements, so
- // use sizeof operator
+ // only simple data elements, so
+ // use sizeof operator
return sizeof (*this);
}
DataOutBase::EpsFlags::EpsFlags (const unsigned int height_vector,
- const unsigned int color_vector,
- const SizeType size_type,
- const unsigned int size,
- const double line_width,
- const double azimut_angle,
- const double turn_angle,
- const double z_scaling,
- const bool draw_mesh,
- const bool draw_cells,
- const bool shade_cells,
- const ColorFunction color_function)
+ const unsigned int color_vector,
+ const SizeType size_type,
+ const unsigned int size,
+ const double line_width,
+ const double azimut_angle,
+ const double turn_angle,
+ const double z_scaling,
+ const bool draw_mesh,
+ const bool draw_cells,
+ const bool shade_cells,
+ const ColorFunction color_function)
:
- height_vector(height_vector),
- color_vector(color_vector),
- size_type(size_type),
- size(size),
- line_width(line_width),
- azimut_angle(azimut_angle),
- turn_angle(turn_angle),
- z_scaling(z_scaling),
- draw_mesh(draw_mesh),
- draw_cells(draw_cells),
- shade_cells(shade_cells),
- color_function(color_function)
+ height_vector(height_vector),
+ color_vector(color_vector),
+ size_type(size_type),
+ size(size),
+ line_width(line_width),
+ azimut_angle(azimut_angle),
+ turn_angle(turn_angle),
+ z_scaling(z_scaling),
+ draw_mesh(draw_mesh),
+ draw_cells(draw_cells),
+ shade_cells(shade_cells),
+ color_function(color_function)
{}
DataOutBase::EpsFlags::RgbValues
DataOutBase::EpsFlags::default_color_function (const double x,
- const double xmin,
- const double xmax)
+ const double xmin,
+ const double xmax)
{
RgbValues rgb_values = { 0,0,0 };
if (dif!=0)
{
switch (where)
- {
- case 0:
- rgb_values.red = 0;
- rgb_values.green = 0;
- rgb_values.blue = (x-xmin)*4.*rezdif;
- break;
- case 1:
- rgb_values.red = 0;
- rgb_values.green = (4*x-3*xmin-xmax)*rezdif;
- rgb_values.blue = (sum22-4.*x)*rezdif;
- break;
- case 2:
- rgb_values.red = (4*x-2*sum)*rezdif;
- rgb_values.green = (xmin+3*xmax-4*x)*rezdif;
- rgb_values.blue = 0;
- break;
- case 3:
- rgb_values.red = 1;
- rgb_values.green = (4*x-xmin-3*xmax)*rezdif;
- rgb_values.blue = (4.*x-sum13)*rezdif;
- default:
- break;
- }
+ {
+ case 0:
+ rgb_values.red = 0;
+ rgb_values.green = 0;
+ rgb_values.blue = (x-xmin)*4.*rezdif;
+ break;
+ case 1:
+ rgb_values.red = 0;
+ rgb_values.green = (4*x-3*xmin-xmax)*rezdif;
+ rgb_values.blue = (sum22-4.*x)*rezdif;
+ break;
+ case 2:
+ rgb_values.red = (4*x-2*sum)*rezdif;
+ rgb_values.green = (xmin+3*xmax-4*x)*rezdif;
+ rgb_values.blue = 0;
+ break;
+ case 3:
+ rgb_values.red = 1;
+ rgb_values.green = (4*x-xmin-3*xmax)*rezdif;
+ rgb_values.blue = (4.*x-sum13)*rezdif;
+ default:
+ break;
+ }
}
else // White
rgb_values.red = rgb_values.green = rgb_values.blue = 1;
DataOutBase::EpsFlags::RgbValues
DataOutBase::EpsFlags::grey_scale_color_function (const double x,
- const double xmin,
- const double xmax)
+ const double xmin,
+ const double xmax)
{
DataOutBase::EpsFlags::RgbValues rgb_values;
rgb_values.red = rgb_values.blue = rgb_values.green
- = (x-xmin)/(xmax-xmin);
+ = (x-xmin)/(xmax-xmin);
return rgb_values;
}
DataOutBase::EpsFlags::RgbValues
DataOutBase::EpsFlags::reverse_grey_scale_color_function (const double x,
- const double xmin,
- const double xmax)
+ const double xmin,
+ const double xmax)
{
DataOutBase::EpsFlags::RgbValues rgb_values;
rgb_values.red = rgb_values.blue = rgb_values.green
- = 1-(x-xmin)/(xmax-xmin);
+ = 1-(x-xmin)/(xmax-xmin);
return rgb_values;
}
bool DataOutBase::EpsCell2d::operator < (const EpsCell2d &e) const
{
- // note the "wrong" order in
- // which we sort the elements
+ // note the "wrong" order in
+ // which we sort the elements
return depth > e.depth;
}
void DataOutBase::EpsFlags::declare_parameters (ParameterHandler &prm)
{
prm.declare_entry ("Index of vector for height", "0",
- Patterns::Integer(),
+ Patterns::Integer(),
"Number of the input vector that is to be used to "
"generate height information");
prm.declare_entry ("Index of vector for color", "0",
- Patterns::Integer(),
+ Patterns::Integer(),
"Number of the input vector that is to be used to "
"generate color information");
prm.declare_entry ("Scale to width or height", "width",
- Patterns::Selection ("width|height"),
+ Patterns::Selection ("width|height"),
"Whether width or height should be scaled to match "
"the given size");
prm.declare_entry ("Size (width or height) in eps units", "300",
- Patterns::Integer(),
+ Patterns::Integer(),
"The size (width or height) to which the eps output "
"file is to be scaled");
prm.declare_entry ("Line widths in eps units", "0.5",
- Patterns::Double(),
+ Patterns::Double(),
"The width in which the postscript renderer is to "
"plot lines");
prm.declare_entry ("Azimut angle", "60",
- Patterns::Double(0,180),
+ Patterns::Double(0,180),
"Angle of the viewing position against the vertical "
"axis");
prm.declare_entry ("Turn angle", "30",
- Patterns::Double(0,360),
+ Patterns::Double(0,360),
"Angle of the viewing direction against the y-axis");
prm.declare_entry ("Scaling for z-axis", "1",
- Patterns::Double (),
+ Patterns::Double (),
"Scaling for the z-direction relative to the scaling "
"used in x- and y-directions");
prm.declare_entry ("Draw mesh lines", "true",
- Patterns::Bool(),
+ Patterns::Bool(),
"Whether the mesh lines, or only the surface should be "
"drawn");
prm.declare_entry ("Fill interior of cells", "true",
- Patterns::Bool(),
+ Patterns::Bool(),
"Whether only the mesh lines, or also the interior of "
"cells should be plotted. If this flag is false, then "
"one can see through the mesh");
prm.declare_entry ("Color shading of interior of cells", "true",
- Patterns::Bool(),
+ Patterns::Bool(),
"Whether the interior of cells shall be shaded");
prm.declare_entry ("Color function", "default",
- Patterns::Selection ("default|grey scale|reverse grey scale"),
+ Patterns::Selection ("default|grey scale|reverse grey scale"),
"Name of a color function used to colorize mesh lines "
"and/or cell interiors");
}
else if (prm.get("Color function") == "reverse grey scale")
color_function = &reverse_grey_scale_color_function;
else
- // we shouldn't get here, since
- // the parameter object should
- // already have checked that the
- // given value is valid
+ // we shouldn't get here, since
+ // the parameter object should
+ // already have checked that the
+ // given value is valid
Assert (false, ExcInternalError());
}
std::size_t
DataOutBase::EpsFlags::memory_consumption () const
{
- // only simple data elements, so
- // use sizeof operator
+ // only simple data elements, so
+ // use sizeof operator
return sizeof (*this);
}
std::size_t
DataOutBase::GmvFlags::memory_consumption () const
{
- // only simple data elements, so
- // use sizeof operator
+ // only simple data elements, so
+ // use sizeof operator
return sizeof (*this);
}
DataOutBase::TecplotFlags::
TecplotFlags (const char* tecplot_binary_file_name,
- const char* zone_name)
+ const char* zone_name)
:
tecplot_binary_file_name(tecplot_binary_file_name),
- zone_name(zone_name)
+ zone_name(zone_name)
{}
std::size_t
DataOutBase::TecplotFlags::memory_consumption () const
{
- // only simple data elements, so
- // use sizeof operator
+ // only simple data elements, so
+ // use sizeof operator
return sizeof (*this);
}
std::size_t
DataOutBase::VtkFlags::memory_consumption () const
{
- // only simple data elements, so
- // use sizeof operator
+ // only simple data elements, so
+ // use sizeof operator
return sizeof (*this);
}
DataOutBase::Deal_II_IntermediateFlags::Deal_II_IntermediateFlags ()
- :
- dummy (0)
+ :
+ dummy (0)
{}
std::size_t
DataOutBase::Deal_II_IntermediateFlags::memory_consumption () const
{
- // only simple data elements, so
- // use sizeof operator
+ // only simple data elements, so
+ // use sizeof operator
return sizeof (*this);
}
AssertThrow (false,
ExcMessage ("The given file format name is not recognized."));
- // return something invalid
+ // return something invalid
return OutputFormat(-1);
}
switch (output_format)
{
case none:
- return "";
+ return "";
case dx:
- return ".dx";
+ return ".dx";
case ucd:
- return ".inp";
+ return ".inp";
case gnuplot:
- return ".gnuplot";
+ return ".gnuplot";
case povray:
- return ".pov";
+ return ".pov";
case eps:
- return ".eps";
+ return ".eps";
case gmv:
- return ".gmv";
+ return ".gmv";
case tecplot:
- return ".dat";
+ return ".dat";
case tecplot_binary:
- return ".plt";
+ return ".plt";
case vtk:
- return ".vtk";
+ return ".vtk";
case vtu:
- return ".vtu";
+ return ".vtu";
case deal_II_intermediate:
- return ".d2";
+ return ".d2";
default:
- Assert (false, ExcNotImplemented());
- return "";
+ Assert (false, ExcNotImplemented());
+ return "";
}
}
template <int dim, int spacedim, typename STREAM>
void
DataOutBase::write_nodes (const std::vector<Patch<dim,spacedim> >& patches,
- STREAM& out)
+ STREAM& out)
{
Assert (dim<=3, ExcNotImplemented());
unsigned int count = 0;
- // We only need this point below,
- // but it does not harm to declare
- // it here.
+ // We only need this point below,
+ // but it does not harm to declare
+ // it here.
Point<spacedim> node;
for (typename std::vector<Patch<dim,spacedim> >::const_iterator
- patch=patches.begin();
+ patch=patches.begin();
patch!=patches.end(); ++patch)
{
const unsigned int n_subdivisions = patch->n_subdivisions;
const unsigned int n = n_subdivisions+1;
- // Length of loops in all
- // dimensions. If a dimension
- // is not used, a loop of
- // length one will do the job.
+ // Length of loops in all
+ // dimensions. If a dimension
+ // is not used, a loop of
+ // length one will do the job.
const unsigned int n1 = (dim>0) ? n : 1;
const unsigned int n2 = (dim>1) ? n : 1;
const unsigned int n3 = (dim>2) ? n : 1;
for (unsigned int i3=0; i3<n3; ++i3)
- for (unsigned int i2=0; i2<n2; ++i2)
- for (unsigned int i1=0; i1<n1; ++i1)
- {
- compute_node(node, &*patch,
- i1,
- i2,
- i3,
- n_subdivisions);
- out.write_point(count++, node);
- }
+ for (unsigned int i2=0; i2<n2; ++i2)
+ for (unsigned int i1=0; i1<n1; ++i1)
+ {
+ compute_node(node, &*patch,
+ i1,
+ i2,
+ i3,
+ n_subdivisions);
+ out.write_point(count++, node);
+ }
}
out.flush_points ();
}
template <int dim, int spacedim, typename STREAM>
void
DataOutBase::write_cells (const std::vector<Patch<dim,spacedim> >& patches,
- STREAM& out)
+ STREAM& out)
{
Assert (dim<=3, ExcNotImplemented());
unsigned int count = 0;
unsigned int first_vertex_of_patch = 0;
- // Array to hold all the node
- // numbers of a cell. 8 is
- // sufficient for 3D
+ // Array to hold all the node
+ // numbers of a cell. 8 is
+ // sufficient for 3D
for (typename std::vector<Patch<dim,spacedim> >::const_iterator
- patch=patches.begin();
+ patch=patches.begin();
patch!=patches.end(); ++patch)
{
const unsigned int n_subdivisions = patch->n_subdivisions;
const unsigned int n = n_subdivisions+1;
- // Length of loops in all dimensons
+ // Length of loops in all dimensons
const unsigned int n1 = (dim>0) ? n_subdivisions : 1;
const unsigned int n2 = (dim>1) ? n_subdivisions : 1;
const unsigned int n3 = (dim>2) ? n_subdivisions : 1;
- // Offsets of outer loops
+ // Offsets of outer loops
unsigned int d1 = 1;
unsigned int d2 = n;
unsigned int d3 = n*n;
for (unsigned int i3=0; i3<n3; ++i3)
- for (unsigned int i2=0; i2<n2; ++i2)
- for (unsigned int i1=0; i1<n1; ++i1)
- {
- const unsigned int offset = first_vertex_of_patch+i3*d3+i2*d2+i1*d1;
- // First write line in x direction
- out.template write_cell<dim>(count++, offset, d1, d2, d3);
- }
- // finally update the number
- // of the first vertex of this patch
+ for (unsigned int i2=0; i2<n2; ++i2)
+ for (unsigned int i1=0; i1<n1; ++i1)
+ {
+ const unsigned int offset = first_vertex_of_patch+i3*d3+i2*d2+i1*d1;
+ // First write line in x direction
+ out.template write_cell<dim>(count++, offset, d1, d2, d3);
+ }
+ // finally update the number
+ // of the first vertex of this patch
first_vertex_of_patch += Utilities::fixed_power<dim>(n_subdivisions+1);
}
unsigned int count = 0;
for (typename std::vector<Patch<dim,spacedim> >::const_iterator patch
- = patches.begin();
+ = patches.begin();
patch != patches.end(); ++patch)
{
const unsigned int n_subdivisions = patch->n_subdivisions;
const unsigned int n = n_subdivisions+1;
- // Length of loops in all dimensions
+ // Length of loops in all dimensions
Assert ((patch->data.n_rows() == n_data_sets && !patch->points_are_available) ||
- (patch->data.n_rows() == n_data_sets+spacedim && patch->points_are_available),
- ExcDimensionMismatch (patch->points_are_available
- ?
- (n_data_sets + spacedim)
- :
- n_data_sets,
- patch->data.n_rows()));
+ (patch->data.n_rows() == n_data_sets+spacedim && patch->points_are_available),
+ ExcDimensionMismatch (patch->points_are_available
+ ?
+ (n_data_sets + spacedim)
+ :
+ n_data_sets,
+ patch->data.n_rows()));
Assert (patch->data.n_cols() == Utilities::fixed_power<dim>(n),
- ExcInvalidDatasetSize (patch->data.n_cols(), n));
+ ExcInvalidDatasetSize (patch->data.n_cols(), n));
std::vector<float> floats(n_data_sets);
std::vector<double> doubles(n_data_sets);
- // Data is already in
- // lexicographic ordering
+ // Data is already in
+ // lexicographic ordering
for (unsigned int i=0; i<Utilities::fixed_power<dim>(n); ++i, ++count)
- if (double_precision)
- {
- for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
- doubles[data_set] = patch->data(data_set, i);
- out.write_dataset(count, doubles);
- }
- else
- {
- for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
- floats[data_set] = patch->data(data_set, i);
- out.write_dataset(count, floats);
- }
+ if (double_precision)
+ {
+ for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
+ doubles[data_set] = patch->data(data_set, i);
+ out.write_dataset(count, doubles);
+ }
+ else
+ {
+ for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
+ floats[data_set] = patch->data(data_set, i);
+ out.write_dataset(count, floats);
+ }
}
}
template <int dim, int spacedim>
void DataOutBase::write_ucd (const std::vector<Patch<dim,spacedim> > &patches,
- const std::vector<std::string> &data_names,
- const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &,
- const UcdFlags &flags,
- std::ostream &out)
+ const std::vector<std::string> &data_names,
+ const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &,
+ const UcdFlags &flags,
+ std::ostream &out)
{
AssertThrow (out, ExcIO());
#ifndef DEAL_II_COMPILER_SUPPORTS_MPI
- // verify that there are indeed
- // patches to be written out. most
- // of the times, people just forget
- // to call build_patches when there
- // are no patches, so a warning is
- // in order. that said, the
- // assertion is disabled if we
- // support MPI since then it can
- // happen that on the coarsest
- // mesh, a processor simply has no
- // cells it actually owns, and in
- // that case it is legit if there
- // are no patches
+ // verify that there are indeed
+ // patches to be written out. most
+ // of the times, people just forget
+ // to call build_patches when there
+ // are no patches, so a warning is
+ // in order. that said, the
+ // assertion is disabled if we
+ // support MPI since then it can
+ // happen that on the coarsest
+ // mesh, a processor simply has no
+ // cells it actually owns, and in
+ // that case it is legit if there
+ // are no patches
Assert (patches.size() > 0, ExcNoPatches());
#else
if (patches.size() == 0)
UcdStream ucd_out(out, flags);
- // first count the number of cells
- // and cells for later use
+ // first count the number of cells
+ // and cells for later use
unsigned int n_nodes;
unsigned int n_cells;
compute_sizes<dim,spacedim> (patches, n_nodes, n_cells);
- ///////////////////////
- // preamble
+ ///////////////////////
+ // preamble
if (flags.write_preamble)
{
std::time_t time1= std::time (0);
std::tm *time = std::localtime(&time1);
out << "# This file was generated by the deal.II library." << '\n'
- << "# Date = "
- << time->tm_year+1900 << "/"
- << time->tm_mon+1 << "/"
- << time->tm_mday << '\n'
- << "# Time = "
- << time->tm_hour << ":"
- << std::setw(2) << time->tm_min << ":"
- << std::setw(2) << time->tm_sec << '\n'
- << "#" << '\n'
- << "# For a description of the UCD format see the AVS Developer's guide."
- << '\n'
- << "#" << '\n';
+ << "# Date = "
+ << time->tm_year+1900 << "/"
+ << time->tm_mon+1 << "/"
+ << time->tm_mday << '\n'
+ << "# Time = "
+ << time->tm_hour << ":"
+ << std::setw(2) << time->tm_min << ":"
+ << std::setw(2) << time->tm_sec << '\n'
+ << "#" << '\n'
+ << "# For a description of the UCD format see the AVS Developer's guide."
+ << '\n'
+ << "#" << '\n';
}
- // start with ucd data
+ // start with ucd data
out << n_nodes << ' '
<< n_cells << ' '
<< n_data_sets << ' '
write_cells(patches, ucd_out);
out << '\n';
- /////////////////////////////
- // now write data
+ /////////////////////////////
+ // now write data
if (n_data_sets != 0)
{
out << n_data_sets << " "; // number of vectors
for (unsigned int i=0; i<n_data_sets; ++i)
- out << 1 << ' '; // number of components;
- // only 1 supported presently
+ out << 1 << ' '; // number of components;
+ // only 1 supported presently
out << '\n';
for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
- out << data_names[data_set]
- << ",dimensionless" // no units supported at present
- << '\n';
+ out << data_names[data_set]
+ << ",dimensionless" // no units supported at present
+ << '\n';
write_data(patches, n_data_sets, true, ucd_out);
}
- // make sure everything now gets to
- // disk
+ // make sure everything now gets to
+ // disk
out.flush ();
- // assert the stream is still ok
+ // assert the stream is still ok
AssertThrow (out, ExcIO());
}
template <int dim, int spacedim>
void DataOutBase::write_dx (const std::vector<Patch<dim,spacedim> > &patches,
- const std::vector<std::string> &data_names,
- const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &,
- const DXFlags &flags,
- std::ostream &out)
+ const std::vector<std::string> &data_names,
+ const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &,
+ const DXFlags &flags,
+ std::ostream &out)
{
AssertThrow (out, ExcIO());
#ifndef DEAL_II_COMPILER_SUPPORTS_MPI
- // verify that there are indeed
- // patches to be written out. most
- // of the times, people just forget
- // to call build_patches when there
- // are no patches, so a warning is
- // in order. that said, the
- // assertion is disabled if we
- // support MPI since then it can
- // happen that on the coarsest
- // mesh, a processor simply has no
- // cells it actually owns, and in
- // that case it is legit if there
- // are no patches
+ // verify that there are indeed
+ // patches to be written out. most
+ // of the times, people just forget
+ // to call build_patches when there
+ // are no patches, so a warning is
+ // in order. that said, the
+ // assertion is disabled if we
+ // support MPI since then it can
+ // happen that on the coarsest
+ // mesh, a processor simply has no
+ // cells it actually owns, and in
+ // that case it is legit if there
+ // are no patches
Assert (patches.size() > 0, ExcNoPatches());
#else
if (patches.size() == 0)
return;
#endif
- // Stream with special features for dx output
+ // Stream with special features for dx output
DXStream dx_out(out, flags);
- // Variable counting the offset of
- // binary data.
+ // Variable counting the offset of
+ // binary data.
unsigned int offset = 0;
const unsigned int n_data_sets = data_names.size();
- // first count the number of cells
- // and cells for later use
+ // first count the number of cells
+ // and cells for later use
unsigned int n_nodes;
unsigned int n_cells;
compute_sizes<dim,spacedim>(patches, n_nodes, n_cells);
- // start with vertices order is
- // lexicographical, x varying
- // fastest
+ // start with vertices order is
+ // lexicographical, x varying
+ // fastest
out << "object \"vertices\" class array type float rank 1 shape " << spacedim
<< " items " << n_nodes;
write_nodes(patches, dx_out);
}
- ///////////////////////////////
- // first write the coordinates of all vertices
+ ///////////////////////////////
+ // first write the coordinates of all vertices
- /////////////////////////////////////////
- // write cells
+ /////////////////////////////////////////
+ // write cells
out << "object \"cells\" class array type int rank 1 shape "
<< GeometryInfo<dim>::vertices_per_cell
<< " items " << n_cells;
<< "attribute \"ref\" string \"positions\"" << '\n';
//TODO:[GK] Patches must be of same size!
- /////////////////////////////
- // write neighbor information
+ /////////////////////////////
+ // write neighbor information
if (flags.write_neighbors)
{
out << "object \"neighbors\" class array type int rank 1 shape "
- << GeometryInfo<dim>::faces_per_cell
- << " items " << n_cells
- << " data follows";
+ << GeometryInfo<dim>::faces_per_cell
+ << " items " << n_cells
+ << " data follows";
for (typename std::vector<Patch<dim,spacedim> >::const_iterator
- patch=patches.begin();
- patch!=patches.end(); ++patch)
- {
- const unsigned int n = patch->n_subdivisions;
- const unsigned int n1 = (dim>0) ? n : 1;
- const unsigned int n2 = (dim>1) ? n : 1;
- const unsigned int n3 = (dim>2) ? n : 1;
- unsigned int cells_per_patch = Utilities::fixed_power<dim>(n);
- unsigned int dx = 1;
- unsigned int dy = n;
- unsigned int dz = n*n;
-
- const unsigned int patch_start = patch->patch_index * cells_per_patch;
-
- for (unsigned int i3=0;i3<n3;++i3)
- for (unsigned int i2=0;i2<n2;++i2)
- for (unsigned int i1=0;i1<n1;++i1)
- {
- const unsigned int nx = i1*dx;
- const unsigned int ny = i2*dy;
- const unsigned int nz = i3*dz;
-
- out << '\n';
- // Direction -x
- // Last cell in row
- // of other patch
- if (i1==0)
- {
- const unsigned int nn = patch->neighbors[0];
- out << '\t';
- if (nn != patch->no_neighbor)
- out << (nn*cells_per_patch+ny+nz+dx*(n-1));
- else
- out << "-1";
- } else {
- out << '\t'
- << patch_start+nx-dx+ny+nz;
- }
- // Direction +x
- // First cell in row
- // of other patch
- if (i1 == n-1)
- {
- const unsigned int nn = patch->neighbors[1];
- out << '\t';
- if (nn != patch->no_neighbor)
- out << (nn*cells_per_patch+ny+nz);
- else
- out << "-1";
- } else {
- out << '\t'
- << patch_start+nx+dx+ny+nz;
- }
- if (dim<2)
- continue;
- // Direction -y
- if (i2==0)
- {
- const unsigned int nn = patch->neighbors[2];
- out << '\t';
- if (nn != patch->no_neighbor)
- out << (nn*cells_per_patch+nx+nz+dy*(n-1));
- else
- out << "-1";
- } else {
- out << '\t'
- << patch_start+nx+ny-dy+nz;
- }
- // Direction +y
- if (i2 == n-1)
- {
- const unsigned int nn = patch->neighbors[3];
- out << '\t';
- if (nn != patch->no_neighbor)
- out << (nn*cells_per_patch+nx+nz);
- else
- out << "-1";
- } else {
- out << '\t'
- << patch_start+nx+ny+dy+nz;
- }
- if (dim<3)
- continue;
-
- // Direction -z
- if (i3==0)
- {
- const unsigned int nn = patch->neighbors[4];
- out << '\t';
- if (nn != patch->no_neighbor)
- out << (nn*cells_per_patch+nx+ny+dz*(n-1));
- else
- out << "-1";
- } else {
- out << '\t'
- << patch_start+nx+ny+nz-dz;
- }
- // Direction +z
- if (i3 == n-1)
- {
- const unsigned int nn = patch->neighbors[5];
- out << '\t';
- if (nn != patch->no_neighbor)
- out << (nn*cells_per_patch+nx+ny);
- else
- out << "-1";
- } else {
- out << '\t'
- << patch_start+nx+ny+nz+dz;
- }
- }
- out << '\n';
- }
+ patch=patches.begin();
+ patch!=patches.end(); ++patch)
+ {
+ const unsigned int n = patch->n_subdivisions;
+ const unsigned int n1 = (dim>0) ? n : 1;
+ const unsigned int n2 = (dim>1) ? n : 1;
+ const unsigned int n3 = (dim>2) ? n : 1;
+ unsigned int cells_per_patch = Utilities::fixed_power<dim>(n);
+ unsigned int dx = 1;
+ unsigned int dy = n;
+ unsigned int dz = n*n;
+
+ const unsigned int patch_start = patch->patch_index * cells_per_patch;
+
+ for (unsigned int i3=0;i3<n3;++i3)
+ for (unsigned int i2=0;i2<n2;++i2)
+ for (unsigned int i1=0;i1<n1;++i1)
+ {
+ const unsigned int nx = i1*dx;
+ const unsigned int ny = i2*dy;
+ const unsigned int nz = i3*dz;
+
+ out << '\n';
+ // Direction -x
+ // Last cell in row
+ // of other patch
+ if (i1==0)
+ {
+ const unsigned int nn = patch->neighbors[0];
+ out << '\t';
+ if (nn != patch->no_neighbor)
+ out << (nn*cells_per_patch+ny+nz+dx*(n-1));
+ else
+ out << "-1";
+ } else {
+ out << '\t'
+ << patch_start+nx-dx+ny+nz;
+ }
+ // Direction +x
+ // First cell in row
+ // of other patch
+ if (i1 == n-1)
+ {
+ const unsigned int nn = patch->neighbors[1];
+ out << '\t';
+ if (nn != patch->no_neighbor)
+ out << (nn*cells_per_patch+ny+nz);
+ else
+ out << "-1";
+ } else {
+ out << '\t'
+ << patch_start+nx+dx+ny+nz;
+ }
+ if (dim<2)
+ continue;
+ // Direction -y
+ if (i2==0)
+ {
+ const unsigned int nn = patch->neighbors[2];
+ out << '\t';
+ if (nn != patch->no_neighbor)
+ out << (nn*cells_per_patch+nx+nz+dy*(n-1));
+ else
+ out << "-1";
+ } else {
+ out << '\t'
+ << patch_start+nx+ny-dy+nz;
+ }
+ // Direction +y
+ if (i2 == n-1)
+ {
+ const unsigned int nn = patch->neighbors[3];
+ out << '\t';
+ if (nn != patch->no_neighbor)
+ out << (nn*cells_per_patch+nx+nz);
+ else
+ out << "-1";
+ } else {
+ out << '\t'
+ << patch_start+nx+ny+dy+nz;
+ }
+ if (dim<3)
+ continue;
+
+ // Direction -z
+ if (i3==0)
+ {
+ const unsigned int nn = patch->neighbors[4];
+ out << '\t';
+ if (nn != patch->no_neighbor)
+ out << (nn*cells_per_patch+nx+ny+dz*(n-1));
+ else
+ out << "-1";
+ } else {
+ out << '\t'
+ << patch_start+nx+ny+nz-dz;
+ }
+ // Direction +z
+ if (i3 == n-1)
+ {
+ const unsigned int nn = patch->neighbors[5];
+ out << '\t';
+ if (nn != patch->no_neighbor)
+ out << (nn*cells_per_patch+nx+ny);
+ else
+ out << "-1";
+ } else {
+ out << '\t'
+ << patch_start+nx+ny+nz+dz;
+ }
+ }
+ out << '\n';
+ }
}
- /////////////////////////////
- // now write data
+ /////////////////////////////
+ // now write data
if (n_data_sets != 0)
{
out << "object \"data\" class array type float rank 1 shape "
- << n_data_sets
- << " items " << n_nodes;
+ << n_data_sets
+ << " items " << n_nodes;
if (flags.data_binary)
- {
- out << " lsb ieee data " << offset << '\n';
- offset += n_data_sets * n_nodes * ((flags.data_double)
- ? sizeof(double)
- : sizeof(float));
- }
+ {
+ out << " lsb ieee data " << offset << '\n';
+ offset += n_data_sets * n_nodes * ((flags.data_double)
+ ? sizeof(double)
+ : sizeof(float));
+ }
else
- {
- out << " data follows" << '\n';
- write_data(patches, n_data_sets, flags.data_double, dx_out);
- }
+ {
+ out << " data follows" << '\n';
+ write_data(patches, n_data_sets, flags.data_double, dx_out);
+ }
- // loop over all patches
+ // loop over all patches
out << "attribute \"dep\" string \"positions\"" << '\n';
} else {
out << "object \"data\" class constantarray type float rank 0 items " << n_nodes << " data follows"
- << '\n' << '0' << '\n';
+ << '\n' << '0' << '\n';
}
- // no model data
+ // no model data
out << "object \"deal data\" class field" << '\n'
<< "component \"positions\" value \"vertices\"" << '\n'
std::time_t time1= std::time (0);
std::tm *time = std::localtime(&time1);
out << "attribute \"created\" string \""
- << time->tm_year+1900 << "/"
- << time->tm_mon+1 << "/"
- << time->tm_mday
- << ' '
- << time->tm_hour << ":"
- << std::setw(2) << time->tm_min << ":"
- << std::setw(2) << time->tm_sec << '"' << '\n';
+ << time->tm_year+1900 << "/"
+ << time->tm_mon+1 << "/"
+ << time->tm_mday
+ << ' '
+ << time->tm_hour << ":"
+ << std::setw(2) << time->tm_min << ":"
+ << std::setw(2) << time->tm_sec << '"' << '\n';
}
out << "end" << '\n';
- // Write all binary data now
+ // Write all binary data now
if (flags.coordinates_binary)
write_nodes(patches, dx_out);
if (flags.int_binary)
if (flags.data_binary)
write_data(patches, n_data_sets, flags.data_double, dx_out);
- // make sure everything now gets to
- // disk
+ // make sure everything now gets to
+ // disk
out.flush ();
- // assert the stream is still ok
+ // assert the stream is still ok
AssertThrow (out, ExcIO());
}
template <int dim, int spacedim>
void DataOutBase::write_gnuplot (const std::vector<Patch<dim,spacedim> > &patches,
- const std::vector<std::string> &data_names,
- const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &,
- const GnuplotFlags &/*flags*/,
- std::ostream &out)
+ const std::vector<std::string> &data_names,
+ const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &,
+ const GnuplotFlags &/*flags*/,
+ std::ostream &out)
{
AssertThrow (out, ExcIO());
#ifndef DEAL_II_COMPILER_SUPPORTS_MPI
- // verify that there are indeed
- // patches to be written out. most
- // of the times, people just forget
- // to call build_patches when there
- // are no patches, so a warning is
- // in order. that said, the
- // assertion is disabled if we
- // support MPI since then it can
- // happen that on the coarsest
- // mesh, a processor simply has no
- // cells it actually owns, and in
- // that case it is legit if there
- // are no patches
+ // verify that there are indeed
+ // patches to be written out. most
+ // of the times, people just forget
+ // to call build_patches when there
+ // are no patches, so a warning is
+ // in order. that said, the
+ // assertion is disabled if we
+ // support MPI since then it can
+ // happen that on the coarsest
+ // mesh, a processor simply has no
+ // cells it actually owns, and in
+ // that case it is legit if there
+ // are no patches
Assert (patches.size() > 0, ExcNoPatches());
#else
if (patches.size() == 0)
const unsigned int n_data_sets = data_names.size();
- // write preamble
+ // write preamble
if (true)
{
- // block this to have local
- // variables destroyed after
- // use
+ // block this to have local
+ // variables destroyed after
+ // use
const std::time_t time1= std::time (0);
const std::tm *time = std::localtime(&time1);
out << "# This file was generated by the deal.II library." << '\n'
- << "# Date = "
- << time->tm_year+1900 << "/"
- << time->tm_mon+1 << "/"
- << time->tm_mday << '\n'
- << "# Time = "
- << time->tm_hour << ":"
- << std::setw(2) << time->tm_min << ":"
- << std::setw(2) << time->tm_sec << '\n'
- << "#" << '\n'
- << "# For a description of the GNUPLOT format see the GNUPLOT manual."
- << '\n'
- << "#" << '\n'
- << "# ";
+ << "# Date = "
+ << time->tm_year+1900 << "/"
+ << time->tm_mon+1 << "/"
+ << time->tm_mday << '\n'
+ << "# Time = "
+ << time->tm_hour << ":"
+ << std::setw(2) << time->tm_min << ":"
+ << std::setw(2) << time->tm_sec << '\n'
+ << "#" << '\n'
+ << "# For a description of the GNUPLOT format see the GNUPLOT manual."
+ << '\n'
+ << "#" << '\n'
+ << "# ";
switch (spacedim)
- {
- case 1:
- out << "<x> ";
- break;
- case 2:
- out << "<x> <y> ";
- break;
- case 3:
- out << "<x> <y> <z> ";
- break;
-
- default:
- Assert (false, ExcNotImplemented());
- }
+ {
+ case 1:
+ out << "<x> ";
+ break;
+ case 2:
+ out << "<x> <y> ";
+ break;
+ case 3:
+ out << "<x> <y> <z> ";
+ break;
+
+ default:
+ Assert (false, ExcNotImplemented());
+ }
for (unsigned int i=0; i<data_names.size(); ++i)
- out << '<' << data_names[i] << "> ";
+ out << '<' << data_names[i] << "> ";
out << '\n';
}
- // loop over all patches
+ // loop over all patches
for (typename std::vector<Patch<dim,spacedim> >::const_iterator patch=patches.begin();
patch != patches.end(); ++patch)
{
const unsigned int n_subdivisions = patch->n_subdivisions;
const unsigned int n = n_subdivisions+1;
- // Length of loops in all dimensions
+ // Length of loops in all dimensions
const unsigned int n1 = (dim>0) ? n : 1;
const unsigned int n2 = (dim>1) ? n : 1;
const unsigned int n3 = (dim>2) ? n : 1;
unsigned int d3 = n*n;
Assert ((patch->data.n_rows() == n_data_sets && !patch->points_are_available) ||
- (patch->data.n_rows() == n_data_sets+spacedim && patch->points_are_available),
- ExcDimensionMismatch (patch->points_are_available
- ?
- (n_data_sets + spacedim)
- :
- n_data_sets,
- patch->data.n_rows()));
+ (patch->data.n_rows() == n_data_sets+spacedim && patch->points_are_available),
+ ExcDimensionMismatch (patch->points_are_available
+ ?
+ (n_data_sets + spacedim)
+ :
+ n_data_sets,
+ patch->data.n_rows()));
Assert (patch->data.n_cols() == Utilities::fixed_power<dim>(n),
- ExcInvalidDatasetSize (patch->data.n_cols(), n_subdivisions+1));
+ ExcInvalidDatasetSize (patch->data.n_cols(), n_subdivisions+1));
Point<spacedim> this_point;
Point<spacedim> node;
if (dim<3)
- {
- for (unsigned int i2=0; i2<n2; ++i2)
- {
- for (unsigned int i1=0; i1<n1; ++i1)
- {
- // compute coordinates for
- // this patch point
- compute_node(node, &*patch, i1, i2, 0, n_subdivisions);
- out << node << ' ';
-
- for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
- out << patch->data(data_set,i1*d1+i2*d2) << ' ';
- out << '\n';
- }
- // end of row in patch
- if (dim>1)
- out << '\n';
- }
- // end of patch
- if (dim==1)
- out << '\n';
- out << '\n';
- }
+ {
+ for (unsigned int i2=0; i2<n2; ++i2)
+ {
+ for (unsigned int i1=0; i1<n1; ++i1)
+ {
+ // compute coordinates for
+ // this patch point
+ compute_node(node, &*patch, i1, i2, 0, n_subdivisions);
+ out << node << ' ';
+
+ for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
+ out << patch->data(data_set,i1*d1+i2*d2) << ' ';
+ out << '\n';
+ }
+ // end of row in patch
+ if (dim>1)
+ out << '\n';
+ }
+ // end of patch
+ if (dim==1)
+ out << '\n';
+ out << '\n';
+ }
else if (dim==3)
- {
- // for all grid points: draw
- // lines into all positive
- // coordinate directions if
- // there is another grid point
- // there
- for (unsigned int i3=0; i3<n3; ++i3)
- for (unsigned int i2=0; i2<n2; ++i2)
- for (unsigned int i1=0; i1<n1; ++i1)
- {
- // compute coordinates for
- // this patch point
- compute_node(this_point, &*patch, i1, i2, i3, n_subdivisions);
- // line into positive x-direction
- // if possible
- if (i1 < n_subdivisions)
- {
- // write point here
- // and its data
- out << this_point;
- for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
- out << ' '
- << patch->data(data_set,i1*d1+i2*d2+i3*d3);
- out << '\n';
-
- // write point there
- // and its data
- compute_node(node, &*patch, i1+1, i2, i3, n_subdivisions);
- out << node;
-
- for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
- out << ' '
- << patch->data(data_set,(i1+1)*d1+i2*d2+i3*d3);
- out << '\n';
-
- // end of line
- out << '\n'
- << '\n';
- }
-
- // line into positive y-direction
- // if possible
- if (i2 < n_subdivisions)
- {
- // write point here
- // and its data
- out << this_point;
- for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
- out << ' '
- << patch->data(data_set, i1*d1+i2*d2+i3*d3);
- out << '\n';
-
- // write point there
- // and its data
- compute_node(node, &*patch, i1, i2+1, i3, n_subdivisions);
- out << node;
-
- for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
- out << ' '
- << patch->data(data_set,i1*d1+(i2+1)*d2+i3*d3);
- out << '\n';
-
- // end of line
- out << '\n'
- << '\n';
- }
-
- // line into positive z-direction
- // if possible
- if (i3 < n_subdivisions)
- {
- // write point here
- // and its data
- out << this_point;
- for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
- out << ' '
- << patch->data(data_set,i1*d1+i2*d2+i3*d3);
- out << '\n';
-
- // write point there
- // and its data
- compute_node(node, &*patch, i1, i2, i3+1, n_subdivisions);
- out << node;
-
- for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
- out << ' '
- << patch->data(data_set,i1*d1+i2*d2+(i3+1)*d3);
- out << '\n';
- // end of line
- out << '\n'
- << '\n';
- }
-
- }
- }
+ {
+ // for all grid points: draw
+ // lines into all positive
+ // coordinate directions if
+ // there is another grid point
+ // there
+ for (unsigned int i3=0; i3<n3; ++i3)
+ for (unsigned int i2=0; i2<n2; ++i2)
+ for (unsigned int i1=0; i1<n1; ++i1)
+ {
+ // compute coordinates for
+ // this patch point
+ compute_node(this_point, &*patch, i1, i2, i3, n_subdivisions);
+ // line into positive x-direction
+ // if possible
+ if (i1 < n_subdivisions)
+ {
+ // write point here
+ // and its data
+ out << this_point;
+ for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
+ out << ' '
+ << patch->data(data_set,i1*d1+i2*d2+i3*d3);
+ out << '\n';
+
+ // write point there
+ // and its data
+ compute_node(node, &*patch, i1+1, i2, i3, n_subdivisions);
+ out << node;
+
+ for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
+ out << ' '
+ << patch->data(data_set,(i1+1)*d1+i2*d2+i3*d3);
+ out << '\n';
+
+ // end of line
+ out << '\n'
+ << '\n';
+ }
+
+ // line into positive y-direction
+ // if possible
+ if (i2 < n_subdivisions)
+ {
+ // write point here
+ // and its data
+ out << this_point;
+ for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
+ out << ' '
+ << patch->data(data_set, i1*d1+i2*d2+i3*d3);
+ out << '\n';
+
+ // write point there
+ // and its data
+ compute_node(node, &*patch, i1, i2+1, i3, n_subdivisions);
+ out << node;
+
+ for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
+ out << ' '
+ << patch->data(data_set,i1*d1+(i2+1)*d2+i3*d3);
+ out << '\n';
+
+ // end of line
+ out << '\n'
+ << '\n';
+ }
+
+ // line into positive z-direction
+ // if possible
+ if (i3 < n_subdivisions)
+ {
+ // write point here
+ // and its data
+ out << this_point;
+ for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
+ out << ' '
+ << patch->data(data_set,i1*d1+i2*d2+i3*d3);
+ out << '\n';
+
+ // write point there
+ // and its data
+ compute_node(node, &*patch, i1, i2, i3+1, n_subdivisions);
+ out << node;
+
+ for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
+ out << ' '
+ << patch->data(data_set,i1*d1+i2*d2+(i3+1)*d3);
+ out << '\n';
+ // end of line
+ out << '\n'
+ << '\n';
+ }
+
+ }
+ }
else
- Assert (false, ExcNotImplemented());
+ Assert (false, ExcNotImplemented());
}
- // make sure everything now gets to
- // disk
+ // make sure everything now gets to
+ // disk
out.flush ();
AssertThrow (out, ExcIO());
template <int dim, int spacedim>
void DataOutBase::write_povray (const std::vector<Patch<dim,spacedim> > &patches,
- const std::vector<std::string> &data_names,
- const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &,
- const PovrayFlags &flags,
- std::ostream &out)
+ const std::vector<std::string> &data_names,
+ const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &,
+ const PovrayFlags &flags,
+ std::ostream &out)
{
AssertThrow (out, ExcIO());
#ifndef DEAL_II_COMPILER_SUPPORTS_MPI
- // verify that there are indeed
- // patches to be written out. most
- // of the times, people just forget
- // to call build_patches when there
- // are no patches, so a warning is
- // in order. that said, the
- // assertion is disabled if we
- // support MPI since then it can
- // happen that on the coarsest
- // mesh, a processor simply has no
- // cells it actually owns, and in
- // that case it is legit if there
- // are no patches
+ // verify that there are indeed
+ // patches to be written out. most
+ // of the times, people just forget
+ // to call build_patches when there
+ // are no patches, so a warning is
+ // in order. that said, the
+ // assertion is disabled if we
+ // support MPI since then it can
+ // happen that on the coarsest
+ // mesh, a processor simply has no
+ // cells it actually owns, and in
+ // that case it is legit if there
+ // are no patches
Assert (patches.size() > 0, ExcNoPatches());
#else
if (patches.size() == 0)
const unsigned int n_data_sets = data_names.size();
- // write preamble
+ // write preamble
if (true)
{
- // block this to have local
- // variables destroyed after use
+ // block this to have local
+ // variables destroyed after use
const std::time_t time1= std::time (0);
const std::tm *time = std::localtime(&time1);
out << "/* This file was generated by the deal.II library." << '\n'
- << " Date = "
- << time->tm_year+1900 << "/"
- << time->tm_mon+1 << "/"
- << time->tm_mday << '\n'
- << " Time = "
- << time->tm_hour << ":"
- << std::setw(2) << time->tm_min << ":"
- << std::setw(2) << time->tm_sec << '\n'
- << '\n'
- << " For a description of the POVRAY format see the POVRAY manual."
- << '\n'
- << "*/ " << '\n';
-
- // include files
+ << " Date = "
+ << time->tm_year+1900 << "/"
+ << time->tm_mon+1 << "/"
+ << time->tm_mday << '\n'
+ << " Time = "
+ << time->tm_hour << ":"
+ << std::setw(2) << time->tm_min << ":"
+ << std::setw(2) << time->tm_sec << '\n'
+ << '\n'
+ << " For a description of the POVRAY format see the POVRAY manual."
+ << '\n'
+ << "*/ " << '\n';
+
+ // include files
out << "#include \"colors.inc\" " << '\n'
- << "#include \"textures.inc\" " << '\n';
+ << "#include \"textures.inc\" " << '\n';
- // use external include file for textures,
- // camera and light
+ // use external include file for textures,
+ // camera and light
if (flags.external_data)
- out << "#include \"data.inc\" " << '\n';
+ out << "#include \"data.inc\" " << '\n';
else // all definitions in data file
- {
- // camera
- out << '\n' << '\n'
- << "camera {" << '\n'
- << " location <1,4,-7>" << '\n'
- << " look_at <0,0,0>" << '\n'
- << " angle 30" << '\n'
- << "}" << '\n';
-
- // light
- out << '\n'
- << "light_source {" << '\n'
- << " <1,4,-7>" << '\n'
- << " color Grey" << '\n'
- << "}" << '\n';
- out << '\n'
- << "light_source {" << '\n'
- << " <0,20,0>" << '\n'
- << " color White" << '\n'
- << "}" << '\n';
- }
+ {
+ // camera
+ out << '\n' << '\n'
+ << "camera {" << '\n'
+ << " location <1,4,-7>" << '\n'
+ << " look_at <0,0,0>" << '\n'
+ << " angle 30" << '\n'
+ << "}" << '\n';
+
+ // light
+ out << '\n'
+ << "light_source {" << '\n'
+ << " <1,4,-7>" << '\n'
+ << " color Grey" << '\n'
+ << "}" << '\n';
+ out << '\n'
+ << "light_source {" << '\n'
+ << " <0,20,0>" << '\n'
+ << " color White" << '\n'
+ << "}" << '\n';
+ }
}
- // max. and min. heigth of solution
+ // max. and min. heigth of solution
typename std::vector<Patch<dim,spacedim> >::const_iterator patch=patches.begin();
Assert(patch!=patches.end(), ExcInternalError());
double hmin=patch->data(0,0);
const unsigned int n_subdivisions = patch->n_subdivisions;
Assert ((patch->data.n_rows() == n_data_sets && !patch->points_are_available) ||
- (patch->data.n_rows() == n_data_sets+spacedim && patch->points_are_available),
- ExcDimensionMismatch (patch->points_are_available
- ?
- (n_data_sets + spacedim)
- :
- n_data_sets,
- patch->data.n_rows()));
+ (patch->data.n_rows() == n_data_sets+spacedim && patch->points_are_available),
+ ExcDimensionMismatch (patch->points_are_available
+ ?
+ (n_data_sets + spacedim)
+ :
+ n_data_sets,
+ patch->data.n_rows()));
Assert (patch->data.n_cols() == Utilities::fixed_power<dim>(n_subdivisions+1),
- ExcInvalidDatasetSize (patch->data.n_cols(), n_subdivisions+1));
+ ExcInvalidDatasetSize (patch->data.n_cols(), n_subdivisions+1));
for (unsigned int i=0; i<n_subdivisions+1; ++i)
- for (unsigned int j=0; j<n_subdivisions+1; ++j)
- {
- const int dl = i*(n_subdivisions+1)+j;
- if (patch->data(0,dl)<hmin)
- hmin=patch->data(0,dl);
- if (patch->data(0,dl)>hmax)
- hmax=patch->data(0,dl);
- }
+ for (unsigned int j=0; j<n_subdivisions+1; ++j)
+ {
+ const int dl = i*(n_subdivisions+1)+j;
+ if (patch->data(0,dl)<hmin)
+ hmin=patch->data(0,dl);
+ if (patch->data(0,dl)>hmax)
+ hmax=patch->data(0,dl);
+ }
}
out << "#declare HMIN=" << hmin << ";" << '\n'
if (!flags.external_data)
{
- // texture with scaled niveau lines
- // 10 lines in the surface
+ // texture with scaled niveau lines
+ // 10 lines in the surface
out << "#declare Tex=texture{" << '\n'
- << " pigment {" << '\n'
- << " gradient y" << '\n'
- << " scale y*(HMAX-HMIN)*" << 0.1 << '\n'
- << " color_map {" << '\n'
- << " [0.00 color Light_Purple] " << '\n'
- << " [0.95 color Light_Purple] " << '\n'
- << " [1.00 color White] " << '\n'
- << "} } }" << '\n' << '\n';
+ << " pigment {" << '\n'
+ << " gradient y" << '\n'
+ << " scale y*(HMAX-HMIN)*" << 0.1 << '\n'
+ << " color_map {" << '\n'
+ << " [0.00 color Light_Purple] " << '\n'
+ << " [0.95 color Light_Purple] " << '\n'
+ << " [1.00 color White] " << '\n'
+ << "} } }" << '\n' << '\n';
}
if (!flags.bicubic_patch)
{ // start of mesh header
out << '\n'
- << "mesh {" << '\n';
+ << "mesh {" << '\n';
}
- // loop over all patches
+ // loop over all patches
for (typename std::vector<Patch<dim,spacedim> >::const_iterator patch=patches.begin();
patch != patches.end(); ++patch)
{
const unsigned int d2=n;
Assert ((patch->data.n_rows() == n_data_sets && !patch->points_are_available) ||
- (patch->data.n_rows() == n_data_sets+spacedim && patch->points_are_available),
- ExcDimensionMismatch (patch->points_are_available
- ?
- (n_data_sets + spacedim)
- :
- n_data_sets,
- patch->data.n_rows()));
+ (patch->data.n_rows() == n_data_sets+spacedim && patch->points_are_available),
+ ExcDimensionMismatch (patch->points_are_available
+ ?
+ (n_data_sets + spacedim)
+ :
+ n_data_sets,
+ patch->data.n_rows()));
Assert (patch->data.n_cols() == Utilities::fixed_power<dim>(n),
- ExcInvalidDatasetSize (patch->data.n_cols(), n_subdivisions+1));
+ ExcInvalidDatasetSize (patch->data.n_cols(), n_subdivisions+1));
std::vector<Point<spacedim> > ver(n*n);
for (unsigned int i2=0; i2<n; ++i2)
- for (unsigned int i1=0; i1<n; ++i1)
- {
- // compute coordinates for
- // this patch point, storing in ver
- compute_node(ver[i1*d1+i2*d2], &*patch, i1, i2, 0, n_subdivisions);
- }
+ for (unsigned int i1=0; i1<n; ++i1)
+ {
+ // compute coordinates for
+ // this patch point, storing in ver
+ compute_node(ver[i1*d1+i2*d2], &*patch, i1, i2, 0, n_subdivisions);
+ }
if (!flags.bicubic_patch)
- {
- // aproximate normal
- // vectors in patch
- std::vector<Point<3> > nrml;
- // only if smooth triangles are used
- if (flags.smooth)
- {
- nrml.resize(n*n);
- // These are
- // difference
- // quotients of
- // the surface
- // mapping. We
- // take them
- // symmetric
- // inside the
- // patch and
- // one-sided at
- // the edges
- Point<3> h1,h2;
- // Now compute normals in every point
- for (unsigned int i=0; i<n;++i)
- for (unsigned int j=0; j<n;++j)
- {
- const unsigned int il = (i==0) ? i : (i-1);
- const unsigned int ir = (i==n_subdivisions) ? i : (i+1);
- const unsigned int jl = (j==0) ? j : (j-1);
- const unsigned int jr = (j==n_subdivisions) ? j : (j+1);
-
- h1(0)=ver[ir*d1+j*d2](0) - ver[il*d1+j*d2](0);
- h1(1)=patch->data(0,ir*d1+j*d2)-
- patch->data(0,il*d1+j*d2);
- h1(2)=ver[ir*d1+j*d2](1) - ver[il*d1+j*d2](1);
-
- h2(0)=ver[i*d1+jr*d2](0) - ver[i*d1+jl*d2](0);
- h2(1)=patch->data(0,i*d1+jr*d2)-
- patch->data(0,i*d1+jl*d2);
- h2(2)=ver[i*d1+jr*d2](1) - ver[i*d1+jl*d2](1);
-
- nrml[i*d1+j*d2](0)=h1(1)*h2(2)-h1(2)*h2(1);
- nrml[i*d1+j*d2](1)=h1(2)*h2(0)-h1(0)*h2(2);
- nrml[i*d1+j*d2](2)=h1(0)*h2(1)-h1(1)*h2(0);
-
- // normalize Vector
- double norm=std::sqrt(
- std::pow(nrml[i*d1+j*d2](0),2.)+
- std::pow(nrml[i*d1+j*d2](1),2.)+
- std::pow(nrml[i*d1+j*d2](2),2.));
-
- if (nrml[i*d1+j*d2](1)<0)
- norm*=-1.;
-
- for (unsigned int k=0;k<3;++k)
- nrml[i*d1+j*d2](k)/=norm;
- }
- }
-
- // setting up triangles
- for (unsigned int i=0; i<n_subdivisions; ++i)
- for (unsigned int j=0; j<n_subdivisions; ++j)
- {
- // down/left vertex of triangle
- const int dl = i*d1+j*d2;
- if (flags.smooth)
- {
- // writing smooth_triangles
-
- // down/right triangle
- out << "smooth_triangle {" << '\n' << "\t<"
- << ver[dl](0) << ","
- << patch->data(0,dl) << ","
- << ver[dl](1) << ">, <"
- << nrml[dl](0) << ", "
- << nrml[dl](1) << ", "
- << nrml[dl](2)
- << ">," << '\n';
- out << " \t<"
- << ver[dl+d1](0) << ","
- << patch->data(0,dl+d1) << ","
- << ver[dl+d1](1) << ">, <"
- << nrml[dl+d1](0) << ", "
- << nrml[dl+d1](1) << ", "
- << nrml[dl+d1](2)
- << ">," << '\n';
- out << "\t<"
- << ver[dl+d1+d2](0) << ","
- << patch->data(0,dl+d1+d2) << ","
- << ver[dl+d1+d2](1) << ">, <"
- << nrml[dl+d1+d2](0) << ", "
- << nrml[dl+d1+d2](1) << ", "
- << nrml[dl+d1+d2](2)
- << ">}" << '\n';
-
- // upper/left triangle
- out << "smooth_triangle {" << '\n' << "\t<"
- << ver[dl](0) << ","
- << patch->data(0,dl) << ","
- << ver[dl](1) << ">, <"
- << nrml[dl](0) << ", "
- << nrml[dl](1) << ", "
- << nrml[dl](2)
- << ">," << '\n';
- out << "\t<"
- << ver[dl+d1+d2](0) << ","
- << patch->data(0,dl+d1+d2) << ","
- << ver[dl+d1+d2](1) << ">, <"
- << nrml[dl+d1+d2](0) << ", "
- << nrml[dl+d1+d2](1) << ", "
- << nrml[dl+d1+d2](2)
- << ">," << '\n';
- out << "\t<"
- << ver[dl+d2](0) << ","
- << patch->data(0,dl+d2) << ","
- << ver[dl+d2](1) << ">, <"
- << nrml[dl+d2](0) << ", "
- << nrml[dl+d2](1) << ", "
- << nrml[dl+d2](2)
- << ">}" << '\n';
- }
- else
- {
- // writing standard triangles
- // down/right triangle
- out << "triangle {" << '\n' << "\t<"
- << ver[dl](0) << ","
- << patch->data(0,dl) << ","
- << ver[dl](1) << ">," << '\n';
- out << "\t<"
- << ver[dl+d1](0) << ","
- << patch->data(0,dl+d1) << ","
- << ver[dl+d1](1) << ">," << '\n';
- out << "\t<"
- << ver[dl+d1+d2](0) << ","
- << patch->data(0,dl+d1+d2) << ","
- << ver[dl+d1+d2](1) << ">}" << '\n';
-
- // upper/left triangle
- out << "triangle {" << '\n' << "\t<"
- << ver[dl](0) << ","
- << patch->data(0,dl) << ","
- << ver[dl](1) << ">," << '\n';
- out << "\t<"
- << ver[dl+d1+d2](0) << ","
- << patch->data(0,dl+d1+d2) << ","
- << ver[dl+d1+d2](1) << ">," << '\n';
- out << "\t<"
- << ver[dl+d2](0) << ","
- << patch->data(0,dl+d2) << ","
- << ver[dl+d2](1) << ">}" << '\n';
- }
- }
- }
+ {
+ // aproximate normal
+ // vectors in patch
+ std::vector<Point<3> > nrml;
+ // only if smooth triangles are used
+ if (flags.smooth)
+ {
+ nrml.resize(n*n);
+ // These are
+ // difference
+ // quotients of
+ // the surface
+ // mapping. We
+ // take them
+ // symmetric
+ // inside the
+ // patch and
+ // one-sided at
+ // the edges
+ Point<3> h1,h2;
+ // Now compute normals in every point
+ for (unsigned int i=0; i<n;++i)
+ for (unsigned int j=0; j<n;++j)
+ {
+ const unsigned int il = (i==0) ? i : (i-1);
+ const unsigned int ir = (i==n_subdivisions) ? i : (i+1);
+ const unsigned int jl = (j==0) ? j : (j-1);
+ const unsigned int jr = (j==n_subdivisions) ? j : (j+1);
+
+ h1(0)=ver[ir*d1+j*d2](0) - ver[il*d1+j*d2](0);
+ h1(1)=patch->data(0,ir*d1+j*d2)-
+ patch->data(0,il*d1+j*d2);
+ h1(2)=ver[ir*d1+j*d2](1) - ver[il*d1+j*d2](1);
+
+ h2(0)=ver[i*d1+jr*d2](0) - ver[i*d1+jl*d2](0);
+ h2(1)=patch->data(0,i*d1+jr*d2)-
+ patch->data(0,i*d1+jl*d2);
+ h2(2)=ver[i*d1+jr*d2](1) - ver[i*d1+jl*d2](1);
+
+ nrml[i*d1+j*d2](0)=h1(1)*h2(2)-h1(2)*h2(1);
+ nrml[i*d1+j*d2](1)=h1(2)*h2(0)-h1(0)*h2(2);
+ nrml[i*d1+j*d2](2)=h1(0)*h2(1)-h1(1)*h2(0);
+
+ // normalize Vector
+ double norm=std::sqrt(
+ std::pow(nrml[i*d1+j*d2](0),2.)+
+ std::pow(nrml[i*d1+j*d2](1),2.)+
+ std::pow(nrml[i*d1+j*d2](2),2.));
+
+ if (nrml[i*d1+j*d2](1)<0)
+ norm*=-1.;
+
+ for (unsigned int k=0;k<3;++k)
+ nrml[i*d1+j*d2](k)/=norm;
+ }
+ }
+
+ // setting up triangles
+ for (unsigned int i=0; i<n_subdivisions; ++i)
+ for (unsigned int j=0; j<n_subdivisions; ++j)
+ {
+ // down/left vertex of triangle
+ const int dl = i*d1+j*d2;
+ if (flags.smooth)
+ {
+ // writing smooth_triangles
+
+ // down/right triangle
+ out << "smooth_triangle {" << '\n' << "\t<"
+ << ver[dl](0) << ","
+ << patch->data(0,dl) << ","
+ << ver[dl](1) << ">, <"
+ << nrml[dl](0) << ", "
+ << nrml[dl](1) << ", "
+ << nrml[dl](2)
+ << ">," << '\n';
+ out << " \t<"
+ << ver[dl+d1](0) << ","
+ << patch->data(0,dl+d1) << ","
+ << ver[dl+d1](1) << ">, <"
+ << nrml[dl+d1](0) << ", "
+ << nrml[dl+d1](1) << ", "
+ << nrml[dl+d1](2)
+ << ">," << '\n';
+ out << "\t<"
+ << ver[dl+d1+d2](0) << ","
+ << patch->data(0,dl+d1+d2) << ","
+ << ver[dl+d1+d2](1) << ">, <"
+ << nrml[dl+d1+d2](0) << ", "
+ << nrml[dl+d1+d2](1) << ", "
+ << nrml[dl+d1+d2](2)
+ << ">}" << '\n';
+
+ // upper/left triangle
+ out << "smooth_triangle {" << '\n' << "\t<"
+ << ver[dl](0) << ","
+ << patch->data(0,dl) << ","
+ << ver[dl](1) << ">, <"
+ << nrml[dl](0) << ", "
+ << nrml[dl](1) << ", "
+ << nrml[dl](2)
+ << ">," << '\n';
+ out << "\t<"
+ << ver[dl+d1+d2](0) << ","
+ << patch->data(0,dl+d1+d2) << ","
+ << ver[dl+d1+d2](1) << ">, <"
+ << nrml[dl+d1+d2](0) << ", "
+ << nrml[dl+d1+d2](1) << ", "
+ << nrml[dl+d1+d2](2)
+ << ">," << '\n';
+ out << "\t<"
+ << ver[dl+d2](0) << ","
+ << patch->data(0,dl+d2) << ","
+ << ver[dl+d2](1) << ">, <"
+ << nrml[dl+d2](0) << ", "
+ << nrml[dl+d2](1) << ", "
+ << nrml[dl+d2](2)
+ << ">}" << '\n';
+ }
+ else
+ {
+ // writing standard triangles
+ // down/right triangle
+ out << "triangle {" << '\n' << "\t<"
+ << ver[dl](0) << ","
+ << patch->data(0,dl) << ","
+ << ver[dl](1) << ">," << '\n';
+ out << "\t<"
+ << ver[dl+d1](0) << ","
+ << patch->data(0,dl+d1) << ","
+ << ver[dl+d1](1) << ">," << '\n';
+ out << "\t<"
+ << ver[dl+d1+d2](0) << ","
+ << patch->data(0,dl+d1+d2) << ","
+ << ver[dl+d1+d2](1) << ">}" << '\n';
+
+ // upper/left triangle
+ out << "triangle {" << '\n' << "\t<"
+ << ver[dl](0) << ","
+ << patch->data(0,dl) << ","
+ << ver[dl](1) << ">," << '\n';
+ out << "\t<"
+ << ver[dl+d1+d2](0) << ","
+ << patch->data(0,dl+d1+d2) << ","
+ << ver[dl+d1+d2](1) << ">," << '\n';
+ out << "\t<"
+ << ver[dl+d2](0) << ","
+ << patch->data(0,dl+d2) << ","
+ << ver[dl+d2](1) << ">}" << '\n';
+ }
+ }
+ }
else
- { // writing bicubic_patch
- Assert (n_subdivisions==3, ExcDimensionMismatch(n_subdivisions,3));
- out << '\n'
- << "bicubic_patch {" << '\n'
- << " type 0" << '\n'
- << " flatness 0" << '\n'
- << " u_steps 0" << '\n'
- << " v_steps 0" << '\n';
- for (int i=0;i<16;++i)
- {
- out << "\t<" << ver[i](0) << "," << patch->data(0,i) << "," << ver[i](1) << ">";
- if (i!=15) out << ",";
- out << '\n';
- }
- out << " texture {Tex}" << '\n'
- << "}" << '\n';
- }
+ { // writing bicubic_patch
+ Assert (n_subdivisions==3, ExcDimensionMismatch(n_subdivisions,3));
+ out << '\n'
+ << "bicubic_patch {" << '\n'
+ << " type 0" << '\n'
+ << " flatness 0" << '\n'
+ << " u_steps 0" << '\n'
+ << " v_steps 0" << '\n';
+ for (int i=0;i<16;++i)
+ {
+ out << "\t<" << ver[i](0) << "," << patch->data(0,i) << "," << ver[i](1) << ">";
+ if (i!=15) out << ",";
+ out << '\n';
+ }
+ out << " texture {Tex}" << '\n'
+ << "}" << '\n';
+ }
}
if (!flags.bicubic_patch)
{ // the end of the mesh
out << " texture {Tex}" << '\n'
- << "}" << '\n'
- << '\n';
+ << "}" << '\n'
+ << '\n';
}
- // make sure everything now gets to
- // disk
+ // make sure everything now gets to
+ // disk
out.flush ();
AssertThrow (out, ExcIO());
template <int dim, int spacedim>
void DataOutBase::write_eps (const std::vector<Patch<dim,spacedim> > &patches,
- const std::vector<std::string> &/*data_names*/,
- const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &,
- const EpsFlags &flags,
- std::ostream &out)
+ const std::vector<std::string> &/*data_names*/,
+ const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &,
+ const EpsFlags &flags,
+ std::ostream &out)
{
Assert (out, ExcIO());
#ifndef DEAL_II_COMPILER_SUPPORTS_MPI
- // verify that there are indeed
- // patches to be written out. most
- // of the times, people just forget
- // to call build_patches when there
- // are no patches, so a warning is
- // in order. that said, the
- // assertion is disabled if we
- // support MPI since then it can
- // happen that on the coarsest
- // mesh, a processor simply has no
- // cells it actually owns, and in
- // that case it is legit if there
- // are no patches
+ // verify that there are indeed
+ // patches to be written out. most
+ // of the times, people just forget
+ // to call build_patches when there
+ // are no patches, so a warning is
+ // in order. that said, the
+ // assertion is disabled if we
+ // support MPI since then it can
+ // happen that on the coarsest
+ // mesh, a processor simply has no
+ // cells it actually owns, and in
+ // that case it is legit if there
+ // are no patches
Assert (patches.size() > 0, ExcNoPatches());
#else
if (patches.size() == 0)
return;
#endif
- // Do not allow volume rendering
+ // Do not allow volume rendering
AssertThrow (dim==2, ExcNotImplemented());
const unsigned int old_precision = out.precision();
- // set up an array of cells to be
- // written later. this array holds the
- // cells of all the patches as
- // projected to the plane perpendicular
- // to the line of sight.
- //
- // note that they are kept sorted by
- // the set, where we chose the value
- // of the center point of the cell
- // along the line of sight as value
- // for sorting
+ // set up an array of cells to be
+ // written later. this array holds the
+ // cells of all the patches as
+ // projected to the plane perpendicular
+ // to the line of sight.
+ //
+ // note that they are kept sorted by
+ // the set, where we chose the value
+ // of the center point of the cell
+ // along the line of sight as value
+ // for sorting
std::multiset<EpsCell2d> cells;
- // two variables in which we
- // will store the minimum and
- // maximum values of the field
- // to be used for colorization
- //
- // preset them by 0 to calm down the
- // compiler; they are initialized later
+ // two variables in which we
+ // will store the minimum and
+ // maximum values of the field
+ // to be used for colorization
+ //
+ // preset them by 0 to calm down the
+ // compiler; they are initialized later
double min_color_value=0, max_color_value=0;
- // Array for z-coordinates of points.
- // The elevation determined by a function if spacedim=2
- // or the z-cooridate of the grid point if spacedim=3
+ // Array for z-coordinates of points.
+ // The elevation determined by a function if spacedim=2
+ // or the z-cooridate of the grid point if spacedim=3
double heights[4] = { 0, 0, 0, 0 };
- // compute the cells for output and
- // enter them into the set above
- // note that since dim==2, we
- // have exactly four vertices per
- // patch and per cell
+ // compute the cells for output and
+ // enter them into the set above
+ // note that since dim==2, we
+ // have exactly four vertices per
+ // patch and per cell
for (typename std::vector<Patch<dim,spacedim> >::const_iterator patch=patches.begin();
patch!=patches.end(); ++patch)
{
const unsigned int d2 = n;
for (unsigned int i2=0; i2<n_subdivisions; ++i2)
- for (unsigned int i1=0; i1<n_subdivisions; ++i1)
- {
- Point<spacedim> points[4];
- compute_node(points[0], &*patch, i1, i2, 0, n_subdivisions);
- compute_node(points[1], &*patch, i1+1, i2, 0, n_subdivisions);
- compute_node(points[2], &*patch, i1, i2+1, 0, n_subdivisions);
- compute_node(points[3], &*patch, i1+1, i2+1, 0, n_subdivisions);
-
- switch (spacedim)
- {
- case 2:
- Assert ((flags.height_vector < patch->data.n_rows()) ||
- patch->data.n_rows() == 0,
- ExcIndexRange (flags.height_vector, 0,
- patch->data.n_rows()));
- heights[0] = patch->data.n_rows() != 0 ?
- patch->data(flags.height_vector,i1*d1 + i2*d2) * flags.z_scaling
- : 0;
- heights[1] = patch->data.n_rows() != 0 ?
- patch->data(flags.height_vector,(i1+1)*d1 + i2*d2) * flags.z_scaling
- : 0;
- heights[2] = patch->data.n_rows() != 0 ?
- patch->data(flags.height_vector,i1*d1 + (i2+1)*d2) * flags.z_scaling
- : 0;
- heights[3] = patch->data.n_rows() != 0 ?
- patch->data(flags.height_vector,(i1+1)*d1 + (i2+1)*d2) * flags.z_scaling
- : 0;
-
- break;
- case 3:
- // Copy z-coordinates into the height vector
- for (unsigned int i=0;i<4;++i)
- heights[i] = points[i](2);
- break;
- default:
- Assert(false, ExcNotImplemented());
- }
-
-
- // now compute the projection of
- // the bilinear cell given by the
- // four vertices and their heights
- // and write them to a proper
- // cell object. note that we only
- // need the first two components
- // of the projected position for
- // output, but we need the value
- // along the line of sight for
- // sorting the cells for back-to-
- // front-output
- //
- // this computation was first written
- // by Stefan Nauber. please no-one
- // ask me why it works that way (or
- // may be not), especially not about
- // the angles and the sign of
- // the height field, I don't know
- // it.
- EpsCell2d eps_cell;
- const double pi = numbers::PI;
- const double cx = -std::cos(pi-flags.azimut_angle * 2*pi / 360.),
- cz = -std::cos(flags.turn_angle * 2*pi / 360.),
- sx = std::sin(pi-flags.azimut_angle * 2*pi / 360.),
- sz = std::sin(flags.turn_angle * 2*pi / 360.);
- for (unsigned int vertex=0; vertex<4; ++vertex)
- {
- const double x = points[vertex](0),
- y = points[vertex](1),
- z = -heights[vertex];
-
- eps_cell.vertices[vertex](0) = - cz*x+ sz*y;
- eps_cell.vertices[vertex](1) = -cx*sz*x-cx*cz*y-sx*z;
-
- // ( 1 0 0 )
- // D1 = ( 0 cx -sx )
- // ( 0 sx cx )
-
- // ( cy 0 sy )
- // Dy = ( 0 1 0 )
- // (-sy 0 cy )
-
- // ( cz -sz 0 )
- // Dz = ( sz cz 0 )
- // ( 0 0 1 )
+ for (unsigned int i1=0; i1<n_subdivisions; ++i1)
+ {
+ Point<spacedim> points[4];
+ compute_node(points[0], &*patch, i1, i2, 0, n_subdivisions);
+ compute_node(points[1], &*patch, i1+1, i2, 0, n_subdivisions);
+ compute_node(points[2], &*patch, i1, i2+1, 0, n_subdivisions);
+ compute_node(points[3], &*patch, i1+1, i2+1, 0, n_subdivisions);
+
+ switch (spacedim)
+ {
+ case 2:
+ Assert ((flags.height_vector < patch->data.n_rows()) ||
+ patch->data.n_rows() == 0,
+ ExcIndexRange (flags.height_vector, 0,
+ patch->data.n_rows()));
+ heights[0] = patch->data.n_rows() != 0 ?
+ patch->data(flags.height_vector,i1*d1 + i2*d2) * flags.z_scaling
+ : 0;
+ heights[1] = patch->data.n_rows() != 0 ?
+ patch->data(flags.height_vector,(i1+1)*d1 + i2*d2) * flags.z_scaling
+ : 0;
+ heights[2] = patch->data.n_rows() != 0 ?
+ patch->data(flags.height_vector,i1*d1 + (i2+1)*d2) * flags.z_scaling
+ : 0;
+ heights[3] = patch->data.n_rows() != 0 ?
+ patch->data(flags.height_vector,(i1+1)*d1 + (i2+1)*d2) * flags.z_scaling
+ : 0;
+
+ break;
+ case 3:
+ // Copy z-coordinates into the height vector
+ for (unsigned int i=0;i<4;++i)
+ heights[i] = points[i](2);
+ break;
+ default:
+ Assert(false, ExcNotImplemented());
+ }
+
+
+ // now compute the projection of
+ // the bilinear cell given by the
+ // four vertices and their heights
+ // and write them to a proper
+ // cell object. note that we only
+ // need the first two components
+ // of the projected position for
+ // output, but we need the value
+ // along the line of sight for
+ // sorting the cells for back-to-
+ // front-output
+ //
+ // this computation was first written
+ // by Stefan Nauber. please no-one
+ // ask me why it works that way (or
+ // may be not), especially not about
+ // the angles and the sign of
+ // the height field, I don't know
+ // it.
+ EpsCell2d eps_cell;
+ const double pi = numbers::PI;
+ const double cx = -std::cos(pi-flags.azimut_angle * 2*pi / 360.),
+ cz = -std::cos(flags.turn_angle * 2*pi / 360.),
+ sx = std::sin(pi-flags.azimut_angle * 2*pi / 360.),
+ sz = std::sin(flags.turn_angle * 2*pi / 360.);
+ for (unsigned int vertex=0; vertex<4; ++vertex)
+ {
+ const double x = points[vertex](0),
+ y = points[vertex](1),
+ z = -heights[vertex];
+
+ eps_cell.vertices[vertex](0) = - cz*x+ sz*y;
+ eps_cell.vertices[vertex](1) = -cx*sz*x-cx*cz*y-sx*z;
+
+ // ( 1 0 0 )
+ // D1 = ( 0 cx -sx )
+ // ( 0 sx cx )
+
+ // ( cy 0 sy )
+ // Dy = ( 0 1 0 )
+ // (-sy 0 cy )
+
+ // ( cz -sz 0 )
+ // Dz = ( sz cz 0 )
+ // ( 0 0 1 )
// ( cz -sz 0 )( 1 0 0 )(x) ( cz*x-sz*(cx*y-sx*z)+0*(sx*y+cx*z) )
// Dxz = ( sz cz 0 )( 0 cx -sx )(y) = ( sz*x+cz*(cx*y-sx*z)+0*(sx*y+cx*z) )
-// ( 0 0 1 )( 0 sx cx )(z) ( 0*x+ *(cx*y-sx*z)+1*(sx*y+cx*z) )
- }
-
- // compute coordinates of
- // center of cell
- const Point<spacedim> center_point
- = (points[0] + points[1] + points[2] + points[3]) / 4;
- const double center_height
- = -(heights[0] + heights[1] + heights[2] + heights[3]) / 4;
-
- // compute the depth into
- // the picture
- eps_cell.depth = -sx*sz*center_point(0)
- -sx*cz*center_point(1)
- +cx*center_height;
-
- if (flags.draw_cells && flags.shade_cells)
- {
- Assert ((flags.color_vector < patch->data.n_rows()) ||
- patch->data.n_rows() == 0,
- ExcIndexRange (flags.color_vector, 0,
- patch->data.n_rows()));
- const double color_values[4]
- = { patch->data.n_rows() != 0 ?
- patch->data(flags.color_vector,i1*d1 + i2*d2) : 1,
-
- patch->data.n_rows() != 0 ?
- patch->data(flags.color_vector,(i1+1)*d1 + i2*d2) : 1,
-
- patch->data.n_rows() != 0 ?
- patch->data(flags.color_vector,i1*d1 + (i2+1)*d2) : 1,
-
- patch->data.n_rows() != 0 ?
- patch->data(flags.color_vector,(i1+1)*d1 + (i2+1)*d2) : 1};
-
- // set color value to average of the value
- // at the vertices
- eps_cell.color_value = (color_values[0] +
- color_values[1] +
- color_values[3] +
- color_values[2]) / 4;
-
- // update bounds of color
- // field
- if (patch == patches.begin())
- min_color_value = max_color_value = eps_cell.color_value;
- else
- {
- min_color_value = (min_color_value < eps_cell.color_value ?
- min_color_value : eps_cell.color_value);
- max_color_value = (max_color_value > eps_cell.color_value ?
- max_color_value : eps_cell.color_value);
- }
- }
-
- // finally add this cell
- cells.insert (eps_cell);
- }
+// ( 0 0 1 )( 0 sx cx )(z) ( 0*x+ *(cx*y-sx*z)+1*(sx*y+cx*z) )
+ }
+
+ // compute coordinates of
+ // center of cell
+ const Point<spacedim> center_point
+ = (points[0] + points[1] + points[2] + points[3]) / 4;
+ const double center_height
+ = -(heights[0] + heights[1] + heights[2] + heights[3]) / 4;
+
+ // compute the depth into
+ // the picture
+ eps_cell.depth = -sx*sz*center_point(0)
+ -sx*cz*center_point(1)
+ +cx*center_height;
+
+ if (flags.draw_cells && flags.shade_cells)
+ {
+ Assert ((flags.color_vector < patch->data.n_rows()) ||
+ patch->data.n_rows() == 0,
+ ExcIndexRange (flags.color_vector, 0,
+ patch->data.n_rows()));
+ const double color_values[4]
+ = { patch->data.n_rows() != 0 ?
+ patch->data(flags.color_vector,i1*d1 + i2*d2) : 1,
+
+ patch->data.n_rows() != 0 ?
+ patch->data(flags.color_vector,(i1+1)*d1 + i2*d2) : 1,
+
+ patch->data.n_rows() != 0 ?
+ patch->data(flags.color_vector,i1*d1 + (i2+1)*d2) : 1,
+
+ patch->data.n_rows() != 0 ?
+ patch->data(flags.color_vector,(i1+1)*d1 + (i2+1)*d2) : 1};
+
+ // set color value to average of the value
+ // at the vertices
+ eps_cell.color_value = (color_values[0] +
+ color_values[1] +
+ color_values[3] +
+ color_values[2]) / 4;
+
+ // update bounds of color
+ // field
+ if (patch == patches.begin())
+ min_color_value = max_color_value = eps_cell.color_value;
+ else
+ {
+ min_color_value = (min_color_value < eps_cell.color_value ?
+ min_color_value : eps_cell.color_value);
+ max_color_value = (max_color_value > eps_cell.color_value ?
+ max_color_value : eps_cell.color_value);
+ }
+ }
+
+ // finally add this cell
+ cells.insert (eps_cell);
+ }
}
- // find out minimum and maximum x and
- // y coordinates to compute offsets
- // and scaling factors
+ // find out minimum and maximum x and
+ // y coordinates to compute offsets
+ // and scaling factors
double x_min = cells.begin()->vertices[0](0);
double x_max = x_min;
double y_min = cells.begin()->vertices[0](1);
double y_max = y_min;
for (typename std::multiset<EpsCell2d>::const_iterator
- cell=cells.begin();
+ cell=cells.begin();
cell!=cells.end(); ++cell)
for (unsigned int vertex=0; vertex<4; ++vertex)
{
- x_min = std::min (x_min, cell->vertices[vertex](0));
- x_max = std::max (x_max, cell->vertices[vertex](0));
- y_min = std::min (y_min, cell->vertices[vertex](1));
- y_max = std::max (y_max, cell->vertices[vertex](1));
+ x_min = std::min (x_min, cell->vertices[vertex](0));
+ x_max = std::max (x_max, cell->vertices[vertex](0));
+ y_min = std::min (y_min, cell->vertices[vertex](1));
+ y_max = std::max (y_max, cell->vertices[vertex](1));
}
- // scale in x-direction such that
- // in the output 0 <= x <= 300.
- // don't scale in y-direction to
- // preserve the shape of the
- // triangulation
+ // scale in x-direction such that
+ // in the output 0 <= x <= 300.
+ // don't scale in y-direction to
+ // preserve the shape of the
+ // triangulation
const double scale = (flags.size /
- (flags.size_type==EpsFlags::width ?
- x_max - x_min :
- y_min - y_max));
+ (flags.size_type==EpsFlags::width ?
+ x_max - x_min :
+ y_min - y_max));
const Point<2> offset(x_min, y_min);
- // now write preamble
+ // now write preamble
if (true)
{
- // block this to have local
- // variables destroyed after
- // use
+ // block this to have local
+ // variables destroyed after
+ // use
std::time_t time1= std::time (0);
std::tm *time = std::localtime(&time1);
out << "%!PS-Adobe-2.0 EPSF-1.2" << '\n'
- << "%%Title: deal.II Output" << '\n'
- << "%%Creator: the deal.II library" << '\n'
- << "%%Creation Date: "
- << time->tm_year+1900 << "/"
- << time->tm_mon+1 << "/"
- << time->tm_mday << " - "
- << time->tm_hour << ":"
- << std::setw(2) << time->tm_min << ":"
- << std::setw(2) << time->tm_sec << '\n'
- << "%%BoundingBox: "
- // lower left corner
- << "0 0 "
- // upper right corner
- << static_cast<unsigned int>( (x_max-x_min) * scale + 0.5)
- << ' '
- << static_cast<unsigned int>( (y_max-y_min) * scale + 0.5)
- << '\n';
-
- // define some abbreviations to keep
- // the output small:
- // m=move turtle to
- // l=define a line
- // s=set rgb color
- // sg=set gray value
- // lx=close the line and plot the line
- // lf=close the line and fill the interior
+ << "%%Title: deal.II Output" << '\n'
+ << "%%Creator: the deal.II library" << '\n'
+ << "%%Creation Date: "
+ << time->tm_year+1900 << "/"
+ << time->tm_mon+1 << "/"
+ << time->tm_mday << " - "
+ << time->tm_hour << ":"
+ << std::setw(2) << time->tm_min << ":"
+ << std::setw(2) << time->tm_sec << '\n'
+ << "%%BoundingBox: "
+ // lower left corner
+ << "0 0 "
+ // upper right corner
+ << static_cast<unsigned int>( (x_max-x_min) * scale + 0.5)
+ << ' '
+ << static_cast<unsigned int>( (y_max-y_min) * scale + 0.5)
+ << '\n';
+
+ // define some abbreviations to keep
+ // the output small:
+ // m=move turtle to
+ // l=define a line
+ // s=set rgb color
+ // sg=set gray value
+ // lx=close the line and plot the line
+ // lf=close the line and fill the interior
out << "/m {moveto} bind def" << '\n'
- << "/l {lineto} bind def" << '\n'
- << "/s {setrgbcolor} bind def" << '\n'
- << "/sg {setgray} bind def" << '\n'
- << "/lx {lineto closepath stroke} bind def" << '\n'
- << "/lf {lineto closepath fill} bind def" << '\n';
+ << "/l {lineto} bind def" << '\n'
+ << "/s {setrgbcolor} bind def" << '\n'
+ << "/sg {setgray} bind def" << '\n'
+ << "/lx {lineto closepath stroke} bind def" << '\n'
+ << "/lf {lineto closepath fill} bind def" << '\n';
out << "%%EndProlog" << '\n'
- << '\n';
- // set fine lines
+ << '\n';
+ // set fine lines
out << flags.line_width << " setlinewidth" << '\n';
- // allow only five digits
- // for output (instead of the
- // default six); this should suffice
- // even for fine grids, but reduces
- // the file size significantly
+ // allow only five digits
+ // for output (instead of the
+ // default six); this should suffice
+ // even for fine grids, but reduces
+ // the file size significantly
out << std::setprecision (5);
}
- // check if min and max
- // values for the color are
- // actually different. If
- // that is not the case (such
- // things happen, for
- // example, in the very first
- // time step of a time
- // dependent problem, if the
- // initial values are zero),
- // all values are equal, and
- // then we can draw
- // everything in an arbitrary
- // color. Thus, change one of
- // the two values arbitrarily
+ // check if min and max
+ // values for the color are
+ // actually different. If
+ // that is not the case (such
+ // things happen, for
+ // example, in the very first
+ // time step of a time
+ // dependent problem, if the
+ // initial values are zero),
+ // all values are equal, and
+ // then we can draw
+ // everything in an arbitrary
+ // color. Thus, change one of
+ // the two values arbitrarily
if (max_color_value == min_color_value)
max_color_value = min_color_value+1;
- // now we've got all the information
- // we need. write the cells.
- // note: due to the ordering, we
- // traverse the list of cells
- // back-to-front
+ // now we've got all the information
+ // we need. write the cells.
+ // note: due to the ordering, we
+ // traverse the list of cells
+ // back-to-front
for (typename std::multiset<EpsCell2d>::const_iterator
- cell=cells.begin();
+ cell=cells.begin();
cell!=cells.end(); ++cell)
{
if (flags.draw_cells)
- {
- if (flags.shade_cells)
- {
- const EpsFlags::RgbValues rgb_values
- = (*flags.color_function) (cell->color_value,
- min_color_value,
- max_color_value);
-
- // write out color
- if (rgb_values.is_grey())
- out << rgb_values.red << " sg ";
- else
- out << rgb_values.red << ' '
- << rgb_values.green << ' '
- << rgb_values.blue << " s ";
- }
- else
- out << "1 sg ";
-
- out << (cell->vertices[0]-offset) * scale << " m "
- << (cell->vertices[1]-offset) * scale << " l "
- << (cell->vertices[3]-offset) * scale << " l "
- << (cell->vertices[2]-offset) * scale << " lf"
- << '\n';
- }
+ {
+ if (flags.shade_cells)
+ {
+ const EpsFlags::RgbValues rgb_values
+ = (*flags.color_function) (cell->color_value,
+ min_color_value,
+ max_color_value);
+
+ // write out color
+ if (rgb_values.is_grey())
+ out << rgb_values.red << " sg ";
+ else
+ out << rgb_values.red << ' '
+ << rgb_values.green << ' '
+ << rgb_values.blue << " s ";
+ }
+ else
+ out << "1 sg ";
+
+ out << (cell->vertices[0]-offset) * scale << " m "
+ << (cell->vertices[1]-offset) * scale << " l "
+ << (cell->vertices[3]-offset) * scale << " l "
+ << (cell->vertices[2]-offset) * scale << " lf"
+ << '\n';
+ }
if (flags.draw_mesh)
- out << "0 sg " // draw lines in black
- << (cell->vertices[0]-offset) * scale << " m "
- << (cell->vertices[1]-offset) * scale << " l "
- << (cell->vertices[3]-offset) * scale << " l "
- << (cell->vertices[2]-offset) * scale << " lx"
- << '\n';
+ out << "0 sg " // draw lines in black
+ << (cell->vertices[0]-offset) * scale << " m "
+ << (cell->vertices[1]-offset) * scale << " l "
+ << (cell->vertices[3]-offset) * scale << " l "
+ << (cell->vertices[2]-offset) * scale << " lx"
+ << '\n';
}
out << "showpage" << '\n';
- // make sure everything now gets to
- // disk
+ // make sure everything now gets to
+ // disk
out << std::setprecision(old_precision);
out.flush ();
template <int dim, int spacedim>
void DataOutBase::write_gmv (const std::vector<Patch<dim,spacedim> > &patches,
- const std::vector<std::string> &data_names,
- const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &,
- const GmvFlags &flags,
- std::ostream &out)
+ const std::vector<std::string> &data_names,
+ const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &,
+ const GmvFlags &flags,
+ std::ostream &out)
{
Assert(dim<=3, ExcNotImplemented());
AssertThrow (out, ExcIO());
#ifndef DEAL_II_COMPILER_SUPPORTS_MPI
- // verify that there are indeed
- // patches to be written out. most
- // of the times, people just forget
- // to call build_patches when there
- // are no patches, so a warning is
- // in order. that said, the
- // assertion is disabled if we
- // support MPI since then it can
- // happen that on the coarsest
- // mesh, a processor simply has no
- // cells it actually owns, and in
- // that case it is legit if there
- // are no patches
+ // verify that there are indeed
+ // patches to be written out. most
+ // of the times, people just forget
+ // to call build_patches when there
+ // are no patches, so a warning is
+ // in order. that said, the
+ // assertion is disabled if we
+ // support MPI since then it can
+ // happen that on the coarsest
+ // mesh, a processor simply has no
+ // cells it actually owns, and in
+ // that case it is legit if there
+ // are no patches
Assert (patches.size() > 0, ExcNoPatches());
#else
if (patches.size() == 0)
GmvStream gmv_out(out, flags);
const unsigned int n_data_sets = data_names.size();
- // check against # of data sets in
- // first patch. checks against all
- // other patches are made in
- // write_gmv_reorder_data_vectors
+ // check against # of data sets in
+ // first patch. checks against all
+ // other patches are made in
+ // write_gmv_reorder_data_vectors
Assert ((patches[0].data.n_rows() == n_data_sets && !patches[0].points_are_available) ||
- (patches[0].data.n_rows() == n_data_sets+spacedim && patches[0].points_are_available),
- ExcDimensionMismatch (patches[0].points_are_available
- ?
- (n_data_sets + spacedim)
- :
- n_data_sets,
- patches[0].data.n_rows()));
-
- ///////////////////////
- // preamble
+ (patches[0].data.n_rows() == n_data_sets+spacedim && patches[0].points_are_available),
+ ExcDimensionMismatch (patches[0].points_are_available
+ ?
+ (n_data_sets + spacedim)
+ :
+ n_data_sets,
+ patches[0].data.n_rows()));
+
+ ///////////////////////
+ // preamble
out << "gmvinput ascii"
<< '\n'
<< '\n';
- // first count the number of cells
- // and cells for later use
+ // first count the number of cells
+ // and cells for later use
unsigned int n_nodes;
unsigned int n_cells;
compute_sizes<dim,spacedim>(patches, n_nodes, n_cells);
- // in gmv format the vertex
- // coordinates and the data have an
- // order that is a bit unpleasant
- // (first all x coordinates, then
- // all y coordinate, ...; first all
- // data of variable 1, then
- // variable 2, etc), so we have to
- // copy the data vectors a bit around
- //
- // note that we copy vectors when
- // looping over the patches since we
- // have to write them one variable
- // at a time and don't want to use
- // more than one loop
- //
- // this copying of data vectors can
- // be done while we already output
- // the vertices, so do this on a
- // separate task and when wanting
- // to write out the data, we wait
- // for that task to finish
+ // in gmv format the vertex
+ // coordinates and the data have an
+ // order that is a bit unpleasant
+ // (first all x coordinates, then
+ // all y coordinate, ...; first all
+ // data of variable 1, then
+ // variable 2, etc), so we have to
+ // copy the data vectors a bit around
+ //
+ // note that we copy vectors when
+ // looping over the patches since we
+ // have to write them one variable
+ // at a time and don't want to use
+ // more than one loop
+ //
+ // this copying of data vectors can
+ // be done while we already output
+ // the vertices, so do this on a
+ // separate task and when wanting
+ // to write out the data, we wait
+ // for that task to finish
Table<2,double> data_vectors (n_data_sets, n_nodes);
void (*fun_ptr) (const std::vector<Patch<dim,spacedim> > &,
- Table<2,double> &)
+ Table<2,double> &)
= &DataOutBase::template write_gmv_reorder_data_vectors<dim,spacedim>;
Threads::Task<> reorder_task = Threads::new_task (fun_ptr, patches, data_vectors);
- ///////////////////////////////
- // first make up a list of used
- // vertices along with their
- // coordinates
- //
- // note that we have to print
- // 3 dimensions
+ ///////////////////////////////
+ // first make up a list of used
+ // vertices along with their
+ // coordinates
+ //
+ // note that we have to print
+ // 3 dimensions
out << "nodes " << n_nodes << '\n';
for (unsigned int d=0;d<spacedim;++d)
{
for (unsigned int d=spacedim;d<3;++d)
{
for (unsigned int i=0;i<n_nodes;++i)
- out << "0 ";
+ out << "0 ";
out << '\n';
}
- /////////////////////////////////
- // now for the cells. note that
- // vertices are counted from 1 onwards
+ /////////////////////////////////
+ // now for the cells. note that
+ // vertices are counted from 1 onwards
out << "cells " << n_cells << '\n';
write_cells(patches, gmv_out);
- ///////////////////////////////////////
- // data output.
+ ///////////////////////////////////////
+ // data output.
out << "variable" << '\n';
- // now write the data vectors to
- // @p{out} first make sure that all
- // data is in place
+ // now write the data vectors to
+ // @p{out} first make sure that all
+ // data is in place
reorder_task.join ();
- // then write data.
- // the '1' means: node data (as opposed
- // to cell data, which we do not
- // support explicitly here)
+ // then write data.
+ // the '1' means: node data (as opposed
+ // to cell data, which we do not
+ // support explicitly here)
for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
{
out << data_names[data_set] << " 1" << '\n';
std::copy (data_vectors[data_set].begin(),
- data_vectors[data_set].end(),
- std::ostream_iterator<double>(out, " "));
+ data_vectors[data_set].end(),
+ std::ostream_iterator<double>(out, " "));
out << '\n'
- << '\n';
+ << '\n';
}
- // end of variable section
+ // end of variable section
out << "endvars" << '\n';
- // end of output
+ // end of output
out << "endgmv"
<< '\n';
- // make sure everything now gets to
- // disk
+ // make sure everything now gets to
+ // disk
out.flush ();
- // assert the stream is still ok
+ // assert the stream is still ok
AssertThrow (out, ExcIO());
}
template <int dim, int spacedim>
void DataOutBase::write_tecplot (const std::vector<Patch<dim,spacedim> > &patches,
- const std::vector<std::string> &data_names,
- const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &,
- const TecplotFlags &flags,
- std::ostream &out)
+ const std::vector<std::string> &data_names,
+ const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &,
+ const TecplotFlags &flags,
+ std::ostream &out)
{
AssertThrow (out, ExcIO());
#ifndef DEAL_II_COMPILER_SUPPORTS_MPI
- // verify that there are indeed
- // patches to be written out. most
- // of the times, people just forget
- // to call build_patches when there
- // are no patches, so a warning is
- // in order. that said, the
- // assertion is disabled if we
- // support MPI since then it can
- // happen that on the coarsest
- // mesh, a processor simply has no
- // cells it actually owns, and in
- // that case it is legit if there
- // are no patches
+ // verify that there are indeed
+ // patches to be written out. most
+ // of the times, people just forget
+ // to call build_patches when there
+ // are no patches, so a warning is
+ // in order. that said, the
+ // assertion is disabled if we
+ // support MPI since then it can
+ // happen that on the coarsest
+ // mesh, a processor simply has no
+ // cells it actually owns, and in
+ // that case it is legit if there
+ // are no patches
Assert (patches.size() > 0, ExcNoPatches());
#else
if (patches.size() == 0)
TecplotStream tecplot_out(out, flags);
const unsigned int n_data_sets = data_names.size();
- // check against # of data sets in
- // first patch. checks against all
- // other patches are made in
- // write_gmv_reorder_data_vectors
+ // check against # of data sets in
+ // first patch. checks against all
+ // other patches are made in
+ // write_gmv_reorder_data_vectors
Assert ((patches[0].data.n_rows() == n_data_sets && !patches[0].points_are_available) ||
- (patches[0].data.n_rows() == n_data_sets+spacedim && patches[0].points_are_available),
- ExcDimensionMismatch (patches[0].points_are_available
- ?
- (n_data_sets + spacedim)
- :
- n_data_sets,
- patches[0].data.n_rows()));
-
- // first count the number of cells
- // and cells for later use
+ (patches[0].data.n_rows() == n_data_sets+spacedim && patches[0].points_are_available),
+ ExcDimensionMismatch (patches[0].points_are_available
+ ?
+ (n_data_sets + spacedim)
+ :
+ n_data_sets,
+ patches[0].data.n_rows()));
+
+ // first count the number of cells
+ // and cells for later use
unsigned int n_nodes;
unsigned int n_cells;
compute_sizes<dim,spacedim>(patches, n_nodes, n_cells);
- ///////////
- // preamble
+ ///////////
+ // preamble
{
std::time_t time1= std::time (0);
std::tm *time = std::localtime(&time1);
out << "# This file was generated by the deal.II library." << '\n'
- << "# Date = "
- << time->tm_year+1900 << "/"
- << time->tm_mon+1 << "/"
- << time->tm_mday << '\n'
- << "# Time = "
- << time->tm_hour << ":"
- << std::setw(2) << time->tm_min << ":"
- << std::setw(2) << time->tm_sec << '\n'
- << "#" << '\n'
- << "# For a description of the Tecplot format see the Tecplot documentation."
- << '\n'
- << "#" << '\n';
+ << "# Date = "
+ << time->tm_year+1900 << "/"
+ << time->tm_mon+1 << "/"
+ << time->tm_mday << '\n'
+ << "# Time = "
+ << time->tm_hour << ":"
+ << std::setw(2) << time->tm_min << ":"
+ << std::setw(2) << time->tm_sec << '\n'
+ << "#" << '\n'
+ << "# For a description of the Tecplot format see the Tecplot documentation."
+ << '\n'
+ << "#" << '\n';
out << "Variables=";
switch (spacedim)
{
case 1:
- out << "\"x\"";
- break;
+ out << "\"x\"";
+ break;
case 2:
- out << "\"x\", \"y\"";
- break;
+ out << "\"x\", \"y\"";
+ break;
case 3:
- out << "\"x\", \"y\", \"z\"";
- break;
- default:
- Assert (false, ExcNotImplemented());
+ out << "\"x\", \"y\", \"z\"";
+ break;
+ default:
+ Assert (false, ExcNotImplemented());
}
for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
out << "t=\"" << flags.zone_name << "\" ";
out << "f=feblock, n=" << n_nodes << ", e=" << n_cells
- << ", et=" << tecplot_cell_type[dim] << '\n';
+ << ", et=" << tecplot_cell_type[dim] << '\n';
}
for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
{
std::copy (data_vectors[data_set].begin(),
- data_vectors[data_set].end(),
- std::ostream_iterator<double>(out, "\n"));
+ data_vectors[data_set].end(),
+ std::ostream_iterator<double>(out, "\n"));
out << '\n';
}
write_cells(patches, tecplot_out);
- // make sure everything now gets to
- // disk
+ // make sure everything now gets to
+ // disk
out.flush ();
// assert the stream is still ok
inline
TecplotMacros::TecplotMacros(const unsigned int n_nodes,
- const unsigned int n_vars,
- const unsigned int n_cells,
- const unsigned int n_vert)
+ const unsigned int n_vars,
+ const unsigned int n_cells,
+ const unsigned int n_vert)
:
- n_nodes(n_nodes),
- n_vars(n_vars),
- n_cells(n_cells),
- n_vert(n_vert)
+ n_nodes(n_nodes),
+ n_vars(n_vars),
+ n_cells(n_cells),
+ n_vert(n_vert)
{
nodalData.resize(n_nodes*n_vars);
connData.resize(n_cells*n_vert);
template <int dim, int spacedim>
void DataOutBase::write_tecplot_binary (const std::vector<Patch<dim,spacedim> > &patches,
- const std::vector<std::string> &data_names,
- const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
- const TecplotFlags &flags,
- std::ostream &out)
+ const std::vector<std::string> &data_names,
+ const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
+ const TecplotFlags &flags,
+ std::ostream &out)
{
#ifndef DEAL_II_HAVE_TECPLOT
if (file_name == NULL)
{
- // At least in debug mode we
- // should tell users why they
- // don't get tecplot binary
- // output
+ // At least in debug mode we
+ // should tell users why they
+ // don't get tecplot binary
+ // output
Assert(false, ExcMessage("Specify the name of the tecplot_binary"
- " file through the TecplotFlags interface."));
+ " file through the TecplotFlags interface."));
write_tecplot (patches, data_names, vector_data_ranges, flags, out);
return;
}
AssertThrow (out, ExcIO());
#ifndef DEAL_II_COMPILER_SUPPORTS_MPI
- // verify that there are indeed
- // patches to be written out. most
- // of the times, people just forget
- // to call build_patches when there
- // are no patches, so a warning is
- // in order. that said, the
- // assertion is disabled if we
- // support MPI since then it can
- // happen that on the coarsest
- // mesh, a processor simply has no
- // cells it actually owns, and in
- // that case it is legit if there
- // are no patches
+ // verify that there are indeed
+ // patches to be written out. most
+ // of the times, people just forget
+ // to call build_patches when there
+ // are no patches, so a warning is
+ // in order. that said, the
+ // assertion is disabled if we
+ // support MPI since then it can
+ // happen that on the coarsest
+ // mesh, a processor simply has no
+ // cells it actually owns, and in
+ // that case it is legit if there
+ // are no patches
Assert (patches.size() > 0, ExcNoPatches());
#else
if (patches.size() == 0)
#endif
const unsigned int n_data_sets = data_names.size();
- // check against # of data sets in
- // first patch. checks against all
- // other patches are made in
- // write_gmv_reorder_data_vectors
+ // check against # of data sets in
+ // first patch. checks against all
+ // other patches are made in
+ // write_gmv_reorder_data_vectors
Assert ((patches[0].data.n_rows() == n_data_sets && !patches[0].points_are_available) ||
- (patches[0].data.n_rows() == n_data_sets+spacedim && patches[0].points_are_available),
- ExcDimensionMismatch (patches[0].points_are_available
- ?
- (n_data_sets + spacedim)
- :
- n_data_sets,
- patches[0].data.n_rows()));
-
- // first count the number of cells
- // and cells for later use
+ (patches[0].data.n_rows() == n_data_sets+spacedim && patches[0].points_are_available),
+ ExcDimensionMismatch (patches[0].points_are_available
+ ?
+ (n_data_sets + spacedim)
+ :
+ n_data_sets,
+ patches[0].data.n_rows()));
+
+ // first count the number of cells
+ // and cells for later use
unsigned int n_nodes;
unsigned int n_cells;
compute_sizes<dim,spacedim>(patches, n_nodes, n_cells);
- // local variables only needed to write Tecplot
- // binary output files
+ // local variables only needed to write Tecplot
+ // binary output files
const unsigned int vars_per_node = (spacedim+n_data_sets),
nodes_per_cell = GeometryInfo<dim>::vertices_per_cell;
switch (spacedim)
{
case 2:
- tec_var_names = "x y";
- break;
+ tec_var_names = "x y";
+ break;
case 3:
- tec_var_names = "x y z";
- break;
+ tec_var_names = "x y z";
+ break;
default:
Assert(false, ExcNotImplemented());
}
tec_var_names += " ";
tec_var_names += data_names[data_set];
}
- // in Tecplot FEBLOCK format the vertex
- // coordinates and the data have an
- // order that is a bit unpleasant
- // (first all x coordinates, then
- // all y coordinate, ...; first all
- // data of variable 1, then
- // variable 2, etc), so we have to
- // copy the data vectors a bit around
- //
- // note that we copy vectors when
- // looping over the patches since we
- // have to write them one variable
- // at a time and don't want to use
- // more than one loop
- //
- // this copying of data vectors can
- // be done while we already output
- // the vertices, so do this on a
- // separate task and when wanting
- // to write out the data, we wait
- // for that task to finish
+ // in Tecplot FEBLOCK format the vertex
+ // coordinates and the data have an
+ // order that is a bit unpleasant
+ // (first all x coordinates, then
+ // all y coordinate, ...; first all
+ // data of variable 1, then
+ // variable 2, etc), so we have to
+ // copy the data vectors a bit around
+ //
+ // note that we copy vectors when
+ // looping over the patches since we
+ // have to write them one variable
+ // at a time and don't want to use
+ // more than one loop
+ //
+ // this copying of data vectors can
+ // be done while we already output
+ // the vertices, so do this on a
+ // separate task and when wanting
+ // to write out the data, we wait
+ // for that task to finish
Table<2,double> data_vectors (n_data_sets, n_nodes);
void (*fun_ptr) (const std::vector<Patch<dim,spacedim> > &,
= &DataOutBase::template write_gmv_reorder_data_vectors<dim,spacedim>;
Threads::Task<> reorder_task = Threads::new_task (fun_ptr, patches, data_vectors);
- ///////////////////////////////
- // first make up a list of used
- // vertices along with their
- // coordinates
+ ///////////////////////////////
+ // first make up a list of used
+ // vertices along with their
+ // coordinates
for (unsigned int d=1; d<=spacedim; ++d)
{
unsigned int entry=0;
for (typename std::vector<Patch<dim,spacedim> >::const_iterator patch=patches.begin();
- patch!=patches.end(); ++patch)
- {
- const unsigned int n_subdivisions = patch->n_subdivisions;
-
- switch (dim)
- {
- case 2:
- {
- for (unsigned int j=0; j<n_subdivisions+1; ++j)
- for (unsigned int i=0; i<n_subdivisions+1; ++i)
- {
- const double x_frac = i * 1./n_subdivisions,
- y_frac = j * 1./n_subdivisions;
-
- tm.nd((d-1),entry) = static_cast<float>(
- (((patch->vertices[1](d-1) * x_frac) +
- (patch->vertices[0](d-1) * (1-x_frac))) * (1-y_frac) +
- ((patch->vertices[3](d-1) * x_frac) +
- (patch->vertices[2](d-1) * (1-x_frac))) * y_frac)
- );
- entry++;
- }
- break;
- }
-
- case 3:
- {
- for (unsigned int j=0; j<n_subdivisions+1; ++j)
- for (unsigned int k=0; k<n_subdivisions+1; ++k)
- for (unsigned int i=0; i<n_subdivisions+1; ++i)
- {
- const double x_frac = i * 1./n_subdivisions,
- y_frac = k * 1./n_subdivisions,
- z_frac = j * 1./n_subdivisions;
-
- // compute coordinates for
- // this patch point
- tm.nd((d-1),entry) = static_cast<float>(
- ((((patch->vertices[1](d-1) * x_frac) +
- (patch->vertices[0](d-1) * (1-x_frac))) * (1-y_frac) +
- ((patch->vertices[3](d-1) * x_frac) +
- (patch->vertices[2](d-1) * (1-x_frac))) * y_frac) * (1-z_frac) +
- (((patch->vertices[5](d-1) * x_frac) +
- (patch->vertices[4](d-1) * (1-x_frac))) * (1-y_frac) +
- ((patch->vertices[7](d-1) * x_frac) +
- (patch->vertices[6](d-1) * (1-x_frac))) * y_frac) * z_frac)
- );
- entry++;
- }
- break;
- }
-
- default:
- Assert (false, ExcNotImplemented());
- }
- }
+ patch!=patches.end(); ++patch)
+ {
+ const unsigned int n_subdivisions = patch->n_subdivisions;
+
+ switch (dim)
+ {
+ case 2:
+ {
+ for (unsigned int j=0; j<n_subdivisions+1; ++j)
+ for (unsigned int i=0; i<n_subdivisions+1; ++i)
+ {
+ const double x_frac = i * 1./n_subdivisions,
+ y_frac = j * 1./n_subdivisions;
+
+ tm.nd((d-1),entry) = static_cast<float>(
+ (((patch->vertices[1](d-1) * x_frac) +
+ (patch->vertices[0](d-1) * (1-x_frac))) * (1-y_frac) +
+ ((patch->vertices[3](d-1) * x_frac) +
+ (patch->vertices[2](d-1) * (1-x_frac))) * y_frac)
+ );
+ entry++;
+ }
+ break;
+ }
+
+ case 3:
+ {
+ for (unsigned int j=0; j<n_subdivisions+1; ++j)
+ for (unsigned int k=0; k<n_subdivisions+1; ++k)
+ for (unsigned int i=0; i<n_subdivisions+1; ++i)
+ {
+ const double x_frac = i * 1./n_subdivisions,
+ y_frac = k * 1./n_subdivisions,
+ z_frac = j * 1./n_subdivisions;
+
+ // compute coordinates for
+ // this patch point
+ tm.nd((d-1),entry) = static_cast<float>(
+ ((((patch->vertices[1](d-1) * x_frac) +
+ (patch->vertices[0](d-1) * (1-x_frac))) * (1-y_frac) +
+ ((patch->vertices[3](d-1) * x_frac) +
+ (patch->vertices[2](d-1) * (1-x_frac))) * y_frac) * (1-z_frac) +
+ (((patch->vertices[5](d-1) * x_frac) +
+ (patch->vertices[4](d-1) * (1-x_frac))) * (1-y_frac) +
+ ((patch->vertices[7](d-1) * x_frac) +
+ (patch->vertices[6](d-1) * (1-x_frac))) * y_frac) * z_frac)
+ );
+ entry++;
+ }
+ break;
+ }
+
+ default:
+ Assert (false, ExcNotImplemented());
+ }
+ }
}
- ///////////////////////////////////////
- // data output.
- //
+ ///////////////////////////////////////
+ // data output.
+ //
reorder_task.join ();
- // then write data.
+ // then write data.
for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
for (unsigned int entry=0; entry<data_vectors[data_set].size(); entry++)
tm.nd((spacedim+data_set),entry) = static_cast<float>(data_vectors[data_set][entry]);
- /////////////////////////////////
- // now for the cells. note that
- // vertices are counted from 1 onwards
+ /////////////////////////////////
+ // now for the cells. note that
+ // vertices are counted from 1 onwards
unsigned int first_vertex_of_patch = 0;
unsigned int elem=0;
const unsigned int d1=1;
const unsigned int d2=n;
const unsigned int d3=n*n;
- // write out the cells making
- // up this patch
+ // write out the cells making
+ // up this patch
switch (dim)
- {
- case 2:
- {
- for (unsigned int i2=0; i2<n_subdivisions; ++i2)
- for (unsigned int i1=0; i1<n_subdivisions; ++i1)
- {
- tm.cd(0,elem) = first_vertex_of_patch+(i1 )*d1+(i2 )*d2+1;
- tm.cd(1,elem) = first_vertex_of_patch+(i1+1)*d1+(i2 )*d2+1;
- tm.cd(2,elem) = first_vertex_of_patch+(i1+1)*d1+(i2+1)*d2+1;
- tm.cd(3,elem) = first_vertex_of_patch+(i1 )*d1+(i2+1)*d2+1;
-
- elem++;
- }
- break;
- }
-
- case 3:
- {
- for (unsigned int i3=0; i3<n_subdivisions; ++i3)
- for (unsigned int i2=0; i2<n_subdivisions; ++i2)
- for (unsigned int i1=0; i1<n_subdivisions; ++i1)
- {
- // note: vertex indices start with 1!
-
-
- tm.cd(0,elem) = first_vertex_of_patch+(i1 )*d1+(i2 )*d2+(i3 )*d3+1;
- tm.cd(1,elem) = first_vertex_of_patch+(i1+1)*d1+(i2 )*d2+(i3 )*d3+1;
- tm.cd(2,elem) = first_vertex_of_patch+(i1+1)*d1+(i2+1)*d2+(i3 )*d3+1;
- tm.cd(3,elem) = first_vertex_of_patch+(i1 )*d1+(i2+1)*d2+(i3 )*d3+1;
- tm.cd(4,elem) = first_vertex_of_patch+(i1 )*d1+(i2 )*d2+(i3+1)*d3+1;
- tm.cd(5,elem) = first_vertex_of_patch+(i1+1)*d1+(i2 )*d2+(i3+1)*d3+1;
- tm.cd(6,elem) = first_vertex_of_patch+(i1+1)*d1+(i2+1)*d2+(i3+1)*d3+1;
- tm.cd(7,elem) = first_vertex_of_patch+(i1 )*d1+(i2+1)*d2+(i3+1)*d3+1;
-
- elem++;
- }
- break;
- }
-
- default:
- Assert (false, ExcNotImplemented());
- }
-
-
- // finally update the number
- // of the first vertex of this patch
+ {
+ case 2:
+ {
+ for (unsigned int i2=0; i2<n_subdivisions; ++i2)
+ for (unsigned int i1=0; i1<n_subdivisions; ++i1)
+ {
+ tm.cd(0,elem) = first_vertex_of_patch+(i1 )*d1+(i2 )*d2+1;
+ tm.cd(1,elem) = first_vertex_of_patch+(i1+1)*d1+(i2 )*d2+1;
+ tm.cd(2,elem) = first_vertex_of_patch+(i1+1)*d1+(i2+1)*d2+1;
+ tm.cd(3,elem) = first_vertex_of_patch+(i1 )*d1+(i2+1)*d2+1;
+
+ elem++;
+ }
+ break;
+ }
+
+ case 3:
+ {
+ for (unsigned int i3=0; i3<n_subdivisions; ++i3)
+ for (unsigned int i2=0; i2<n_subdivisions; ++i2)
+ for (unsigned int i1=0; i1<n_subdivisions; ++i1)
+ {
+ // note: vertex indices start with 1!
+
+
+ tm.cd(0,elem) = first_vertex_of_patch+(i1 )*d1+(i2 )*d2+(i3 )*d3+1;
+ tm.cd(1,elem) = first_vertex_of_patch+(i1+1)*d1+(i2 )*d2+(i3 )*d3+1;
+ tm.cd(2,elem) = first_vertex_of_patch+(i1+1)*d1+(i2+1)*d2+(i3 )*d3+1;
+ tm.cd(3,elem) = first_vertex_of_patch+(i1 )*d1+(i2+1)*d2+(i3 )*d3+1;
+ tm.cd(4,elem) = first_vertex_of_patch+(i1 )*d1+(i2 )*d2+(i3+1)*d3+1;
+ tm.cd(5,elem) = first_vertex_of_patch+(i1+1)*d1+(i2 )*d2+(i3+1)*d3+1;
+ tm.cd(6,elem) = first_vertex_of_patch+(i1+1)*d1+(i2+1)*d2+(i3+1)*d3+1;
+ tm.cd(7,elem) = first_vertex_of_patch+(i1 )*d1+(i2+1)*d2+(i3+1)*d3+1;
+
+ elem++;
+ }
+ break;
+ }
+
+ default:
+ Assert (false, ExcNotImplemented());
+ }
+
+
+ // finally update the number
+ // of the first vertex of this patch
first_vertex_of_patch += Utilities::fixed_power<dim>(n);
}
{
int ierr = 0,
- num_nodes = static_cast<int>(n_nodes),
- num_cells = static_cast<int>(n_cells);
+ num_nodes = static_cast<int>(n_nodes),
+ num_cells = static_cast<int>(n_cells);
char dot[2] = {'.', 0};
- // Unfortunately, TECINI takes a
- // char *, but c_str() gives a
- // const char *. As we don't do
- // anything else with
- // tec_var_names following
- // const_cast is ok
+ // Unfortunately, TECINI takes a
+ // char *, but c_str() gives a
+ // const char *. As we don't do
+ // anything else with
+ // tec_var_names following
+ // const_cast is ok
char *var_names=const_cast<char *> (tec_var_names.c_str());
ierr = TECINI (NULL,
- var_names,
- file_name,
- dot,
- &tec_debug,
- &is_double);
+ var_names,
+ file_name,
+ dot,
+ &tec_debug,
+ &is_double);
Assert (ierr == 0, ExcErrorOpeningTecplotFile(file_name));
char FEBLOCK[] = {'F','E','B','L','O','C','K',0};
ierr = TECZNE (NULL,
- &num_nodes,
- &num_cells,
- &cell_type,
- FEBLOCK,
- NULL);
+ &num_nodes,
+ &num_cells,
+ &cell_type,
+ FEBLOCK,
+ NULL);
Assert (ierr == 0, ExcTecplotAPIError());
int total = (vars_per_node*num_nodes);
ierr = TECDAT (&total,
- &tm.nodalData[0],
- &is_double);
+ &tm.nodalData[0],
+ &is_double);
Assert (ierr == 0, ExcTecplotAPIError());
template <int dim, int spacedim>
void
DataOutBase::write_vtk (const std::vector<Patch<dim,spacedim> > &patches,
- const std::vector<std::string> &data_names,
- const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
- const VtkFlags &flags,
- std::ostream &out)
+ const std::vector<std::string> &data_names,
+ const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
+ const VtkFlags &flags,
+ std::ostream &out)
{
AssertThrow (out, ExcIO());
#ifndef DEAL_II_COMPILER_SUPPORTS_MPI
- // verify that there are indeed
- // patches to be written out. most
- // of the times, people just forget
- // to call build_patches when there
- // are no patches, so a warning is
- // in order. that said, the
- // assertion is disabled if we
- // support MPI since then it can
- // happen that on the coarsest
- // mesh, a processor simply has no
- // cells it actually owns, and in
- // that case it is legit if there
- // are no patches
+ // verify that there are indeed
+ // patches to be written out. most
+ // of the times, people just forget
+ // to call build_patches when there
+ // are no patches, so a warning is
+ // in order. that said, the
+ // assertion is disabled if we
+ // support MPI since then it can
+ // happen that on the coarsest
+ // mesh, a processor simply has no
+ // cells it actually owns, and in
+ // that case it is legit if there
+ // are no patches
Assert (patches.size() > 0, ExcNoPatches());
#else
if (patches.size() == 0)
VtkStream vtk_out(out, flags);
const unsigned int n_data_sets = data_names.size();
- // check against # of data sets in
- // first patch. checks against all
- // other patches are made in
- // write_gmv_reorder_data_vectors
+ // check against # of data sets in
+ // first patch. checks against all
+ // other patches are made in
+ // write_gmv_reorder_data_vectors
Assert ((patches[0].data.n_rows() == n_data_sets && !patches[0].points_are_available) ||
- (patches[0].data.n_rows() == n_data_sets+spacedim && patches[0].points_are_available),
- ExcDimensionMismatch (patches[0].points_are_available
- ?
- (n_data_sets + spacedim)
- :
- n_data_sets,
- patches[0].data.n_rows()));
-
- ///////////////////////
- // preamble
+ (patches[0].data.n_rows() == n_data_sets+spacedim && patches[0].points_are_available),
+ ExcDimensionMismatch (patches[0].points_are_available
+ ?
+ (n_data_sets + spacedim)
+ :
+ n_data_sets,
+ patches[0].data.n_rows()));
+
+ ///////////////////////
+ // preamble
if (true)
{
std::time_t time1= std::time (0);
std::tm *time = std::localtime(&time1);
out << "# vtk DataFile Version 3.0"
- << '\n'
- << "#This file was generated by the deal.II library on "
- << time->tm_year+1900 << "/"
- << time->tm_mon+1 << "/"
- << time->tm_mday << " at "
- << time->tm_hour << ":"
- << std::setw(2) << time->tm_min << ":"
- << std::setw(2) << time->tm_sec
- << '\n'
- << "ASCII"
- << '\n'
- << "DATASET UNSTRUCTURED_GRID\n"
- << '\n';
+ << '\n'
+ << "#This file was generated by the deal.II library on "
+ << time->tm_year+1900 << "/"
+ << time->tm_mon+1 << "/"
+ << time->tm_mday << " at "
+ << time->tm_hour << ":"
+ << std::setw(2) << time->tm_min << ":"
+ << std::setw(2) << time->tm_sec
+ << '\n'
+ << "ASCII"
+ << '\n'
+ << "DATASET UNSTRUCTURED_GRID\n"
+ << '\n';
}
- // first count the number of cells
- // and cells for later use
+ // first count the number of cells
+ // and cells for later use
unsigned int n_nodes;
unsigned int n_cells;
compute_sizes<dim,spacedim>(patches, n_nodes, n_cells);
- // in gmv format the vertex
- // coordinates and the data have an
- // order that is a bit unpleasant
- // (first all x coordinates, then
- // all y coordinate, ...; first all
- // data of variable 1, then
- // variable 2, etc), so we have to
- // copy the data vectors a bit around
- //
- // note that we copy vectors when
- // looping over the patches since we
- // have to write them one variable
- // at a time and don't want to use
- // more than one loop
- //
- // this copying of data vectors can
- // be done while we already output
- // the vertices, so do this on a
- // separate task and when wanting
- // to write out the data, we wait
- // for that task to finish
+ // in gmv format the vertex
+ // coordinates and the data have an
+ // order that is a bit unpleasant
+ // (first all x coordinates, then
+ // all y coordinate, ...; first all
+ // data of variable 1, then
+ // variable 2, etc), so we have to
+ // copy the data vectors a bit around
+ //
+ // note that we copy vectors when
+ // looping over the patches since we
+ // have to write them one variable
+ // at a time and don't want to use
+ // more than one loop
+ //
+ // this copying of data vectors can
+ // be done while we already output
+ // the vertices, so do this on a
+ // separate task and when wanting
+ // to write out the data, we wait
+ // for that task to finish
Table<2,double> data_vectors (n_data_sets, n_nodes);
void (*fun_ptr) (const std::vector<Patch<dim,spacedim> > &,
- Table<2,double> &)
+ Table<2,double> &)
= &DataOutBase::template write_gmv_reorder_data_vectors<dim,spacedim>;
Threads::Task<> reorder_task = Threads::new_task (fun_ptr, patches, data_vectors);
- ///////////////////////////////
- // first make up a list of used
- // vertices along with their
- // coordinates
- //
- // note that we have to print
- // d=1..3 dimensions
+ ///////////////////////////////
+ // first make up a list of used
+ // vertices along with their
+ // coordinates
+ //
+ // note that we have to print
+ // d=1..3 dimensions
out << "POINTS " << n_nodes << " double" << '\n';
write_nodes(patches, vtk_out);
out << '\n';
- /////////////////////////////////
- // now for the cells
+ /////////////////////////////////
+ // now for the cells
out << "CELLS " << n_cells << ' '
<< n_cells*(GeometryInfo<dim>::vertices_per_cell+1)
<< '\n';
write_cells(patches, vtk_out);
out << '\n';
- // next output the types of the
- // cells. since all cells are
- // the same, this is simple
+ // next output the types of the
+ // cells. since all cells are
+ // the same, this is simple
out << "CELL_TYPES " << n_cells << '\n';
for (unsigned int i=0; i<n_cells; ++i)
out << ' ' << vtk_cell_type[dim];
out << '\n';
- ///////////////////////////////////////
- // data output.
+ ///////////////////////////////////////
+ // data output.
- // now write the data vectors to
- // @p{out} first make sure that all
- // data is in place
+ // now write the data vectors to
+ // @p{out} first make sure that all
+ // data is in place
reorder_task.join ();
- // then write data. the
- // 'POINT_DATA' means: node data
- // (as opposed to cell data, which
- // we do not support explicitly
- // here). all following data sets
- // are point data
+ // then write data. the
+ // 'POINT_DATA' means: node data
+ // (as opposed to cell data, which
+ // we do not support explicitly
+ // here). all following data sets
+ // are point data
out << "POINT_DATA " << n_nodes
<< '\n';
- // when writing, first write out
- // all vector data, then handle the
- // scalar data sets that have been
- // left over
+ // when writing, first write out
+ // all vector data, then handle the
+ // scalar data sets that have been
+ // left over
std::vector<bool> data_set_written (n_data_sets, false);
for (unsigned int n_th_vector=0; n_th_vector<vector_data_ranges.size(); ++n_th_vector)
{
AssertThrow (std_cxx1x::get<1>(vector_data_ranges[n_th_vector]) >=
- std_cxx1x::get<0>(vector_data_ranges[n_th_vector]),
- ExcLowerRange (std_cxx1x::get<1>(vector_data_ranges[n_th_vector]),
- std_cxx1x::get<0>(vector_data_ranges[n_th_vector])));
+ std_cxx1x::get<0>(vector_data_ranges[n_th_vector]),
+ ExcLowerRange (std_cxx1x::get<1>(vector_data_ranges[n_th_vector]),
+ std_cxx1x::get<0>(vector_data_ranges[n_th_vector])));
AssertThrow (std_cxx1x::get<1>(vector_data_ranges[n_th_vector]) < n_data_sets,
- ExcIndexRange (std_cxx1x::get<1>(vector_data_ranges[n_th_vector]),
- 0, n_data_sets));
+ ExcIndexRange (std_cxx1x::get<1>(vector_data_ranges[n_th_vector]),
+ 0, n_data_sets));
AssertThrow (std_cxx1x::get<1>(vector_data_ranges[n_th_vector]) + 1
- - std_cxx1x::get<0>(vector_data_ranges[n_th_vector]) <= 3,
- ExcMessage ("Can't declare a vector with more than 3 components "
- "in VTK"));
+ - std_cxx1x::get<0>(vector_data_ranges[n_th_vector]) <= 3,
+ ExcMessage ("Can't declare a vector with more than 3 components "
+ "in VTK"));
- // mark these components as already written:
+ // mark these components as already written:
for (unsigned int i=std_cxx1x::get<0>(vector_data_ranges[n_th_vector]);
- i<=std_cxx1x::get<1>(vector_data_ranges[n_th_vector]);
- ++i)
- data_set_written[i] = true;
-
- // write the
- // header. concatenate all the
- // component names with double
- // underscores unless a vector
- // name has been specified
+ i<=std_cxx1x::get<1>(vector_data_ranges[n_th_vector]);
+ ++i)
+ data_set_written[i] = true;
+
+ // write the
+ // header. concatenate all the
+ // component names with double
+ // underscores unless a vector
+ // name has been specified
out << "VECTORS ";
if (std_cxx1x::get<2>(vector_data_ranges[n_th_vector]) != "")
- out << std_cxx1x::get<2>(vector_data_ranges[n_th_vector]);
+ out << std_cxx1x::get<2>(vector_data_ranges[n_th_vector]);
else
- {
- for (unsigned int i=std_cxx1x::get<0>(vector_data_ranges[n_th_vector]);
- i<std_cxx1x::get<1>(vector_data_ranges[n_th_vector]);
- ++i)
- out << data_names[i] << "__";
- out << data_names[std_cxx1x::get<1>(vector_data_ranges[n_th_vector])];
- }
+ {
+ for (unsigned int i=std_cxx1x::get<0>(vector_data_ranges[n_th_vector]);
+ i<std_cxx1x::get<1>(vector_data_ranges[n_th_vector]);
+ ++i)
+ out << data_names[i] << "__";
+ out << data_names[std_cxx1x::get<1>(vector_data_ranges[n_th_vector])];
+ }
out << " double"
- << '\n';
+ << '\n';
- // now write data. pad all
- // vectors to have three
- // components
+ // now write data. pad all
+ // vectors to have three
+ // components
for (unsigned int n=0; n<n_nodes; ++n)
- {
- switch (std_cxx1x::get<1>(vector_data_ranges[n_th_vector]) -
- std_cxx1x::get<0>(vector_data_ranges[n_th_vector]))
- {
- case 0:
- out << data_vectors(std_cxx1x::get<0>(vector_data_ranges[n_th_vector]), n) << " 0 0"
- << '\n';
- break;
-
- case 1:
- out << data_vectors(std_cxx1x::get<0>(vector_data_ranges[n_th_vector]), n) << ' '
- << data_vectors(std_cxx1x::get<0>(vector_data_ranges[n_th_vector])+1, n) << " 0"
- << '\n';
- break;
- case 2:
- out << data_vectors(std_cxx1x::get<0>(vector_data_ranges[n_th_vector]), n) << ' '
- << data_vectors(std_cxx1x::get<0>(vector_data_ranges[n_th_vector])+1, n) << ' '
- << data_vectors(std_cxx1x::get<0>(vector_data_ranges[n_th_vector])+2, n)
- << '\n';
- break;
-
- default:
- // VTK doesn't
- // support
- // anything else
- // than vectors
- // with 1, 2, or
- // 3 components
- Assert (false, ExcInternalError());
- }
- }
+ {
+ switch (std_cxx1x::get<1>(vector_data_ranges[n_th_vector]) -
+ std_cxx1x::get<0>(vector_data_ranges[n_th_vector]))
+ {
+ case 0:
+ out << data_vectors(std_cxx1x::get<0>(vector_data_ranges[n_th_vector]), n) << " 0 0"
+ << '\n';
+ break;
+
+ case 1:
+ out << data_vectors(std_cxx1x::get<0>(vector_data_ranges[n_th_vector]), n) << ' '
+ << data_vectors(std_cxx1x::get<0>(vector_data_ranges[n_th_vector])+1, n) << " 0"
+ << '\n';
+ break;
+ case 2:
+ out << data_vectors(std_cxx1x::get<0>(vector_data_ranges[n_th_vector]), n) << ' '
+ << data_vectors(std_cxx1x::get<0>(vector_data_ranges[n_th_vector])+1, n) << ' '
+ << data_vectors(std_cxx1x::get<0>(vector_data_ranges[n_th_vector])+2, n)
+ << '\n';
+ break;
+
+ default:
+ // VTK doesn't
+ // support
+ // anything else
+ // than vectors
+ // with 1, 2, or
+ // 3 components
+ Assert (false, ExcInternalError());
+ }
+ }
}
- // now do the left over scalar data sets
+ // now do the left over scalar data sets
for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
if (data_set_written[data_set] == false)
{
- out << "SCALARS "
- << data_names[data_set]
- << " double 1"
- << '\n'
- << "LOOKUP_TABLE default"
- << '\n';
- std::copy (data_vectors[data_set].begin(),
- data_vectors[data_set].end(),
- std::ostream_iterator<double>(out, " "));
- out << '\n';
+ out << "SCALARS "
+ << data_names[data_set]
+ << " double 1"
+ << '\n'
+ << "LOOKUP_TABLE default"
+ << '\n';
+ std::copy (data_vectors[data_set].begin(),
+ data_vectors[data_set].end(),
+ std::ostream_iterator<double>(out, " "));
+ out << '\n';
}
- // make sure everything now gets to
- // disk
+ // make sure everything now gets to
+ // disk
out.flush ();
- // assert the stream is still ok
+ // assert the stream is still ok
AssertThrow (out, ExcIO());
}
AssertThrow (out, ExcIO());
#ifndef DEAL_II_COMPILER_SUPPORTS_MPI
- // verify that there are indeed
- // patches to be written out. most
- // of the times, people just forget
- // to call build_patches when there
- // are no patches, so a warning is
- // in order. that said, the
- // assertion is disabled if we
- // support MPI since then it can
- // happen that on the coarsest
- // mesh, a processor simply has no
- // cells it actually owns, and in
- // that case it is legit if there
- // are no patches
+ // verify that there are indeed
+ // patches to be written out. most
+ // of the times, people just forget
+ // to call build_patches when there
+ // are no patches, so a warning is
+ // in order. that said, the
+ // assertion is disabled if we
+ // support MPI since then it can
+ // happen that on the coarsest
+ // mesh, a processor simply has no
+ // cells it actually owns, and in
+ // that case it is legit if there
+ // are no patches
Assert (patches.size() > 0, ExcNoPatches());
#else
if (patches.size() == 0)
VtuStream vtu_out(out, flags);
const unsigned int n_data_sets = data_names.size();
- // check against # of data sets in
- // first patch. checks against all
- // other patches are made in
- // write_gmv_reorder_data_vectors
+ // check against # of data sets in
+ // first patch. checks against all
+ // other patches are made in
+ // write_gmv_reorder_data_vectors
Assert ((patches[0].data.n_rows() == n_data_sets && !patches[0].points_are_available) ||
- (patches[0].data.n_rows() == n_data_sets+spacedim && patches[0].points_are_available),
- ExcDimensionMismatch (patches[0].points_are_available
- ?
- (n_data_sets + spacedim)
- :
- n_data_sets,
- patches[0].data.n_rows()));
+ (patches[0].data.n_rows() == n_data_sets+spacedim && patches[0].points_are_available),
+ ExcDimensionMismatch (patches[0].points_are_available
+ ?
+ (n_data_sets + spacedim)
+ :
+ n_data_sets,
+ patches[0].data.n_rows()));
#ifdef HAVE_LIBZ
#endif
- // first count the number of cells
- // and cells for later use
+ // first count the number of cells
+ // and cells for later use
unsigned int n_nodes;
unsigned int n_cells;
compute_sizes<dim,spacedim>(patches, n_nodes, n_cells);
- // in gmv format the vertex
- // coordinates and the data have an
- // order that is a bit unpleasant
- // (first all x coordinates, then
- // all y coordinate, ...; first all
- // data of variable 1, then
- // variable 2, etc), so we have to
- // copy the data vectors a bit around
- //
- // note that we copy vectors when
- // looping over the patches since we
- // have to write them one variable
- // at a time and don't want to use
- // more than one loop
- //
- // this copying of data vectors can
- // be done while we already output
- // the vertices, so do this on a
- // separate task and when wanting
- // to write out the data, we wait
- // for that task to finish
+ // in gmv format the vertex
+ // coordinates and the data have an
+ // order that is a bit unpleasant
+ // (first all x coordinates, then
+ // all y coordinate, ...; first all
+ // data of variable 1, then
+ // variable 2, etc), so we have to
+ // copy the data vectors a bit around
+ //
+ // note that we copy vectors when
+ // looping over the patches since we
+ // have to write them one variable
+ // at a time and don't want to use
+ // more than one loop
+ //
+ // this copying of data vectors can
+ // be done while we already output
+ // the vertices, so do this on a
+ // separate task and when wanting
+ // to write out the data, we wait
+ // for that task to finish
Table<2,double> data_vectors (n_data_sets, n_nodes);
void (*fun_ptr) (const std::vector<Patch<dim,spacedim> > &,
- Table<2,double> &)
+ Table<2,double> &)
= &DataOutBase::template write_gmv_reorder_data_vectors<dim,spacedim>;
Threads::Task<> reorder_task = Threads::new_task (fun_ptr, patches,
- data_vectors);
-
- ///////////////////////////////
- // first make up a list of used
- // vertices along with their
- // coordinates
- //
- // note that according to the standard, we
- // have to print d=1..3 dimensions, even if
- // we are in reality in 2d, for example
+ data_vectors);
+
+ ///////////////////////////////
+ // first make up a list of used
+ // vertices along with their
+ // coordinates
+ //
+ // note that according to the standard, we
+ // have to print d=1..3 dimensions, even if
+ // we are in reality in 2d, for example
out << "<Piece NumberOfPoints=\"" << n_nodes
<<"\" NumberOfCells=\"" << n_cells << "\" >\n";
out << " <Points>\n";
write_nodes(patches, vtu_out);
out << " </DataArray>\n";
out << " </Points>\n\n";
- /////////////////////////////////
- // now for the cells
+ /////////////////////////////////
+ // now for the cells
out << " <Cells>\n";
out << " <DataArray type=\"Int32\" Name=\"connectivity\" format=\""
<< ascii_or_binary << "\">\n";
write_cells(patches, vtu_out);
out << " </DataArray>\n";
- // XML VTU format uses offsets; this is
- // different than the VTK format, which
- // puts the number of nodes per cell in
- // front of the connectivity list.
+ // XML VTU format uses offsets; this is
+ // different than the VTK format, which
+ // puts the number of nodes per cell in
+ // front of the connectivity list.
out << " <DataArray type=\"Int32\" Name=\"offsets\" format=\""
<< ascii_or_binary << "\">\n";
out << "\n";
out << " </DataArray>\n";
- // next output the types of the
- // cells. since all cells are
- // the same, this is simple
+ // next output the types of the
+ // cells. since all cells are
+ // the same, this is simple
out << " <DataArray type=\"UInt8\" Name=\"types\" format=\""
<< ascii_or_binary << "\">\n";
{
- // uint8_t might be a typedef to unsigned
- // char which is then not printed as
- // ascii integers
+ // uint8_t might be a typedef to unsigned
+ // char which is then not printed as
+ // ascii integers
#ifdef HAVE_LIBZ
std::vector<uint8_t> cell_types (n_cells,
- static_cast<uint8_t>(vtk_cell_type[dim]));
+ static_cast<uint8_t>(vtk_cell_type[dim]));
#else
std::vector<unsigned int> cell_types (n_cells,
- vtk_cell_type[dim]);
+ vtk_cell_type[dim]);
#endif
- // this should compress well :-)
+ // this should compress well :-)
vtu_out << cell_types;
}
out << "\n";
out << " </Cells>\n";
- ///////////////////////////////////////
- // data output.
+ ///////////////////////////////////////
+ // data output.
- // now write the data vectors to
- // @p{out} first make sure that all
- // data is in place
+ // now write the data vectors to
+ // @p{out} first make sure that all
+ // data is in place
reorder_task.join ();
- // then write data. the
- // 'POINT_DATA' means: node data
- // (as opposed to cell data, which
- // we do not support explicitly
- // here). all following data sets
- // are point data
+ // then write data. the
+ // 'POINT_DATA' means: node data
+ // (as opposed to cell data, which
+ // we do not support explicitly
+ // here). all following data sets
+ // are point data
out << " <PointData Scalars=\"scalars\">\n";
- // when writing, first write out
- // all vector data, then handle the
- // scalar data sets that have been
- // left over
+ // when writing, first write out
+ // all vector data, then handle the
+ // scalar data sets that have been
+ // left over
std::vector<bool> data_set_written (n_data_sets, false);
for (unsigned int n_th_vector=0; n_th_vector<vector_data_ranges.size(); ++n_th_vector)
{
AssertThrow (std_cxx1x::get<1>(vector_data_ranges[n_th_vector]) >=
- std_cxx1x::get<0>(vector_data_ranges[n_th_vector]),
- ExcLowerRange (std_cxx1x::get<1>(vector_data_ranges[n_th_vector]),
- std_cxx1x::get<0>(vector_data_ranges[n_th_vector])));
+ std_cxx1x::get<0>(vector_data_ranges[n_th_vector]),
+ ExcLowerRange (std_cxx1x::get<1>(vector_data_ranges[n_th_vector]),
+ std_cxx1x::get<0>(vector_data_ranges[n_th_vector])));
AssertThrow (std_cxx1x::get<1>(vector_data_ranges[n_th_vector]) < n_data_sets,
- ExcIndexRange (std_cxx1x::get<1>(vector_data_ranges[n_th_vector]),
- 0, n_data_sets));
+ ExcIndexRange (std_cxx1x::get<1>(vector_data_ranges[n_th_vector]),
+ 0, n_data_sets));
AssertThrow (std_cxx1x::get<1>(vector_data_ranges[n_th_vector]) + 1
- - std_cxx1x::get<0>(vector_data_ranges[n_th_vector]) <= 3,
- ExcMessage ("Can't declare a vector with more than 3 components "
- "in VTK"));
+ - std_cxx1x::get<0>(vector_data_ranges[n_th_vector]) <= 3,
+ ExcMessage ("Can't declare a vector with more than 3 components "
+ "in VTK"));
- // mark these components as already
- // written:
+ // mark these components as already
+ // written:
for (unsigned int i=std_cxx1x::get<0>(vector_data_ranges[n_th_vector]);
- i<=std_cxx1x::get<1>(vector_data_ranges[n_th_vector]);
- ++i)
- data_set_written[i] = true;
-
- // write the
- // header. concatenate all the
- // component names with double
- // underscores unless a vector
- // name has been specified
+ i<=std_cxx1x::get<1>(vector_data_ranges[n_th_vector]);
+ ++i)
+ data_set_written[i] = true;
+
+ // write the
+ // header. concatenate all the
+ // component names with double
+ // underscores unless a vector
+ // name has been specified
out << " <DataArray type=\"Float64\" Name=\"";
if (std_cxx1x::get<2>(vector_data_ranges[n_th_vector]) != "")
- out << std_cxx1x::get<2>(vector_data_ranges[n_th_vector]);
+ out << std_cxx1x::get<2>(vector_data_ranges[n_th_vector]);
else
- {
- for (unsigned int i=std_cxx1x::get<0>(vector_data_ranges[n_th_vector]);
- i<std_cxx1x::get<1>(vector_data_ranges[n_th_vector]);
- ++i)
- out << data_names[i] << "__";
- out << data_names[std_cxx1x::get<1>(vector_data_ranges[n_th_vector])];
- }
+ {
+ for (unsigned int i=std_cxx1x::get<0>(vector_data_ranges[n_th_vector]);
+ i<std_cxx1x::get<1>(vector_data_ranges[n_th_vector]);
+ ++i)
+ out << data_names[i] << "__";
+ out << data_names[std_cxx1x::get<1>(vector_data_ranges[n_th_vector])];
+ }
out << "\" NumberOfComponents=\"3\" format=\""
- << ascii_or_binary << "\">\n";
+ << ascii_or_binary << "\">\n";
- // now write data. pad all
- // vectors to have three
- // components
+ // now write data. pad all
+ // vectors to have three
+ // components
std::vector<double> data;
data.reserve (n_nodes*dim);
for (unsigned int n=0; n<n_nodes; ++n)
- {
- switch (std_cxx1x::get<1>(vector_data_ranges[n_th_vector]) -
- std_cxx1x::get<0>(vector_data_ranges[n_th_vector]))
- {
- case 0:
- data.push_back (data_vectors(std_cxx1x::get<0>(vector_data_ranges[n_th_vector]), n));
- data.push_back (0);
- data.push_back (0);
- break;
-
- case 1:
- data.push_back (data_vectors(std_cxx1x::get<0>(vector_data_ranges[n_th_vector]), n));
- data.push_back (data_vectors(std_cxx1x::get<0>(vector_data_ranges[n_th_vector])+1, n));
- data.push_back (0);
- break;
- case 2:
- data.push_back (data_vectors(std_cxx1x::get<0>(vector_data_ranges[n_th_vector]), n));
- data.push_back (data_vectors(std_cxx1x::get<0>(vector_data_ranges[n_th_vector])+1, n));
- data.push_back (data_vectors(std_cxx1x::get<0>(vector_data_ranges[n_th_vector])+2, n));
- break;
-
- default:
- // VTK doesn't
- // support
- // anything else
- // than vectors
- // with 1, 2, or
- // 3 components
- Assert (false, ExcInternalError());
- }
- }
+ {
+ switch (std_cxx1x::get<1>(vector_data_ranges[n_th_vector]) -
+ std_cxx1x::get<0>(vector_data_ranges[n_th_vector]))
+ {
+ case 0:
+ data.push_back (data_vectors(std_cxx1x::get<0>(vector_data_ranges[n_th_vector]), n));
+ data.push_back (0);
+ data.push_back (0);
+ break;
+
+ case 1:
+ data.push_back (data_vectors(std_cxx1x::get<0>(vector_data_ranges[n_th_vector]), n));
+ data.push_back (data_vectors(std_cxx1x::get<0>(vector_data_ranges[n_th_vector])+1, n));
+ data.push_back (0);
+ break;
+ case 2:
+ data.push_back (data_vectors(std_cxx1x::get<0>(vector_data_ranges[n_th_vector]), n));
+ data.push_back (data_vectors(std_cxx1x::get<0>(vector_data_ranges[n_th_vector])+1, n));
+ data.push_back (data_vectors(std_cxx1x::get<0>(vector_data_ranges[n_th_vector])+2, n));
+ break;
+
+ default:
+ // VTK doesn't
+ // support
+ // anything else
+ // than vectors
+ // with 1, 2, or
+ // 3 components
+ Assert (false, ExcInternalError());
+ }
+ }
vtu_out << data;
out << " </DataArray>\n";
}
- // now do the left over scalar data sets
+ // now do the left over scalar data sets
for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
if (data_set_written[data_set] == false)
{
- out << " <DataArray type=\"Float64\" Name=\""
- << data_names[data_set]
- << "\" format=\""
- << ascii_or_binary << "\">\n";
-
- std::vector<double> data (data_vectors[data_set].begin(),
- data_vectors[data_set].end());
- vtu_out << data;
- out << " </DataArray>\n";
+ out << " <DataArray type=\"Float64\" Name=\""
+ << data_names[data_set]
+ << "\" format=\""
+ << ascii_or_binary << "\">\n";
+
+ std::vector<double> data (data_vectors[data_set].begin(),
+ data_vectors[data_set].end());
+ vtu_out << data;
+ out << " </DataArray>\n";
}
out << " </PointData>\n";
- // Finish up writing a valid XML file
+ // Finish up writing a valid XML file
out << " </Piece>\n";
- // make sure everything now gets to
- // disk
+ // make sure everything now gets to
+ // disk
out.flush ();
- // assert the stream is still ok
+ // assert the stream is still ok
AssertThrow (out, ExcIO());
}
void
DataOutBase::
write_deal_II_intermediate (const std::vector<Patch<dim,spacedim> > &patches,
- const std::vector<std::string> &data_names,
- const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
- const Deal_II_IntermediateFlags &/*flags*/,
- std::ostream &out)
+ const std::vector<std::string> &data_names,
+ const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
+ const Deal_II_IntermediateFlags &/*flags*/,
+ std::ostream &out)
{
AssertThrow (out, ExcIO());
out << vector_data_ranges.size() << '\n';
for (unsigned int i=0; i<vector_data_ranges.size(); ++i)
out << std_cxx1x::get<0>(vector_data_ranges[i]) << ' '
- << std_cxx1x::get<1>(vector_data_ranges[i]) << '\n'
- << std_cxx1x::get<2>(vector_data_ranges[i]) << '\n';
+ << std_cxx1x::get<1>(vector_data_ranges[i]) << '\n'
+ << std_cxx1x::get<2>(vector_data_ranges[i]) << '\n';
out << '\n';
- // make sure everything now gets to
- // disk
+ // make sure everything now gets to
+ // disk
out.flush ();
}
template <int dim, int spacedim>
void
DataOutBase::write_gmv_reorder_data_vectors (const std::vector<Patch<dim,spacedim> > &patches,
- Table<2,double> &data_vectors)
+ Table<2,double> &data_vectors)
{
- // unlike in the main function, we
- // don't have here the data_names
- // field, so we initialize it with
- // the number of data sets in the
- // first patch. the equivalence of
- // these two definitions is checked
- // in the main function.
-
- // we have to take care, however, whether the
- // points are appended to the end of the
- // patch->data table
+ // unlike in the main function, we
+ // don't have here the data_names
+ // field, so we initialize it with
+ // the number of data sets in the
+ // first patch. the equivalence of
+ // these two definitions is checked
+ // in the main function.
+
+ // we have to take care, however, whether the
+ // points are appended to the end of the
+ // patch->data table
const unsigned int n_data_sets
=patches[0].points_are_available ? (patches[0].data.n_rows() - spacedim) : patches[0].data.n_rows();
Assert (data_vectors.size()[0] == n_data_sets,
- ExcInternalError());
+ ExcInternalError());
- // loop over all patches
+ // loop over all patches
unsigned int next_value = 0;
for (typename std::vector<Patch<dim,spacedim> >::const_iterator patch=patches.begin();
patch != patches.end(); ++patch)
const unsigned int n_subdivisions = patch->n_subdivisions;
Assert ((patch->data.n_rows() == n_data_sets && !patch->points_are_available) ||
- (patch->data.n_rows() == n_data_sets+spacedim && patch->points_are_available),
- ExcDimensionMismatch (patch->points_are_available
- ?
- (n_data_sets + spacedim)
- :
- n_data_sets,
- patch->data.n_rows()));
+ (patch->data.n_rows() == n_data_sets+spacedim && patch->points_are_available),
+ ExcDimensionMismatch (patch->points_are_available
+ ?
+ (n_data_sets + spacedim)
+ :
+ n_data_sets,
+ patch->data.n_rows()));
Assert (patch->data.n_cols() == Utilities::fixed_power<dim>(n_subdivisions+1),
- ExcInvalidDatasetSize (patch->data.n_cols(), n_subdivisions+1));
+ ExcInvalidDatasetSize (patch->data.n_cols(), n_subdivisions+1));
for (unsigned int i=0;i<patch->data.n_cols();++i, ++next_value)
- for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
- data_vectors[data_set][next_value] = patch->data(data_set,i);
+ for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
+ data_vectors[data_set][next_value] = patch->data(data_set,i);
}
for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
Assert (data_vectors[data_set].size() == next_value,
- ExcInternalError());
+ ExcInternalError());
}
template <int dim, int spacedim>
DataOutInterface<dim,spacedim>::DataOutInterface ()
- : default_subdivisions(1)
+ : default_subdivisions(1)
{}
void DataOutInterface<dim,spacedim>::write_dx (std::ostream &out) const
{
DataOutBase::write_dx (get_patches(), get_dataset_names(),
- get_vector_data_ranges(),
- dx_flags, out);
+ get_vector_data_ranges(),
+ dx_flags, out);
}
void DataOutInterface<dim,spacedim>::write_ucd (std::ostream &out) const
{
DataOutBase::write_ucd (get_patches(), get_dataset_names(),
- get_vector_data_ranges(),
- ucd_flags, out);
+ get_vector_data_ranges(),
+ ucd_flags, out);
}
void DataOutInterface<dim,spacedim>::write_gnuplot (std::ostream &out) const
{
DataOutBase::write_gnuplot (get_patches(), get_dataset_names(),
- get_vector_data_ranges(),
- gnuplot_flags, out);
+ get_vector_data_ranges(),
+ gnuplot_flags, out);
}
void DataOutInterface<dim,spacedim>::write_povray (std::ostream &out) const
{
DataOutBase::write_povray (get_patches(), get_dataset_names(),
- get_vector_data_ranges(),
- povray_flags, out);
+ get_vector_data_ranges(),
+ povray_flags, out);
}
void DataOutInterface<dim,spacedim>::write_eps (std::ostream &out) const
{
DataOutBase::write_eps (get_patches(), get_dataset_names(),
- get_vector_data_ranges(),
- eps_flags, out);
+ get_vector_data_ranges(),
+ eps_flags, out);
}
void DataOutInterface<dim,spacedim>::write_gmv (std::ostream &out) const
{
DataOutBase::write_gmv (get_patches(), get_dataset_names(),
- get_vector_data_ranges(),
- gmv_flags, out);
+ get_vector_data_ranges(),
+ gmv_flags, out);
}
void DataOutInterface<dim,spacedim>::write_tecplot (std::ostream &out) const
{
DataOutBase::write_tecplot (get_patches(), get_dataset_names(),
- get_vector_data_ranges(),
- tecplot_flags, out);
+ get_vector_data_ranges(),
+ tecplot_flags, out);
}
void DataOutInterface<dim,spacedim>::write_tecplot_binary (std::ostream &out) const
{
DataOutBase::write_tecplot_binary (get_patches(), get_dataset_names(),
- get_vector_data_ranges(),
- tecplot_flags, out);
+ get_vector_data_ranges(),
+ tecplot_flags, out);
}
void DataOutInterface<dim,spacedim>::write_vtk (std::ostream &out) const
{
DataOutBase::write_vtk (get_patches(), get_dataset_names(),
- get_vector_data_ranges(),
- vtk_flags, out);
+ get_vector_data_ranges(),
+ vtk_flags, out);
}
template <int dim, int spacedim>
void DataOutInterface<dim,spacedim>::write_vtu (std::ostream &out) const
{
DataOutBase::write_vtu (get_patches(), get_dataset_names(),
- get_vector_data_ranges(),
- vtk_flags, out);
+ get_vector_data_ranges(),
+ vtk_flags, out);
}
template <int dim, int spacedim>
template <int dim, int spacedim>
void
DataOutInterface<dim,spacedim>::write_pvtu_record (std::ostream &out,
- const std::vector<std::string> &piece_names) const
+ const std::vector<std::string> &piece_names) const
{
AssertThrow (out, ExcIO());
out << " <PUnstructuredGrid GhostLevel=\"0\">\n";
out << " <PPointData Scalars=\"scalars\">\n";
- // We need to output in the same order as
- // the write_vtu function does:
+ // We need to output in the same order as
+ // the write_vtu function does:
std::vector<bool> data_set_written (n_data_sets, false);
for (unsigned int n_th_vector=0; n_th_vector<vector_data_ranges.size(); ++n_th_vector)
{
AssertThrow (std_cxx1x::get<1>(vector_data_ranges[n_th_vector]) >=
- std_cxx1x::get<0>(vector_data_ranges[n_th_vector]),
- ExcLowerRange (std_cxx1x::get<1>(vector_data_ranges[n_th_vector]),
- std_cxx1x::get<0>(vector_data_ranges[n_th_vector])));
+ std_cxx1x::get<0>(vector_data_ranges[n_th_vector]),
+ ExcLowerRange (std_cxx1x::get<1>(vector_data_ranges[n_th_vector]),
+ std_cxx1x::get<0>(vector_data_ranges[n_th_vector])));
AssertThrow (std_cxx1x::get<1>(vector_data_ranges[n_th_vector]) < n_data_sets,
- ExcIndexRange (std_cxx1x::get<1>(vector_data_ranges[n_th_vector]),
- 0, n_data_sets));
+ ExcIndexRange (std_cxx1x::get<1>(vector_data_ranges[n_th_vector]),
+ 0, n_data_sets));
AssertThrow (std_cxx1x::get<1>(vector_data_ranges[n_th_vector]) + 1
- - std_cxx1x::get<0>(vector_data_ranges[n_th_vector]) <= 3,
- ExcMessage ("Can't declare a vector with more than 3 components "
- "in VTK"));
+ - std_cxx1x::get<0>(vector_data_ranges[n_th_vector]) <= 3,
+ ExcMessage ("Can't declare a vector with more than 3 components "
+ "in VTK"));
- // mark these components as already
- // written:
+ // mark these components as already
+ // written:
for (unsigned int i=std_cxx1x::get<0>(vector_data_ranges[n_th_vector]);
- i<=std_cxx1x::get<1>(vector_data_ranges[n_th_vector]);
- ++i)
- data_set_written[i] = true;
-
- // write the
- // header. concatenate all the
- // component names with double
- // underscores unless a vector
- // name has been specified
+ i<=std_cxx1x::get<1>(vector_data_ranges[n_th_vector]);
+ ++i)
+ data_set_written[i] = true;
+
+ // write the
+ // header. concatenate all the
+ // component names with double
+ // underscores unless a vector
+ // name has been specified
out << " <PDataArray type=\"Float64\" Name=\"";
if (std_cxx1x::get<2>(vector_data_ranges[n_th_vector]) != "")
- out << std_cxx1x::get<2>(vector_data_ranges[n_th_vector]);
+ out << std_cxx1x::get<2>(vector_data_ranges[n_th_vector]);
else
- {
- for (unsigned int i=std_cxx1x::get<0>(vector_data_ranges[n_th_vector]);
- i<std_cxx1x::get<1>(vector_data_ranges[n_th_vector]);
- ++i)
- out << data_names[i] << "__";
- out << data_names[std_cxx1x::get<1>(vector_data_ranges[n_th_vector])];
- }
+ {
+ for (unsigned int i=std_cxx1x::get<0>(vector_data_ranges[n_th_vector]);
+ i<std_cxx1x::get<1>(vector_data_ranges[n_th_vector]);
+ ++i)
+ out << data_names[i] << "__";
+ out << data_names[std_cxx1x::get<1>(vector_data_ranges[n_th_vector])];
+ }
out << "\" NumberOfComponents=\"3\" format=\"ascii\"/>\n";
}
for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
if (data_set_written[data_set] == false)
{
- out << " <PDataArray type=\"Float64\" Name=\""
- << data_names[data_set]
- << "\" format=\"ascii\"/>\n";
+ out << " <PDataArray type=\"Float64\" Name=\""
+ << data_names[data_set]
+ << "\" format=\"ascii\"/>\n";
}
out << " </PPointData>\n";
out.flush();
- // assert the stream is still ok
+ // assert the stream is still ok
AssertThrow (out, ExcIO());
}
template <int dim, int spacedim>
void
DataOutInterface<dim,spacedim>::write_visit_record (std::ostream &out,
- const std::vector<std::string> &piece_names) const
+ const std::vector<std::string> &piece_names) const
{
out << "!NBLOCKS " << piece_names.size() << std::endl;
for (unsigned int i=0; i<piece_names.size(); ++i)
write_deal_II_intermediate (std::ostream &out) const
{
DataOutBase::write_deal_II_intermediate (get_patches(), get_dataset_names(),
- get_vector_data_ranges(),
- deal_II_intermediate_flags, out);
+ get_vector_data_ranges(),
+ deal_II_intermediate_flags, out);
}
template <int dim, int spacedim>
void
DataOutInterface<dim,spacedim>::write (std::ostream &out,
- const OutputFormat output_format_) const
+ const OutputFormat output_format_) const
{
OutputFormat output_format = output_format_;
if (output_format == default_format)
switch (output_format)
{
case none:
- break;
+ break;
case dx:
- write_dx (out);
- break;
+ write_dx (out);
+ break;
case ucd:
- write_ucd (out);
- break;
+ write_ucd (out);
+ break;
case gnuplot:
- write_gnuplot (out);
- break;
+ write_gnuplot (out);
+ break;
case povray:
- write_povray (out);
- break;
+ write_povray (out);
+ break;
case eps:
- write_eps(out);
- break;
+ write_eps(out);
+ break;
case gmv:
- write_gmv (out);
- break;
+ write_gmv (out);
+ break;
case tecplot:
- write_tecplot (out);
- break;
+ write_tecplot (out);
+ break;
case tecplot_binary:
- write_tecplot_binary (out);
- break;
+ write_tecplot_binary (out);
+ break;
case vtk:
- write_vtk (out);
- break;
+ write_vtk (out);
+ break;
case vtu:
- write_vtu (out);
- break;
+ write_vtu (out);
+ break;
case deal_II_intermediate:
- write_deal_II_intermediate (out);
- break;
+ write_deal_II_intermediate (out);
+ break;
default:
- Assert (false, ExcNotImplemented());
+ Assert (false, ExcNotImplemented());
}
}
DataOutInterface<dim,spacedim>::declare_parameters (ParameterHandler &prm)
{
prm.declare_entry ("Output format", "gnuplot",
- Patterns::Selection (get_output_format_names ()),
+ Patterns::Selection (get_output_format_names ()),
"A name for the output format to be used");
prm.declare_entry("Subdivisions", "1", Patterns::Integer(),
- "Number of subdivisions of each mesh cell");
+ "Number of subdivisions of each mesh cell");
prm.enter_subsection ("DX output parameters");
DXFlags::declare_parameters (prm);
DataOutInterface<dim,spacedim>::memory_consumption () const
{
return (sizeof (default_fmt) +
- MemoryConsumption::memory_consumption (dx_flags) +
- MemoryConsumption::memory_consumption (ucd_flags) +
- MemoryConsumption::memory_consumption (gnuplot_flags) +
- MemoryConsumption::memory_consumption (povray_flags) +
- MemoryConsumption::memory_consumption (eps_flags) +
- MemoryConsumption::memory_consumption (gmv_flags) +
- MemoryConsumption::memory_consumption (tecplot_flags) +
- MemoryConsumption::memory_consumption (vtk_flags) +
- MemoryConsumption::memory_consumption (deal_II_intermediate_flags));
+ MemoryConsumption::memory_consumption (dx_flags) +
+ MemoryConsumption::memory_consumption (ucd_flags) +
+ MemoryConsumption::memory_consumption (gnuplot_flags) +
+ MemoryConsumption::memory_consumption (povray_flags) +
+ MemoryConsumption::memory_consumption (eps_flags) +
+ MemoryConsumption::memory_consumption (gmv_flags) +
+ MemoryConsumption::memory_consumption (tecplot_flags) +
+ MemoryConsumption::memory_consumption (vtk_flags) +
+ MemoryConsumption::memory_consumption (deal_II_intermediate_flags));
}
{
Assert (in, ExcIO());
- // first empty previous content
+ // first empty previous content
{
std::vector<typename dealii::DataOutBase::Patch<dim,spacedim> >
tmp;
tmp.swap (vector_data_ranges);
}
- // then check that we have the
- // correct header of this
- // file. both the first and second
- // real lines have to match, as
- // well as the dimension
- // information written before that
- // and the Version information
- // written in the third line
+ // then check that we have the
+ // correct header of this
+ // file. both the first and second
+ // real lines have to match, as
+ // well as the dimension
+ // information written before that
+ // and the Version information
+ // written in the third line
{
std::pair<unsigned int, unsigned int>
dimension_info
s << "[Version: " << dealii::DataOutBase::Deal_II_IntermediateFlags::format_version << "]";
Assert (header == s.str(),
- ExcMessage("Invalid or incompatible file format. Intermediate format "
- "files can only be read by the same deal.II version as they "
- "are written by."));
+ ExcMessage("Invalid or incompatible file format. Intermediate format "
+ "files can only be read by the same deal.II version as they "
+ "are written by."));
}
- // then read the rest of the data
+ // then read the rest of the data
unsigned int n_datasets;
in >> n_datasets;
dataset_names.resize (n_datasets);
for (unsigned int i=0; i<n_vector_data_ranges; ++i)
{
in >> std_cxx1x::get<0>(vector_data_ranges[i])
- >> std_cxx1x::get<1>(vector_data_ranges[i]);
-
- // read in the name of that vector
- // range. because it is on a separate
- // line, we first need to read to the
- // end of the previous line (nothing
- // should be there any more after we've
- // read the previous two integers) and
- // then read the entire next line for
- // the name
+ >> std_cxx1x::get<1>(vector_data_ranges[i]);
+
+ // read in the name of that vector
+ // range. because it is on a separate
+ // line, we first need to read to the
+ // end of the previous line (nothing
+ // should be there any more after we've
+ // read the previous two integers) and
+ // then read the entire next line for
+ // the name
std::string name;
getline(in, name);
getline(in, name);
Assert (get_dataset_names() == source.get_dataset_names(),
ExcIncompatibleDatasetNames());
- // check equality of the vector data
- // specifications
+ // check equality of the vector data
+ // specifications
Assert (get_vector_data_ranges().size() ==
- source.get_vector_data_ranges().size(),
- ExcMessage ("Both sources need to declare the same components "
- "as vectors."));
+ source.get_vector_data_ranges().size(),
+ ExcMessage ("Both sources need to declare the same components "
+ "as vectors."));
for (unsigned int i=0; i<get_vector_data_ranges().size(); ++i)
{
Assert (std_cxx1x::get<0>(get_vector_data_ranges()[i]) ==
- std_cxx1x::get<0>(source.get_vector_data_ranges()[i]),
- ExcMessage ("Both sources need to declare the same components "
- "as vectors."));
+ std_cxx1x::get<0>(source.get_vector_data_ranges()[i]),
+ ExcMessage ("Both sources need to declare the same components "
+ "as vectors."));
Assert (std_cxx1x::get<1>(get_vector_data_ranges()[i]) ==
- std_cxx1x::get<1>(source.get_vector_data_ranges()[i]),
- ExcMessage ("Both sources need to declare the same components "
- "as vectors."));
+ std_cxx1x::get<1>(source.get_vector_data_ranges()[i]),
+ ExcMessage ("Both sources need to declare the same components "
+ "as vectors."));
Assert (std_cxx1x::get<2>(get_vector_data_ranges()[i]) ==
- std_cxx1x::get<2>(source.get_vector_data_ranges()[i]),
- ExcMessage ("Both sources need to declare the same components "
- "as vectors."));
+ std_cxx1x::get<2>(source.get_vector_data_ranges()[i]),
+ ExcMessage ("Both sources need to declare the same components "
+ "as vectors."));
}
// make sure patches are compatible
template <int dim, int spacedim>
std::ostream &
operator << (std::ostream &out,
- const DataOutBase::Patch<dim,spacedim> &patch)
+ const DataOutBase::Patch<dim,spacedim> &patch)
{
- // write a header line
+ // write a header line
out << "[deal.II intermediate Patch<" << dim << ',' << spacedim << ">]"
<< '\n';
- // then write all the data that is
- // in this patch
+ // then write all the data that is
+ // in this patch
for (unsigned int i=0; i<GeometryInfo<dim>::vertices_per_cell; ++i)
out << patch.vertices[GeometryInfo<dim>::ucd_to_deal[i]] << ' ';
out << '\n';
template <int dim, int spacedim>
std::istream &
operator >> (std::istream &in,
- DataOutBase::Patch<dim,spacedim> &patch)
+ DataOutBase::Patch<dim,spacedim> &patch)
{
Assert (in, ExcIO());
- // read a header line and compare
- // it to what we usually
- // write. skip all lines that
- // contain only blanks at the start
+ // read a header line and compare
+ // it to what we usually
+ // write. skip all lines that
+ // contain only blanks at the start
{
std::string header;
do
{
- getline (in, header);
- while ((header.size() != 0) &&
- (header[header.size()-1] == ' '))
- header.erase(header.size()-1);
+ getline (in, header);
+ while ((header.size() != 0) &&
+ (header[header.size()-1] == ' '))
+ header.erase(header.size()-1);
}
while ((header == "") && in);
}
- // then read all the data that is
- // in this patch
+ // then read all the data that is
+ // in this patch
for (unsigned int i=0; i<GeometryInfo<dim>::vertices_per_cell; ++i)
in >> patch.vertices[GeometryInfo<dim>::ucd_to_deal[i]];
template \
std::ostream & \
operator << (std::ostream &out, \
- const DataOutBase::Patch<dim,spacedim> &patch); \
+ const DataOutBase::Patch<dim,spacedim> &patch); \
template \
std::istream & \
operator >> (std::istream &in, \
- DataOutBase::Patch<dim,spacedim> &patch)
+ DataOutBase::Patch<dim,spacedim> &patch)
INSTANTIATE(1,1);
INSTANTIATE(2,2);
// $Id$
// Version: $Name$
//
-// Copyright (C) 2010 by the deal.II authors
+// Copyright (C) 2010, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
names.push_back(name);
Event result;
- // The constructor generated an
- // object with all flags equal
- // zero. Now we set the new one.
+ // The constructor generated an
+ // object with all flags equal
+ // zero. Now we set the new one.
result.flags[index] = true;
return result;
Event::Event ()
- :
- all_true(false),
- flags(names.size(), false)
+ :
+ all_true(false),
+ flags(names.size(), false)
{}
// $Id$
// Version: $Name$
//
-// Copyright (C) 1998, 2000, 2001, 2002, 2003, 2005, 2006, 2009 by the deal.II authors
+// Copyright (C) 1998, 2000, 2001, 2002, 2003, 2005, 2006, 2009, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
ExceptionBase::ExceptionBase ()
:
- file(""), line(0), function(""), cond(""), exc(""),
- stacktrace (0),
- n_stacktrace_frames (0)
+ file(""), line(0), function(""), cond(""), exc(""),
+ stacktrace (0),
+ n_stacktrace_frames (0)
{}
ExceptionBase::ExceptionBase (const char* f, const int l, const char *func,
- const char* c, const char *e)
+ const char* c, const char *e)
:
- file(f), line(l), function(func), cond(c), exc(e),
- stacktrace (0),
- n_stacktrace_frames (0)
+ file(f), line(l), function(func), cond(c), exc(e),
+ stacktrace (0),
+ n_stacktrace_frames (0)
{}
ExceptionBase::ExceptionBase (const ExceptionBase &exc)
:
std::exception (exc),
- file(exc.file), line(exc.line),
+ file(exc.file), line(exc.line),
function(exc.function), cond(exc.cond), exc(exc.exc),
// don't copy stacktrace to
// avoid double de-allocation
// problem
- stacktrace (0),
- n_stacktrace_frames (0)
+ stacktrace (0),
+ n_stacktrace_frames (0)
{}
void ExceptionBase::set_fields (const char* f,
- const int l,
- const char *func,
- const char *c,
- const char *e)
+ const int l,
+ const char *func,
+ const char *c,
+ const char *e)
{
file = f;
line = l;
cond = c;
exc = e;
- // if the system supports this, get
- // a stacktrace how we got here
+ // if the system supports this, get
+ // a stacktrace how we got here
#ifdef HAVE_GLIBC_STACKTRACE
void * array[25];
n_stacktrace_frames = backtrace(array, 25);
stacktrace = backtrace_symbols(array, n_stacktrace_frames);
-#endif
+#endif
}
if (deal_II_exceptions::show_stacktrace == false)
return;
-
-
- // if there is a stackframe stored, print it
+
+
+ // if there is a stackframe stored, print it
out << std::endl;
out << "Stacktrace:" << std::endl
<< "-----------" << std::endl;
-
- // print the stacktrace. first
- // omit all those frames that have
- // ExceptionBase or
- // deal_II_exceptions in their
- // names, as these correspond to
- // the exception raising mechanism
- // themselves, rather than the
- // place where the exception was
- // triggered
+
+ // print the stacktrace. first
+ // omit all those frames that have
+ // ExceptionBase or
+ // deal_II_exceptions in their
+ // names, as these correspond to
+ // the exception raising mechanism
+ // themselves, rather than the
+ // place where the exception was
+ // triggered
int frame = 0;
while ((frame < n_stacktrace_frames)
- &&
- ((std::string(stacktrace[frame]).find ("ExceptionBase") != std::string::npos)
- ||
- (std::string(stacktrace[frame]).find ("deal_II_exceptions") != std::string::npos)))
+ &&
+ ((std::string(stacktrace[frame]).find ("ExceptionBase") != std::string::npos)
+ ||
+ (std::string(stacktrace[frame]).find ("deal_II_exceptions") != std::string::npos)))
++frame;
- // output the rest
+ // output the rest
const unsigned int first_significant_frame = frame;
for (; frame < n_stacktrace_frames; ++frame)
{
out << '#' << frame - first_significant_frame
- << " ";
-
- // the stacktrace frame is
- // actually of the format
- // "filename(functionname+offset)
- // [address]". let's try to
- // get the mangled
- // functionname out:
+ << " ";
+
+ // the stacktrace frame is
+ // actually of the format
+ // "filename(functionname+offset)
+ // [address]". let's try to
+ // get the mangled
+ // functionname out:
std::string stacktrace_entry (stacktrace[frame]);
const unsigned int pos_start = stacktrace_entry.find('('),
- pos_end = stacktrace_entry.find('+');
+ pos_end = stacktrace_entry.find('+');
std::string functionname = stacktrace_entry.substr (pos_start+1,
- pos_end-pos_start-1);
-
- // demangle, and if successful
- // replace old mangled string
- // by unmangled one (skipping
- // address and offset). treat
- // "main" differently, since
- // it is apparently demangled
- // as "unsigned int" for
- // unknown reasons :-)
- // if we can, demangle the
- // function name
+ pos_end-pos_start-1);
+
+ // demangle, and if successful
+ // replace old mangled string
+ // by unmangled one (skipping
+ // address and offset). treat
+ // "main" differently, since
+ // it is apparently demangled
+ // as "unsigned int" for
+ // unknown reasons :-)
+ // if we can, demangle the
+ // function name
#ifdef HAVE_LIBSTDCXX_DEMANGLER
int status;
char *p = abi::__cxa_demangle(functionname.c_str(), 0, 0, &status);
-
+
if ((status == 0) && (functionname != "main"))
- {
- std::string realname(p);
- // in MT mode, one often
- // gets backtraces
- // spanning several lines
- // because we have so many
- // boost::tuple arguments
- // in the MT calling
- // functions. most of the
- // trailing arguments of
- // these tuples are
- // actually unused
- // boost::tuples::null_type,
- // so we should split them
- // off if they are
- // trailing a template
- // argument list
- while (realname.find (", boost::tuples::null_type>")
- != std::string::npos)
- realname.erase (realname.find (", boost::tuples::null_type>"),
- std::string (", boost::tuples::null_type").size());
-
- stacktrace_entry = stacktrace_entry.substr(0, pos_start)
- +
- ": "
- +
- realname;
- }
+ {
+ std::string realname(p);
+ // in MT mode, one often
+ // gets backtraces
+ // spanning several lines
+ // because we have so many
+ // boost::tuple arguments
+ // in the MT calling
+ // functions. most of the
+ // trailing arguments of
+ // these tuples are
+ // actually unused
+ // boost::tuples::null_type,
+ // so we should split them
+ // off if they are
+ // trailing a template
+ // argument list
+ while (realname.find (", boost::tuples::null_type>")
+ != std::string::npos)
+ realname.erase (realname.find (", boost::tuples::null_type>"),
+ std::string (", boost::tuples::null_type").size());
+
+ stacktrace_entry = stacktrace_entry.substr(0, pos_start)
+ +
+ ": "
+ +
+ realname;
+ }
else
- stacktrace_entry = stacktrace_entry.substr(0, pos_start)
- +
- ": "
- +
- functionname;
+ stacktrace_entry = stacktrace_entry.substr(0, pos_start)
+ +
+ ": "
+ +
+ functionname;
free (p);
-
-#else
+
+#else
stacktrace_entry = stacktrace_entry.substr(0, pos_start)
- +
- ": "
- +
- functionname;
+ +
+ ": "
+ +
+ functionname;
#endif
-
- // then output what we have
+
+ // then output what we have
out << stacktrace_entry
- << std::endl;
+ << std::endl;
- // stop if we're in main()
+ // stop if we're in main()
if (functionname == "main")
- break;
+ break;
}
}
<< "The name and call sequence of the exception was:" << std::endl
<< " " << exc << std::endl
<< "Additional Information: " << std::endl;
- // Additionally, leave a trace in
- // deallog if we do not stop here
+ // Additionally, leave a trace in
+ // deallog if we do not stop here
if (deal_II_exceptions::abort_on_exception == false)
deallog << exc << std::endl;
}
// if we say that this function
// does not throw exceptions, we
// better make sure it does not
- try
+ try
{
// have a place where to store the
// description of the exception as
return description.c_str();
}
- catch (std::exception &exc)
+ catch (std::exception &exc)
{
std::cerr << "*** Exception encountered in exception handling routines ***"
<< std::endl
namespace deal_II_exceptions
{
- namespace internals
+ namespace internals
{
-
- /**
- * Number of exceptions dealt
- * with so far. Zero at program
- * start. Messages are only
- * displayed if the value is
- * zero.
- */
+
+ /**
+ * Number of exceptions dealt
+ * with so far. Zero at program
+ * start. Messages are only
+ * displayed if the value is
+ * zero.
+ */
unsigned int n_treated_exceptions;
ExceptionBase *last_exception;
-
+
void issue_error_assert (const char *file,
- int line,
- const char *function,
- const char *cond,
- const char *exc_name,
- ExceptionBase &e)
+ int line,
+ const char *function,
+ const char *cond,
+ const char *exc_name,
+ ExceptionBase &e)
{
// fill the fields of the
- // exception object
+ // exception object
e.set_fields (file, line, function, cond, exc_name);
-
- // if no other exception has
- // been displayed before, show
- // this one
+
+ // if no other exception has
+ // been displayed before, show
+ // this one
if (n_treated_exceptions == 0)
- {
+ {
std::cerr << "--------------------------------------------------------"
- << std::endl;
- // print out general data
- e.print_exc_data (std::cerr);
- // print out exception
- // specific data
- e.print_info (std::cerr);
- e.print_stack_trace (std::cerr);
- std::cerr << "--------------------------------------------------------"
- << std::endl;
-
- // if there is more to say,
- // do so
- if (!additional_assert_output.empty())
- std::cerr << additional_assert_output << std::endl;
- }
+ << std::endl;
+ // print out general data
+ e.print_exc_data (std::cerr);
+ // print out exception
+ // specific data
+ e.print_info (std::cerr);
+ e.print_stack_trace (std::cerr);
+ std::cerr << "--------------------------------------------------------"
+ << std::endl;
+
+ // if there is more to say,
+ // do so
+ if (!additional_assert_output.empty())
+ std::cerr << additional_assert_output << std::endl;
+ }
else
- {
- // if this is the first
- // follow-up message,
- // display a message that
- // further exceptions are
- // suppressed
- if (n_treated_exceptions == 1)
- std::cerr << "******** More assertions fail but messages are suppressed! ********"
- << std::endl;
- };
-
- // increase number of treated
- // exceptions by one
+ {
+ // if this is the first
+ // follow-up message,
+ // display a message that
+ // further exceptions are
+ // suppressed
+ if (n_treated_exceptions == 1)
+ std::cerr << "******** More assertions fail but messages are suppressed! ********"
+ << std::endl;
+ };
+
+ // increase number of treated
+ // exceptions by one
n_treated_exceptions++;
last_exception = &e;
-
-
- // abort the program now since
- // something has gone horribly
- // wrong. however, there is one
- // case where we do not want to
- // do that, namely when another
- // exception, possibly thrown
- // by AssertThrow is active,
- // since in that case we will
- // not come to see the original
- // exception. in that case
- // indicate that the program is
- // not aborted due to this
- // reason.
+
+
+ // abort the program now since
+ // something has gone horribly
+ // wrong. however, there is one
+ // case where we do not want to
+ // do that, namely when another
+ // exception, possibly thrown
+ // by AssertThrow is active,
+ // since in that case we will
+ // not come to see the original
+ // exception. in that case
+ // indicate that the program is
+ // not aborted due to this
+ // reason.
if (std::uncaught_exception() == true)
- {
- // only display message once
- if (n_treated_exceptions <= 1)
- std::cerr << "******** Program is not aborted since another exception is active! ********"
- << std::endl;
- }
+ {
+ // only display message once
+ if (n_treated_exceptions <= 1)
+ std::cerr << "******** Program is not aborted since another exception is active! ********"
+ << std::endl;
+ }
else if(deal_II_exceptions::abort_on_exception == true)
std::abort ();
else
- --n_treated_exceptions;
+ --n_treated_exceptions;
}
if (deal_II_exceptions::abort_on_exception == true)
std::abort ();
}
-
+
}
-
+
}
extern void __verbose_terminate_handler ();
}
-namespace
+namespace
{
struct preload_terminate_dummy
{
// $Id$
// Version: $Name$
//
-// Copyright (C) 2007, 2008, 2010, 2011 by the deal.II authors
+// Copyright (C) 2007, 2008, 2010, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
template<int dim>
FlowFunction<dim>::FlowFunction()
- :
- Function<dim>(dim+1),
- mean_pressure(0),
- aux_values(dim+1),
- aux_gradients(dim+1)
+ :
+ Function<dim>(dim+1),
+ mean_pressure(0),
+ aux_values(dim+1),
+ aux_gradients(dim+1)
{}
const unsigned int n_points = points.size();
Assert(values.size() == n_points, ExcDimensionMismatch(values.size(), n_points));
- // guard access to the aux_*
- // variables in multithread mode
+ // guard access to the aux_*
+ // variables in multithread mode
Threads::Mutex::ScopedLock lock (mutex);
for (unsigned int d=0;d<dim+1;++d)
for (unsigned int k=0;k<n_points;++k)
{
- Assert(values[k].size() == dim+1, ExcDimensionMismatch(values[k].size(), dim+1));
- for (unsigned int d=0;d<dim+1;++d)
- values[k](d) = aux_values[d][k];
+ Assert(values[k].size() == dim+1, ExcDimensionMismatch(values[k].size(), dim+1));
+ for (unsigned int d=0;d<dim+1;++d)
+ values[k](d) = aux_values[d][k];
}
}
std::vector<Point<dim> > points(1);
points[0] = point;
- // guard access to the aux_*
- // variables in multithread mode
+ // guard access to the aux_*
+ // variables in multithread mode
Threads::Mutex::ScopedLock lock (mutex);
for (unsigned int d=0;d<dim+1;++d)
std::vector<Point<dim> > points(1);
points[0] = point;
- // guard access to the aux_*
- // variables in multithread mode
+ // guard access to the aux_*
+ // variables in multithread mode
Threads::Mutex::ScopedLock lock (mutex);
for (unsigned int d=0;d<dim+1;++d)
const unsigned int n_points = points.size();
Assert(values.size() == n_points, ExcDimensionMismatch(values.size(), n_points));
- // guard access to the aux_*
- // variables in multithread mode
+ // guard access to the aux_*
+ // variables in multithread mode
Threads::Mutex::ScopedLock lock (mutex);
for (unsigned int d=0;d<dim+1;++d)
for (unsigned int k=0;k<n_points;++k)
{
- Assert(values[k].size() == dim+1, ExcDimensionMismatch(values[k].size(), dim+1));
- for (unsigned int d=0;d<dim+1;++d)
- values[k][d] = aux_gradients[d][k];
+ Assert(values[k].size() == dim+1, ExcDimensionMismatch(values[k].size(), dim+1));
+ for (unsigned int d=0;d<dim+1;++d)
+ values[k][d] = aux_gradients[d][k];
}
}
const unsigned int n_points = points.size();
Assert(values.size() == n_points, ExcDimensionMismatch(values.size(), n_points));
- // guard access to the aux_*
- // variables in multithread mode
+ // guard access to the aux_*
+ // variables in multithread mode
Threads::Mutex::ScopedLock lock (mutex);
for (unsigned int d=0;d<dim+1;++d)
for (unsigned int k=0;k<n_points;++k)
{
- Assert(values[k].size() == dim+1, ExcDimensionMismatch(values[k].size(), dim+1));
- for (unsigned int d=0;d<dim+1;++d)
- values[k](d) = aux_values[d][k];
+ Assert(values[k].size() == dim+1, ExcDimensionMismatch(values[k].size(), dim+1));
+ for (unsigned int d=0;d<dim+1;++d)
+ values[k](d) = aux_values[d][k];
}
}
template<int dim>
PoisseuilleFlow<dim>::PoisseuilleFlow(const double r,
- const double Re)
- :
- radius(r), Reynolds(Re)
+ const double Re)
+ :
+ radius(r), Reynolds(Re)
{
Assert(Reynolds != 0., ExcMessage("Reynolds number cannot be zero"));
}
for (unsigned int k=0;k<n;++k)
{
- const Point<dim>& p = points[k];
- // First, compute the
- // square of the distance to
- // the x-axis divided by the
- // radius.
- double r2 = 0;
- for (unsigned int d=1;d<dim;++d)
- r2 += p(d)*p(d)*stretch*stretch;
-
- // x-velocity
- values[0][k] = 1.-r2;
- // other velocities
- for (unsigned int d=1;d<dim;++d)
- values[d][k] = 0.;
- // pressure
- values[dim][k] = -2*(dim-1)*stretch*stretch*p(0)/Reynolds + this->mean_pressure;
+ const Point<dim>& p = points[k];
+ // First, compute the
+ // square of the distance to
+ // the x-axis divided by the
+ // radius.
+ double r2 = 0;
+ for (unsigned int d=1;d<dim;++d)
+ r2 += p(d)*p(d)*stretch*stretch;
+
+ // x-velocity
+ values[0][k] = 1.-r2;
+ // other velocities
+ for (unsigned int d=1;d<dim;++d)
+ values[d][k] = 0.;
+ // pressure
+ values[dim][k] = -2*(dim-1)*stretch*stretch*p(0)/Reynolds + this->mean_pressure;
}
}
for (unsigned int k=0;k<n;++k)
{
- const Point<dim>& p = points[k];
- // x-velocity
- values[0][k][0] = 0.;
- for (unsigned int d=1;d<dim;++d)
- values[0][k][d] = -2.*p(d)*stretch*stretch;
- // other velocities
- for (unsigned int d=1;d<dim;++d)
- values[d][k] = 0.;
- // pressure
- values[dim][k][0] = -2*(dim-1)*stretch*stretch/Reynolds;
- for (unsigned int d=1;d<dim;++d)
- values[dim][k][d] = 0.;
+ const Point<dim>& p = points[k];
+ // x-velocity
+ values[0][k][0] = 0.;
+ for (unsigned int d=1;d<dim;++d)
+ values[0][k][d] = -2.*p(d)*stretch*stretch;
+ // other velocities
+ for (unsigned int d=1;d<dim;++d)
+ values[d][k] = 0.;
+ // pressure
+ values[dim][k][0] = -2*(dim-1)*stretch*stretch/Reynolds;
+ for (unsigned int d=1;d<dim;++d)
+ values[dim][k][d] = 0.;
}
}
for (unsigned int d=0;d<values.size();++d)
for (unsigned int k=0;k<values[d].size();++k)
- values[d][k] = 0.;
+ values[d][k] = 0.;
}
//----------------------------------------------------------------------//
template<int dim>
StokesCosine<dim>::StokesCosine(const double nu, const double r)
- :
- viscosity(nu), reaction(r)
+ :
+ viscosity(nu), reaction(r)
{}
for (unsigned int k=0;k<n;++k)
{
- const Point<dim>& p = points[k];
- const double x = numbers::PI/2. * p(0);
- const double y = numbers::PI/2. * p(1);
- const double cx = cos(x);
- const double cy = cos(y);
- const double sx = sin(x);
- const double sy = sin(y);
-
- if (dim==2)
- {
- values[0][k] = cx*cx*cy*sy;
- values[1][k] = -cx*sx*cy*cy;
- values[2][k] = cx*sx*cy*sy + this->mean_pressure;
- }
- else if (dim==3)
- {
- const double z = numbers::PI/2. * p(2);
- const double cz = cos(z);
- const double sz = sin(z);
-
- values[0][k] = cx*cx*cy*sy*cz*sz;
- values[1][k] = cx*sx*cy*cy*cz*sz;
- values[2][k] = -2.*cx*sx*cy*sy*cz*cz;
- values[3][k] = cx*sx*cy*sy*cz*sz + this->mean_pressure;
- }
- else
- {
- Assert(false, ExcNotImplemented());
- }
+ const Point<dim>& p = points[k];
+ const double x = numbers::PI/2. * p(0);
+ const double y = numbers::PI/2. * p(1);
+ const double cx = cos(x);
+ const double cy = cos(y);
+ const double sx = sin(x);
+ const double sy = sin(y);
+
+ if (dim==2)
+ {
+ values[0][k] = cx*cx*cy*sy;
+ values[1][k] = -cx*sx*cy*cy;
+ values[2][k] = cx*sx*cy*sy + this->mean_pressure;
+ }
+ else if (dim==3)
+ {
+ const double z = numbers::PI/2. * p(2);
+ const double cz = cos(z);
+ const double sz = sin(z);
+
+ values[0][k] = cx*cx*cy*sy*cz*sz;
+ values[1][k] = cx*sx*cy*cy*cz*sz;
+ values[2][k] = -2.*cx*sx*cy*sy*cz*cz;
+ values[3][k] = cx*sx*cy*sy*cz*sz + this->mean_pressure;
+ }
+ else
+ {
+ Assert(false, ExcNotImplemented());
+ }
}
}
for (unsigned int k=0;k<n;++k)
{
- const Point<dim>& p = points[k];
- const double x = numbers::PI/2. * p(0);
- const double y = numbers::PI/2. * p(1);
- const double c2x = cos(2*x);
- const double c2y = cos(2*y);
- const double s2x = sin(2*x);
- const double s2y = sin(2*y);
- const double cx2 = .5+.5*c2x; // cos^2 x
- const double cy2 = .5+.5*c2y; // cos^2 y
-
- if (dim==2)
- {
- values[0][k][0] = -.25*numbers::PI * s2x*s2y;
- values[0][k][1] = .5 *numbers::PI * cx2*c2y;
- values[1][k][0] = -.5 *numbers::PI * c2x*cy2;
- values[1][k][1] = .25*numbers::PI * s2x*s2y;
- values[2][k][0] = .25*numbers::PI * c2x*s2y;
- values[2][k][1] = .25*numbers::PI * s2x*c2y;
- }
- else if (dim==3)
- {
- const double z = numbers::PI/2. * p(2);
- const double c2z = cos(2*z);
- const double s2z = sin(2*z);
- const double cz2 = .5+.5*c2z; // cos^2 z
-
- values[0][k][0] = -.125*numbers::PI * s2x*s2y*s2z;
- values[0][k][1] = .25 *numbers::PI * cx2*c2y*s2z;
- values[0][k][2] = .25 *numbers::PI * cx2*s2y*c2z;
-
- values[1][k][0] = .25 *numbers::PI * c2x*cy2*s2z;
- values[1][k][1] = -.125*numbers::PI * s2x*s2y*s2z;
- values[1][k][2] = .25 *numbers::PI * s2x*cy2*c2z;
-
- values[2][k][0] = -.5 *numbers::PI * c2x*s2y*cz2;
- values[2][k][1] = -.5 *numbers::PI * s2x*c2y*cz2;
- values[2][k][2] = .25 *numbers::PI * s2x*s2y*s2z;
-
- values[3][k][0] = .125*numbers::PI * c2x*s2y*s2z;
- values[3][k][1] = .125*numbers::PI * s2x*c2y*s2z;
- values[3][k][2] = .125*numbers::PI * s2x*s2y*c2z;
- }
- else
- {
- Assert(false, ExcNotImplemented());
- }
+ const Point<dim>& p = points[k];
+ const double x = numbers::PI/2. * p(0);
+ const double y = numbers::PI/2. * p(1);
+ const double c2x = cos(2*x);
+ const double c2y = cos(2*y);
+ const double s2x = sin(2*x);
+ const double s2y = sin(2*y);
+ const double cx2 = .5+.5*c2x; // cos^2 x
+ const double cy2 = .5+.5*c2y; // cos^2 y
+
+ if (dim==2)
+ {
+ values[0][k][0] = -.25*numbers::PI * s2x*s2y;
+ values[0][k][1] = .5 *numbers::PI * cx2*c2y;
+ values[1][k][0] = -.5 *numbers::PI * c2x*cy2;
+ values[1][k][1] = .25*numbers::PI * s2x*s2y;
+ values[2][k][0] = .25*numbers::PI * c2x*s2y;
+ values[2][k][1] = .25*numbers::PI * s2x*c2y;
+ }
+ else if (dim==3)
+ {
+ const double z = numbers::PI/2. * p(2);
+ const double c2z = cos(2*z);
+ const double s2z = sin(2*z);
+ const double cz2 = .5+.5*c2z; // cos^2 z
+
+ values[0][k][0] = -.125*numbers::PI * s2x*s2y*s2z;
+ values[0][k][1] = .25 *numbers::PI * cx2*c2y*s2z;
+ values[0][k][2] = .25 *numbers::PI * cx2*s2y*c2z;
+
+ values[1][k][0] = .25 *numbers::PI * c2x*cy2*s2z;
+ values[1][k][1] = -.125*numbers::PI * s2x*s2y*s2z;
+ values[1][k][2] = .25 *numbers::PI * s2x*cy2*c2z;
+
+ values[2][k][0] = -.5 *numbers::PI * c2x*s2y*cz2;
+ values[2][k][1] = -.5 *numbers::PI * s2x*c2y*cz2;
+ values[2][k][2] = .25 *numbers::PI * s2x*s2y*s2z;
+
+ values[3][k][0] = .125*numbers::PI * c2x*s2y*s2z;
+ values[3][k][1] = .125*numbers::PI * s2x*c2y*s2z;
+ values[3][k][2] = .125*numbers::PI * s2x*s2y*c2z;
+ }
+ else
+ {
+ Assert(false, ExcNotImplemented());
+ }
}
}
if (reaction != 0.)
{
- vector_values(points, values);
- for (unsigned int d=0;d<dim;++d)
- for (unsigned int k=0;k<values[d].size();++k)
- values[d][k] *= -reaction;
+ vector_values(points, values);
+ for (unsigned int d=0;d<dim;++d)
+ for (unsigned int k=0;k<values[d].size();++k)
+ values[d][k] *= -reaction;
}
else
{
- for (unsigned int d=0;d<dim;++d)
- for (unsigned int k=0;k<values[d].size();++k)
- values[d][k] = 0.;
+ for (unsigned int d=0;d<dim;++d)
+ for (unsigned int k=0;k<values[d].size();++k)
+ values[d][k] = 0.;
}
for (unsigned int k=0;k<n;++k)
{
- const Point<dim>& p = points[k];
- const double x = numbers::PI/2. * p(0);
- const double y = numbers::PI/2. * p(1);
- const double c2x = cos(2*x);
- const double c2y = cos(2*y);
- const double s2x = sin(2*x);
- const double s2y = sin(2*y);
- const double pi2 = .25 * numbers::PI * numbers::PI;
-
- if (dim==2)
- {
- values[0][k] += - viscosity*pi2 * (1.+2.*c2x) * s2y - numbers::PI/4. * c2x*s2y;
- values[1][k] += viscosity*pi2 * s2x * (1.+2.*c2y) - numbers::PI/4. * s2x*c2y;
- values[2][k] = 0.;
- }
- else if (dim==3)
- {
- const double z = numbers::PI * p(2);
- const double c2z = cos(2*z);
- const double s2z = sin(2*z);
-
- values[0][k] += - .5*viscosity*pi2 * (1.+2.*c2x) * s2y * s2z - numbers::PI/8. * c2x * s2y * s2z;
- values[1][k] += .5*viscosity*pi2 * s2x * (1.+2.*c2y) * s2z - numbers::PI/8. * s2x * c2y * s2z;
- values[2][k] += - .5*viscosity*pi2 * s2x * s2y * (1.+2.*c2z) - numbers::PI/8. * s2x * s2y * c2z;
- values[3][k] = 0.;
- }
- else
- {
- Assert(false, ExcNotImplemented());
- }
+ const Point<dim>& p = points[k];
+ const double x = numbers::PI/2. * p(0);
+ const double y = numbers::PI/2. * p(1);
+ const double c2x = cos(2*x);
+ const double c2y = cos(2*y);
+ const double s2x = sin(2*x);
+ const double s2y = sin(2*y);
+ const double pi2 = .25 * numbers::PI * numbers::PI;
+
+ if (dim==2)
+ {
+ values[0][k] += - viscosity*pi2 * (1.+2.*c2x) * s2y - numbers::PI/4. * c2x*s2y;
+ values[1][k] += viscosity*pi2 * s2x * (1.+2.*c2y) - numbers::PI/4. * s2x*c2y;
+ values[2][k] = 0.;
+ }
+ else if (dim==3)
+ {
+ const double z = numbers::PI * p(2);
+ const double c2z = cos(2*z);
+ const double s2z = sin(2*z);
+
+ values[0][k] += - .5*viscosity*pi2 * (1.+2.*c2x) * s2y * s2z - numbers::PI/8. * c2x * s2y * s2z;
+ values[1][k] += .5*viscosity*pi2 * s2x * (1.+2.*c2y) * s2z - numbers::PI/8. * s2x * c2y * s2z;
+ values[2][k] += - .5*viscosity*pi2 * s2x * s2y * (1.+2.*c2z) - numbers::PI/8. * s2x * s2y * c2z;
+ values[3][k] = 0.;
+ }
+ else
+ {
+ Assert(false, ExcNotImplemented());
+ }
}
}
const double StokesLSingularity::lambda = 0.54448373678246;
StokesLSingularity::StokesLSingularity()
- :
- omega (3./2.*numbers::PI),
- coslo (cos(lambda*omega)),
- lp(1.+lambda),
- lm(1.-lambda)
+ :
+ omega (3./2.*numbers::PI),
+ coslo (cos(lambda*omega)),
+ lp(1.+lambda),
+ lm(1.-lambda)
{}
for (unsigned int k=0;k<n;++k)
{
- const Point<2>& p = points[k];
- const double x = p(0);
- const double y = p(1);
-
- if ((x<0) || (y<0))
- {
- const double phi = std::atan2(y,-x)+numbers::PI;
- const double r2 = x*x+y*y;
- const double rl = pow(r2,lambda/2.);
- const double rl1 = pow(r2,lambda/2.-.5);
- values[0][k] = rl * (lp*sin(phi)*Psi(phi) + cos(phi)*Psi_1(phi));
- values[1][k] = rl * (lp*cos(phi)*Psi(phi) - sin(phi)*Psi_1(phi));
- values[2][k] = -rl1 * (lp*lp*Psi_1(phi) + Psi_3(phi)) / lm + this->mean_pressure;
- }
- else
- {
- for (unsigned int d=0;d<3;++d)
- values[d][k] = 0.;
- }
+ const Point<2>& p = points[k];
+ const double x = p(0);
+ const double y = p(1);
+
+ if ((x<0) || (y<0))
+ {
+ const double phi = std::atan2(y,-x)+numbers::PI;
+ const double r2 = x*x+y*y;
+ const double rl = pow(r2,lambda/2.);
+ const double rl1 = pow(r2,lambda/2.-.5);
+ values[0][k] = rl * (lp*sin(phi)*Psi(phi) + cos(phi)*Psi_1(phi));
+ values[1][k] = rl * (lp*cos(phi)*Psi(phi) - sin(phi)*Psi_1(phi));
+ values[2][k] = -rl1 * (lp*lp*Psi_1(phi) + Psi_3(phi)) / lm + this->mean_pressure;
+ }
+ else
+ {
+ for (unsigned int d=0;d<3;++d)
+ values[d][k] = 0.;
+ }
}
}
for (unsigned int k=0;k<n;++k)
{
- const Point<2>& p = points[k];
- const double x = p(0);
- const double y = p(1);
-
- if ((x<0) || (y<0))
- {
- const double phi = std::atan2(y,-x)+numbers::PI;
- const double r2 = x*x+y*y;
- const double r = sqrt(r2);
- const double rl = pow(r2,lambda/2.);
- const double rl1 = pow(r2,lambda/2.-.5);
- const double rl2 = pow(r2,lambda/2.-1.);
- const double psi =Psi(phi);
- const double psi1=Psi_1(phi);
- const double psi2=Psi_2(phi);
- const double cosp= cos(phi);
- const double sinp= sin(phi);
-
- // Derivatives of u with respect to r, phi
- const double udr = lambda * rl1 * (lp*sinp*psi + cosp*psi1);
- const double udp = rl * (lp*cosp*psi + lp*sinp*psi1 - sinp*psi1 + cosp*psi2);
- // Derivatives of v with respect to r, phi
- const double vdr = lambda * rl1 * (lp*cosp*psi - sinp*psi1);
- const double vdp = rl * (lp*(cosp*psi1 - sinp*psi) - cosp*psi1 - sinp*psi2);
- // Derivatives of p with respect to r, phi
- const double pdr = -(lambda-1.) * rl2 * (lp*lp*psi1+Psi_3(phi)) / lm;
- const double pdp = -rl1 * (lp*lp*psi2+Psi_4(phi)) / lm;
- values[0][k][0] = cosp*udr - sinp/r*udp;
- values[0][k][1] = - sinp*udr - cosp/r*udp;
- values[1][k][0] = cosp*vdr - sinp/r*vdp;
- values[1][k][1] = - sinp*vdr - cosp/r*vdp;
- values[2][k][0] = cosp*pdr - sinp/r*pdp;
- values[2][k][1] = - sinp*pdr - cosp/r*pdp;
- }
- else
- {
- for (unsigned int d=0;d<3;++d)
- values[d][k] = 0.;
- }
+ const Point<2>& p = points[k];
+ const double x = p(0);
+ const double y = p(1);
+
+ if ((x<0) || (y<0))
+ {
+ const double phi = std::atan2(y,-x)+numbers::PI;
+ const double r2 = x*x+y*y;
+ const double r = sqrt(r2);
+ const double rl = pow(r2,lambda/2.);
+ const double rl1 = pow(r2,lambda/2.-.5);
+ const double rl2 = pow(r2,lambda/2.-1.);
+ const double psi =Psi(phi);
+ const double psi1=Psi_1(phi);
+ const double psi2=Psi_2(phi);
+ const double cosp= cos(phi);
+ const double sinp= sin(phi);
+
+ // Derivatives of u with respect to r, phi
+ const double udr = lambda * rl1 * (lp*sinp*psi + cosp*psi1);
+ const double udp = rl * (lp*cosp*psi + lp*sinp*psi1 - sinp*psi1 + cosp*psi2);
+ // Derivatives of v with respect to r, phi
+ const double vdr = lambda * rl1 * (lp*cosp*psi - sinp*psi1);
+ const double vdp = rl * (lp*(cosp*psi1 - sinp*psi) - cosp*psi1 - sinp*psi2);
+ // Derivatives of p with respect to r, phi
+ const double pdr = -(lambda-1.) * rl2 * (lp*lp*psi1+Psi_3(phi)) / lm;
+ const double pdp = -rl1 * (lp*lp*psi2+Psi_4(phi)) / lm;
+ values[0][k][0] = cosp*udr - sinp/r*udp;
+ values[0][k][1] = - sinp*udr - cosp/r*udp;
+ values[1][k][0] = cosp*vdr - sinp/r*vdp;
+ values[1][k][1] = - sinp*vdr - cosp/r*vdp;
+ values[2][k][0] = cosp*pdr - sinp/r*pdp;
+ values[2][k][1] = - sinp*pdr - cosp/r*pdp;
+ }
+ else
+ {
+ for (unsigned int d=0;d<3;++d)
+ values[d][k] = 0.;
+ }
}
}
for (unsigned int d=0;d<values.size();++d)
for (unsigned int k=0;k<values[d].size();++k)
- values[d][k] = 0.;
+ values[d][k] = 0.;
}
//----------------------------------------------------------------------//
Kovasznay::Kovasznay(double Re, bool stokes)
- :
- Reynolds(Re),
- stokes(stokes)
+ :
+ Reynolds(Re),
+ stokes(stokes)
{
long double r2 = Reynolds/2.;
long double b = 4*numbers::PI*numbers::PI;
long double l = -b/(r2+std::sqrt(r2*r2+b));
lbda = l;
- // mean pressure for a domain
- // spreading from -.5 to 1.5 in
- // x-direction
+ // mean pressure for a domain
+ // spreading from -.5 to 1.5 in
+ // x-direction
p_average = 1/(8*l)*(std::exp(3.*l)-std::exp(-l));
}
for (unsigned int k=0;k<n;++k)
{
- const Point<2>& p = points[k];
- const double x = p(0);
- const double y = 2. * numbers::PI * p(1);
- const double elx = std::exp(lbda*x);
-
- values[0][k] = 1. - elx * cos(y);
- values[1][k] = .5 / numbers::PI * lbda * elx * sin(y);
- values[2][k] = -.5 * elx * elx + p_average + this->mean_pressure;
+ const Point<2>& p = points[k];
+ const double x = p(0);
+ const double y = 2. * numbers::PI * p(1);
+ const double elx = std::exp(lbda*x);
+
+ values[0][k] = 1. - elx * cos(y);
+ values[1][k] = .5 / numbers::PI * lbda * elx * sin(y);
+ values[2][k] = -.5 * elx * elx + p_average + this->mean_pressure;
}
}
Assert (gradients.size() == 3, ExcDimensionMismatch(gradients.size(), 3));
Assert (gradients[0].size() == n,
- ExcDimensionMismatch(gradients[0].size(), n));
+ ExcDimensionMismatch(gradients[0].size(), n));
for (unsigned int i=0;i<n;++i)
{
- const double x = points[i](0);
- const double y = points[i](1);
-
- const double elx = std::exp(lbda*x);
- const double cy = cos(2*numbers::PI*y);
- const double sy = sin(2*numbers::PI*y);
-
- // u
- gradients[0][i][0] = -lbda*elx*cy;
- gradients[0][i][1] = 2. * numbers::PI*elx*sy;
- gradients[1][i][0] = lbda*lbda/(2*numbers::PI)*elx*sy;
- gradients[1][i][1] =lbda*elx*cy;
- // p
- gradients[2][i][0] = -lbda*elx*elx;
- gradients[2][i][1] = 0.;
+ const double x = points[i](0);
+ const double y = points[i](1);
+
+ const double elx = std::exp(lbda*x);
+ const double cy = cos(2*numbers::PI*y);
+ const double sy = sin(2*numbers::PI*y);
+
+ // u
+ gradients[0][i][0] = -lbda*elx*cy;
+ gradients[0][i][1] = 2. * numbers::PI*elx*sy;
+ gradients[1][i][0] = lbda*lbda/(2*numbers::PI)*elx*sy;
+ gradients[1][i][1] =lbda*elx*cy;
+ // p
+ gradients[2][i][0] = -lbda*elx*elx;
+ gradients[2][i][1] = 0.;
}
}
if (stokes)
{
- const double zp = 2. * numbers::PI;
- for (unsigned int k=0;k<n;++k)
- {
- const Point<2>& p = points[k];
- const double x = p(0);
- const double y = zp * p(1);
- const double elx = std::exp(lbda*x);
- const double u = 1. - elx * cos(y);
- const double ux = -lbda * elx * cos(y);
- const double uy = elx * zp * sin(y);
- const double v = lbda/zp * elx * sin(y);
- const double vx = lbda*lbda/zp * elx * sin(y);
- const double vy = zp*lbda/zp * elx * cos(y);
-
- values[0][k] = u*ux+v*uy;
- values[1][k] = u*vx+v*vy;
- values[2][k] = 0.;
- }
+ const double zp = 2. * numbers::PI;
+ for (unsigned int k=0;k<n;++k)
+ {
+ const Point<2>& p = points[k];
+ const double x = p(0);
+ const double y = zp * p(1);
+ const double elx = std::exp(lbda*x);
+ const double u = 1. - elx * cos(y);
+ const double ux = -lbda * elx * cos(y);
+ const double uy = elx * zp * sin(y);
+ const double v = lbda/zp * elx * sin(y);
+ const double vx = lbda*lbda/zp * elx * sin(y);
+ const double vy = zp*lbda/zp * elx * cos(y);
+
+ values[0][k] = u*ux+v*uy;
+ values[1][k] = u*vx+v*vy;
+ values[2][k] = 0.;
+ }
}
else
{
- for (unsigned int d=0;d<values.size();++d)
- for (unsigned int k=0;k<values[d].size();++k)
- values[d][k] = 0.;
+ for (unsigned int d=0;d<values.size();++d)
+ for (unsigned int k=0;k<values[d].size();++k)
+ values[d][k] = 0.;
}
}
// $Id$
// Version: $Name$
//
-// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009, 2010, 2011 by the deal.II authors
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009, 2010, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
template <int dim>
Function<dim>::Function (const unsigned int n_components,
- const double initial_time)
+ const double initial_time)
:
- FunctionTime(initial_time),
- n_components(n_components)
+ FunctionTime(initial_time),
+ n_components(n_components)
{
// avoid the construction of function
// objects that don't return any
template <int dim>
double Function<dim>::value (const Point<dim> &,
- const unsigned int) const
+ const unsigned int) const
{
Assert (false, ExcPureFunctionCalled());
return 0;
template <int dim>
void Function<dim>::value_list (const std::vector<Point<dim> > &points,
- std::vector<double> &values,
- const unsigned int component) const
+ std::vector<double> &values,
+ const unsigned int component) const
{
- // check whether component is in
- // the valid range is up to the
- // derived class
+ // check whether component is in
+ // the valid range is up to the
+ // derived class
Assert (values.size() == points.size(),
- ExcDimensionMismatch(values.size(), points.size()));
+ ExcDimensionMismatch(values.size(), points.size()));
for (unsigned int i=0; i<points.size(); ++i)
values[i] = this->value (points[i], component);
template <int dim>
void Function<dim>::vector_value_list (const std::vector<Point<dim> > &points,
- std::vector<Vector<double> > &values) const
+ std::vector<Vector<double> > &values) const
{
- // check whether component is in
- // the valid range is up to the
- // derived class
+ // check whether component is in
+ // the valid range is up to the
+ // derived class
Assert (values.size() == points.size(),
- ExcDimensionMismatch(values.size(), points.size()));
+ ExcDimensionMismatch(values.size(), points.size()));
for (unsigned int i=0; i<points.size(); ++i)
this->vector_value (points[i], values[i]);
template <int dim>
Tensor<1,dim> Function<dim>::gradient (const Point<dim> &,
- const unsigned int) const
+ const unsigned int) const
{
Assert (false, ExcPureFunctionCalled());
return Point<dim>();
template <int dim>
void Function<dim>::gradient_list (const std::vector<Point<dim> > &points,
- std::vector<Tensor<1,dim> > &gradients,
- const unsigned int component) const
+ std::vector<Tensor<1,dim> > &gradients,
+ const unsigned int component) const
{
Assert (gradients.size() == points.size(),
- ExcDimensionMismatch(gradients.size(), points.size()));
+ ExcDimensionMismatch(gradients.size(), points.size()));
for (unsigned int i=0; i<points.size(); ++i)
gradients[i] = gradient(points[i], component);
template <int dim>
void Function<dim>::vector_gradient_list (const std::vector<Point<dim> > &points,
- std::vector<std::vector<Tensor<1,dim> > > &gradients) const
+ std::vector<std::vector<Tensor<1,dim> > > &gradients) const
{
Assert (gradients.size() == points.size(),
- ExcDimensionMismatch(gradients.size(), points.size()));
+ ExcDimensionMismatch(gradients.size(), points.size()));
for (unsigned int i=0; i<points.size(); ++i)
{
Assert (gradients[i].size() == n_components,
- ExcDimensionMismatch(gradients[i].size(), n_components));
+ ExcDimensionMismatch(gradients[i].size(), n_components));
vector_gradient (points[i], gradients[i]);
}
}
template <int dim>
double Function<dim>::laplacian (const Point<dim> &,
- const unsigned int) const
+ const unsigned int) const
{
Assert (false, ExcPureFunctionCalled());
return 0;
template <int dim>
void Function<dim>::vector_laplacian (const Point<dim> &,
- Vector<double> &) const
+ Vector<double> &) const
{
Assert (false, ExcPureFunctionCalled());
}
template <int dim>
void Function<dim>::laplacian_list (const std::vector<Point<dim> > &points,
- std::vector<double> &laplacians,
- const unsigned int component) const
+ std::vector<double> &laplacians,
+ const unsigned int component) const
{
- // check whether component is in
- // the valid range is up to the
- // derived class
+ // check whether component is in
+ // the valid range is up to the
+ // derived class
Assert (laplacians.size() == points.size(),
- ExcDimensionMismatch(laplacians.size(), points.size()));
+ ExcDimensionMismatch(laplacians.size(), points.size()));
for (unsigned int i=0; i<points.size(); ++i)
laplacians[i] = this->laplacian (points[i], component);
template <int dim>
void Function<dim>::vector_laplacian_list (const std::vector<Point<dim> > &points,
- std::vector<Vector<double> > &laplacians) const
+ std::vector<Vector<double> > &laplacians) const
{
- // check whether component is in
- // the valid range is up to the
- // derived class
+ // check whether component is in
+ // the valid range is up to the
+ // derived class
Assert (laplacians.size() == points.size(),
- ExcDimensionMismatch(laplacians.size(), points.size()));
+ ExcDimensionMismatch(laplacians.size(), points.size()));
for (unsigned int i=0; i<points.size(); ++i)
this->vector_laplacian (points[i], laplacians[i]);
std::size_t
Function<dim>::memory_consumption () const
{
- // only simple data elements, so
- // use sizeof operator
+ // only simple data elements, so
+ // use sizeof operator
return sizeof (*this);
}
template <int dim>
ZeroFunction<dim>::ZeroFunction (const unsigned int n_components)
:
- Function<dim> (n_components)
+ Function<dim> (n_components)
{}
template <int dim>
double ZeroFunction<dim>::value (const Point<dim> &,
- const unsigned int) const
+ const unsigned int) const
{
return 0.;
}
template <int dim>
void ZeroFunction<dim>::vector_value (const Point<dim> &,
- Vector<double> &return_value) const
+ Vector<double> &return_value) const
{
Assert (return_value.size() == this->n_components,
- ExcDimensionMismatch (return_value.size(), this->n_components));
+ ExcDimensionMismatch (return_value.size(), this->n_components));
std::fill (return_value.begin(), return_value.end(), 0.0);
}
template <int dim>
void ZeroFunction<dim>::value_list (const std::vector<Point<dim> > &points,
- std::vector<double> &values,
- const unsigned int /*component*/) const {
+ std::vector<double> &values,
+ const unsigned int /*component*/) const {
Assert (values.size() == points.size(),
- ExcDimensionMismatch(values.size(), points.size()));
+ ExcDimensionMismatch(values.size(), points.size()));
std::fill (values.begin(), values.end(), 0.);
}
template <int dim>
void ZeroFunction<dim>::vector_value_list (const std::vector<Point<dim> > &points,
- std::vector<Vector<double> > &values) const
+ std::vector<Vector<double> > &values) const
{
Assert (values.size() == points.size(),
- ExcDimensionMismatch(values.size(), points.size()));
+ ExcDimensionMismatch(values.size(), points.size()));
for (unsigned int i=0; i<points.size(); ++i)
{
Assert (values[i].size() == this->n_components,
- ExcDimensionMismatch(values[i].size(), this->n_components));
+ ExcDimensionMismatch(values[i].size(), this->n_components));
std::fill (values[i].begin(), values[i].end(), 0.);
};
}
template <int dim>
Tensor<1,dim> ZeroFunction<dim>::gradient (const Point<dim> &,
- const unsigned int) const
+ const unsigned int) const
{
return Tensor<1,dim>();
}
template <int dim>
void ZeroFunction<dim>::vector_gradient (const Point<dim> &,
- std::vector<Tensor<1,dim> > &gradients) const
+ std::vector<Tensor<1,dim> > &gradients) const
{
Assert (gradients.size() == this->n_components,
- ExcDimensionMismatch(gradients.size(), this->n_components));
+ ExcDimensionMismatch(gradients.size(), this->n_components));
for (unsigned int c=0; c<this->n_components; ++c)
gradients[c].clear ();
template <int dim>
void ZeroFunction<dim>::gradient_list (const std::vector<Point<dim> > &points,
- std::vector<Tensor<1,dim> > &gradients,
- const unsigned int /*component*/) const
+ std::vector<Tensor<1,dim> > &gradients,
+ const unsigned int /*component*/) const
{
Assert (gradients.size() == points.size(),
- ExcDimensionMismatch(gradients.size(), points.size()));
+ ExcDimensionMismatch(gradients.size(), points.size()));
for (unsigned int i=0; i<points.size(); ++i)
gradients[i].clear ();
template <int dim>
void ZeroFunction<dim>::vector_gradient_list (const std::vector<Point<dim> > &points,
- std::vector<std::vector<Tensor<1,dim> > > &gradients) const
+ std::vector<std::vector<Tensor<1,dim> > > &gradients) const
{
Assert (gradients.size() == points.size(),
- ExcDimensionMismatch(gradients.size(), points.size()));
+ ExcDimensionMismatch(gradients.size(), points.size()));
for (unsigned int i=0; i<points.size(); ++i)
{
Assert (gradients[i].size() == this->n_components,
- ExcDimensionMismatch(gradients[i].size(), this->n_components));
+ ExcDimensionMismatch(gradients[i].size(), this->n_components));
for (unsigned int c=0; c<this->n_components; ++c)
- gradients[i][c].clear ();
+ gradients[i][c].clear ();
};
}
template <int dim>
ConstantFunction<dim>::ConstantFunction (const double value,
- const unsigned int n_components)
+ const unsigned int n_components)
:
- ZeroFunction<dim> (n_components),
- function_value (value)
+ ZeroFunction<dim> (n_components),
+ function_value (value)
{}
template <int dim>
double ConstantFunction<dim>::value (const Point<dim> &,
- const unsigned int component) const
+ const unsigned int component) const
{
Assert (component < this->n_components,
- ExcIndexRange (component, 0, this->n_components));
+ ExcIndexRange (component, 0, this->n_components));
return function_value;
}
template <int dim>
void ConstantFunction<dim>::vector_value (const Point<dim> &,
- Vector<double> &return_value) const
+ Vector<double> &return_value) const
{
Assert (return_value.size() == this->n_components,
- ExcDimensionMismatch (return_value.size(), this->n_components));
+ ExcDimensionMismatch (return_value.size(), this->n_components));
std::fill (return_value.begin(), return_value.end(), function_value);
}
template <int dim>
void ConstantFunction<dim>::value_list (const std::vector<Point<dim> > &points,
- std::vector<double> &values,
- const unsigned int component) const
+ std::vector<double> &values,
+ const unsigned int component) const
{
Assert (component < this->n_components,
- ExcIndexRange (component, 0, this->n_components));
+ ExcIndexRange (component, 0, this->n_components));
Assert (values.size() == points.size(),
- ExcDimensionMismatch(values.size(), points.size()));
+ ExcDimensionMismatch(values.size(), points.size()));
std::fill (values.begin(), values.end(), function_value);
}
template <int dim>
void ConstantFunction<dim>::vector_value_list (const std::vector<Point<dim> > &points,
- std::vector<Vector<double> > &values) const
+ std::vector<Vector<double> > &values) const
{
Assert (values.size() == points.size(),
- ExcDimensionMismatch(values.size(), points.size()));
+ ExcDimensionMismatch(values.size(), points.size()));
for (unsigned int i=0; i<points.size(); ++i)
{
Assert (values[i].size() == this->n_components,
- ExcDimensionMismatch(values[i].size(), this->n_components));
+ ExcDimensionMismatch(values[i].size(), this->n_components));
std::fill (values[i].begin(), values[i].end(), function_value);
};
}
std::size_t
ConstantFunction<dim>::memory_consumption () const
{
- // only simple data elements, so
- // use sizeof operator
+ // only simple data elements, so
+ // use sizeof operator
return sizeof (*this);
}
ComponentSelectFunction (const unsigned int selected,
const double value,
const unsigned int n_components)
- :
- ConstantFunction<dim> (value, n_components),
+ :
+ ConstantFunction<dim> (value, n_components),
selected_components(std::make_pair(selected,selected+1))
{}
ComponentSelectFunction<dim>::
ComponentSelectFunction (const unsigned int selected,
const unsigned int n_components)
- :
- ConstantFunction<dim> (1., n_components),
+ :
+ ConstantFunction<dim> (1., n_components),
selected_components(std::make_pair(selected,selected+1))
{
Assert (selected < n_components,
- ExcIndexRange (selected, 0, n_components));
+ ExcIndexRange (selected, 0, n_components));
}
ComponentSelectFunction<dim>::
ComponentSelectFunction (const std::pair<unsigned int,unsigned int> &selected,
const unsigned int n_components)
- :
- ConstantFunction<dim> (1., n_components),
+ :
+ ConstantFunction<dim> (1., n_components),
selected_components(selected)
{
Assert (selected_components.first < selected_components.second,
template <int dim>
void ComponentSelectFunction<dim>::vector_value (const Point<dim> &,
- Vector<double> &return_value) const
+ Vector<double> &return_value) const
{
Assert (return_value.size() == this->n_components,
- ExcDimensionMismatch (return_value.size(), this->n_components));
+ ExcDimensionMismatch (return_value.size(), this->n_components));
return_value = 0;
std::fill (return_value.begin()+selected_components.first,
template <int dim>
void ComponentSelectFunction<dim>::vector_value_list (const std::vector<Point<dim> > &points,
- std::vector<Vector<double> > &values) const
+ std::vector<Vector<double> > &values) const
{
Assert (values.size() == points.size(),
- ExcDimensionMismatch(values.size(), points.size()));
+ ExcDimensionMismatch(values.size(), points.size()));
for (unsigned int i=0; i<points.size(); ++i)
ComponentSelectFunction<dim>::vector_value (points[i],
std::size_t
ComponentSelectFunction<dim>::memory_consumption () const
{
- // only simple data elements, so
- // use sizeof operator
+ // only simple data elements, so
+ // use sizeof operator
return sizeof (*this);
}
template <int dim>
double
ScalarFunctionFromFunctionObject<dim>::value (const Point<dim> &p,
- const unsigned int component) const
+ const unsigned int component) const
{
Assert (component == 0,
- ExcMessage ("This object represents only scalar functions"));
+ ExcMessage ("This object represents only scalar functions"));
return function_object (p);
}
// $Id$
// Version: $Name$
//
-// Copyright (C) 2000, 2001, 2002, 2003, 2005, 2006, 2007, 2011 by the deal.II authors
+// Copyright (C) 2000, 2001, 2002, 2003, 2005, 2006, 2007, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
template <int dim>
FunctionDerivative<dim>::FunctionDerivative (const Function<dim> &f,
- const Point<dim> &dir,
- const double h)
- :
- AutoDerivativeFunction<dim> (h, f.n_components, f.get_time()),
+ const Point<dim> &dir,
+ const double h)
+ :
+ AutoDerivativeFunction<dim> (h, f.n_components, f.get_time()),
f(f),
h(h),
incr(1, h*dir)
template <int dim>
FunctionDerivative<dim>::FunctionDerivative (const Function<dim>& f,
- const std::vector<Point<dim> >& dir,
- const double h)
- :
- AutoDerivativeFunction<dim> (h, f.n_components, f.get_time()),
+ const std::vector<Point<dim> >& dir,
+ const double h)
+ :
+ AutoDerivativeFunction<dim> (h, f.n_components, f.get_time()),
f(f),
h(h),
incr(dir.size())
template <int dim>
double
FunctionDerivative<dim>::value (const Point<dim> &p,
- const unsigned int component) const
+ const unsigned int component) const
{
Assert (incr.size() == 1,
- ExcMessage ("FunctionDerivative was not initialized for constant direction"));
+ ExcMessage ("FunctionDerivative was not initialized for constant direction"));
switch (formula)
{
case AutoDerivativeFunction<dim>::Euler:
- return (f.value(p+incr[0], component)-f.value(p-incr[0], component))/(2*h);
+ return (f.value(p+incr[0], component)-f.value(p-incr[0], component))/(2*h);
case AutoDerivativeFunction<dim>::UpwindEuler:
- return (f.value(p, component)-f.value(p-incr[0], component))/h;
+ return (f.value(p, component)-f.value(p-incr[0], component))/h;
case AutoDerivativeFunction<dim>::FourthOrder:
- return (-f.value(p+2*incr[0], component) + 8*f.value(p+incr[0], component)
- -8*f.value(p-incr[0], component) + f.value(p-2*incr[0], component))/(12*h);
+ return (-f.value(p+2*incr[0], component) + 8*f.value(p+incr[0], component)
+ -8*f.value(p-incr[0], component) + f.value(p-2*incr[0], component))/(12*h);
default:
- Assert(false, ExcInvalidFormula());
+ Assert(false, ExcInvalidFormula());
}
return 0.;
}
Vector<double>& result) const
{
Assert (incr.size() == 1,
- ExcMessage ("FunctionDerivative was not initialized for constant direction"));
+ ExcMessage ("FunctionDerivative was not initialized for constant direction"));
Vector<double> aux(result.size());
- // Formulas are the same as in
- // value, but here we have to use
- // Vector arithmetic
+ // Formulas are the same as in
+ // value, but here we have to use
+ // Vector arithmetic
switch (formula)
{
case AutoDerivativeFunction<dim>::Euler:
- f.vector_value(p+incr[0], result);
- f.vector_value(p-incr[0], aux);
- result.sadd(1./(2*h), -1./(2*h), aux);
- return;
+ f.vector_value(p+incr[0], result);
+ f.vector_value(p-incr[0], aux);
+ result.sadd(1./(2*h), -1./(2*h), aux);
+ return;
case AutoDerivativeFunction<dim>::UpwindEuler:
- f.vector_value(p, result);
- f.vector_value(p-incr[0], aux);
- result.sadd(1./h, -1./h, aux);
- return;
+ f.vector_value(p, result);
+ f.vector_value(p-incr[0], aux);
+ result.sadd(1./h, -1./h, aux);
+ return;
case AutoDerivativeFunction<dim>::FourthOrder:
- f.vector_value(p-2*incr[0], result);
- f.vector_value(p+2*incr[0], aux);
- result.add(-1., aux);
- f.vector_value(p-incr[0], aux);
- result.add(-8., aux);
- f.vector_value(p+incr[0], aux);
- result.add(8., aux);
- result.scale(1./(12*h));
- return;
+ f.vector_value(p-2*incr[0], result);
+ f.vector_value(p+2*incr[0], aux);
+ result.add(-1., aux);
+ f.vector_value(p-incr[0], aux);
+ result.add(-8., aux);
+ f.vector_value(p+incr[0], aux);
+ result.add(8., aux);
+ result.scale(1./(12*h));
+ return;
default:
- Assert(false, ExcInvalidFormula());
+ Assert(false, ExcInvalidFormula());
}
}
template <int dim>
void
FunctionDerivative<dim>::value_list (const std::vector<Point<dim> > &points,
- std::vector<double> &values,
- const unsigned int component) const
+ std::vector<double> &values,
+ const unsigned int component) const
{
const unsigned int n = points.size();
const bool variable_direction = (incr.size() == 1) ? false : true;
if (variable_direction)
Assert (incr.size() == points.size(),
- ExcDimensionMismatch(incr.size(), points.size()));
+ ExcDimensionMismatch(incr.size(), points.size()));
- // Vector of auxiliary values
+ // Vector of auxiliary values
std::vector<double> aux(n);
- // Vector of auxiliary points
+ // Vector of auxiliary points
std::vector<Point<dim> > paux(n);
- // Use the same formulas as in
- // value, but with vector
- // arithmetic
+ // Use the same formulas as in
+ // value, but with vector
+ // arithmetic
switch (formula)
{
case AutoDerivativeFunction<dim>::Euler:
- for (unsigned int i=0; i<n; ++i)
- paux[i] = points[i]+incr[(variable_direction) ? i : 0U];
- f.value_list(paux, values, component);
- for (unsigned int i=0; i<n; ++i)
- paux[i] = points[i]-incr[(variable_direction) ? i : 0U];
- f.value_list(paux, aux, component);
- for (unsigned int i=0; i<n; ++i)
- values[i] = (values[i]-aux[i])/(2*h);
- return;
+ for (unsigned int i=0; i<n; ++i)
+ paux[i] = points[i]+incr[(variable_direction) ? i : 0U];
+ f.value_list(paux, values, component);
+ for (unsigned int i=0; i<n; ++i)
+ paux[i] = points[i]-incr[(variable_direction) ? i : 0U];
+ f.value_list(paux, aux, component);
+ for (unsigned int i=0; i<n; ++i)
+ values[i] = (values[i]-aux[i])/(2*h);
+ return;
case AutoDerivativeFunction<dim>::UpwindEuler:
- f.value_list(points, values, component);
- for (unsigned int i=0; i<n; ++i)
- paux[i] = points[i]-incr[(variable_direction) ? i : 0U];
- f.value_list(paux, aux, component);
- for (unsigned int i=0; i<n; ++i)
- values[i] = (values[i]-aux[i])/h;
- return;
+ f.value_list(points, values, component);
+ for (unsigned int i=0; i<n; ++i)
+ paux[i] = points[i]-incr[(variable_direction) ? i : 0U];
+ f.value_list(paux, aux, component);
+ for (unsigned int i=0; i<n; ++i)
+ values[i] = (values[i]-aux[i])/h;
+ return;
case AutoDerivativeFunction<dim>::FourthOrder:
- for (unsigned int i=0; i<n; ++i)
- paux[i] = points[i]-2*incr[(variable_direction) ? i : 0U];
- f.value_list(paux, values, component);
- for (unsigned int i=0; i<n; ++i)
- paux[i] = points[i]+2*incr[(variable_direction) ? i : 0U];
- f.value_list(paux, aux, component);
- for (unsigned int i=0; i<n; ++i)
- values[i] -= aux[i];
- for (unsigned int i=0; i<n; ++i)
- paux[i] = points[i]+incr[(variable_direction) ? i : 0U];
- f.value_list(paux, aux, component);
- for (unsigned int i=0; i<n; ++i)
- values[i] += 8.*aux[i];
- for (unsigned int i=0; i<n; ++i)
- paux[i] = points[i]-incr[(variable_direction) ? i : 0U];
- f.value_list(paux, aux, component);
- for (unsigned int i=0; i<n; ++i)
- values[i] = (values[i] - 8.*aux[i])/(12*h);
- return;
+ for (unsigned int i=0; i<n; ++i)
+ paux[i] = points[i]-2*incr[(variable_direction) ? i : 0U];
+ f.value_list(paux, values, component);
+ for (unsigned int i=0; i<n; ++i)
+ paux[i] = points[i]+2*incr[(variable_direction) ? i : 0U];
+ f.value_list(paux, aux, component);
+ for (unsigned int i=0; i<n; ++i)
+ values[i] -= aux[i];
+ for (unsigned int i=0; i<n; ++i)
+ paux[i] = points[i]+incr[(variable_direction) ? i : 0U];
+ f.value_list(paux, aux, component);
+ for (unsigned int i=0; i<n; ++i)
+ values[i] += 8.*aux[i];
+ for (unsigned int i=0; i<n; ++i)
+ paux[i] = points[i]-incr[(variable_direction) ? i : 0U];
+ f.value_list(paux, aux, component);
+ for (unsigned int i=0; i<n; ++i)
+ values[i] = (values[i] - 8.*aux[i])/(12*h);
+ return;
default:
- Assert(false, ExcInvalidFormula());
+ Assert(false, ExcInvalidFormula());
}
}
std::size_t
FunctionDerivative<dim>::memory_consumption () const
{
- // only simple data elements, so
- // use sizeof operator
+ // only simple data elements, so
+ // use sizeof operator
return sizeof (*this);
}
//---------------------------------------------------------------------------
// $Id$
//
-// Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009, 2010, 2011 by the deal.II authors
+// Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009, 2010, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
// in strict ANSI C mode, the following constants are not defined by
// default, so we do it ourselves
#ifndef M_PI
-# define M_PI 3.14159265358979323846
+# define M_PI 3.14159265358979323846
#endif
#ifndef M_PI_2
-# define M_PI_2 1.57079632679489661923
+# define M_PI_2 1.57079632679489661923
#endif
namespace Functions
{
-
-
+
+
template<int dim>
double
SquareFunction<dim>::value (const Point<dim> &p,
- const unsigned int) const
+ const unsigned int) const
{
return p.square();
}
-
+
template<int dim>
void
SquareFunction<dim>::vector_value (const Point<dim> &p,
- Vector<double> &values) const
+ Vector<double> &values) const
{
AssertDimension(values.size(), 1);
values(0) = p.square();
template<int dim>
void
SquareFunction<dim>::value_list (const std::vector<Point<dim> > &points,
- std::vector<double> &values,
- const unsigned int) const
+ std::vector<double> &values,
+ const unsigned int) const
{
Assert (values.size() == points.size(),
- ExcDimensionMismatch(values.size(), points.size()));
-
+ ExcDimensionMismatch(values.size(), points.size()));
+
for (unsigned int i=0;i<points.size();++i)
{
- const Point<dim>& p = points[i];
- values[i] = p.square();
+ const Point<dim>& p = points[i];
+ values[i] = p.square();
}
}
-
-
+
+
template<int dim>
double
SquareFunction<dim>::laplacian (const Point<dim> &,
- const unsigned int) const
+ const unsigned int) const
{
return 2*dim;
}
-
-
+
+
template<int dim>
void
SquareFunction<dim>::laplacian_list (const std::vector<Point<dim> > &points,
- std::vector<double> &values,
- const unsigned int) const
+ std::vector<double> &values,
+ const unsigned int) const
{
Assert (values.size() == points.size(),
- ExcDimensionMismatch(values.size(), points.size()));
-
+ ExcDimensionMismatch(values.size(), points.size()));
+
for (unsigned int i=0;i<points.size();++i)
values[i] = 2*dim;
}
-
-
-
+
+
+
template<int dim>
Tensor<1,dim>
SquareFunction<dim>::gradient (const Point<dim> &p,
- const unsigned int) const
+ const unsigned int) const
{
return p*2.;
}
-
-
+
+
template<int dim>
void
SquareFunction<dim>::vector_gradient (
}
-
+
template<int dim>
void
SquareFunction<dim>::gradient_list (const std::vector<Point<dim> > &points,
- std::vector<Tensor<1,dim> > &gradients,
- const unsigned int) const
+ std::vector<Tensor<1,dim> > &gradients,
+ const unsigned int) const
{
Assert (gradients.size() == points.size(),
- ExcDimensionMismatch(gradients.size(), points.size()));
-
+ ExcDimensionMismatch(gradients.size(), points.size()));
+
for (unsigned int i=0; i<points.size(); ++i)
gradients[i] = points[i]*2;
}
-
-
+
+
//////////////////////////////////////////////////////////////////////
-
-
+
+
template<int dim>
double
Q1WedgeFunction<dim>::value (const Point<dim> &p,
- const unsigned int) const
+ const unsigned int) const
{
Assert (dim>=2, ExcInternalError());
return p(0)*p(1);
}
-
-
-
+
+
+
template<int dim>
void
Q1WedgeFunction<dim>::value_list (const std::vector<Point<dim> > &points,
- std::vector<double> &values,
- const unsigned int) const
+ std::vector<double> &values,
+ const unsigned int) const
{
Assert (dim>=2, ExcInternalError());
Assert (values.size() == points.size(),
- ExcDimensionMismatch(values.size(), points.size()));
-
+ ExcDimensionMismatch(values.size(), points.size()));
+
for (unsigned int i=0;i<points.size();++i)
{
- const Point<dim>& p = points[i];
- values[i] = p(0)*p(1);
+ const Point<dim>& p = points[i];
+ values[i] = p(0)*p(1);
}
}
-
-
+
+
template<int dim>
void
Q1WedgeFunction<dim>::vector_value_list (
{
Assert (dim>=2, ExcInternalError());
Assert (values.size() == points.size(),
- ExcDimensionMismatch(values.size(), points.size()));
+ ExcDimensionMismatch(values.size(), points.size()));
Assert(values[0].size() == 1, ExcDimensionMismatch(values[0].size(), 1));
-
+
for (unsigned int i=0;i<points.size();++i)
{
- const Point<dim>& p = points[i];
- values[i](0) = p(0)*p(1);
+ const Point<dim>& p = points[i];
+ values[i](0) = p(0)*p(1);
}
}
-
-
+
+
template<int dim>
double
Q1WedgeFunction<dim>::laplacian (const Point<dim> &,
- const unsigned int) const
+ const unsigned int) const
{
Assert (dim>=2, ExcInternalError());
return 0.;
}
-
-
+
+
template<int dim>
void
Q1WedgeFunction<dim>::laplacian_list (const std::vector<Point<dim> > &points,
- std::vector<double> &values,
- const unsigned int) const
+ std::vector<double> &values,
+ const unsigned int) const
{
Assert (dim>=2, ExcInternalError());
Assert (values.size() == points.size(),
- ExcDimensionMismatch(values.size(), points.size()));
-
+ ExcDimensionMismatch(values.size(), points.size()));
+
for (unsigned int i=0;i<points.size();++i)
values[i] = 0.;
}
-
-
-
+
+
+
template<int dim>
Tensor<1,dim>
Q1WedgeFunction<dim>::gradient (const Point<dim> &p,
- const unsigned int) const
+ const unsigned int) const
{
Assert (dim>=2, ExcInternalError());
Tensor<1,dim> erg;
erg[1] = p(0);
return erg;
}
-
-
-
+
+
+
template<int dim>
void
Q1WedgeFunction<dim>::gradient_list (const std::vector<Point<dim> > &points,
- std::vector<Tensor<1,dim> > &gradients,
- const unsigned int) const
+ std::vector<Tensor<1,dim> > &gradients,
+ const unsigned int) const
{
Assert (dim>=2, ExcInternalError());
Assert (gradients.size() == points.size(),
- ExcDimensionMismatch(gradients.size(), points.size()));
-
+ ExcDimensionMismatch(gradients.size(), points.size()));
+
for (unsigned int i=0; i<points.size(); ++i)
{
- gradients[i][0] = points[i](1);
- gradients[i][1] = points[i](0);
+ gradients[i][0] = points[i](1);
+ gradients[i][1] = points[i](0);
}
}
-
-
+
+
template<int dim>
void
Q1WedgeFunction<dim>::vector_gradient_list (
{
Assert (dim>=2, ExcInternalError());
Assert (gradients.size() == points.size(),
- ExcDimensionMismatch(gradients.size(), points.size()));
+ ExcDimensionMismatch(gradients.size(), points.size()));
Assert(gradients[0].size() == 1,
- ExcDimensionMismatch(gradients[0].size(), 1));
-
+ ExcDimensionMismatch(gradients[0].size(), 1));
+
for (unsigned int i=0; i<points.size(); ++i)
{
- gradients[i][0][0] = points[i](1);
- gradients[i][0][1] = points[i](0);
+ gradients[i][0][0] = points[i](1);
+ gradients[i][0][1] = points[i](0);
}
}
-
-
+
+
//////////////////////////////////////////////////////////////////////
-
-
+
+
template<int dim>
PillowFunction<dim>::PillowFunction (const double offset)
- :
- offset(offset)
+ :
+ offset(offset)
{}
-
-
+
+
template<int dim>
double
PillowFunction<dim>::value (const Point<dim> &p,
- const unsigned int) const
+ const unsigned int) const
{
switch(dim)
{
- case 1:
- return 1.-p(0)*p(0)+offset;
- case 2:
- return (1.-p(0)*p(0))*(1.-p(1)*p(1))+offset;
- case 3:
- return (1.-p(0)*p(0))*(1.-p(1)*p(1))*(1.-p(2)*p(2))+offset;
- default:
- Assert(false, ExcNotImplemented());
+ case 1:
+ return 1.-p(0)*p(0)+offset;
+ case 2:
+ return (1.-p(0)*p(0))*(1.-p(1)*p(1))+offset;
+ case 3:
+ return (1.-p(0)*p(0))*(1.-p(1)*p(1))*(1.-p(2)*p(2))+offset;
+ default:
+ Assert(false, ExcNotImplemented());
}
return 0.;
}
-
+
template<int dim>
void
PillowFunction<dim>::value_list (const std::vector<Point<dim> > &points,
- std::vector<double> &values,
- const unsigned int) const
+ std::vector<double> &values,
+ const unsigned int) const
{
Assert (values.size() == points.size(),
- ExcDimensionMismatch(values.size(), points.size()));
-
+ ExcDimensionMismatch(values.size(), points.size()));
+
for (unsigned int i=0;i<points.size();++i)
{
- const Point<dim>& p = points[i];
- switch(dim)
- {
- case 1:
- values[i] = 1.-p(0)*p(0)+offset;
- break;
- case 2:
- values[i] = (1.-p(0)*p(0))*(1.-p(1)*p(1))+offset;
- break;
- case 3:
- values[i] = (1.-p(0)*p(0))*(1.-p(1)*p(1))*(1.-p(2)*p(2))+offset;
- break;
- default:
- Assert(false, ExcNotImplemented());
- }
+ const Point<dim>& p = points[i];
+ switch(dim)
+ {
+ case 1:
+ values[i] = 1.-p(0)*p(0)+offset;
+ break;
+ case 2:
+ values[i] = (1.-p(0)*p(0))*(1.-p(1)*p(1))+offset;
+ break;
+ case 3:
+ values[i] = (1.-p(0)*p(0))*(1.-p(1)*p(1))*(1.-p(2)*p(2))+offset;
+ break;
+ default:
+ Assert(false, ExcNotImplemented());
+ }
}
}
-
-
-
+
+
+
template<int dim>
double
PillowFunction<dim>::laplacian (const Point<dim> &p,
- const unsigned int) const
+ const unsigned int) const
{
switch(dim)
{
- case 1:
- return -2.;
- case 2:
- return -2.*((1.-p(0)*p(0))+(1.-p(1)*p(1)));
- case 3:
- return -2.*((1.-p(0)*p(0))*(1.-p(1)*p(1))
- +(1.-p(1)*p(1))*(1.-p(2)*p(2))
- +(1.-p(2)*p(2))*(1.-p(0)*p(0)));
- default:
- Assert(false, ExcNotImplemented());
+ case 1:
+ return -2.;
+ case 2:
+ return -2.*((1.-p(0)*p(0))+(1.-p(1)*p(1)));
+ case 3:
+ return -2.*((1.-p(0)*p(0))*(1.-p(1)*p(1))
+ +(1.-p(1)*p(1))*(1.-p(2)*p(2))
+ +(1.-p(2)*p(2))*(1.-p(0)*p(0)));
+ default:
+ Assert(false, ExcNotImplemented());
}
return 0.;
}
-
+
template<int dim>
void
PillowFunction<dim>::laplacian_list (const std::vector<Point<dim> > &points,
- std::vector<double> &values,
- const unsigned int) const
+ std::vector<double> &values,
+ const unsigned int) const
{
Assert (values.size() == points.size(),
- ExcDimensionMismatch(values.size(), points.size()));
-
+ ExcDimensionMismatch(values.size(), points.size()));
+
for (unsigned int i=0;i<points.size();++i)
{
- const Point<dim>& p = points[i];
- switch(dim)
- {
- case 1:
- values[i] = -2.;
- break;
- case 2:
- values[i] = -2.*((1.-p(0)*p(0))+(1.-p(1)*p(1)));
- break;
- case 3:
- values[i] = -2.*((1.-p(0)*p(0))*(1.-p(1)*p(1))
- +(1.-p(1)*p(1))*(1.-p(2)*p(2))
- +(1.-p(2)*p(2))*(1.-p(0)*p(0)));
- break;
- default:
- Assert(false, ExcNotImplemented());
- }
+ const Point<dim>& p = points[i];
+ switch(dim)
+ {
+ case 1:
+ values[i] = -2.;
+ break;
+ case 2:
+ values[i] = -2.*((1.-p(0)*p(0))+(1.-p(1)*p(1)));
+ break;
+ case 3:
+ values[i] = -2.*((1.-p(0)*p(0))*(1.-p(1)*p(1))
+ +(1.-p(1)*p(1))*(1.-p(2)*p(2))
+ +(1.-p(2)*p(2))*(1.-p(0)*p(0)));
+ break;
+ default:
+ Assert(false, ExcNotImplemented());
+ }
}
}
-
+
template<int dim>
Tensor<1,dim>
PillowFunction<dim>::gradient (const Point<dim> &p,
- const unsigned int) const
+ const unsigned int) const
{
Tensor<1,dim> result;
switch(dim)
{
- case 1:
- result[0] = -2.*p(0);
- break;
- case 2:
- result[0] = -2.*p(0)*(1.-p(1)*p(1));
- result[1] = -2.*p(1)*(1.-p(0)*p(0));
- break;
- case 3:
- result[0] = -2.*p(0)*(1.-p(1)*p(1))*(1.-p(2)*p(2));
- result[1] = -2.*p(1)*(1.-p(0)*p(0))*(1.-p(2)*p(2));
- result[2] = -2.*p(2)*(1.-p(0)*p(0))*(1.-p(1)*p(1));
- break;
- default:
- Assert(false, ExcNotImplemented());
+ case 1:
+ result[0] = -2.*p(0);
+ break;
+ case 2:
+ result[0] = -2.*p(0)*(1.-p(1)*p(1));
+ result[1] = -2.*p(1)*(1.-p(0)*p(0));
+ break;
+ case 3:
+ result[0] = -2.*p(0)*(1.-p(1)*p(1))*(1.-p(2)*p(2));
+ result[1] = -2.*p(1)*(1.-p(0)*p(0))*(1.-p(2)*p(2));
+ result[2] = -2.*p(2)*(1.-p(0)*p(0))*(1.-p(1)*p(1));
+ break;
+ default:
+ Assert(false, ExcNotImplemented());
}
return result;
}
-
+
template<int dim>
void
PillowFunction<dim>::gradient_list (const std::vector<Point<dim> > &points,
- std::vector<Tensor<1,dim> > &gradients,
- const unsigned int) const
+ std::vector<Tensor<1,dim> > &gradients,
+ const unsigned int) const
{
Assert (gradients.size() == points.size(),
- ExcDimensionMismatch(gradients.size(), points.size()));
-
+ ExcDimensionMismatch(gradients.size(), points.size()));
+
for (unsigned int i=0;i<points.size();++i)
{
- const Point<dim>& p = points[i];
- switch(dim)
- {
- case 1:
- gradients[i][0] = -2.*p(0);
- break;
- case 2:
- gradients[i][0] = -2.*p(0)*(1.-p(1)*p(1));
- gradients[i][1] = -2.*p(1)*(1.-p(0)*p(0));
- break;
- case 3:
- gradients[i][0] = -2.*p(0)*(1.-p(1)*p(1))*(1.-p(2)*p(2));
- gradients[i][1] = -2.*p(1)*(1.-p(0)*p(0))*(1.-p(2)*p(2));
- gradients[i][2] = -2.*p(2)*(1.-p(0)*p(0))*(1.-p(1)*p(1));
- break;
- default:
- Assert(false, ExcNotImplemented());
- }
+ const Point<dim>& p = points[i];
+ switch(dim)
+ {
+ case 1:
+ gradients[i][0] = -2.*p(0);
+ break;
+ case 2:
+ gradients[i][0] = -2.*p(0)*(1.-p(1)*p(1));
+ gradients[i][1] = -2.*p(1)*(1.-p(0)*p(0));
+ break;
+ case 3:
+ gradients[i][0] = -2.*p(0)*(1.-p(1)*p(1))*(1.-p(2)*p(2));
+ gradients[i][1] = -2.*p(1)*(1.-p(0)*p(0))*(1.-p(2)*p(2));
+ gradients[i][2] = -2.*p(2)*(1.-p(0)*p(0))*(1.-p(1)*p(1));
+ break;
+ default:
+ Assert(false, ExcNotImplemented());
+ }
}
}
-
+
//////////////////////////////////////////////////////////////////////
template <int dim>
CosineFunction<dim>::CosineFunction (const unsigned int n_components)
- :
- Function<dim> (n_components)
+ :
+ Function<dim> (n_components)
{}
template<int dim>
double
CosineFunction<dim>::value (const Point<dim> &p,
- const unsigned int) const
+ const unsigned int) const
{
switch(dim)
{
- case 1:
- return std::cos(M_PI_2*p(0));
- case 2:
- return std::cos(M_PI_2*p(0)) * std::cos(M_PI_2*p(1));
- case 3:
- return std::cos(M_PI_2*p(0)) * std::cos(M_PI_2*p(1)) * std::cos(M_PI_2*p(2));
- default:
- Assert(false, ExcNotImplemented());
+ case 1:
+ return std::cos(M_PI_2*p(0));
+ case 2:
+ return std::cos(M_PI_2*p(0)) * std::cos(M_PI_2*p(1));
+ case 3:
+ return std::cos(M_PI_2*p(0)) * std::cos(M_PI_2*p(1)) * std::cos(M_PI_2*p(2));
+ default:
+ Assert(false, ExcNotImplemented());
}
return 0.;
}
-
+
template<int dim>
void
CosineFunction<dim>::value_list (const std::vector<Point<dim> > &points,
- std::vector<double> &values,
- const unsigned int) const
+ std::vector<double> &values,
+ const unsigned int) const
{
Assert (values.size() == points.size(),
- ExcDimensionMismatch(values.size(), points.size()));
-
+ ExcDimensionMismatch(values.size(), points.size()));
+
for (unsigned int i=0;i<points.size();++i)
values[i] = value(points[i]);
}
-
-
+
+
template<int dim>
void
CosineFunction<dim>::vector_value_list (
std::vector<Vector<double> > &values) const
{
Assert (values.size() == points.size(),
- ExcDimensionMismatch(values.size(), points.size()));
-
+ ExcDimensionMismatch(values.size(), points.size()));
+
for (unsigned int i=0;i<points.size();++i)
{
- const double v = value(points[i]);
- for (unsigned int k=0;k<values[i].size();++k)
- values[i](k) = v;
+ const double v = value(points[i]);
+ for (unsigned int k=0;k<values[i].size();++k)
+ values[i](k) = v;
}
}
-
-
+
+
template<int dim>
double
CosineFunction<dim>::laplacian (const Point<dim> &p,
- const unsigned int) const
+ const unsigned int) const
{
switch(dim)
{
- case 1:
- return -M_PI_2*M_PI_2* std::cos(M_PI_2*p(0));
- case 2:
- return -2*M_PI_2*M_PI_2* std::cos(M_PI_2*p(0)) * std::cos(M_PI_2*p(1));
- case 3:
- return -3*M_PI_2*M_PI_2* std::cos(M_PI_2*p(0)) * std::cos(M_PI_2*p(1)) * std::cos(M_PI_2*p(2));
- default:
- Assert(false, ExcNotImplemented());
+ case 1:
+ return -M_PI_2*M_PI_2* std::cos(M_PI_2*p(0));
+ case 2:
+ return -2*M_PI_2*M_PI_2* std::cos(M_PI_2*p(0)) * std::cos(M_PI_2*p(1));
+ case 3:
+ return -3*M_PI_2*M_PI_2* std::cos(M_PI_2*p(0)) * std::cos(M_PI_2*p(1)) * std::cos(M_PI_2*p(2));
+ default:
+ Assert(false, ExcNotImplemented());
}
return 0.;
}
-
+
template<int dim>
void
CosineFunction<dim>::laplacian_list (const std::vector<Point<dim> > &points,
- std::vector<double> &values,
- const unsigned int) const
+ std::vector<double> &values,
+ const unsigned int) const
{
Assert (values.size() == points.size(),
- ExcDimensionMismatch(values.size(), points.size()));
-
+ ExcDimensionMismatch(values.size(), points.size()));
+
for (unsigned int i=0;i<points.size();++i)
values[i] = laplacian(points[i]);
}
-
+
template<int dim>
Tensor<1,dim>
CosineFunction<dim>::gradient (const Point<dim> &p,
- const unsigned int) const
+ const unsigned int) const
{
Tensor<1,dim> result;
switch(dim)
{
- case 1:
- result[0] = -M_PI_2* std::sin(M_PI_2*p(0));
- break;
- case 2:
- result[0] = -M_PI_2* std::sin(M_PI_2*p(0)) * std::cos(M_PI_2*p(1));
- result[1] = -M_PI_2* std::cos(M_PI_2*p(0)) * std::sin(M_PI_2*p(1));
- break;
- case 3:
- result[0] = -M_PI_2* std::sin(M_PI_2*p(0)) * std::cos(M_PI_2*p(1)) * std::cos(M_PI_2*p(2));
- result[1] = -M_PI_2* std::cos(M_PI_2*p(0)) * std::sin(M_PI_2*p(1)) * std::cos(M_PI_2*p(2));
- result[2] = -M_PI_2* std::cos(M_PI_2*p(0)) * std::cos(M_PI_2*p(1)) * std::sin(M_PI_2*p(2));
- break;
- default:
- Assert(false, ExcNotImplemented());
+ case 1:
+ result[0] = -M_PI_2* std::sin(M_PI_2*p(0));
+ break;
+ case 2:
+ result[0] = -M_PI_2* std::sin(M_PI_2*p(0)) * std::cos(M_PI_2*p(1));
+ result[1] = -M_PI_2* std::cos(M_PI_2*p(0)) * std::sin(M_PI_2*p(1));
+ break;
+ case 3:
+ result[0] = -M_PI_2* std::sin(M_PI_2*p(0)) * std::cos(M_PI_2*p(1)) * std::cos(M_PI_2*p(2));
+ result[1] = -M_PI_2* std::cos(M_PI_2*p(0)) * std::sin(M_PI_2*p(1)) * std::cos(M_PI_2*p(2));
+ result[2] = -M_PI_2* std::cos(M_PI_2*p(0)) * std::cos(M_PI_2*p(1)) * std::sin(M_PI_2*p(2));
+ break;
+ default:
+ Assert(false, ExcNotImplemented());
}
return result;
}
-
+
template<int dim>
void
CosineFunction<dim>::gradient_list (const std::vector<Point<dim> > &points,
- std::vector<Tensor<1,dim> > &gradients,
- const unsigned int) const
+ std::vector<Tensor<1,dim> > &gradients,
+ const unsigned int) const
{
Assert (gradients.size() == points.size(),
- ExcDimensionMismatch(gradients.size(), points.size()));
-
+ ExcDimensionMismatch(gradients.size(), points.size()));
+
for (unsigned int i=0;i<points.size();++i)
{
- const Point<dim>& p = points[i];
- switch(dim)
- {
- case 1:
- gradients[i][0] = -M_PI_2* std::sin(M_PI_2*p(0));
- break;
- case 2:
- gradients[i][0] = -M_PI_2* std::sin(M_PI_2*p(0)) * std::cos(M_PI_2*p(1));
- gradients[i][1] = -M_PI_2* std::cos(M_PI_2*p(0)) * std::sin(M_PI_2*p(1));
- break;
- case 3:
- gradients[i][0] = -M_PI_2* std::sin(M_PI_2*p(0)) * std::cos(M_PI_2*p(1)) * std::cos(M_PI_2*p(2));
- gradients[i][1] = -M_PI_2* std::cos(M_PI_2*p(0)) * std::sin(M_PI_2*p(1)) * std::cos(M_PI_2*p(2));
- gradients[i][2] = -M_PI_2* std::cos(M_PI_2*p(0)) * std::cos(M_PI_2*p(1)) * std::sin(M_PI_2*p(2));
- break;
- default:
- Assert(false, ExcNotImplemented());
- }
+ const Point<dim>& p = points[i];
+ switch(dim)
+ {
+ case 1:
+ gradients[i][0] = -M_PI_2* std::sin(M_PI_2*p(0));
+ break;
+ case 2:
+ gradients[i][0] = -M_PI_2* std::sin(M_PI_2*p(0)) * std::cos(M_PI_2*p(1));
+ gradients[i][1] = -M_PI_2* std::cos(M_PI_2*p(0)) * std::sin(M_PI_2*p(1));
+ break;
+ case 3:
+ gradients[i][0] = -M_PI_2* std::sin(M_PI_2*p(0)) * std::cos(M_PI_2*p(1)) * std::cos(M_PI_2*p(2));
+ gradients[i][1] = -M_PI_2* std::cos(M_PI_2*p(0)) * std::sin(M_PI_2*p(1)) * std::cos(M_PI_2*p(2));
+ gradients[i][2] = -M_PI_2* std::cos(M_PI_2*p(0)) * std::cos(M_PI_2*p(1)) * std::sin(M_PI_2*p(2));
+ break;
+ default:
+ Assert(false, ExcNotImplemented());
+ }
}
}
-
+
template<int dim>
Tensor<2,dim>
CosineFunction<dim>::hessian (const Point<dim> &p,
- const unsigned int) const
+ const unsigned int) const
{
const double pi2 = M_PI_2*M_PI_2;
-
+
Tensor<2,dim> result;
switch(dim)
{
- case 1:
- result[0][0] = -pi2* std::cos(M_PI_2*p(0));
- break;
- case 2:
- if (true)
- {
- const double coco = -pi2*std::cos(M_PI_2*p(0)) * std::cos(M_PI_2*p(1));
- const double sisi = pi2*std::sin(M_PI_2*p(0)) * std::sin(M_PI_2*p(1));
- result[0][0] = coco;
- result[1][1] = coco;
- result[0][1] = sisi;
- result[1][0] = sisi;
- }
- break;
- case 3:
- if (true)
- {
- const double cococo = -pi2*std::cos(M_PI_2*p(0)) * std::cos(M_PI_2*p(1)) * std::cos(M_PI_2*p(2));
- const double sisico = pi2*std::sin(M_PI_2*p(0)) * std::sin(M_PI_2*p(1)) * std::cos(M_PI_2*p(2));
- const double sicosi = pi2*std::sin(M_PI_2*p(0)) * std::cos(M_PI_2*p(1)) * std::sin(M_PI_2*p(2));
- const double cosisi = pi2*std::cos(M_PI_2*p(0)) * std::sin(M_PI_2*p(1)) * std::sin(M_PI_2*p(2));
-
- result[0][0] = cococo;
- result[1][1] = cococo;
- result[2][2] = cococo;
- result[0][1] = sisico;
- result[1][0] = sisico;
- result[0][2] = sicosi;
- result[2][0] = sicosi;
- result[1][2] = cosisi;
- result[2][1] = cosisi;
- }
- break;
- default:
- Assert(false, ExcNotImplemented());
+ case 1:
+ result[0][0] = -pi2* std::cos(M_PI_2*p(0));
+ break;
+ case 2:
+ if (true)
+ {
+ const double coco = -pi2*std::cos(M_PI_2*p(0)) * std::cos(M_PI_2*p(1));
+ const double sisi = pi2*std::sin(M_PI_2*p(0)) * std::sin(M_PI_2*p(1));
+ result[0][0] = coco;
+ result[1][1] = coco;
+ result[0][1] = sisi;
+ result[1][0] = sisi;
+ }
+ break;
+ case 3:
+ if (true)
+ {
+ const double cococo = -pi2*std::cos(M_PI_2*p(0)) * std::cos(M_PI_2*p(1)) * std::cos(M_PI_2*p(2));
+ const double sisico = pi2*std::sin(M_PI_2*p(0)) * std::sin(M_PI_2*p(1)) * std::cos(M_PI_2*p(2));
+ const double sicosi = pi2*std::sin(M_PI_2*p(0)) * std::cos(M_PI_2*p(1)) * std::sin(M_PI_2*p(2));
+ const double cosisi = pi2*std::cos(M_PI_2*p(0)) * std::sin(M_PI_2*p(1)) * std::sin(M_PI_2*p(2));
+
+ result[0][0] = cococo;
+ result[1][1] = cococo;
+ result[2][2] = cococo;
+ result[0][1] = sisico;
+ result[1][0] = sisico;
+ result[0][2] = sicosi;
+ result[2][0] = sicosi;
+ result[1][2] = cosisi;
+ result[2][1] = cosisi;
+ }
+ break;
+ default:
+ Assert(false, ExcNotImplemented());
}
return result;
}
-
+
template<int dim>
void
CosineFunction<dim>::hessian_list (const std::vector<Point<dim> > &points,
- std::vector<Tensor<2,dim> > &hessians,
- const unsigned int) const
+ std::vector<Tensor<2,dim> > &hessians,
+ const unsigned int) const
{
Assert (hessians.size() == points.size(),
- ExcDimensionMismatch(hessians.size(), points.size()));
-
+ ExcDimensionMismatch(hessians.size(), points.size()));
+
const double pi2 = M_PI_2*M_PI_2;
-
+
for (unsigned int i=0;i<points.size();++i)
{
- const Point<dim>& p = points[i];
- switch(dim)
- {
- case 1:
- hessians[i][0][0] = -pi2* std::cos(M_PI_2*p(0));
- break;
- case 2:
- if (true)
- {
- const double coco = -pi2*std::cos(M_PI_2*p(0)) * std::cos(M_PI_2*p(1));
- const double sisi = pi2*std::sin(M_PI_2*p(0)) * std::sin(M_PI_2*p(1));
- hessians[i][0][0] = coco;
- hessians[i][1][1] = coco;
- hessians[i][0][1] = sisi;
- hessians[i][1][0] = sisi;
- }
- break;
- case 3:
- if (true)
- {
- const double cococo = -pi2*std::cos(M_PI_2*p(0)) * std::cos(M_PI_2*p(1)) * std::cos(M_PI_2*p(2));
- const double sisico = pi2*std::sin(M_PI_2*p(0)) * std::sin(M_PI_2*p(1)) * std::cos(M_PI_2*p(2));
- const double sicosi = pi2*std::sin(M_PI_2*p(0)) * std::cos(M_PI_2*p(1)) * std::sin(M_PI_2*p(2));
- const double cosisi = pi2*std::cos(M_PI_2*p(0)) * std::sin(M_PI_2*p(1)) * std::sin(M_PI_2*p(2));
-
- hessians[i][0][0] = cococo;
- hessians[i][1][1] = cococo;
- hessians[i][2][2] = cococo;
- hessians[i][0][1] = sisico;
- hessians[i][1][0] = sisico;
- hessians[i][0][2] = sicosi;
- hessians[i][2][0] = sicosi;
- hessians[i][1][2] = cosisi;
- hessians[i][2][1] = cosisi;
- }
- break;
- default:
- Assert(false, ExcNotImplemented());
- }
+ const Point<dim>& p = points[i];
+ switch(dim)
+ {
+ case 1:
+ hessians[i][0][0] = -pi2* std::cos(M_PI_2*p(0));
+ break;
+ case 2:
+ if (true)
+ {
+ const double coco = -pi2*std::cos(M_PI_2*p(0)) * std::cos(M_PI_2*p(1));
+ const double sisi = pi2*std::sin(M_PI_2*p(0)) * std::sin(M_PI_2*p(1));
+ hessians[i][0][0] = coco;
+ hessians[i][1][1] = coco;
+ hessians[i][0][1] = sisi;
+ hessians[i][1][0] = sisi;
+ }
+ break;
+ case 3:
+ if (true)
+ {
+ const double cococo = -pi2*std::cos(M_PI_2*p(0)) * std::cos(M_PI_2*p(1)) * std::cos(M_PI_2*p(2));
+ const double sisico = pi2*std::sin(M_PI_2*p(0)) * std::sin(M_PI_2*p(1)) * std::cos(M_PI_2*p(2));
+ const double sicosi = pi2*std::sin(M_PI_2*p(0)) * std::cos(M_PI_2*p(1)) * std::sin(M_PI_2*p(2));
+ const double cosisi = pi2*std::cos(M_PI_2*p(0)) * std::sin(M_PI_2*p(1)) * std::sin(M_PI_2*p(2));
+
+ hessians[i][0][0] = cococo;
+ hessians[i][1][1] = cococo;
+ hessians[i][2][2] = cococo;
+ hessians[i][0][1] = sisico;
+ hessians[i][1][0] = sisico;
+ hessians[i][0][2] = sicosi;
+ hessians[i][2][0] = sicosi;
+ hessians[i][1][2] = cosisi;
+ hessians[i][2][1] = cosisi;
+ }
+ break;
+ default:
+ Assert(false, ExcNotImplemented());
+ }
}
}
-
+
//////////////////////////////////////////////////////////////////////
-
+
template <int dim>
CosineGradFunction<dim>::CosineGradFunction ()
- :
- Function<dim> (dim)
+ :
+ Function<dim> (dim)
{}
-
-
+
+
template<int dim>
double
CosineGradFunction<dim>::value (
const unsigned int d2 = (d+2) % dim;
switch(dim)
{
- case 1:
- return (-M_PI_2* std::sin(M_PI_2*p(0)));
- case 2:
- return (-M_PI_2* std::sin(M_PI_2*p(d)) * std::cos(M_PI_2*p(d1)));
- case 3:
- return (-M_PI_2* std::sin(M_PI_2*p(d)) * std::cos(M_PI_2*p(d1)) * std::cos(M_PI_2*p(d2)));
- default:
- Assert(false, ExcNotImplemented());
+ case 1:
+ return (-M_PI_2* std::sin(M_PI_2*p(0)));
+ case 2:
+ return (-M_PI_2* std::sin(M_PI_2*p(d)) * std::cos(M_PI_2*p(d1)));
+ case 3:
+ return (-M_PI_2* std::sin(M_PI_2*p(d)) * std::cos(M_PI_2*p(d1)) * std::cos(M_PI_2*p(d2)));
+ default:
+ Assert(false, ExcNotImplemented());
}
return 0.;
}
-
+
template<int dim>
void
CosineGradFunction<dim>::vector_value (
AssertDimension(result.size(), dim);
switch(dim)
{
- case 1:
- result(0) = -M_PI_2* std::sin(M_PI_2*p(0));
- break;
- case 2:
- result(0) = -M_PI_2* std::sin(M_PI_2*p(0)) * std::cos(M_PI_2*p(1));
- result(1) = -M_PI_2* std::cos(M_PI_2*p(0)) * std::sin(M_PI_2*p(1));
- break;
- case 3:
- result(0) = -M_PI_2* std::sin(M_PI_2*p(0)) * std::cos(M_PI_2*p(1)) * std::cos(M_PI_2*p(2));
- result(1) = -M_PI_2* std::cos(M_PI_2*p(0)) * std::sin(M_PI_2*p(1)) * std::cos(M_PI_2*p(2));
- result(2) = -M_PI_2* std::cos(M_PI_2*p(0)) * std::cos(M_PI_2*p(1)) * std::sin(M_PI_2*p(2));
- break;
- default:
- Assert(false, ExcNotImplemented());
+ case 1:
+ result(0) = -M_PI_2* std::sin(M_PI_2*p(0));
+ break;
+ case 2:
+ result(0) = -M_PI_2* std::sin(M_PI_2*p(0)) * std::cos(M_PI_2*p(1));
+ result(1) = -M_PI_2* std::cos(M_PI_2*p(0)) * std::sin(M_PI_2*p(1));
+ break;
+ case 3:
+ result(0) = -M_PI_2* std::sin(M_PI_2*p(0)) * std::cos(M_PI_2*p(1)) * std::cos(M_PI_2*p(2));
+ result(1) = -M_PI_2* std::cos(M_PI_2*p(0)) * std::sin(M_PI_2*p(1)) * std::cos(M_PI_2*p(2));
+ result(2) = -M_PI_2* std::cos(M_PI_2*p(0)) * std::cos(M_PI_2*p(1)) * std::sin(M_PI_2*p(2));
+ break;
+ default:
+ Assert(false, ExcNotImplemented());
}
}
-
+
template<int dim>
void
const unsigned int d) const
{
Assert (values.size() == points.size(),
- ExcDimensionMismatch(values.size(), points.size()));
+ ExcDimensionMismatch(values.size(), points.size()));
AssertIndexRange(d, dim);
const unsigned int d1 = (d+1) % dim;
const unsigned int d2 = (d+2) % dim;
-
+
for (unsigned int i=0;i<points.size();++i)
{
- const Point<dim>& p = points[i];
- switch(dim)
- {
- case 1:
- values[i] = -M_PI_2* std::sin(M_PI_2*p(d));
- break;
- case 2:
- values[i] = -M_PI_2* std::sin(M_PI_2*p(d)) * std::cos(M_PI_2*p(d1));
- break;
- case 3:
- values[i] = -M_PI_2* std::sin(M_PI_2*p(d)) * std::cos(M_PI_2*p(d1)) * std::cos(M_PI_2*p(d2));
- break;
- default:
- Assert(false, ExcNotImplemented());
- }
+ const Point<dim>& p = points[i];
+ switch(dim)
+ {
+ case 1:
+ values[i] = -M_PI_2* std::sin(M_PI_2*p(d));
+ break;
+ case 2:
+ values[i] = -M_PI_2* std::sin(M_PI_2*p(d)) * std::cos(M_PI_2*p(d1));
+ break;
+ case 3:
+ values[i] = -M_PI_2* std::sin(M_PI_2*p(d)) * std::cos(M_PI_2*p(d1)) * std::cos(M_PI_2*p(d2));
+ break;
+ default:
+ Assert(false, ExcNotImplemented());
+ }
}
}
-
-
+
+
template<int dim>
void
CosineGradFunction<dim>::vector_value_list (
std::vector<Vector<double> > &values) const
{
Assert (values.size() == points.size(),
- ExcDimensionMismatch(values.size(), points.size()));
-
+ ExcDimensionMismatch(values.size(), points.size()));
+
for (unsigned int i=0;i<points.size();++i)
{
- const Point<dim>& p = points[i];
- switch(dim)
- {
- case 1:
- values[i](0) = -M_PI_2* std::sin(M_PI_2*p(0));
- break;
- case 2:
- values[i](0) = -M_PI_2* std::sin(M_PI_2*p(0)) * std::cos(M_PI_2*p(1));
- values[i](1) = -M_PI_2* std::cos(M_PI_2*p(0)) * std::sin(M_PI_2*p(1));
- break;
- case 3:
- values[i](0) = -M_PI_2* std::sin(M_PI_2*p(0)) * std::cos(M_PI_2*p(1)) * std::cos(M_PI_2*p(2));
- values[i](1) = -M_PI_2* std::cos(M_PI_2*p(0)) * std::sin(M_PI_2*p(1)) * std::cos(M_PI_2*p(2));
- values[i](2) = -M_PI_2* std::cos(M_PI_2*p(0)) * std::cos(M_PI_2*p(1)) * std::sin(M_PI_2*p(2));
- break;
- default:
- Assert(false, ExcNotImplemented());
- }
+ const Point<dim>& p = points[i];
+ switch(dim)
+ {
+ case 1:
+ values[i](0) = -M_PI_2* std::sin(M_PI_2*p(0));
+ break;
+ case 2:
+ values[i](0) = -M_PI_2* std::sin(M_PI_2*p(0)) * std::cos(M_PI_2*p(1));
+ values[i](1) = -M_PI_2* std::cos(M_PI_2*p(0)) * std::sin(M_PI_2*p(1));
+ break;
+ case 3:
+ values[i](0) = -M_PI_2* std::sin(M_PI_2*p(0)) * std::cos(M_PI_2*p(1)) * std::cos(M_PI_2*p(2));
+ values[i](1) = -M_PI_2* std::cos(M_PI_2*p(0)) * std::sin(M_PI_2*p(1)) * std::cos(M_PI_2*p(2));
+ values[i](2) = -M_PI_2* std::cos(M_PI_2*p(0)) * std::cos(M_PI_2*p(1)) * std::sin(M_PI_2*p(2));
+ break;
+ default:
+ Assert(false, ExcNotImplemented());
+ }
}
}
-
-
+
+
template<int dim>
double
CosineGradFunction<dim>::laplacian (
const unsigned int d1 = (d+1) % dim;
const unsigned int d2 = (d+2) % dim;
const double pi2 = M_PI_2*M_PI_2;
-
+
Tensor<1,dim> result;
switch(dim)
{
- case 1:
- result[0] = -pi2* std::cos(M_PI_2*p(0));
- break;
- case 2:
- result[d ] = -pi2*std::cos(M_PI_2*p(d)) * std::cos(M_PI_2*p(d1));
- result[d1] = pi2*std::sin(M_PI_2*p(d)) * std::sin(M_PI_2*p(d1));
- break;
- case 3:
- result[d ] = -pi2*std::cos(M_PI_2*p(d)) * std::cos(M_PI_2*p(d1)) * std::cos(M_PI_2*p(d2));
- result[d1] = pi2*std::sin(M_PI_2*p(d)) * std::sin(M_PI_2*p(d1)) * std::cos(M_PI_2*p(d2));
- result[d2] = pi2*std::sin(M_PI_2*p(d)) * std::cos(M_PI_2*p(d1)) * std::sin(M_PI_2*p(d2));
- break;
- default:
- Assert(false, ExcNotImplemented());
+ case 1:
+ result[0] = -pi2* std::cos(M_PI_2*p(0));
+ break;
+ case 2:
+ result[d ] = -pi2*std::cos(M_PI_2*p(d)) * std::cos(M_PI_2*p(d1));
+ result[d1] = pi2*std::sin(M_PI_2*p(d)) * std::sin(M_PI_2*p(d1));
+ break;
+ case 3:
+ result[d ] = -pi2*std::cos(M_PI_2*p(d)) * std::cos(M_PI_2*p(d1)) * std::cos(M_PI_2*p(d2));
+ result[d1] = pi2*std::sin(M_PI_2*p(d)) * std::sin(M_PI_2*p(d1)) * std::cos(M_PI_2*p(d2));
+ result[d2] = pi2*std::sin(M_PI_2*p(d)) * std::cos(M_PI_2*p(d1)) * std::sin(M_PI_2*p(d2));
+ break;
+ default:
+ Assert(false, ExcNotImplemented());
}
return result;
}
-
+
template<int dim>
void
CosineGradFunction<dim>::gradient_list (
const unsigned int d1 = (d+1) % dim;
const unsigned int d2 = (d+2) % dim;
const double pi2 = M_PI_2*M_PI_2;
-
+
Assert (gradients.size() == points.size(),
- ExcDimensionMismatch(gradients.size(), points.size()));
+ ExcDimensionMismatch(gradients.size(), points.size()));
for (unsigned int i=0;i<points.size();++i)
{
- const Point<dim>& p = points[i];
- Tensor<1,dim>& result = gradients[i];
-
- switch(dim)
- {
- case 1:
- result[0] = -pi2* std::cos(M_PI_2*p(0));
- break;
- case 2:
- result[d ] = -pi2*std::cos(M_PI_2*p(d)) * std::cos(M_PI_2*p(d1));
- result[d1] = pi2*std::sin(M_PI_2*p(d)) * std::sin(M_PI_2*p(d1));
- break;
- case 3:
- result[d ] = -pi2*std::cos(M_PI_2*p(d)) * std::cos(M_PI_2*p(d1)) * std::cos(M_PI_2*p(d2));
- result[d1] = pi2*std::sin(M_PI_2*p(d)) * std::sin(M_PI_2*p(d1)) * std::cos(M_PI_2*p(d2));
- result[d2] = pi2*std::sin(M_PI_2*p(d)) * std::cos(M_PI_2*p(d1)) * std::sin(M_PI_2*p(d2));
- break;
- default:
- Assert(false, ExcNotImplemented());
- }
+ const Point<dim>& p = points[i];
+ Tensor<1,dim>& result = gradients[i];
+
+ switch(dim)
+ {
+ case 1:
+ result[0] = -pi2* std::cos(M_PI_2*p(0));
+ break;
+ case 2:
+ result[d ] = -pi2*std::cos(M_PI_2*p(d)) * std::cos(M_PI_2*p(d1));
+ result[d1] = pi2*std::sin(M_PI_2*p(d)) * std::sin(M_PI_2*p(d1));
+ break;
+ case 3:
+ result[d ] = -pi2*std::cos(M_PI_2*p(d)) * std::cos(M_PI_2*p(d1)) * std::cos(M_PI_2*p(d2));
+ result[d1] = pi2*std::sin(M_PI_2*p(d)) * std::sin(M_PI_2*p(d1)) * std::cos(M_PI_2*p(d2));
+ result[d2] = pi2*std::sin(M_PI_2*p(d)) * std::cos(M_PI_2*p(d1)) * std::sin(M_PI_2*p(d2));
+ break;
+ default:
+ Assert(false, ExcNotImplemented());
+ }
}
}
-
-
+
+
template<int dim>
void
CosineGradFunction<dim>::vector_gradient_list (
const std::vector<Point<dim> > &points,
std::vector<std::vector<Tensor<1,dim> > >& gradients) const
{
- AssertVectorVectorDimension(gradients, points.size(), dim);
+ AssertVectorVectorDimension(gradients, points.size(), dim);
const double pi2 = M_PI_2*M_PI_2;
-
+
for (unsigned int i=0;i<points.size();++i)
{
- const Point<dim>& p = points[i];
- switch(dim)
- {
- case 1:
- gradients[i][0][0] = -pi2* std::cos(M_PI_2*p(0));
- break;
- case 2:
- if (true)
- {
- const double coco = -pi2*std::cos(M_PI_2*p(0)) * std::cos(M_PI_2*p(1));
- const double sisi = pi2*std::sin(M_PI_2*p(0)) * std::sin(M_PI_2*p(1));
- gradients[i][0][0] = coco;
- gradients[i][1][1] = coco;
- gradients[i][0][1] = sisi;
- gradients[i][1][0] = sisi;
- }
- break;
- case 3:
- if (true)
- {
- const double cococo = -pi2*std::cos(M_PI_2*p(0)) * std::cos(M_PI_2*p(1)) * std::cos(M_PI_2*p(2));
- const double sisico = pi2*std::sin(M_PI_2*p(0)) * std::sin(M_PI_2*p(1)) * std::cos(M_PI_2*p(2));
- const double sicosi = pi2*std::sin(M_PI_2*p(0)) * std::cos(M_PI_2*p(1)) * std::sin(M_PI_2*p(2));
- const double cosisi = pi2*std::cos(M_PI_2*p(0)) * std::sin(M_PI_2*p(1)) * std::sin(M_PI_2*p(2));
-
- gradients[i][0][0] = cococo;
- gradients[i][1][1] = cococo;
- gradients[i][2][2] = cococo;
- gradients[i][0][1] = sisico;
- gradients[i][1][0] = sisico;
- gradients[i][0][2] = sicosi;
- gradients[i][2][0] = sicosi;
- gradients[i][1][2] = cosisi;
- gradients[i][2][1] = cosisi;
- }
- break;
- default:
- Assert(false, ExcNotImplemented());
- }
+ const Point<dim>& p = points[i];
+ switch(dim)
+ {
+ case 1:
+ gradients[i][0][0] = -pi2* std::cos(M_PI_2*p(0));
+ break;
+ case 2:
+ if (true)
+ {
+ const double coco = -pi2*std::cos(M_PI_2*p(0)) * std::cos(M_PI_2*p(1));
+ const double sisi = pi2*std::sin(M_PI_2*p(0)) * std::sin(M_PI_2*p(1));
+ gradients[i][0][0] = coco;
+ gradients[i][1][1] = coco;
+ gradients[i][0][1] = sisi;
+ gradients[i][1][0] = sisi;
+ }
+ break;
+ case 3:
+ if (true)
+ {
+ const double cococo = -pi2*std::cos(M_PI_2*p(0)) * std::cos(M_PI_2*p(1)) * std::cos(M_PI_2*p(2));
+ const double sisico = pi2*std::sin(M_PI_2*p(0)) * std::sin(M_PI_2*p(1)) * std::cos(M_PI_2*p(2));
+ const double sicosi = pi2*std::sin(M_PI_2*p(0)) * std::cos(M_PI_2*p(1)) * std::sin(M_PI_2*p(2));
+ const double cosisi = pi2*std::cos(M_PI_2*p(0)) * std::sin(M_PI_2*p(1)) * std::sin(M_PI_2*p(2));
+
+ gradients[i][0][0] = cococo;
+ gradients[i][1][1] = cococo;
+ gradients[i][2][2] = cococo;
+ gradients[i][0][1] = sisico;
+ gradients[i][1][0] = sisico;
+ gradients[i][0][2] = sicosi;
+ gradients[i][2][0] = sicosi;
+ gradients[i][1][2] = cosisi;
+ gradients[i][2][1] = cosisi;
+ }
+ break;
+ default:
+ Assert(false, ExcNotImplemented());
+ }
}
}
-
-
+
+
//////////////////////////////////////////////////////////////////////
-
+
template<int dim>
double
ExpFunction<dim>::value (const Point<dim> &p,
- const unsigned int) const
+ const unsigned int) const
{
switch(dim)
{
- case 1:
- return std::exp(p(0));
- case 2:
- return std::exp(p(0)) * std::exp(p(1));
- case 3:
- return std::exp(p(0)) * std::exp(p(1)) * std::exp(p(2));
- default:
- Assert(false, ExcNotImplemented());
+ case 1:
+ return std::exp(p(0));
+ case 2:
+ return std::exp(p(0)) * std::exp(p(1));
+ case 3:
+ return std::exp(p(0)) * std::exp(p(1)) * std::exp(p(2));
+ default:
+ Assert(false, ExcNotImplemented());
}
return 0.;
}
-
+
template<int dim>
void
ExpFunction<dim>::value_list (const std::vector<Point<dim> > &points,
- std::vector<double> &values,
- const unsigned int) const
+ std::vector<double> &values,
+ const unsigned int) const
{
Assert (values.size() == points.size(),
- ExcDimensionMismatch(values.size(), points.size()));
-
+ ExcDimensionMismatch(values.size(), points.size()));
+
for (unsigned int i=0;i<points.size();++i)
{
- const Point<dim>& p = points[i];
- switch(dim)
- {
- case 1:
- values[i] = std::exp(p(0));
- break;
- case 2:
- values[i] = std::exp(p(0)) * std::exp(p(1));
- break;
- case 3:
- values[i] = std::exp(p(0)) * std::exp(p(1)) * std::exp(p(2));
- break;
- default:
- Assert(false, ExcNotImplemented());
- }
+ const Point<dim>& p = points[i];
+ switch(dim)
+ {
+ case 1:
+ values[i] = std::exp(p(0));
+ break;
+ case 2:
+ values[i] = std::exp(p(0)) * std::exp(p(1));
+ break;
+ case 3:
+ values[i] = std::exp(p(0)) * std::exp(p(1)) * std::exp(p(2));
+ break;
+ default:
+ Assert(false, ExcNotImplemented());
+ }
}
}
-
+
template<int dim>
double
ExpFunction<dim>::laplacian (const Point<dim> &p,
- const unsigned int) const
+ const unsigned int) const
{
switch(dim)
{
- case 1:
- return std::exp(p(0));
- case 2:
- return 2 * std::exp(p(0)) * std::exp(p(1));
- case 3:
- return 3 * std::exp(p(0)) * std::exp(p(1)) * std::exp(p(2));
- default:
- Assert(false, ExcNotImplemented());
+ case 1:
+ return std::exp(p(0));
+ case 2:
+ return 2 * std::exp(p(0)) * std::exp(p(1));
+ case 3:
+ return 3 * std::exp(p(0)) * std::exp(p(1)) * std::exp(p(2));
+ default:
+ Assert(false, ExcNotImplemented());
}
return 0.;
}
-
+
template<int dim>
void
ExpFunction<dim>::laplacian_list (const std::vector<Point<dim> > &points,
- std::vector<double> &values,
- const unsigned int) const
+ std::vector<double> &values,
+ const unsigned int) const
{
Assert (values.size() == points.size(),
- ExcDimensionMismatch(values.size(), points.size()));
-
+ ExcDimensionMismatch(values.size(), points.size()));
+
for (unsigned int i=0;i<points.size();++i)
{
- const Point<dim>& p = points[i];
- switch(dim)
- {
- case 1:
- values[i] = std::exp(p(0));
- break;
- case 2:
- values[i] = 2 * std::exp(p(0)) * std::exp(p(1));
- break;
- case 3:
- values[i] = 3 * std::exp(p(0)) * std::exp(p(1)) * std::exp(p(2));
- break;
- default:
- Assert(false, ExcNotImplemented());
- }
+ const Point<dim>& p = points[i];
+ switch(dim)
+ {
+ case 1:
+ values[i] = std::exp(p(0));
+ break;
+ case 2:
+ values[i] = 2 * std::exp(p(0)) * std::exp(p(1));
+ break;
+ case 3:
+ values[i] = 3 * std::exp(p(0)) * std::exp(p(1)) * std::exp(p(2));
+ break;
+ default:
+ Assert(false, ExcNotImplemented());
+ }
}
}
-
+
template<int dim>
Tensor<1,dim>
ExpFunction<dim>::gradient (const Point<dim> &p,
- const unsigned int) const
+ const unsigned int) const
{
Tensor<1,dim> result;
switch(dim)
{
- case 1:
- result[0] = std::exp(p(0));
- break;
- case 2:
- result[0] = std::exp(p(0)) * std::exp(p(1));
- result[1] = std::exp(p(0)) * std::exp(p(1));
- break;
- case 3:
- result[0] = std::exp(p(0)) * std::exp(p(1)) * std::exp(p(2));
- result[1] = std::exp(p(0)) * std::exp(p(1)) * std::exp(p(2));
- result[2] = std::exp(p(0)) * std::exp(p(1)) * std::exp(p(2));
- break;
- default:
- Assert(false, ExcNotImplemented());
+ case 1:
+ result[0] = std::exp(p(0));
+ break;
+ case 2:
+ result[0] = std::exp(p(0)) * std::exp(p(1));
+ result[1] = std::exp(p(0)) * std::exp(p(1));
+ break;
+ case 3:
+ result[0] = std::exp(p(0)) * std::exp(p(1)) * std::exp(p(2));
+ result[1] = std::exp(p(0)) * std::exp(p(1)) * std::exp(p(2));
+ result[2] = std::exp(p(0)) * std::exp(p(1)) * std::exp(p(2));
+ break;
+ default:
+ Assert(false, ExcNotImplemented());
}
return result;
}
-
+
template<int dim>
void
ExpFunction<dim>::gradient_list (const std::vector<Point<dim> > &points,
- std::vector<Tensor<1,dim> > &gradients,
- const unsigned int) const
+ std::vector<Tensor<1,dim> > &gradients,
+ const unsigned int) const
{
Assert (gradients.size() == points.size(),
- ExcDimensionMismatch(gradients.size(), points.size()));
-
+ ExcDimensionMismatch(gradients.size(), points.size()));
+
for (unsigned int i=0;i<points.size();++i)
{
- const Point<dim>& p = points[i];
- switch(dim)
- {
- case 1:
- gradients[i][0] = std::exp(p(0));
- break;
- case 2:
- gradients[i][0] = std::exp(p(0)) * std::exp(p(1));
- gradients[i][1] = std::exp(p(0)) * std::exp(p(1));
- break;
- case 3:
- gradients[i][0] = std::exp(p(0)) * std::exp(p(1)) * std::exp(p(2));
- gradients[i][1] = std::exp(p(0)) * std::exp(p(1)) * std::exp(p(2));
- gradients[i][2] = std::exp(p(0)) * std::exp(p(1)) * std::exp(p(2));
- break;
- default:
- Assert(false, ExcNotImplemented());
- }
+ const Point<dim>& p = points[i];
+ switch(dim)
+ {
+ case 1:
+ gradients[i][0] = std::exp(p(0));
+ break;
+ case 2:
+ gradients[i][0] = std::exp(p(0)) * std::exp(p(1));
+ gradients[i][1] = std::exp(p(0)) * std::exp(p(1));
+ break;
+ case 3:
+ gradients[i][0] = std::exp(p(0)) * std::exp(p(1)) * std::exp(p(2));
+ gradients[i][1] = std::exp(p(0)) * std::exp(p(1)) * std::exp(p(2));
+ gradients[i][2] = std::exp(p(0)) * std::exp(p(1)) * std::exp(p(2));
+ break;
+ default:
+ Assert(false, ExcNotImplemented());
+ }
}
}
-
+
//////////////////////////////////////////////////////////////////////
-
-
+
+
double
LSingularityFunction::value (const Point<2> &p,
- const unsigned int) const
+ const unsigned int) const
{
double x = p(0);
double y = p(1);
-
+
if ((x>=0) && (y>=0))
return 0.;
-
+
double phi = std::atan2(y,-x)+M_PI;
double r2 = x*x+y*y;
-
+
return std::pow(r2,1./3.) * std::sin(2./3.*phi);
}
-
-
+
+
void
LSingularityFunction::value_list (const std::vector<Point<2> > &points,
- std::vector<double> &values,
- const unsigned int) const
+ std::vector<double> &values,
+ const unsigned int) const
{
Assert (values.size() == points.size(),
- ExcDimensionMismatch(values.size(), points.size()));
-
+ ExcDimensionMismatch(values.size(), points.size()));
+
for (unsigned int i=0;i<points.size();++i)
{
- double x = points[i](0);
- double y = points[i](1);
-
- if ((x>=0) && (y>=0))
- values[i] = 0.;
- else
- {
- double phi = std::atan2(y,-x)+M_PI;
- double r2 = x*x+y*y;
-
- values[i] = std::pow(r2,1./3.) * std::sin(2./3.*phi);
- }
+ double x = points[i](0);
+ double y = points[i](1);
+
+ if ((x>=0) && (y>=0))
+ values[i] = 0.;
+ else
+ {
+ double phi = std::atan2(y,-x)+M_PI;
+ double r2 = x*x+y*y;
+
+ values[i] = std::pow(r2,1./3.) * std::sin(2./3.*phi);
+ }
}
}
-
-
+
+
void
LSingularityFunction::vector_value_list (
const std::vector<Point<2> >& points,
std::vector<Vector<double> >& values) const
{
Assert (values.size() == points.size(),
- ExcDimensionMismatch(values.size(), points.size()));
-
+ ExcDimensionMismatch(values.size(), points.size()));
+
for (unsigned int i=0;i<points.size();++i)
{
- Assert (values[i].size() == 1,
- ExcDimensionMismatch(values[i].size(), 1));
- double x = points[i](0);
- double y = points[i](1);
-
- if ((x>=0) && (y>=0))
- values[i](0) = 0.;
- else
- {
- double phi = std::atan2(y,-x)+M_PI;
- double r2 = x*x+y*y;
-
- values[i](0) = std::pow(r2,1./3.) * std::sin(2./3.*phi);
- }
+ Assert (values[i].size() == 1,
+ ExcDimensionMismatch(values[i].size(), 1));
+ double x = points[i](0);
+ double y = points[i](1);
+
+ if ((x>=0) && (y>=0))
+ values[i](0) = 0.;
+ else
+ {
+ double phi = std::atan2(y,-x)+M_PI;
+ double r2 = x*x+y*y;
+
+ values[i](0) = std::pow(r2,1./3.) * std::sin(2./3.*phi);
+ }
}
}
-
-
+
+
double
LSingularityFunction::laplacian (const Point<2> &,
- const unsigned int) const
+ const unsigned int) const
{
return 0.;
}
-
-
+
+
void
LSingularityFunction::laplacian_list (const std::vector<Point<2> > &points,
- std::vector<double> &values,
- const unsigned int) const
+ std::vector<double> &values,
+ const unsigned int) const
{
Assert (values.size() == points.size(),
- ExcDimensionMismatch(values.size(), points.size()));
-
+ ExcDimensionMismatch(values.size(), points.size()));
+
for (unsigned int i=0;i<points.size();++i)
values[i] = 0.;
}
-
+
Tensor<1,2>
LSingularityFunction::gradient (const Point<2> &p,
- const unsigned int) const
+ const unsigned int) const
{
double x = p(0);
double y = p(1);
double phi = std::atan2(y,-x)+M_PI;
double r43 = std::pow(x*x+y*y,2./3.);
-
+
Tensor<1,2> result;
result[0] = 2./3.*(std::sin(2./3.*phi)*x + std::cos(2./3.*phi)*y)/r43;
result[1] = 2./3.*(std::sin(2./3.*phi)*y - std::cos(2./3.*phi)*x)/r43;
return result;
}
-
-
+
+
void
LSingularityFunction::gradient_list (const std::vector<Point<2> > &points,
- std::vector<Tensor<1,2> > &gradients,
- const unsigned int) const
+ std::vector<Tensor<1,2> > &gradients,
+ const unsigned int) const
{
Assert (gradients.size() == points.size(),
- ExcDimensionMismatch(gradients.size(), points.size()));
-
+ ExcDimensionMismatch(gradients.size(), points.size()));
+
for (unsigned int i=0;i<points.size();++i)
{
- const Point<2>& p = points[i];
- double x = p(0);
- double y = p(1);
- double phi = std::atan2(y,-x)+M_PI;
- double r43 = std::pow(x*x+y*y,2./3.);
-
- gradients[i][0] = 2./3.*(std::sin(2./3.*phi)*x + std::cos(2./3.*phi)*y)/r43;
- gradients[i][1] = 2./3.*(std::sin(2./3.*phi)*y - std::cos(2./3.*phi)*x)/r43;
+ const Point<2>& p = points[i];
+ double x = p(0);
+ double y = p(1);
+ double phi = std::atan2(y,-x)+M_PI;
+ double r43 = std::pow(x*x+y*y,2./3.);
+
+ gradients[i][0] = 2./3.*(std::sin(2./3.*phi)*x + std::cos(2./3.*phi)*y)/r43;
+ gradients[i][1] = 2./3.*(std::sin(2./3.*phi)*y - std::cos(2./3.*phi)*x)/r43;
}
}
-
-
+
+
void
LSingularityFunction::vector_gradient_list (
const std::vector<Point<2> >& points,
std::vector<std::vector<Tensor<1,2> > >& gradients) const
{
Assert (gradients.size() == points.size(),
- ExcDimensionMismatch(gradients.size(), points.size()));
-
+ ExcDimensionMismatch(gradients.size(), points.size()));
+
for (unsigned int i=0;i<points.size();++i)
{
- Assert(gradients[i].size() == 1,
- ExcDimensionMismatch(gradients[i].size(), 1));
- const Point<2>& p = points[i];
- double x = p(0);
- double y = p(1);
- double phi = std::atan2(y,-x)+M_PI;
- double r43 = std::pow(x*x+y*y,2./3.);
-
- gradients[i][0][0] = 2./3.*(std::sin(2./3.*phi)*x + std::cos(2./3.*phi)*y)/r43;
- gradients[i][0][1] = 2./3.*(std::sin(2./3.*phi)*y - std::cos(2./3.*phi)*x)/r43;
+ Assert(gradients[i].size() == 1,
+ ExcDimensionMismatch(gradients[i].size(), 1));
+ const Point<2>& p = points[i];
+ double x = p(0);
+ double y = p(1);
+ double phi = std::atan2(y,-x)+M_PI;
+ double r43 = std::pow(x*x+y*y,2./3.);
+
+ gradients[i][0][0] = 2./3.*(std::sin(2./3.*phi)*x + std::cos(2./3.*phi)*y)/r43;
+ gradients[i][0][1] = 2./3.*(std::sin(2./3.*phi)*y - std::cos(2./3.*phi)*x)/r43;
}
}
-
+
//////////////////////////////////////////////////////////////////////
-
+
LSingularityGradFunction::LSingularityGradFunction ()
- :
- Function<2> (2)
+ :
+ Function<2> (2)
{}
-
+
double
LSingularityGradFunction::value (const Point<2> &p,
- const unsigned int d) const
+ const unsigned int d) const
{
AssertIndexRange(d,2);
-
+
const double x = p(0);
const double y = p(1);
const double phi = std::atan2(y,-x)+M_PI;
const double r43 = std::pow(x*x+y*y,2./3.);
return 2./3.*(std::sin(2./3.*phi)*p(d) +
- (d==0
- ? (std::cos(2./3.*phi)*y)
- : (-std::cos(2./3.*phi)*x)))
+ (d==0
+ ? (std::cos(2./3.*phi)*y)
+ : (-std::cos(2./3.*phi)*x)))
/r43;
}
-
-
+
+
void
LSingularityGradFunction::value_list (
const std::vector<Point<2> >& points,
{
AssertIndexRange(d, 2);
AssertDimension(values.size(), points.size());
-
+
for (unsigned int i=0;i<points.size();++i)
{
- const Point<2>& p = points[i];
- const double x = p(0);
- const double y = p(1);
- const double phi = std::atan2(y,-x)+M_PI;
- const double r43 = std::pow(x*x+y*y,2./3.);
-
- values[i] = 2./3.*(std::sin(2./3.*phi)*p(d) +
- (d==0
- ? (std::cos(2./3.*phi)*y)
- : (-std::cos(2./3.*phi)*x)))
- /r43;
+ const Point<2>& p = points[i];
+ const double x = p(0);
+ const double y = p(1);
+ const double phi = std::atan2(y,-x)+M_PI;
+ const double r43 = std::pow(x*x+y*y,2./3.);
+
+ values[i] = 2./3.*(std::sin(2./3.*phi)*p(d) +
+ (d==0
+ ? (std::cos(2./3.*phi)*y)
+ : (-std::cos(2./3.*phi)*x)))
+ /r43;
}
}
-
-
+
+
void
LSingularityGradFunction::vector_value_list (
const std::vector<Point<2> >& points,
std::vector<Vector<double> >& values) const
{
Assert (values.size() == points.size(),
- ExcDimensionMismatch(values.size(), points.size()));
-
+ ExcDimensionMismatch(values.size(), points.size()));
+
for (unsigned int i=0;i<points.size();++i)
{
- AssertDimension(values[i].size(), 2);
- const Point<2>& p = points[i];
- const double x = p(0);
- const double y = p(1);
- const double phi = std::atan2(y,-x)+M_PI;
- const double r43 = std::pow(x*x+y*y,2./3.);
-
- values[i](0) = 2./3.*(std::sin(2./3.*phi)*x + std::cos(2./3.*phi)*y)/r43;
- values[i](1) = 2./3.*(std::sin(2./3.*phi)*y - std::cos(2./3.*phi)*x)/r43;
+ AssertDimension(values[i].size(), 2);
+ const Point<2>& p = points[i];
+ const double x = p(0);
+ const double y = p(1);
+ const double phi = std::atan2(y,-x)+M_PI;
+ const double r43 = std::pow(x*x+y*y,2./3.);
+
+ values[i](0) = 2./3.*(std::sin(2./3.*phi)*x + std::cos(2./3.*phi)*y)/r43;
+ values[i](1) = 2./3.*(std::sin(2./3.*phi)*y - std::cos(2./3.*phi)*x)/r43;
}
}
-
-
+
+
double
LSingularityGradFunction::laplacian (const Point<2> &,
- const unsigned int) const
+ const unsigned int) const
{
return 0.;
}
-
-
+
+
void
LSingularityGradFunction::laplacian_list (const std::vector<Point<2> > &points,
- std::vector<double> &values,
- const unsigned int) const
+ std::vector<double> &values,
+ const unsigned int) const
{
Assert (values.size() == points.size(),
- ExcDimensionMismatch(values.size(), points.size()));
-
+ ExcDimensionMismatch(values.size(), points.size()));
+
for (unsigned int i=0;i<points.size();++i)
values[i] = 0.;
}
-
-
-
+
+
+
Tensor<1,2>
LSingularityGradFunction::gradient (
const Point<2> &/*p*/,
Assert(false, ExcNotImplemented());
return Tensor<1,2>();
}
-
-
+
+
void
LSingularityGradFunction::gradient_list (
const std::vector<Point<2> >& /*points*/,
{
Assert(false, ExcNotImplemented());
}
-
-
+
+
void
LSingularityGradFunction::vector_gradient_list (
const std::vector<Point<2> >& /*points*/,
{
Assert(false, ExcNotImplemented());
}
-
+
//////////////////////////////////////////////////////////////////////
-
+
template <int dim>
double
SlitSingularityFunction<dim>::value (
{
double x = p(0);
double y = p(1);
-
+
double phi = std::atan2(x,y)+M_PI;
double r2 = x*x+y*y;
-
+
return std::pow(r2,.25) * std::sin(.5*phi);
}
-
-
+
+
template <int dim>
void
SlitSingularityFunction<dim>::value_list (
const unsigned int) const
{
Assert (values.size() == points.size(),
- ExcDimensionMismatch(values.size(), points.size()));
-
+ ExcDimensionMismatch(values.size(), points.size()));
+
for (unsigned int i=0;i<points.size();++i)
{
- double x = points[i](0);
- double y = points[i](1);
-
- double phi = std::atan2(x,y)+M_PI;
- double r2 = x*x+y*y;
-
- values[i] = std::pow(r2,.25) * std::sin(.5*phi);
+ double x = points[i](0);
+ double y = points[i](1);
+
+ double phi = std::atan2(x,y)+M_PI;
+ double r2 = x*x+y*y;
+
+ values[i] = std::pow(r2,.25) * std::sin(.5*phi);
}
}
-
-
+
+
template <int dim>
void
SlitSingularityFunction<dim>::vector_value_list (
std::vector<Vector<double> >& values) const
{
Assert (values.size() == points.size(),
- ExcDimensionMismatch(values.size(), points.size()));
-
+ ExcDimensionMismatch(values.size(), points.size()));
+
for (unsigned int i=0;i<points.size();++i)
{
- Assert (values[i].size() == 1,
- ExcDimensionMismatch(values[i].size(), 1));
-
- double x = points[i](0);
- double y = points[i](1);
-
- double phi = std::atan2(x,y)+M_PI;
- double r2 = x*x+y*y;
-
- values[i](0) = std::pow(r2,.25) * std::sin(.5*phi);
+ Assert (values[i].size() == 1,
+ ExcDimensionMismatch(values[i].size(), 1));
+
+ double x = points[i](0);
+ double y = points[i](1);
+
+ double phi = std::atan2(x,y)+M_PI;
+ double r2 = x*x+y*y;
+
+ values[i](0) = std::pow(r2,.25) * std::sin(.5*phi);
}
}
-
-
+
+
template <int dim>
double
SlitSingularityFunction<dim>::laplacian (const Point<dim> &,
- const unsigned int) const
+ const unsigned int) const
{
return 0.;
}
-
-
+
+
template <int dim>
void
SlitSingularityFunction<dim>::laplacian_list (
const unsigned int) const
{
Assert (values.size() == points.size(),
- ExcDimensionMismatch(values.size(), points.size()));
-
+ ExcDimensionMismatch(values.size(), points.size()));
+
for (unsigned int i=0;i<points.size();++i)
values[i] = 0.;
}
-
-
+
+
template <int dim>
Tensor<1,dim>
SlitSingularityFunction<dim>::gradient (const Point<dim> &p,
- const unsigned int) const
+ const unsigned int) const
{
double x = p(0);
double y = p(1);
double phi = std::atan2(x,y)+M_PI;
double r64 = std::pow(x*x+y*y,3./4.);
-
+
Tensor<1,dim> result;
result[0] = 1./2.*(std::sin(1./2.*phi)*x + std::cos(1./2.*phi)*y)/r64;
result[1] = 1./2.*(std::sin(1./2.*phi)*y - std::cos(1./2.*phi)*x)/r64;
return result;
}
-
-
+
+
template <int dim>
void
SlitSingularityFunction<dim>::gradient_list (const std::vector<Point<dim> > &points,
- std::vector<Tensor<1,dim> > &gradients,
- const unsigned int) const
+ std::vector<Tensor<1,dim> > &gradients,
+ const unsigned int) const
{
Assert (gradients.size() == points.size(),
- ExcDimensionMismatch(gradients.size(), points.size()));
-
+ ExcDimensionMismatch(gradients.size(), points.size()));
+
for (unsigned int i=0;i<points.size();++i)
{
- const Point<dim>& p = points[i];
- double x = p(0);
- double y = p(1);
- double phi = std::atan2(x,y)+M_PI;
- double r64 = std::pow(x*x+y*y,3./4.);
-
- gradients[i][0] = 1./2.*(std::sin(1./2.*phi)*x + std::cos(1./2.*phi)*y)/r64;
- gradients[i][1] = 1./2.*(std::sin(1./2.*phi)*y - std::cos(1./2.*phi)*x)/r64;
- for (unsigned int d=2;d<dim;++d)
- gradients[i][d] = 0.;
+ const Point<dim>& p = points[i];
+ double x = p(0);
+ double y = p(1);
+ double phi = std::atan2(x,y)+M_PI;
+ double r64 = std::pow(x*x+y*y,3./4.);
+
+ gradients[i][0] = 1./2.*(std::sin(1./2.*phi)*x + std::cos(1./2.*phi)*y)/r64;
+ gradients[i][1] = 1./2.*(std::sin(1./2.*phi)*y - std::cos(1./2.*phi)*x)/r64;
+ for (unsigned int d=2;d<dim;++d)
+ gradients[i][d] = 0.;
}
}
-
+
template <int dim>
void
SlitSingularityFunction<dim>::vector_gradient_list (
std::vector<std::vector<Tensor<1,dim> > >& gradients) const
{
Assert (gradients.size() == points.size(),
- ExcDimensionMismatch(gradients.size(), points.size()));
-
+ ExcDimensionMismatch(gradients.size(), points.size()));
+
for (unsigned int i=0;i<points.size();++i)
{
- Assert(gradients[i].size() == 1,
- ExcDimensionMismatch(gradients[i].size(), 1));
-
- const Point<dim>& p = points[i];
- double x = p(0);
- double y = p(1);
- double phi = std::atan2(x,y)+M_PI;
- double r64 = std::pow(x*x+y*y,3./4.);
-
- gradients[i][0][0] = 1./2.*(std::sin(1./2.*phi)*x + std::cos(1./2.*phi)*y)/r64;
- gradients[i][0][1] = 1./2.*(std::sin(1./2.*phi)*y - std::cos(1./2.*phi)*x)/r64;
- for (unsigned int d=2;d<dim;++d)
- gradients[i][0][d] = 0.;
+ Assert(gradients[i].size() == 1,
+ ExcDimensionMismatch(gradients[i].size(), 1));
+
+ const Point<dim>& p = points[i];
+ double x = p(0);
+ double y = p(1);
+ double phi = std::atan2(x,y)+M_PI;
+ double r64 = std::pow(x*x+y*y,3./4.);
+
+ gradients[i][0][0] = 1./2.*(std::sin(1./2.*phi)*x + std::cos(1./2.*phi)*y)/r64;
+ gradients[i][0][1] = 1./2.*(std::sin(1./2.*phi)*y - std::cos(1./2.*phi)*x)/r64;
+ for (unsigned int d=2;d<dim;++d)
+ gradients[i][0][d] = 0.;
}
}
-
+
//////////////////////////////////////////////////////////////////////
-
-
+
+
double
SlitHyperSingularityFunction::value (const Point<2> &p,
- const unsigned int) const
+ const unsigned int) const
{
double x = p(0);
double y = p(1);
-
+
double phi = std::atan2(x,y)+M_PI;
double r2 = x*x+y*y;
-
+
return std::pow(r2,.125) * std::sin(.25*phi);
}
-
-
+
+
void
SlitHyperSingularityFunction::value_list (
const std::vector<Point<2> > &points,
const unsigned int) const
{
Assert (values.size() == points.size(),
- ExcDimensionMismatch(values.size(), points.size()));
-
+ ExcDimensionMismatch(values.size(), points.size()));
+
for (unsigned int i=0;i<points.size();++i)
{
- double x = points[i](0);
- double y = points[i](1);
-
- double phi = std::atan2(x,y)+M_PI;
- double r2 = x*x+y*y;
-
- values[i] = std::pow(r2,.125) * std::sin(.25*phi);
+ double x = points[i](0);
+ double y = points[i](1);
+
+ double phi = std::atan2(x,y)+M_PI;
+ double r2 = x*x+y*y;
+
+ values[i] = std::pow(r2,.125) * std::sin(.25*phi);
}
}
-
-
+
+
void
SlitHyperSingularityFunction::vector_value_list (
const std::vector<Point<2> >& points,
std::vector<Vector<double> >& values) const
{
Assert (values.size() == points.size(),
- ExcDimensionMismatch(values.size(), points.size()));
-
+ ExcDimensionMismatch(values.size(), points.size()));
+
for (unsigned int i=0;i<points.size();++i)
{
- Assert(values[i].size() == 1,
- ExcDimensionMismatch(values[i].size(), 1));
-
- double x = points[i](0);
- double y = points[i](1);
-
- double phi = std::atan2(x,y)+M_PI;
- double r2 = x*x+y*y;
-
- values[i](0) = std::pow(r2,.125) * std::sin(.25*phi);
+ Assert(values[i].size() == 1,
+ ExcDimensionMismatch(values[i].size(), 1));
+
+ double x = points[i](0);
+ double y = points[i](1);
+
+ double phi = std::atan2(x,y)+M_PI;
+ double r2 = x*x+y*y;
+
+ values[i](0) = std::pow(r2,.125) * std::sin(.25*phi);
}
}
-
-
+
+
double
SlitHyperSingularityFunction::laplacian (
const Point<2> &,
{
return 0.;
}
-
-
+
+
void
SlitHyperSingularityFunction::laplacian_list (
const std::vector<Point<2> > &points,
const unsigned int) const
{
Assert (values.size() == points.size(),
- ExcDimensionMismatch(values.size(), points.size()));
-
+ ExcDimensionMismatch(values.size(), points.size()));
+
for (unsigned int i=0;i<points.size();++i)
values[i] = 0.;
}
-
-
+
+
Tensor<1,2>
SlitHyperSingularityFunction::gradient (
const Point<2> &p,
double y = p(1);
double phi = std::atan2(x,y)+M_PI;
double r78 = std::pow(x*x+y*y,7./8.);
-
-
+
+
Tensor<1,2> result;
result[0] = 1./4.*(std::sin(1./4.*phi)*x + std::cos(1./4.*phi)*y)/r78;
result[1] = 1./4.*(std::sin(1./4.*phi)*y - std::cos(1./4.*phi)*x)/r78;
return result;
}
-
-
+
+
void
SlitHyperSingularityFunction::gradient_list (
const std::vector<Point<2> > &points,
const unsigned int) const
{
Assert (gradients.size() == points.size(),
- ExcDimensionMismatch(gradients.size(), points.size()));
-
+ ExcDimensionMismatch(gradients.size(), points.size()));
+
for (unsigned int i=0;i<points.size();++i)
{
- const Point<2>& p = points[i];
- double x = p(0);
- double y = p(1);
- double phi = std::atan2(x,y)+M_PI;
- double r78 = std::pow(x*x+y*y,7./8.);
-
- gradients[i][0] = 1./4.*(std::sin(1./4.*phi)*x + std::cos(1./4.*phi)*y)/r78;
- gradients[i][1] = 1./4.*(std::sin(1./4.*phi)*y - std::cos(1./4.*phi)*x)/r78;
+ const Point<2>& p = points[i];
+ double x = p(0);
+ double y = p(1);
+ double phi = std::atan2(x,y)+M_PI;
+ double r78 = std::pow(x*x+y*y,7./8.);
+
+ gradients[i][0] = 1./4.*(std::sin(1./4.*phi)*x + std::cos(1./4.*phi)*y)/r78;
+ gradients[i][1] = 1./4.*(std::sin(1./4.*phi)*y - std::cos(1./4.*phi)*x)/r78;
}
}
-
-
+
+
void
SlitHyperSingularityFunction::vector_gradient_list (
const std::vector<Point<2> > &points,
std::vector<std::vector<Tensor<1,2> > >& gradients) const
{
Assert (gradients.size() == points.size(),
- ExcDimensionMismatch(gradients.size(), points.size()));
-
+ ExcDimensionMismatch(gradients.size(), points.size()));
+
for (unsigned int i=0;i<points.size();++i)
{
- Assert(gradients[i].size() == 1,
- ExcDimensionMismatch(gradients[i].size(), 1));
-
- const Point<2>& p = points[i];
- double x = p(0);
- double y = p(1);
- double phi = std::atan2(x,y)+M_PI;
- double r78 = std::pow(x*x+y*y,7./8.);
-
- gradients[i][0][0] = 1./4.*(std::sin(1./4.*phi)*x + std::cos(1./4.*phi)*y)/r78;
- gradients[i][0][1] = 1./4.*(std::sin(1./4.*phi)*y - std::cos(1./4.*phi)*x)/r78;
+ Assert(gradients[i].size() == 1,
+ ExcDimensionMismatch(gradients[i].size(), 1));
+
+ const Point<2>& p = points[i];
+ double x = p(0);
+ double y = p(1);
+ double phi = std::atan2(x,y)+M_PI;
+ double r78 = std::pow(x*x+y*y,7./8.);
+
+ gradients[i][0][0] = 1./4.*(std::sin(1./4.*phi)*x + std::cos(1./4.*phi)*y)/r78;
+ gradients[i][0][1] = 1./4.*(std::sin(1./4.*phi)*y - std::cos(1./4.*phi)*x)/r78;
}
}
-
+
//////////////////////////////////////////////////////////////////////
-
+
template<int dim>
JumpFunction<dim>::JumpFunction(const Point<dim> &direction,
- const double steepness)
- :
- direction(direction),
- steepness(steepness)
+ const double steepness)
+ :
+ direction(direction),
+ steepness(steepness)
{
switch (dim)
{
- case 1:
- angle = 0;
- break;
- case 2:
- angle = std::atan2(direction(0),direction(1));
- break;
- case 3:
- Assert(false, ExcNotImplemented());
+ case 1:
+ angle = 0;
+ break;
+ case 2:
+ angle = std::atan2(direction(0),direction(1));
+ break;
+ case 3:
+ Assert(false, ExcNotImplemented());
}
sine = std::sin(angle);
cosine = std::cos(angle);
}
-
-
-
+
+
+
template<int dim>
double
JumpFunction<dim>::value (const Point<dim> &p,
- const unsigned int) const
+ const unsigned int) const
{
double x = steepness*(-cosine*p(0)+sine*p(1));
return -std::atan(x);
}
-
-
-
+
+
+
template<int dim>
void
JumpFunction<dim>::value_list (const std::vector<Point<dim> > &p,
- std::vector<double> &values,
- const unsigned int) const
+ std::vector<double> &values,
+ const unsigned int) const
{
Assert (values.size() == p.size(),
- ExcDimensionMismatch(values.size(), p.size()));
-
+ ExcDimensionMismatch(values.size(), p.size()));
+
for (unsigned int i=0;i<p.size();++i)
{
- double x = steepness*(-cosine*p[i](0)+sine*p[i](1));
- values[i] = -std::atan(x);
+ double x = steepness*(-cosine*p[i](0)+sine*p[i](1));
+ values[i] = -std::atan(x);
}
}
-
-
+
+
template<int dim>
double
JumpFunction<dim>::laplacian (const Point<dim> &p,
- const unsigned int) const
+ const unsigned int) const
{
double x = steepness*(-cosine*p(0)+sine*p(1));
double r = 1+x*x;
return 2*steepness*steepness*x/(r*r);
}
-
-
+
+
template<int dim>
void
JumpFunction<dim>::laplacian_list (const std::vector<Point<dim> > &p,
- std::vector<double> &values,
- const unsigned int) const
+ std::vector<double> &values,
+ const unsigned int) const
{
Assert (values.size() == p.size(),
- ExcDimensionMismatch(values.size(), p.size()));
-
+ ExcDimensionMismatch(values.size(), p.size()));
+
double f = 2*steepness*steepness;
-
+
for (unsigned int i=0;i<p.size();++i)
{
- double x = steepness*(-cosine*p[i](0)+sine*p[i](1));
- double r = 1+x*x;
- values[i] = f*x/(r*r);
+ double x = steepness*(-cosine*p[i](0)+sine*p[i](1));
+ double r = 1+x*x;
+ values[i] = f*x/(r*r);
}
}
-
-
-
+
+
+
template<int dim>
Tensor<1,dim>
JumpFunction<dim>::gradient (const Point<dim> &p,
- const unsigned int) const
+ const unsigned int) const
{
double x = steepness*(-cosine*p(0)+sine*p(1));
double r = -steepness*(1+x*x);
erg[1] = sine*r;
return erg;
}
-
-
-
+
+
+
template<int dim>
void
JumpFunction<dim>::gradient_list (const std::vector<Point<dim> > &p,
- std::vector<Tensor<1,dim> > &gradients,
- const unsigned int) const
+ std::vector<Tensor<1,dim> > &gradients,
+ const unsigned int) const
{
Assert (gradients.size() == p.size(),
- ExcDimensionMismatch(gradients.size(), p.size()));
-
+ ExcDimensionMismatch(gradients.size(), p.size()));
+
for (unsigned int i=0; i<p.size(); ++i)
{
- double x = steepness*(cosine*p[i](0)+sine*p[i](1));
- double r = -steepness*(1+x*x);
- gradients[i][0] = cosine*r;
- gradients[i][1] = sine*r;
+ double x = steepness*(cosine*p[i](0)+sine*p[i](1));
+ double r = -steepness*(1+x*x);
+ gradients[i][0] = cosine*r;
+ gradients[i][1] = sine*r;
}
}
-
-
-
+
+
+
template <int dim>
std::size_t
JumpFunction<dim>::memory_consumption () const
{
- // only simple data elements, so
- // use sizeof operator
+ // only simple data elements, so
+ // use sizeof operator
return sizeof (*this);
}
-
-
-
-
-
+
+
+
+
+
/* ---------------------- FourierCosineFunction ----------------------- */
-
-
+
+
template <int dim>
FourierCosineFunction<dim>::
FourierCosineFunction (const Point<dim> &fourier_coefficients)
- :
- Function<dim> (1),
- fourier_coefficients (fourier_coefficients)
+ :
+ Function<dim> (1),
+ fourier_coefficients (fourier_coefficients)
{}
-
-
-
+
+
+
template <int dim>
double
FourierCosineFunction<dim>::value (const Point<dim> &p,
- const unsigned int component) const
+ const unsigned int component) const
{
Assert (component==0, ExcIndexRange(component,0,1));
return std::cos(fourier_coefficients * p);
}
-
-
-
+
+
+
template <int dim>
Tensor<1,dim>
FourierCosineFunction<dim>::gradient (const Point<dim> &p,
- const unsigned int component) const
+ const unsigned int component) const
{
Assert (component==0, ExcIndexRange(component,0,1));
return -fourier_coefficients * std::sin(fourier_coefficients * p);
}
-
-
-
+
+
+
template <int dim>
double
FourierCosineFunction<dim>::laplacian (const Point<dim> &p,
- const unsigned int component) const
+ const unsigned int component) const
{
Assert (component==0, ExcIndexRange(component,0,1));
return fourier_coefficients.square() * (-std::cos(fourier_coefficients * p));
}
-
-
-
-
+
+
+
+
/* ---------------------- FourierSineFunction ----------------------- */
-
-
-
+
+
+
template <int dim>
FourierSineFunction<dim>::
FourierSineFunction (const Point<dim> &fourier_coefficients)
- :
- Function<dim> (1),
- fourier_coefficients (fourier_coefficients)
+ :
+ Function<dim> (1),
+ fourier_coefficients (fourier_coefficients)
{}
-
-
-
+
+
+
template <int dim>
double
FourierSineFunction<dim>::value (const Point<dim> &p,
- const unsigned int component) const
+ const unsigned int component) const
{
Assert (component==0, ExcIndexRange(component,0,1));
return std::sin(fourier_coefficients * p);
}
-
-
-
+
+
+
template <int dim>
Tensor<1,dim>
FourierSineFunction<dim>::gradient (const Point<dim> &p,
- const unsigned int component) const
+ const unsigned int component) const
{
Assert (component==0, ExcIndexRange(component,0,1));
return fourier_coefficients * std::cos(fourier_coefficients * p);
}
-
-
-
+
+
+
template <int dim>
double
FourierSineFunction<dim>::laplacian (const Point<dim> &p,
- const unsigned int component) const
+ const unsigned int component) const
{
Assert (component==0, ExcIndexRange(component,0,1));
return fourier_coefficients.square() * (-std::sin(fourier_coefficients * p));
}
-
+
/* ---------------------- FourierSineSum ----------------------- */
-
-
-
+
+
+
template <int dim>
FourierSineSum<dim>::
FourierSineSum (const std::vector<Point<dim> > &fourier_coefficients,
- const std::vector<double> &weights)
- :
- Function<dim> (1),
- fourier_coefficients (fourier_coefficients),
- weights (weights)
+ const std::vector<double> &weights)
+ :
+ Function<dim> (1),
+ fourier_coefficients (fourier_coefficients),
+ weights (weights)
{
Assert (fourier_coefficients.size() > 0, ExcZero());
Assert (fourier_coefficients.size() == weights.size(),
- ExcDimensionMismatch(fourier_coefficients.size(),
- weights.size()));
+ ExcDimensionMismatch(fourier_coefficients.size(),
+ weights.size()));
}
-
-
-
+
+
+
template <int dim>
double
FourierSineSum<dim>::value (const Point<dim> &p,
- const unsigned int component) const
+ const unsigned int component) const
{
Assert (component==0, ExcIndexRange(component,0,1));
double sum = 0;
for (unsigned int s=0; s<n; ++s)
sum += weights[s] * std::sin(fourier_coefficients[s] * p);
-
+
return sum;
}
-
-
-
+
+
+
template <int dim>
Tensor<1,dim>
FourierSineSum<dim>::gradient (const Point<dim> &p,
- const unsigned int component) const
+ const unsigned int component) const
{
Assert (component==0, ExcIndexRange(component,0,1));
Tensor<1,dim> sum;
for (unsigned int s=0; s<n; ++s)
sum += fourier_coefficients[s] * std::cos(fourier_coefficients[s] * p);
-
+
return sum;
}
-
-
-
+
+
+
template <int dim>
double
FourierSineSum<dim>::laplacian (const Point<dim> &p,
- const unsigned int component) const
+ const unsigned int component) const
{
Assert (component==0, ExcIndexRange(component,0,1));
double sum = 0;
for (unsigned int s=0; s<n; ++s)
sum -= fourier_coefficients[s].square() * std::sin(fourier_coefficients[s] * p);
-
+
return sum;
}
/* ---------------------- FourierCosineSum ----------------------- */
-
-
-
+
+
+
template <int dim>
FourierCosineSum<dim>::
FourierCosineSum (const std::vector<Point<dim> > &fourier_coefficients,
- const std::vector<double> &weights)
- :
- Function<dim> (1),
- fourier_coefficients (fourier_coefficients),
- weights (weights)
+ const std::vector<double> &weights)
+ :
+ Function<dim> (1),
+ fourier_coefficients (fourier_coefficients),
+ weights (weights)
{
Assert (fourier_coefficients.size() > 0, ExcZero());
Assert (fourier_coefficients.size() == weights.size(),
- ExcDimensionMismatch(fourier_coefficients.size(),
- weights.size()));
+ ExcDimensionMismatch(fourier_coefficients.size(),
+ weights.size()));
}
-
-
-
+
+
+
template <int dim>
double
FourierCosineSum<dim>::value (const Point<dim> &p,
- const unsigned int component) const
+ const unsigned int component) const
{
Assert (component==0, ExcIndexRange(component,0,1));
double sum = 0;
for (unsigned int s=0; s<n; ++s)
sum += weights[s] * std::cos(fourier_coefficients[s] * p);
-
+
return sum;
}
-
-
-
+
+
+
template <int dim>
Tensor<1,dim>
FourierCosineSum<dim>::gradient (const Point<dim> &p,
- const unsigned int component) const
+ const unsigned int component) const
{
Assert (component==0, ExcIndexRange(component,0,1));
Tensor<1,dim> sum;
for (unsigned int s=0; s<n; ++s)
sum -= fourier_coefficients[s] * std::sin(fourier_coefficients[s] * p);
-
+
return sum;
}
-
-
-
+
+
+
template <int dim>
double
FourierCosineSum<dim>::laplacian (const Point<dim> &p,
- const unsigned int component) const
+ const unsigned int component) const
{
Assert (component==0, ExcIndexRange(component,0,1));
double sum = 0;
for (unsigned int s=0; s<n; ++s)
sum -= fourier_coefficients[s].square() * std::cos(fourier_coefficients[s] * p);
-
+
return sum;
}
/* ---------------------- Monomial ----------------------- */
-
-
-
+
+
+
template <int dim>
Monomial<dim>::
Monomial (const Tensor<1,dim> &exponents,
- const unsigned int n_components)
- :
- Function<dim> (n_components),
- exponents (exponents)
+ const unsigned int n_components)
+ :
+ Function<dim> (n_components),
+ exponents (exponents)
{}
-
-
-
+
+
+
template <int dim>
double
Monomial<dim>::value (const Point<dim> &p,
- const unsigned int component) const
+ const unsigned int component) const
{
Assert (component<this->n_components,
- ExcIndexRange(component, 0, this->n_components)) ;
+ ExcIndexRange(component, 0, this->n_components)) ;
double prod = 1;
for (unsigned int s=0; s<dim; ++s)
prod *= std::pow(p[s], exponents[s]);
-
+
return prod;
}
template <int dim>
void
Monomial<dim>::vector_value (const Point<dim> &p,
- Vector<double> &values) const
+ Vector<double> &values) const
{
Assert (values.size() == this->n_components,
- ExcDimensionMismatch (values.size(), this->n_components));
+ ExcDimensionMismatch (values.size(), this->n_components));
for (unsigned int i=0; i<values.size(); ++i)
values(i) = Monomial<dim>::value(p,i);
}
-
-
-
+
+
+
template <int dim>
Tensor<1,dim>
Monomial<dim>::gradient (const Point<dim> &p,
- const unsigned int component) const
+ const unsigned int component) const
{
Assert (component==0, ExcIndexRange(component,0,1)) ;
Tensor<1,dim> r;
for (unsigned int d=0; d<dim; ++d)
{
- double prod = 1;
- for (unsigned int s=0; s<dim; ++s)
- prod *= (s==d
- ?
- exponents[s] * std::pow(p[s], exponents[s]-1)
- :
- std::pow(p[s], exponents[s]));
-
- r[d] = prod;
+ double prod = 1;
+ for (unsigned int s=0; s<dim; ++s)
+ prod *= (s==d
+ ?
+ exponents[s] * std::pow(p[s], exponents[s]-1)
+ :
+ std::pow(p[s], exponents[s]));
+
+ r[d] = prod;
}
-
+
return r;
}
template<int dim>
void
Monomial<dim>::value_list (const std::vector<Point<dim> > &points,
- std::vector<double> &values,
- const unsigned int component) const
+ std::vector<double> &values,
+ const unsigned int component) const
{
Assert (values.size() == points.size(),
- ExcDimensionMismatch(values.size(), points.size()));
+ ExcDimensionMismatch(values.size(), points.size()));
for (unsigned int i=0; i<points.size(); ++i)
values[i] = Monomial<dim>::value (points[i], component);
}
-
-
+
+
template <int dim>
Bessel1<dim>::Bessel1(
const unsigned int order,
const double wave_number,
const Point<dim> center)
- :
- order(order),
- wave_number(wave_number),
- center(center)
+ :
+ order(order),
+ wave_number(wave_number),
+ center(center)
{}
-
+
template <int dim>
double
Bessel1<dim>::value(const Point<dim>& p, const unsigned int) const
return r;
#endif
}
-
-
+
+
template <int dim>
void
Bessel1<dim>::value_list (
for (unsigned int k=0;k<points.size();++k)
{
#ifdef HAVE_JN_
- const double r = points[k].distance(center);
- values[k] = jn(order, r*wave_number);
+ const double r = points[k].distance(center);
+ values[k] = jn(order, r*wave_number);
#else
Assert(false, ExcMessage("Bessel function jn was not found by configure"));
-#endif
+#endif
}
}
-
+
template <int dim>
Tensor<1,dim>
Bessel1<dim>::gradient (const Point<dim> &p,
- const unsigned int) const
+ const unsigned int) const
{
Assert(dim==2, ExcNotImplemented());
const double r = p.distance(center);
const double co = (r==0.) ? 0. : (p(0)-center(0))/r;
const double si = (r==0.) ? 0. : (p(1)-center(1))/r;
-
+
const double dJn = (order==0)
- ? (-jn(1, r*wave_number))
- : (.5*(jn(order-1, wave_number*r) -jn(order+1, wave_number*r)));
+ ? (-jn(1, r*wave_number))
+ : (.5*(jn(order-1, wave_number*r) -jn(order+1, wave_number*r)));
Tensor<1,dim> result;
result[0] = wave_number * co * dJn;
result[1] = wave_number * si * dJn;
return Tensor<1,dim>();
#endif
}
-
-
+
+
template <int dim>
void
Bessel1<dim>::gradient_list (
AssertDimension(points.size(), gradients.size());
for (unsigned int k=0;k<points.size();++k)
{
- const Point<dim>& p = points[k];
- const double r = p.distance(center);
- const double co = (r==0.) ? 0. : (p(0)-center(0))/r;
- const double si = (r==0.) ? 0. : (p(1)-center(1))/r;
-
+ const Point<dim>& p = points[k];
+ const double r = p.distance(center);
+ const double co = (r==0.) ? 0. : (p(0)-center(0))/r;
+ const double si = (r==0.) ? 0. : (p(1)-center(1))/r;
+
#ifdef HAVE_JN_
- const double dJn = (order==0)
- ? (-jn(1, r*wave_number))
- : (.5*(jn(order-1, wave_number*r) -jn(order+1, wave_number*r)));
+ const double dJn = (order==0)
+ ? (-jn(1, r*wave_number))
+ : (.5*(jn(order-1, wave_number*r) -jn(order+1, wave_number*r)));
#else
- const double dJn = 0.;
- Assert(false, ExcMessage("Bessel function jn was not found by configure"));
+ const double dJn = 0.;
+ Assert(false, ExcMessage("Bessel function jn was not found by configure"));
#endif
- Tensor<1,dim>& result = gradients[k];
- result[0] = wave_number * co * dJn;
- result[1] = wave_number * si * dJn;
+ Tensor<1,dim>& result = gradients[k];
+ result[0] = wave_number * co * dJn;
+ result[1] = wave_number * si * dJn;
}
}
-
-// explicit instantiations
+
+// explicit instantiations
template class SquareFunction<1>;
template class SquareFunction<2>;
template class SquareFunction<3>;
// $Id$
// Version: $Name$
//
-// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2010 by the deal.II authors
+// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2010, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
{
template<int dim>
CutOffFunctionBase<dim>::CutOffFunctionBase (const double r,
- const Point<dim> p,
- const unsigned int n_components,
- const unsigned int select)
- :
- Function<dim> (n_components),
+ const Point<dim> p,
+ const unsigned int n_components,
+ const unsigned int select)
+ :
+ Function<dim> (n_components),
center(p),
radius(r),
selected(select)
template<int dim>
CutOffFunctionLinfty<dim>::CutOffFunctionLinfty (const double r,
- const Point<dim> p,
- const unsigned int n_components,
- const unsigned int select)
- :
- CutOffFunctionBase<dim> (r, p, n_components, select)
+ const Point<dim> p,
+ const unsigned int n_components,
+ const unsigned int select)
+ :
+ CutOffFunctionBase<dim> (r, p, n_components, select)
{}
template<int dim>
double
CutOffFunctionLinfty<dim>::value (const Point<dim> &p,
- const unsigned int component) const
+ const unsigned int component) const
{
if (this->selected==CutOffFunctionBase<dim>::no_component
- ||
- component==this->selected)
+ ||
+ component==this->selected)
return ((this->center.distance(p)<this->radius) ? 1. : 0.);
return 0.;
}
template<int dim>
void
CutOffFunctionLinfty<dim>::value_list (const std::vector<Point<dim> > &points,
- std::vector<double> &values,
- const unsigned int component) const
+ std::vector<double> &values,
+ const unsigned int component) const
{
Assert (values.size() == points.size(),
- ExcDimensionMismatch(values.size(), points.size()));
+ ExcDimensionMismatch(values.size(), points.size()));
Assert (component < this->n_components,
- ExcIndexRange(component,0,this->n_components));
+ ExcIndexRange(component,0,this->n_components));
if (this->selected==CutOffFunctionBase<dim>::no_component
- ||
- component==this->selected)
+ ||
+ component==this->selected)
for (unsigned int k=0;k<values.size();++k)
- values[k] = (this->center.distance(points[k])<this->radius) ? 1. : 0.;
+ values[k] = (this->center.distance(points[k])<this->radius) ? 1. : 0.;
else
std::fill (values.begin(), values.end(), 0.);
}
std::vector<Vector<double> > &values) const
{
Assert (values.size() == points.size(),
- ExcDimensionMismatch(values.size(), points.size()));
+ ExcDimensionMismatch(values.size(), points.size()));
for (unsigned int k=0;k<values.size();++k)
{
- const double
- val = (this->center.distance(points[k])<this->radius) ? 1. : 0.;
- if (this->selected==CutOffFunctionBase<dim>::no_component)
- values[k] = val;
- else
- {
- values[k] = 0;
- values[k](this->selected) = val;
- }
+ const double
+ val = (this->center.distance(points[k])<this->radius) ? 1. : 0.;
+ if (this->selected==CutOffFunctionBase<dim>::no_component)
+ values[k] = val;
+ else
+ {
+ values[k] = 0;
+ values[k](this->selected) = val;
+ }
}
}
template<int dim>
CutOffFunctionW1<dim>::CutOffFunctionW1 (const double r,
- const Point<dim> p,
- const unsigned int n_components,
- const unsigned int select)
- :
- CutOffFunctionBase<dim> (r, p, n_components, select)
+ const Point<dim> p,
+ const unsigned int n_components,
+ const unsigned int select)
+ :
+ CutOffFunctionBase<dim> (r, p, n_components, select)
{}
template<int dim>
double
CutOffFunctionW1<dim>::value (const Point<dim> &p,
- const unsigned int component) const
+ const unsigned int component) const
{
if (this->selected==CutOffFunctionBase<dim>::no_component
- ||
- component==this->selected)
+ ||
+ component==this->selected)
{
- const double d = this->center.distance(p);
- return ((d<this->radius) ? (this->radius-d) : 0.);
+ const double d = this->center.distance(p);
+ return ((d<this->radius) ? (this->radius-d) : 0.);
}
return 0.;
}
template<int dim>
void
CutOffFunctionW1<dim>::value_list (const std::vector<Point<dim> > &points,
- std::vector<double> &values,
- const unsigned int component) const
+ std::vector<double> &values,
+ const unsigned int component) const
{
Assert (values.size() == points.size(),
- ExcDimensionMismatch(values.size(), points.size()));
+ ExcDimensionMismatch(values.size(), points.size()));
if (this->selected==CutOffFunctionBase<dim>::no_component
- ||
- component==this->selected)
+ ||
+ component==this->selected)
for (unsigned int i=0;i<values.size();++i)
- {
- const double d = this->center.distance(points[i]);
- values[i] = ((d<this->radius) ? (this->radius-d) : 0.);
- }
+ {
+ const double d = this->center.distance(points[i]);
+ values[i] = ((d<this->radius) ? (this->radius-d) : 0.);
+ }
else
std::fill (values.begin(), values.end(), 0.);
}
std::vector<Vector<double> > &values) const
{
Assert (values.size() == points.size(),
- ExcDimensionMismatch(values.size(), points.size()));
+ ExcDimensionMismatch(values.size(), points.size()));
for (unsigned int k=0;k<values.size();++k)
{
- const double d = this->center.distance(points[k]);
- const double
- val = (d<this->radius) ? (this->radius-d) : 0.;
- if (this->selected==CutOffFunctionBase<dim>::no_component)
- values[k] = val;
- else
- {
- values[k] = 0;
- values[k](this->selected) = val;
- }
+ const double d = this->center.distance(points[k]);
+ const double
+ val = (d<this->radius) ? (this->radius-d) : 0.;
+ if (this->selected==CutOffFunctionBase<dim>::no_component)
+ values[k] = val;
+ else
+ {
+ values[k] = 0;
+ values[k](this->selected) = val;
+ }
}
}
template<int dim>
CutOffFunctionCinfty<dim>::CutOffFunctionCinfty (const double r,
- const Point<dim> p,
- const unsigned int n_components,
- const unsigned int select)
- :
- CutOffFunctionBase<dim> (r, p, n_components, select)
+ const Point<dim> p,
+ const unsigned int n_components,
+ const unsigned int select)
+ :
+ CutOffFunctionBase<dim> (r, p, n_components, select)
{}
template<int dim>
double
CutOffFunctionCinfty<dim>::value (const Point<dim> &p,
- const unsigned int component) const
+ const unsigned int component) const
{
if (this->selected==CutOffFunctionBase<dim>::no_component
- ||
- component==this->selected)
+ ||
+ component==this->selected)
{
- const double d = this->center.distance(p);
- const double r = this->radius;
- if (d>=r)
- return 0.;
- const double e = -r*r/(r*r-d*d);
- return ((e<-50) ? 0. : numbers::E * exp(e));
+ const double d = this->center.distance(p);
+ const double r = this->radius;
+ if (d>=r)
+ return 0.;
+ const double e = -r*r/(r*r-d*d);
+ return ((e<-50) ? 0. : numbers::E * exp(e));
}
return 0.;
}
template<int dim>
void
CutOffFunctionCinfty<dim>::value_list (const std::vector<Point<dim> > &points,
- std::vector<double> &values,
- const unsigned int component) const
+ std::vector<double> &values,
+ const unsigned int component) const
{
Assert (values.size() == points.size(),
- ExcDimensionMismatch(values.size(), points.size()));
+ ExcDimensionMismatch(values.size(), points.size()));
const double r = this->radius;
if (this->selected==CutOffFunctionBase<dim>::no_component
- ||
- component==this->selected)
+ ||
+ component==this->selected)
for (unsigned int i=0; i<values.size();++i)
- {
- const double d = this->center.distance(points[i]);
- if (d>=r)
- {
- values[i] = 0.;
- } else {
- const double e = -r*r/(r*r-d*d);
- values[i] = (e<-50) ? 0. : numbers::E * exp(e);
- }
- }
+ {
+ const double d = this->center.distance(points[i]);
+ if (d>=r)
+ {
+ values[i] = 0.;
+ } else {
+ const double e = -r*r/(r*r-d*d);
+ values[i] = (e<-50) ? 0. : numbers::E * exp(e);
+ }
+ }
else
std::fill (values.begin(), values.end(), 0.);
}
std::vector<Vector<double> > &values) const
{
Assert (values.size() == points.size(),
- ExcDimensionMismatch(values.size(), points.size()));
+ ExcDimensionMismatch(values.size(), points.size()));
for (unsigned int k=0;k<values.size();++k)
{
- const double d = this->center.distance(points[k]);
- const double r = this->radius;
- double e = 0.;
- double val = 0.;
- if (d<this->radius)
- {
- e = -r*r/(r*r-d*d);
- if (e>-50)
- val = numbers::E * exp(e);
- }
-
- if (this->selected==CutOffFunctionBase<dim>::no_component)
- values[k] = val;
- else
- {
- values[k] = 0;
- values[k](this->selected) = val;
- }
+ const double d = this->center.distance(points[k]);
+ const double r = this->radius;
+ double e = 0.;
+ double val = 0.;
+ if (d<this->radius)
+ {
+ e = -r*r/(r*r-d*d);
+ if (e>-50)
+ val = numbers::E * exp(e);
+ }
+
+ if (this->selected==CutOffFunctionBase<dim>::no_component)
+ values[k] = val;
+ else
+ {
+ values[k] = 0;
+ values[k](this->selected) = val;
+ }
}
}
template<int dim>
Tensor<1,dim>
CutOffFunctionCinfty<dim>::gradient (const Point<dim> &p,
- const unsigned int) const
+ const unsigned int) const
{
const double d = this->center.distance(p);
const double r = this->radius;
return Tensor<1,dim>();
const double e = -d*d/(r-d)/(r+d);
return ((e<-50) ?
- Point<dim>() :
- (p-this->center)/d*(-2.0*r*r/pow(-r*r+d*d,2.0)*d*exp(e)));
+ Point<dim>() :
+ (p-this->center)/d*(-2.0*r*r/pow(-r*r+d*d,2.0)*d*exp(e)));
}
// $Id$
// Version: $Name$
//
-// Copyright (C) 2005, 2006, 2007, 2009 by the deal.II authors
+// Copyright (C) 2005, 2006, 2007, 2009, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
template <int dim>
FunctionParser<dim>::FunctionParser(const unsigned int n_components,
- const double initial_time)
+ const double initial_time)
:
Function<dim>(n_components, initial_time),
fp (0)
template <int dim>
void FunctionParser<dim>::initialize (const std::string &variables,
- const std::vector<std::string> &expressions,
- const std::map<std::string, double> &constants,
- const std::map<std::string, double> &units,
- const bool time_dependent,
- const bool use_degrees)
+ const std::vector<std::string> &expressions,
+ const std::map<std::string, double> &constants,
+ const std::map<std::string, double> &units,
+ const bool time_dependent,
+ const bool use_degrees)
{
- // We check that the number of
- // components of this function
- // matches the number of components
- // passed in as a vector of
- // strings.
+ // We check that the number of
+ // components of this function
+ // matches the number of components
+ // passed in as a vector of
+ // strings.
AssertThrow(this->n_components == expressions.size(),
- ExcInvalidExpressionSize(this->n_components,
- expressions.size()) );
+ ExcInvalidExpressionSize(this->n_components,
+ expressions.size()) );
- // Add the various constants to
- // the parser.
+ // Add the various constants to
+ // the parser.
std::map< std::string, double >::const_iterator
- constant = constants.begin(),
- endc = constants.end();
+ constant = constants.begin(),
+ endc = constants.end();
for(; constant != endc; ++constant)
- {
- const bool success = fp[i].AddConstant(constant->first, constant->second);
- AssertThrow (success, ExcMessage("Invalid Constant Name"));
- }
+ {
+ const bool success = fp[i].AddConstant(constant->first, constant->second);
+ AssertThrow (success, ExcMessage("Invalid Constant Name"));
+ }
const int ret_value = fp[i].Parse(expressions[i],
- variables,
- use_degrees);
+ variables,
+ use_degrees);
AssertThrow (ret_value == -1,
- ExcParseError(ret_value, fp[i].ErrorMsg()));
-
- // The fact that the parser did
- // not throw an error does not
- // mean that everything went
- // ok... we can still have
- // problems with the number of
- // variables...
+ ExcParseError(ret_value, fp[i].ErrorMsg()));
+
+ // The fact that the parser did
+ // not throw an error does not
+ // mean that everything went
+ // ok... we can still have
+ // problems with the number of
+ // variables...
}
- // Now we define how many variables
- // we expect to read in. We
- // distinguish between two cases:
- // Time dependent problems, and not
- // time dependent problems. In the
- // first case the number of
- // variables is given by the
- // dimension plus one. In the other
- // case, the number of variables is
- // equal to the dimension. Once we
- // parsed the variables string, if
- // none of this is the case, then
- // an exception is thrown.
+ // Now we define how many variables
+ // we expect to read in. We
+ // distinguish between two cases:
+ // Time dependent problems, and not
+ // time dependent problems. In the
+ // first case the number of
+ // variables is given by the
+ // dimension plus one. In the other
+ // case, the number of variables is
+ // equal to the dimension. Once we
+ // parsed the variables string, if
+ // none of this is the case, then
+ // an exception is thrown.
if (time_dependent)
n_vars = dim+1;
else
n_vars = dim;
- // Let's check if the number of
- // variables is correct...
+ // Let's check if the number of
+ // variables is correct...
AssertThrow (n_vars == fp[0].NVars(),
- ExcDimensionMismatch(n_vars,fp[0].NVars()));
+ ExcDimensionMismatch(n_vars,fp[0].NVars()));
- // Now set the initialization bit.
+ // Now set the initialization bit.
initialized = true;
}
template <int dim>
void FunctionParser<dim>::initialize (const std::string &variables,
- const std::string &expression,
- const std::map<std::string, double> &constants,
- const bool time_dependent,
- const bool use_degrees)
+ const std::string &expression,
+ const std::map<std::string, double> &constants,
+ const bool time_dependent,
+ const bool use_degrees)
{
- // initialize with the things
- // we got.
+ // initialize with the things
+ // we got.
initialize (variables,
Utilities::split_string_list (expression, ';'),
constants,
template <int dim>
double FunctionParser<dim>::value (const Point<dim> &p,
- const unsigned int component) const
+ const unsigned int component) const
{
Assert (initialized==true, ExcNotInitialized());
Assert (component < this->n_components,
- ExcIndexRange(component, 0, this->n_components));
+ ExcIndexRange(component, 0, this->n_components));
- // Statically allocate dim+1
- // double variables.
+ // Statically allocate dim+1
+ // double variables.
double vars[dim+1];
for (unsigned int i=0; i<dim; ++i)
vars[i] = p(i);
- // We need the time variable only
- // if the number of variables is
- // different from the dimension. In
- // this case it can only be dim+1,
- // otherwise an exception would
- // have already been thrown
+ // We need the time variable only
+ // if the number of variables is
+ // different from the dimension. In
+ // this case it can only be dim+1,
+ // otherwise an exception would
+ // have already been thrown
if (dim != n_vars)
vars[dim] = this->get_time();
double my_value = fp[component].Eval((double*)vars);
AssertThrow (fp[component].EvalError() == 0,
- ExcMessage(fp[component].ErrorMsg()));
+ ExcMessage(fp[component].ErrorMsg()));
return my_value;
}
template <int dim>
void FunctionParser<dim>::vector_value (const Point<dim> &p,
- Vector<double> &values) const
+ Vector<double> &values) const
{
Assert (initialized==true, ExcNotInitialized());
Assert (values.size() == this->n_components,
- ExcDimensionMismatch (values.size(), this->n_components));
+ ExcDimensionMismatch (values.size(), this->n_components));
- // Statically allocates dim+1
- // double variables.
+ // Statically allocates dim+1
+ // double variables.
double vars[dim+1];
for(unsigned int i=0; i<dim; ++i)
vars[i] = p(i);
- // We need the time variable only
- // if the number of variables is
- // different from the dimension. In
- // this case it can only be dim+1,
- // otherwise an exception would
- // have already been thrown
+ // We need the time variable only
+ // if the number of variables is
+ // different from the dimension. In
+ // this case it can only be dim+1,
+ // otherwise an exception would
+ // have already been thrown
if(dim != n_vars)
vars[dim] = this->get_time();
{
values(component) = fp[component].Eval((double*)vars);
AssertThrow(fp[component].EvalError() == 0,
- ExcMessage(fp[component].ErrorMsg()));
+ ExcMessage(fp[component].ErrorMsg()));
}
}
template <int dim>
void
FunctionParser<dim>::initialize(const std::string &,
- const std::vector<std::string> &,
- const std::map<std::string, double> &,
- const bool,
- const bool)
+ const std::vector<std::string> &,
+ const std::map<std::string, double> &,
+ const bool,
+ const bool)
{
Assert(false, ExcDisabled("parser"));
}
template <int dim>
void
FunctionParser<dim>::initialize(const std::string &,
- const std::string &,
- const std::map<std::string, double> &,
- const bool,
- const bool)
+ const std::string &,
+ const std::map<std::string, double> &,
+ const bool,
+ const bool)
{
Assert(false, ExcDisabled("parser"));
}
// $Id$
// Version: $Name$
//
-// Copyright (C) 1999, 2000, 2001, 2002, 2003, 2005, 2006 by the deal.II authors
+// Copyright (C) 1999, 2000, 2001, 2002, 2003, 2005, 2006, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
FunctionTime::FunctionTime(const double initial_time)
- :
- time(initial_time)
+ :
+ time(initial_time)
{}
// $Id$
// Version: $Name$
//
-// Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2011 by the deal.II authors
+// Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
template<>
double
GeometryInfo<1>::subface_ratio(const internal::SubfaceCase<1> &,
- const unsigned int)
+ const unsigned int)
{
return 1;
}
template<>
double
GeometryInfo<2>::subface_ratio(const internal::SubfaceCase<2> &subface_case,
- const unsigned int)
+ const unsigned int)
{
const unsigned int dim=2;
switch (subface_case)
{
case internal::SubfaceCase<dim>::case_none:
- // Here, an
- // Assert(false,ExcInternalError())
- // would be the right
- // choice, but
- // unfortunately the
- // current function is
- // also called for faces
- // without children (see
- // tests/fe/mapping.cc).
-// Assert(false, ExcMessage("Face has no subfaces."));
- // Furthermore, assign
- // following value as
- // otherwise the
- // bits/volume_x tests
- // break
- ratio=1./GeometryInfo<dim>::max_children_per_face;
- break;
+ // Here, an
+ // Assert(false,ExcInternalError())
+ // would be the right
+ // choice, but
+ // unfortunately the
+ // current function is
+ // also called for faces
+ // without children (see
+ // tests/fe/mapping.cc).
+// Assert(false, ExcMessage("Face has no subfaces."));
+ // Furthermore, assign
+ // following value as
+ // otherwise the
+ // bits/volume_x tests
+ // break
+ ratio=1./GeometryInfo<dim>::max_children_per_face;
+ break;
case internal::SubfaceCase<dim>::case_x:
- ratio=0.5;
- break;
+ ratio=0.5;
+ break;
default:
- // there should be no
- // cases left
- Assert(false, ExcInternalError());
- break;
+ // there should be no
+ // cases left
+ Assert(false, ExcInternalError());
+ break;
}
return ratio;
template<>
double
GeometryInfo<3>::subface_ratio(const internal::SubfaceCase<3> &subface_case,
- const unsigned int subface_no)
+ const unsigned int subface_no)
{
const unsigned int dim=3;
switch (subface_case)
{
case internal::SubfaceCase<dim>::case_none:
- // Here, an
- // Assert(false,ExcInternalError())
- // would be the right
- // choice, but
- // unfortunately the
- // current function is
- // also called for faces
- // without children (see
- // tests/bits/mesh_3d_16.cc). Add
- // following switch to
- // avoid diffs in
- // tests/bits/mesh_3d_16
- ratio=1./GeometryInfo<dim>::max_children_per_face;
- break;
+ // Here, an
+ // Assert(false,ExcInternalError())
+ // would be the right
+ // choice, but
+ // unfortunately the
+ // current function is
+ // also called for faces
+ // without children (see
+ // tests/bits/mesh_3d_16.cc). Add
+ // following switch to
+ // avoid diffs in
+ // tests/bits/mesh_3d_16
+ ratio=1./GeometryInfo<dim>::max_children_per_face;
+ break;
case internal::SubfaceCase<dim>::case_x:
case internal::SubfaceCase<dim>::case_y:
- ratio=0.5;
- break;
+ ratio=0.5;
+ break;
case internal::SubfaceCase<dim>::case_xy:
case internal::SubfaceCase<dim>::case_x1y2y:
case internal::SubfaceCase<dim>::case_y1x2x:
- ratio=0.25;
- break;
+ ratio=0.25;
+ break;
case internal::SubfaceCase<dim>::case_x1y:
case internal::SubfaceCase<dim>::case_y1x:
- if (subface_no<2)
- ratio=0.25;
- else
- ratio=0.5;
- break;
+ if (subface_no<2)
+ ratio=0.25;
+ else
+ ratio=0.5;
+ break;
case internal::SubfaceCase<dim>::case_x2y:
case internal::SubfaceCase<dim>::case_y2x:
- if (subface_no==0)
- ratio=0.5;
- else
- ratio=0.25;
- break;
+ if (subface_no==0)
+ ratio=0.5;
+ else
+ ratio=0.25;
+ break;
default:
- // there should be no
- // cases left
- Assert(false, ExcInternalError());
- break;
+ // there should be no
+ // cases left
+ Assert(false, ExcInternalError());
+ break;
}
return ratio;
template<>
RefinementCase<0>
GeometryInfo<1>::face_refinement_case(const RefinementCase<1> &,
- const unsigned int,
- const bool,
- const bool,
- const bool)
+ const unsigned int,
+ const bool,
+ const bool,
+ const bool)
{
Assert(false, ExcImpossibleInDim(1));
template<>
RefinementCase<1>
GeometryInfo<2>::face_refinement_case(const RefinementCase<2> &cell_refinement_case,
- const unsigned int face_no,
- const bool,
- const bool,
- const bool)
+ const unsigned int face_no,
+ const bool,
+ const bool,
+ const bool)
{
const unsigned int dim=2;
Assert(cell_refinement_case<RefinementCase<dim>::isotropic_refinement+1,
- ExcIndexRange(cell_refinement_case, 0, RefinementCase<dim>::isotropic_refinement+1));
+ ExcIndexRange(cell_refinement_case, 0, RefinementCase<dim>::isotropic_refinement+1));
Assert(face_no<GeometryInfo<dim>::faces_per_cell,
- ExcIndexRange(face_no, 0, GeometryInfo<dim>::faces_per_cell));
+ ExcIndexRange(face_no, 0, GeometryInfo<dim>::faces_per_cell));
static const RefinementCase<dim-1>
ref_cases[RefinementCase<dim>::isotropic_refinement+1][GeometryInfo<dim>::faces_per_cell/2]=
template<>
RefinementCase<2>
GeometryInfo<3>::face_refinement_case(const RefinementCase<3> &cell_refinement_case,
- const unsigned int face_no,
- const bool face_orientation,
- const bool /*face_flip*/,
- const bool face_rotation)
+ const unsigned int face_no,
+ const bool face_orientation,
+ const bool /*face_flip*/,
+ const bool face_rotation)
{
const unsigned int dim=3;
Assert(cell_refinement_case<RefinementCase<dim>::isotropic_refinement+1,
- ExcIndexRange(cell_refinement_case, 0, RefinementCase<dim>::isotropic_refinement+1));
+ ExcIndexRange(cell_refinement_case, 0, RefinementCase<dim>::isotropic_refinement+1));
Assert(face_no<GeometryInfo<dim>::faces_per_cell,
- ExcIndexRange(face_no, 0, GeometryInfo<dim>::faces_per_cell));
+ ExcIndexRange(face_no, 0, GeometryInfo<dim>::faces_per_cell));
static const RefinementCase<dim-1>
ref_cases[RefinementCase<dim>::isotropic_refinement+1][GeometryInfo<dim>::faces_per_cell/2]=
RefinementCase<dim-1>::cut_x,
RefinementCase<dim-1>::cut_xy};
- // correct the ref_case for face_orientation
- // and face_rotation. for face_orientation,
- // 'true' is the default value whereas for
- // face_rotation, 'false' is standard. If
- // <tt>face_rotation==face_orientation</tt>,
- // then one of them is non-standard and we
- // have to swap cut_x and cut_y, otherwise no
- // change is necessary. face_flip has no
- // influence. however, in order to keep the
- // interface consistent with other functions,
- // we still include it as an argument to this
- // function
+ // correct the ref_case for face_orientation
+ // and face_rotation. for face_orientation,
+ // 'true' is the default value whereas for
+ // face_rotation, 'false' is standard. If
+ // <tt>face_rotation==face_orientation</tt>,
+ // then one of them is non-standard and we
+ // have to swap cut_x and cut_y, otherwise no
+ // change is necessary. face_flip has no
+ // influence. however, in order to keep the
+ // interface consistent with other functions,
+ // we still include it as an argument to this
+ // function
return (face_orientation==face_rotation) ? flip[ref_case] : ref_case;
}
template<>
RefinementCase<1>
GeometryInfo<1>::line_refinement_case(const RefinementCase<1> &cell_refinement_case,
- const unsigned int line_no)
+ const unsigned int line_no)
{
const unsigned int dim = 1;
Assert(cell_refinement_case<RefinementCase<dim>::isotropic_refinement+1,
- ExcIndexRange(cell_refinement_case, 0, RefinementCase<dim>::isotropic_refinement+1));
+ ExcIndexRange(cell_refinement_case, 0, RefinementCase<dim>::isotropic_refinement+1));
Assert(line_no<GeometryInfo<dim>::lines_per_cell,
- ExcIndexRange(line_no, 0, GeometryInfo<dim>::lines_per_cell));
+ ExcIndexRange(line_no, 0, GeometryInfo<dim>::lines_per_cell));
return cell_refinement_case;
}
template<>
RefinementCase<1>
GeometryInfo<2>::line_refinement_case(const RefinementCase<2> &cell_refinement_case,
- const unsigned int line_no)
+ const unsigned int line_no)
{
- // Assertions are in face_refinement_case()
+ // Assertions are in face_refinement_case()
return face_refinement_case(cell_refinement_case, line_no);
}
template<>
RefinementCase<1>
GeometryInfo<3>::line_refinement_case(const RefinementCase<3> &cell_refinement_case,
- const unsigned int line_no)
+ const unsigned int line_no)
{
const unsigned int dim=3;
Assert(cell_refinement_case<RefinementCase<dim>::isotropic_refinement+1,
- ExcIndexRange(cell_refinement_case, 0, RefinementCase<dim>::isotropic_refinement+1));
+ ExcIndexRange(cell_refinement_case, 0, RefinementCase<dim>::isotropic_refinement+1));
Assert(line_no<GeometryInfo<dim>::lines_per_cell,
- ExcIndexRange(line_no, 0, GeometryInfo<dim>::lines_per_cell));
-
- // array indicating, which simple refine
- // case cuts a line in dirextion x, y or
- // z. For example, cut_y and everything
- // containing cut_y (cut_xy, cut_yz,
- // cut_xyz) cuts lines, which are in y
- // direction.
+ ExcIndexRange(line_no, 0, GeometryInfo<dim>::lines_per_cell));
+
+ // array indicating, which simple refine
+ // case cuts a line in dirextion x, y or
+ // z. For example, cut_y and everything
+ // containing cut_y (cut_xy, cut_yz,
+ // cut_xyz) cuts lines, which are in y
+ // direction.
static const RefinementCase<dim>
cut_one[dim] =
{RefinementCase<dim>::cut_x,
RefinementCase<dim>::cut_y,
RefinementCase<dim>::cut_z};
- // order the direction of lines
- // 0->x, 1->y, 2->z
+ // order the direction of lines
+ // 0->x, 1->y, 2->z
static const unsigned int direction[lines_per_cell]=
{1,1,0,0,1,1,0,0,2,2,2,2};
template<>
RefinementCase<1>
GeometryInfo<1>::min_cell_refinement_case_for_face_refinement(const RefinementCase<0> &,
- const unsigned int,
- const bool,
- const bool,
- const bool)
+ const unsigned int,
+ const bool,
+ const bool,
+ const bool)
{
const unsigned int dim = 1;
Assert(false, ExcImpossibleInDim(dim));
template<>
RefinementCase<2>
GeometryInfo<2>::min_cell_refinement_case_for_face_refinement(const RefinementCase<1> &face_refinement_case,
- const unsigned int face_no,
- const bool,
- const bool,
- const bool)
+ const unsigned int face_no,
+ const bool,
+ const bool,
+ const bool)
{
const unsigned int dim = 2;
Assert(face_refinement_case<RefinementCase<dim-1>::isotropic_refinement+1,
- ExcIndexRange(face_refinement_case, 0, RefinementCase<dim-1>::isotropic_refinement+1));
+ ExcIndexRange(face_refinement_case, 0, RefinementCase<dim-1>::isotropic_refinement+1));
Assert(face_no<GeometryInfo<dim>::faces_per_cell,
- ExcIndexRange(face_no, 0, GeometryInfo<dim>::faces_per_cell));
+ ExcIndexRange(face_no, 0, GeometryInfo<dim>::faces_per_cell));
if (face_refinement_case==RefinementCase<dim>::cut_x)
return (face_no/2) ? RefinementCase<dim>::cut_x : RefinementCase<dim>::cut_y;
template<>
RefinementCase<3>
GeometryInfo<3>::min_cell_refinement_case_for_face_refinement(const RefinementCase<2> &face_refinement_case,
- const unsigned int face_no,
- const bool face_orientation,
- const bool /*face_flip*/,
- const bool face_rotation)
+ const unsigned int face_no,
+ const bool face_orientation,
+ const bool /*face_flip*/,
+ const bool face_rotation)
{
const unsigned int dim=3;
Assert(face_refinement_case<RefinementCase<dim-1>::isotropic_refinement+1,
- ExcIndexRange(face_refinement_case, 0, RefinementCase<dim-1>::isotropic_refinement+1));
+ ExcIndexRange(face_refinement_case, 0, RefinementCase<dim-1>::isotropic_refinement+1));
Assert(face_no<GeometryInfo<dim>::faces_per_cell,
- ExcIndexRange(face_no, 0, GeometryInfo<dim>::faces_per_cell));
+ ExcIndexRange(face_no, 0, GeometryInfo<dim>::faces_per_cell));
static const RefinementCase<2> flip[4]=
{RefinementCase<2>::no_refinement,
RefinementCase<2>::cut_x,
RefinementCase<2>::cut_xy};
- // correct the face_refinement_case for
- // face_orientation and face_rotation. for
- // face_orientation, 'true' is the default
- // value whereas for face_rotation, 'false'
- // is standard. If
- // <tt>face_rotation==face_orientation</tt>,
- // then one of them is non-standard and we
- // have to swap cut_x and cut_y, otherwise no
- // change is necessary. face_flip has no
- // influence. however, in order to keep the
- // interface consistent with other functions,
- // we still include it as an argument to this
- // function
+ // correct the face_refinement_case for
+ // face_orientation and face_rotation. for
+ // face_orientation, 'true' is the default
+ // value whereas for face_rotation, 'false'
+ // is standard. If
+ // <tt>face_rotation==face_orientation</tt>,
+ // then one of them is non-standard and we
+ // have to swap cut_x and cut_y, otherwise no
+ // change is necessary. face_flip has no
+ // influence. however, in order to keep the
+ // interface consistent with other functions,
+ // we still include it as an argument to this
+ // function
const RefinementCase<dim-1> std_face_ref = (face_orientation==face_rotation) ? flip[face_refinement_case] : face_refinement_case;
static const RefinementCase<dim> face_to_cell[3][4]=
{
const unsigned int dim = 2;
Assert(line_no<GeometryInfo<dim>::lines_per_cell,
- ExcIndexRange(line_no, 0, GeometryInfo<dim>::lines_per_cell));
+ ExcIndexRange(line_no, 0, GeometryInfo<dim>::lines_per_cell));
return (line_no/2) ? RefinementCase<2>::cut_x : RefinementCase<2>::cut_y;
}
{
const unsigned int dim=3;
Assert(line_no<GeometryInfo<dim>::lines_per_cell,
- ExcIndexRange(line_no, 0, GeometryInfo<dim>::lines_per_cell));
+ ExcIndexRange(line_no, 0, GeometryInfo<dim>::lines_per_cell));
static const RefinementCase<dim> ref_cases[6]=
{RefinementCase<dim>::cut_y, // lines 0 and 1
template <>
unsigned int
GeometryInfo<3>::standard_to_real_face_vertex(const unsigned int vertex,
- const bool face_orientation,
- const bool face_flip,
- const bool face_rotation)
+ const bool face_orientation,
+ const bool face_flip,
+ const bool face_rotation)
{
Assert(vertex<GeometryInfo<3>::vertices_per_face,
- ExcIndexRange(vertex,0,GeometryInfo<3>::vertices_per_face));
+ ExcIndexRange(vertex,0,GeometryInfo<3>::vertices_per_face));
- // set up a table to make sure that
- // we handle non-standard faces correctly
+ // set up a table to make sure that
+ // we handle non-standard faces correctly
//
// so set up a table that for each vertex (of
// a quad in standard position) describes
// which vertex to take
- //
- // first index: four vertices 0...3
- //
- // second index: face_orientation; 0:
- // opposite normal, 1: standard
- //
- // third index: face_flip; 0: standard, 1:
- // face rotated by 180 degrees
- //
- // forth index: face_rotation: 0: standard,
- // 1: face rotated by 90 degrees
+ //
+ // first index: four vertices 0...3
+ //
+ // second index: face_orientation; 0:
+ // opposite normal, 1: standard
+ //
+ // third index: face_flip; 0: standard, 1:
+ // face rotated by 180 degrees
+ //
+ // forth index: face_rotation: 0: standard,
+ // 1: face rotated by 90 degrees
static const unsigned int vertex_translation[4][2][2][2] =
{ { { { 0, 2 }, // vertex 0, face_orientation=false, face_flip=false, face_rotation=false and true
- { 3, 1 }}, // vertex 0, face_orientation=false, face_flip=true, face_rotation=false and true
- { { 0, 2 }, // vertex 0, face_orientation=true, face_flip=false, face_rotation=false and true
- { 3, 1 }}},// vertex 0, face_orientation=true, face_flip=true, face_rotation=false and true
+ { 3, 1 }}, // vertex 0, face_orientation=false, face_flip=true, face_rotation=false and true
+ { { 0, 2 }, // vertex 0, face_orientation=true, face_flip=false, face_rotation=false and true
+ { 3, 1 }}},// vertex 0, face_orientation=true, face_flip=true, face_rotation=false and true
{ { { 2, 3 }, // vertex 1 ...
- { 1, 0 }},
- { { 1, 0 },
- { 2, 3 }}},
+ { 1, 0 }},
+ { { 1, 0 },
+ { 2, 3 }}},
{ { { 1, 0 }, // vertex 2 ...
- { 2, 3 }},
- { { 2, 3 },
- { 1, 0 }}},
+ { 2, 3 }},
+ { { 2, 3 },
+ { 1, 0 }}},
{ { { 3, 1 }, // vertex 3 ...
- { 0, 2 }},
- { { 3, 1 },
- { 0, 2 }}}};
+ { 0, 2 }},
+ { { 3, 1 },
+ { 0, 2 }}}};
return vertex_translation[vertex][face_orientation][face_flip][face_rotation];
}
template <int dim>
unsigned int
GeometryInfo<dim>::standard_to_real_face_vertex(const unsigned int vertex,
- const bool,
- const bool,
- const bool)
+ const bool,
+ const bool,
+ const bool)
{
Assert(dim>1, ExcImpossibleInDim(dim));
Assert(vertex<GeometryInfo<dim>::vertices_per_face,
- ExcIndexRange(vertex,0,GeometryInfo<dim>::vertices_per_face));
+ ExcIndexRange(vertex,0,GeometryInfo<dim>::vertices_per_face));
return vertex;
}
template <>
unsigned int
GeometryInfo<3>::real_to_standard_face_vertex(const unsigned int vertex,
- const bool face_orientation,
- const bool face_flip,
- const bool face_rotation)
+ const bool face_orientation,
+ const bool face_flip,
+ const bool face_rotation)
{
Assert(vertex<GeometryInfo<3>::vertices_per_face,
- ExcIndexRange(vertex,0,GeometryInfo<3>::vertices_per_face));
+ ExcIndexRange(vertex,0,GeometryInfo<3>::vertices_per_face));
- // set up a table to make sure that
- // we handle non-standard faces correctly
+ // set up a table to make sure that
+ // we handle non-standard faces correctly
//
// so set up a table that for each vertex (of
// a quad in standard position) describes
// which vertex to take
- //
- // first index: four vertices 0...3
- //
- // second index: face_orientation; 0:
- // opposite normal, 1: standard
- //
- // third index: face_flip; 0: standard, 1:
- // face rotated by 180 degrees
- //
- // forth index: face_rotation: 0: standard,
- // 1: face rotated by 90 degrees
+ //
+ // first index: four vertices 0...3
+ //
+ // second index: face_orientation; 0:
+ // opposite normal, 1: standard
+ //
+ // third index: face_flip; 0: standard, 1:
+ // face rotated by 180 degrees
+ //
+ // forth index: face_rotation: 0: standard,
+ // 1: face rotated by 90 degrees
static const unsigned int vertex_translation[4][2][2][2] =
{ { { { 0, 2 }, // vertex 0, face_orientation=false, face_flip=false, face_rotation=false and true
- { 3, 1 }}, // vertex 0, face_orientation=false, face_flip=true, face_rotation=false and true
- { { 0, 1 }, // vertex 0, face_orientation=true, face_flip=false, face_rotation=false and true
- { 3, 2 }}},// vertex 0, face_orientation=true, face_flip=true, face_rotation=false and true
+ { 3, 1 }}, // vertex 0, face_orientation=false, face_flip=true, face_rotation=false and true
+ { { 0, 1 }, // vertex 0, face_orientation=true, face_flip=false, face_rotation=false and true
+ { 3, 2 }}},// vertex 0, face_orientation=true, face_flip=true, face_rotation=false and true
{ { { 2, 3 }, // vertex 1 ...
- { 1, 0 }},
- { { 1, 3 },
- { 2, 0 }}},
+ { 1, 0 }},
+ { { 1, 3 },
+ { 2, 0 }}},
{ { { 1, 0 }, // vertex 2 ...
- { 2, 3 }},
- { { 2, 0 },
- { 1, 3 }}},
+ { 2, 3 }},
+ { { 2, 0 },
+ { 1, 3 }}},
{ { { 3, 1 }, // vertex 3 ...
- { 0, 2 }},
- { { 3, 2 },
- { 0, 1 }}}};
+ { 0, 2 }},
+ { { 3, 2 },
+ { 0, 1 }}}};
return vertex_translation[vertex][face_orientation][face_flip][face_rotation];
}
template <int dim>
unsigned int
GeometryInfo<dim>::real_to_standard_face_vertex(const unsigned int vertex,
- const bool,
- const bool,
- const bool)
+ const bool,
+ const bool,
+ const bool)
{
Assert(dim>1, ExcImpossibleInDim(dim));
Assert(vertex<GeometryInfo<dim>::vertices_per_face,
- ExcIndexRange(vertex,0,GeometryInfo<dim>::vertices_per_face));
+ ExcIndexRange(vertex,0,GeometryInfo<dim>::vertices_per_face));
return vertex;
}
template <>
unsigned int
GeometryInfo<3>::standard_to_real_face_line(const unsigned int line,
- const bool face_orientation,
- const bool face_flip,
- const bool face_rotation)
+ const bool face_orientation,
+ const bool face_flip,
+ const bool face_rotation)
{
Assert(line<GeometryInfo<3>::lines_per_face,
- ExcIndexRange(line,0,GeometryInfo<3>::lines_per_face));
+ ExcIndexRange(line,0,GeometryInfo<3>::lines_per_face));
- // make sure we handle
+ // make sure we handle
// non-standard faces correctly
//
// so set up a table that for each line (of a
// quad) describes which line to take
- //
- // first index: four lines 0...3
- //
- // second index: face_orientation; 0:
- // opposite normal, 1: standard
- //
- // third index: face_flip; 0: standard, 1:
- // face rotated by 180 degrees
- //
- // forth index: face_rotation: 0: standard,
- // 1: face rotated by 90 degrees
+ //
+ // first index: four lines 0...3
+ //
+ // second index: face_orientation; 0:
+ // opposite normal, 1: standard
+ //
+ // third index: face_flip; 0: standard, 1:
+ // face rotated by 180 degrees
+ //
+ // forth index: face_rotation: 0: standard,
+ // 1: face rotated by 90 degrees
static const unsigned int line_translation[4][2][2][2] =
{ { { { 2, 0 }, // line 0, face_orientation=false, face_flip=false, face_rotation=false and true
- { 3, 1 }}, // line 0, face_orientation=false, face_flip=true, face_rotation=false and true
- { { 0, 3 }, // line 0, face_orientation=true, face_flip=false, face_rotation=false and true
- { 1, 2 }}},// line 0, face_orientation=true, face_flip=true, face_rotation=false and true
+ { 3, 1 }}, // line 0, face_orientation=false, face_flip=true, face_rotation=false and true
+ { { 0, 3 }, // line 0, face_orientation=true, face_flip=false, face_rotation=false and true
+ { 1, 2 }}},// line 0, face_orientation=true, face_flip=true, face_rotation=false and true
{ { { 3, 1 }, // line 1 ...
- { 2, 0 }},
- { { 1, 2 },
- { 0, 3 }}},
+ { 2, 0 }},
+ { { 1, 2 },
+ { 0, 3 }}},
{ { { 0, 3 }, // line 2 ...
- { 1, 2 }},
- { { 2, 0 },
- { 3, 1 }}},
+ { 1, 2 }},
+ { { 2, 0 },
+ { 3, 1 }}},
{ { { 1, 2 }, // line 3 ...
- { 0, 3 }},
- { { 3, 1 },
- { 2, 0 }}}};
+ { 0, 3 }},
+ { { 3, 1 },
+ { 2, 0 }}}};
return line_translation[line][face_orientation][face_flip][face_rotation];
}
template <int dim>
unsigned int
GeometryInfo<dim>::standard_to_real_face_line(const unsigned int line,
- const bool,
- const bool,
- const bool)
+ const bool,
+ const bool,
+ const bool)
{
Assert(false, ExcNotImplemented());
return line;
template <>
unsigned int
GeometryInfo<3>::real_to_standard_face_line(const unsigned int line,
- const bool face_orientation,
- const bool face_flip,
- const bool face_rotation)
+ const bool face_orientation,
+ const bool face_flip,
+ const bool face_rotation)
{
Assert(line<GeometryInfo<3>::lines_per_face,
- ExcIndexRange(line,0,GeometryInfo<3>::lines_per_face));
+ ExcIndexRange(line,0,GeometryInfo<3>::lines_per_face));
- // make sure we handle
+ // make sure we handle
// non-standard faces correctly
//
// so set up a table that for each line (of a
// quad) describes which line to take
- //
- // first index: four lines 0...3
- //
- // second index: face_orientation; 0:
- // opposite normal, 1: standard
- //
- // third index: face_flip; 0: standard, 1:
- // face rotated by 180 degrees
- //
- // forth index: face_rotation: 0: standard,
- // 1: face rotated by 90 degrees
+ //
+ // first index: four lines 0...3
+ //
+ // second index: face_orientation; 0:
+ // opposite normal, 1: standard
+ //
+ // third index: face_flip; 0: standard, 1:
+ // face rotated by 180 degrees
+ //
+ // forth index: face_rotation: 0: standard,
+ // 1: face rotated by 90 degrees
static const unsigned int line_translation[4][2][2][2] =
{ { { { 2, 0 }, // line 0, face_orientation=false, face_flip=false, face_rotation=false and true
- { 3, 1 }}, // line 0, face_orientation=false, face_flip=true, face_rotation=false and true
- { { 0, 2 }, // line 0, face_orientation=true, face_flip=false, face_rotation=false and true
- { 1, 3 }}},// line 0, face_orientation=true, face_flip=true, face_rotation=false and true
+ { 3, 1 }}, // line 0, face_orientation=false, face_flip=true, face_rotation=false and true
+ { { 0, 2 }, // line 0, face_orientation=true, face_flip=false, face_rotation=false and true
+ { 1, 3 }}},// line 0, face_orientation=true, face_flip=true, face_rotation=false and true
{ { { 3, 1 }, // line 1 ...
- { 2, 0 }},
- { { 1, 3 },
- { 0, 2 }}},
+ { 2, 0 }},
+ { { 1, 3 },
+ { 0, 2 }}},
{ { { 0, 3 }, // line 2 ...
- { 1, 2 }},
- { { 2, 1 },
- { 3, 0 }}},
+ { 1, 2 }},
+ { { 2, 1 },
+ { 3, 0 }}},
{ { { 1, 2 }, // line 3 ...
- { 0, 3 }},
- { { 3, 0 },
- { 2, 1 }}}};
+ { 0, 3 }},
+ { { 3, 0 },
+ { 2, 1 }}}};
return line_translation[line][face_orientation][face_flip][face_rotation];
}
template <int dim>
unsigned int
GeometryInfo<dim>::real_to_standard_face_line(const unsigned int line,
- const bool,
- const bool,
- const bool)
+ const bool,
+ const bool,
+ const bool)
{
Assert(false, ExcNotImplemented());
return line;
template <>
unsigned int
GeometryInfo<1>::child_cell_on_face (const RefinementCase<1> &,
- const unsigned int face,
+ const unsigned int face,
const unsigned int subface,
- const bool, const bool, const bool,
- const RefinementCase<0> &)
+ const bool, const bool, const bool,
+ const RefinementCase<0> &)
{
Assert (face<faces_per_cell, ExcIndexRange(face, 0, faces_per_cell));
Assert (subface<max_children_per_face,
- ExcIndexRange(subface, 0, max_children_per_face));
+ ExcIndexRange(subface, 0, max_children_per_face));
return face;
}
template <>
unsigned int
GeometryInfo<2>::child_cell_on_face (const RefinementCase<2> &ref_case,
- const unsigned int face,
+ const unsigned int face,
const unsigned int subface,
- const bool, const bool, const bool,
- const RefinementCase<1> &)
+ const bool, const bool, const bool,
+ const RefinementCase<1> &)
{
Assert (face<faces_per_cell, ExcIndexRange(face, 0, faces_per_cell));
Assert (subface<max_children_per_face,
- ExcIndexRange(subface, 0, max_children_per_face));
-
- // always return the child adjacent to the specified
- // subface. if the face of a cell is not refined, don't
- // throw an assertion but deliver the child adjacent to
- // the face nevertheless, i.e. deliver the child of
- // this cell adjacent to the subface of a possibly
- // refined neighbor. this simplifies setting neighbor
- // information in execute_refinement.
+ ExcIndexRange(subface, 0, max_children_per_face));
+
+ // always return the child adjacent to the specified
+ // subface. if the face of a cell is not refined, don't
+ // throw an assertion but deliver the child adjacent to
+ // the face nevertheless, i.e. deliver the child of
+ // this cell adjacent to the subface of a possibly
+ // refined neighbor. this simplifies setting neighbor
+ // information in execute_refinement.
static const unsigned int
subcells[RefinementCase<2>::isotropic_refinement][faces_per_cell][max_children_per_face] =
{{{0,0},{1,1},{0,1},{0,1}}, // cut_x
template <>
unsigned int
GeometryInfo<3>::child_cell_on_face (const RefinementCase<3> &ref_case,
- const unsigned int face,
- const unsigned int subface,
- const bool face_orientation,
- const bool face_flip,
- const bool face_rotation,
- const RefinementCase<2> &face_ref_case)
+ const unsigned int face,
+ const unsigned int subface,
+ const bool face_orientation,
+ const bool face_flip,
+ const bool face_rotation,
+ const RefinementCase<2> &face_ref_case)
{
const unsigned int dim = 3;
Assert (ref_case>RefinementCase<dim-1>::no_refinement, ExcMessage("Cell has no children."));
Assert (face<faces_per_cell, ExcIndexRange(face, 0, faces_per_cell));
Assert (subface<GeometryInfo<dim-1>::n_children(face_ref_case) ||
- (subface==0 && face_ref_case==RefinementCase<dim-1>::no_refinement),
- ExcIndexRange(subface, 0, GeometryInfo<2>::n_children(face_ref_case)));
+ (subface==0 && face_ref_case==RefinementCase<dim-1>::no_refinement),
+ ExcIndexRange(subface, 0, GeometryInfo<2>::n_children(face_ref_case)));
- // invalid number used for invalid cases,
- // e.g. when the children are more refined at
- // a given face than the face itself
+ // invalid number used for invalid cases,
+ // e.g. when the children are more refined at
+ // a given face than the face itself
static const unsigned int e=invalid_unsigned_int;
- // the whole process of finding a child cell
- // at a given subface considering the
- // possibly anisotropic refinement cases of
- // the cell and the face as well as
- // orientation, flip and rotation of the face
- // is quite complicated. thus, we break it
- // down into several steps.
-
- // first step: convert the given face refine
- // case to a face refine case concerning the
- // face in standard orientation (, flip and
- // rotation). This only affects cut_x and
- // cut_y
+ // the whole process of finding a child cell
+ // at a given subface considering the
+ // possibly anisotropic refinement cases of
+ // the cell and the face as well as
+ // orientation, flip and rotation of the face
+ // is quite complicated. thus, we break it
+ // down into several steps.
+
+ // first step: convert the given face refine
+ // case to a face refine case concerning the
+ // face in standard orientation (, flip and
+ // rotation). This only affects cut_x and
+ // cut_y
static const RefinementCase<dim-1> flip[4]=
{RefinementCase<dim-1>::no_refinement,
RefinementCase<dim-1>::cut_y,
RefinementCase<dim-1>::cut_x,
RefinementCase<dim-1>::cut_xy};
- // for face_orientation, 'true' is the
- // default value whereas for face_rotation,
- // 'false' is standard. If
- // <tt>face_rotation==face_orientation</tt>,
- // then one of them is non-standard and we
- // have to swap cut_x and cut_y, otherwise no
- // change is necessary.
+ // for face_orientation, 'true' is the
+ // default value whereas for face_rotation,
+ // 'false' is standard. If
+ // <tt>face_rotation==face_orientation</tt>,
+ // then one of them is non-standard and we
+ // have to swap cut_x and cut_y, otherwise no
+ // change is necessary.
const RefinementCase<dim-1> std_face_ref = (face_orientation==face_rotation) ? flip[face_ref_case] : face_ref_case;
- // second step: convert the given subface
- // index to the one for a standard face
- // respecting face_orientation, face_flip and
- // face_rotation
+ // second step: convert the given subface
+ // index to the one for a standard face
+ // respecting face_orientation, face_flip and
+ // face_rotation
- // first index: face_ref_case
- // second index: face_orientation
- // third index: face_flip
- // forth index: face_rotation
- // fifth index: subface index
+ // first index: face_ref_case
+ // second index: face_orientation
+ // third index: face_flip
+ // forth index: face_rotation
+ // fifth index: subface index
static const unsigned int subface_exchange[4][2][2][2][4]=
{
- // no_refinement (subface 0 stays 0,
- // all others are invalid)
- {{{{0,e,e,e},
- {0,e,e,e}},
- {{0,e,e,e},
- {0,e,e,e}}},
- {{{0,e,e,e},
- {0,e,e,e}},
- {{0,e,e,e},
- {0,e,e,e}}}},
- // cut_x (here, if the face is only
- // rotated OR only falsely oriented,
- // then subface 0 of the non-standard
- // face does NOT correspond to one of
- // the subfaces of a standard
- // face. Thus we indicate the subface
- // which is located at the lower left
- // corner (the origin of the face's
- // local coordinate system) with
- // '0'. The rest of this issue is
- // taken care of using the above
- // conversion to a 'standard face
- // refine case')
- {{{{0,1,e,e},
- {0,1,e,e}},
- {{1,0,e,e},
- {1,0,e,e}}},
- {{{0,1,e,e},
- {0,1,e,e}},
- {{1,0,e,e},
- {1,0,e,e}}}},
- // cut_y (the same applies as for
- // cut_x)
- {{{{0,1,e,e},
- {1,0,e,e}},
- {{1,0,e,e},
- {0,1,e,e}}},
- {{{0,1,e,e},
- {1,0,e,e}},
- {{1,0,e,e},
- {0,1,e,e}}}},
- // cut_xyz: this information is
- // identical to the information
- // returned by
- // GeometryInfo<3>::real_to_standard_face_vertex()
- {{{{0,2,1,3}, // face_orientation=false, face_flip=false, face_rotation=false, subfaces 0,1,2,3
- {2,3,0,1}}, // face_orientation=false, face_flip=false, face_rotation=true, subfaces 0,1,2,3
- {{3,1,2,0}, // face_orientation=false, face_flip=true, face_rotation=false, subfaces 0,1,2,3
- {1,0,3,2}}}, // face_orientation=false, face_flip=true, face_rotation=true, subfaces 0,1,2,3
- {{{0,1,2,3}, // face_orientation=true, face_flip=false, face_rotation=false, subfaces 0,1,2,3
- {1,3,0,2}}, // face_orientation=true, face_flip=false, face_rotation=true, subfaces 0,1,2,3
- {{3,2,1,0}, // face_orientation=true, face_flip=true, face_rotation=false, subfaces 0,1,2,3
- {2,0,3,1}}}}};// face_orientation=true, face_flip=true, face_rotation=true, subfaces 0,1,2,3
+ // no_refinement (subface 0 stays 0,
+ // all others are invalid)
+ {{{{0,e,e,e},
+ {0,e,e,e}},
+ {{0,e,e,e},
+ {0,e,e,e}}},
+ {{{0,e,e,e},
+ {0,e,e,e}},
+ {{0,e,e,e},
+ {0,e,e,e}}}},
+ // cut_x (here, if the face is only
+ // rotated OR only falsely oriented,
+ // then subface 0 of the non-standard
+ // face does NOT correspond to one of
+ // the subfaces of a standard
+ // face. Thus we indicate the subface
+ // which is located at the lower left
+ // corner (the origin of the face's
+ // local coordinate system) with
+ // '0'. The rest of this issue is
+ // taken care of using the above
+ // conversion to a 'standard face
+ // refine case')
+ {{{{0,1,e,e},
+ {0,1,e,e}},
+ {{1,0,e,e},
+ {1,0,e,e}}},
+ {{{0,1,e,e},
+ {0,1,e,e}},
+ {{1,0,e,e},
+ {1,0,e,e}}}},
+ // cut_y (the same applies as for
+ // cut_x)
+ {{{{0,1,e,e},
+ {1,0,e,e}},
+ {{1,0,e,e},
+ {0,1,e,e}}},
+ {{{0,1,e,e},
+ {1,0,e,e}},
+ {{1,0,e,e},
+ {0,1,e,e}}}},
+ // cut_xyz: this information is
+ // identical to the information
+ // returned by
+ // GeometryInfo<3>::real_to_standard_face_vertex()
+ {{{{0,2,1,3}, // face_orientation=false, face_flip=false, face_rotation=false, subfaces 0,1,2,3
+ {2,3,0,1}}, // face_orientation=false, face_flip=false, face_rotation=true, subfaces 0,1,2,3
+ {{3,1,2,0}, // face_orientation=false, face_flip=true, face_rotation=false, subfaces 0,1,2,3
+ {1,0,3,2}}}, // face_orientation=false, face_flip=true, face_rotation=true, subfaces 0,1,2,3
+ {{{0,1,2,3}, // face_orientation=true, face_flip=false, face_rotation=false, subfaces 0,1,2,3
+ {1,3,0,2}}, // face_orientation=true, face_flip=false, face_rotation=true, subfaces 0,1,2,3
+ {{3,2,1,0}, // face_orientation=true, face_flip=true, face_rotation=false, subfaces 0,1,2,3
+ {2,0,3,1}}}}};// face_orientation=true, face_flip=true, face_rotation=true, subfaces 0,1,2,3
const unsigned int std_subface=subface_exchange
- [face_ref_case]
- [face_orientation]
- [face_flip]
- [face_rotation]
- [subface];
+ [face_ref_case]
+ [face_orientation]
+ [face_flip]
+ [face_rotation]
+ [subface];
Assert (std_subface!=e, ExcInternalError());
- // third step: these are the children, which
- // can be found at the given subfaces of an
- // isotropically refined (standard) face
- //
- // first index: (refinement_case-1)
- // second index: face_index
- // third index: subface_index (isotropic refinement)
+ // third step: these are the children, which
+ // can be found at the given subfaces of an
+ // isotropically refined (standard) face
+ //
+ // first index: (refinement_case-1)
+ // second index: face_index
+ // third index: subface_index (isotropic refinement)
static const unsigned int
iso_children[RefinementCase<dim>::cut_xyz][faces_per_cell][max_children_per_face] =
{
- // cut_x
- {{0, 0, 0, 0}, // face 0, subfaces 0,1,2,3
- {1, 1, 1, 1}, // face 1, subfaces 0,1,2,3
- {0, 0, 1, 1}, // face 2, subfaces 0,1,2,3
- {0, 0, 1, 1}, // face 3, subfaces 0,1,2,3
- {0, 1, 0, 1}, // face 4, subfaces 0,1,2,3
- {0, 1, 0, 1}}, // face 5, subfaces 0,1,2,3
- // cut_y
- {{0, 1, 0, 1},
- {0, 1, 0, 1},
- {0, 0, 0, 0},
- {1, 1, 1, 1},
- {0, 0, 1, 1},
- {0, 0, 1, 1}},
- // cut_xy
- {{0, 2, 0, 2},
- {1, 3, 1, 3},
- {0, 0, 1, 1},
- {2, 2, 3, 3},
- {0, 1, 2, 3},
- {0, 1, 2, 3}},
- // cut_z
- {{0, 0, 1, 1},
- {0, 0, 1, 1},
- {0, 1, 0, 1},
- {0, 1, 0, 1},
- {0, 0, 0, 0},
- {1, 1, 1, 1}},
- // cut_xz
- {{0, 0, 1, 1},
- {2, 2, 3, 3},
- {0, 1, 2, 3},
- {0, 1, 2, 3},
- {0, 2, 0, 2},
- {1, 3, 1, 3}},
- // cut_yz
- {{0, 1, 2, 3},
- {0, 1, 2, 3},
- {0, 2, 0, 2},
- {1, 3, 1, 3},
- {0, 0, 1, 1},
- {2, 2, 3, 3}},
- // cut_xyz
- {{0, 2, 4, 6},
- {1, 3, 5, 7},
- {0, 4, 1, 5},
- {2, 6, 3, 7},
- {0, 1, 2, 3},
- {4, 5, 6, 7}}};
-
- // forth step: check, whether the given face
- // refine case is valid for the given cell
- // refine case. this is the case, if the
- // given face refine case is at least as
- // refined as the face is for the given cell
- // refine case
-
- // note, that we are considering standard
- // face refinement cases here and thus must
- // not pass the given orientation, flip and
- // rotation flags
+ // cut_x
+ {{0, 0, 0, 0}, // face 0, subfaces 0,1,2,3
+ {1, 1, 1, 1}, // face 1, subfaces 0,1,2,3
+ {0, 0, 1, 1}, // face 2, subfaces 0,1,2,3
+ {0, 0, 1, 1}, // face 3, subfaces 0,1,2,3
+ {0, 1, 0, 1}, // face 4, subfaces 0,1,2,3
+ {0, 1, 0, 1}}, // face 5, subfaces 0,1,2,3
+ // cut_y
+ {{0, 1, 0, 1},
+ {0, 1, 0, 1},
+ {0, 0, 0, 0},
+ {1, 1, 1, 1},
+ {0, 0, 1, 1},
+ {0, 0, 1, 1}},
+ // cut_xy
+ {{0, 2, 0, 2},
+ {1, 3, 1, 3},
+ {0, 0, 1, 1},
+ {2, 2, 3, 3},
+ {0, 1, 2, 3},
+ {0, 1, 2, 3}},
+ // cut_z
+ {{0, 0, 1, 1},
+ {0, 0, 1, 1},
+ {0, 1, 0, 1},
+ {0, 1, 0, 1},
+ {0, 0, 0, 0},
+ {1, 1, 1, 1}},
+ // cut_xz
+ {{0, 0, 1, 1},
+ {2, 2, 3, 3},
+ {0, 1, 2, 3},
+ {0, 1, 2, 3},
+ {0, 2, 0, 2},
+ {1, 3, 1, 3}},
+ // cut_yz
+ {{0, 1, 2, 3},
+ {0, 1, 2, 3},
+ {0, 2, 0, 2},
+ {1, 3, 1, 3},
+ {0, 0, 1, 1},
+ {2, 2, 3, 3}},
+ // cut_xyz
+ {{0, 2, 4, 6},
+ {1, 3, 5, 7},
+ {0, 4, 1, 5},
+ {2, 6, 3, 7},
+ {0, 1, 2, 3},
+ {4, 5, 6, 7}}};
+
+ // forth step: check, whether the given face
+ // refine case is valid for the given cell
+ // refine case. this is the case, if the
+ // given face refine case is at least as
+ // refined as the face is for the given cell
+ // refine case
+
+ // note, that we are considering standard
+ // face refinement cases here and thus must
+ // not pass the given orientation, flip and
+ // rotation flags
if ((std_face_ref & face_refinement_case(ref_case, face))
== face_refinement_case(ref_case, face))
{
- // all is fine. for anisotropic face
- // refine cases, select one of the
- // isotropic subfaces which neighbors the
- // same child
+ // all is fine. for anisotropic face
+ // refine cases, select one of the
+ // isotropic subfaces which neighbors the
+ // same child
- // first index: (standard) face refine case
- // second index: subface index
+ // first index: (standard) face refine case
+ // second index: subface index
static const unsigned int equivalent_iso_subface[4][4]=
- {{0,e,e,e}, // no_refinement
- {0,3,e,e}, // cut_x
- {0,3,e,e}, // cut_y
- {0,1,2,3}}; // cut_xy
+ {{0,e,e,e}, // no_refinement
+ {0,3,e,e}, // cut_x
+ {0,3,e,e}, // cut_y
+ {0,1,2,3}}; // cut_xy
const unsigned int equ_std_subface
- =equivalent_iso_subface[std_face_ref][std_subface];
+ =equivalent_iso_subface[std_face_ref][std_subface];
Assert (equ_std_subface!=e, ExcInternalError());
return iso_children[ref_case-1][face][equ_std_subface];
}
else
{
- // the face_ref_case was too coarse,
- // throw an error
+ // the face_ref_case was too coarse,
+ // throw an error
Assert(false,
- ExcMessage("The face RefineCase is too coarse "
- "for the given cell RefineCase."));
+ ExcMessage("The face RefineCase is too coarse "
+ "for the given cell RefineCase."));
}
- // we only get here in case of an error
+ // we only get here in case of an error
return e;
}
template <>
unsigned int
GeometryInfo<4>::child_cell_on_face (const RefinementCase<4> &,
- const unsigned int,
- const unsigned int,
- const bool, const bool, const bool,
- const RefinementCase<3> &)
+ const unsigned int,
+ const unsigned int,
+ const bool, const bool, const bool,
+ const RefinementCase<3> &)
{
Assert(false, ExcNotImplemented());
return invalid_unsigned_int;
template <>
unsigned int
GeometryInfo<1>::line_to_cell_vertices (const unsigned int line,
- const unsigned int vertex)
+ const unsigned int vertex)
{
Assert (line<lines_per_cell, ExcIndexRange(line, 0, lines_per_cell));
Assert (vertex<2, ExcIndexRange(vertex, 0, 2));
template <>
unsigned int
GeometryInfo<2>::line_to_cell_vertices (const unsigned int line,
- const unsigned int vertex)
+ const unsigned int vertex)
{
return child_cell_on_face(RefinementCase<2>::isotropic_refinement, line, vertex);
}
template <>
unsigned int
GeometryInfo<3>::line_to_cell_vertices (const unsigned int line,
- const unsigned int vertex)
+ const unsigned int vertex)
{
Assert (line<lines_per_cell, ExcIndexRange(line, 0, lines_per_cell));
Assert (vertex<2, ExcIndexRange(vertex, 0, 2));
static const unsigned
vertices[lines_per_cell][2] = {{0, 2}, // bottom face
- {1, 3},
- {0, 1},
- {2, 3},
- {4, 6}, // top face
- {5, 7},
- {4, 5},
- {6, 7},
- {0, 4}, // connects of bottom
- {1, 5}, // top face
- {2, 6},
- {3, 7}};
+ {1, 3},
+ {0, 1},
+ {2, 3},
+ {4, 6}, // top face
+ {5, 7},
+ {4, 5},
+ {6, 7},
+ {0, 4}, // connects of bottom
+ {1, 5}, // top face
+ {2, 6},
+ {3, 7}};
return vertices[line][vertex];
}
template <>
unsigned int
GeometryInfo<1>::face_to_cell_lines (const unsigned int face,
- const unsigned int line,
- const bool, const bool, const bool)
+ const unsigned int line,
+ const bool, const bool, const bool)
{
Assert (face+1<faces_per_cell+1, ExcIndexRange(face, 0, faces_per_cell));
Assert (line+1<lines_per_face+1, ExcIndexRange(line, 0, lines_per_face));
- // There is only a single line, so
- // it must be this.
+ // There is only a single line, so
+ // it must be this.
return 0;
}
template <>
unsigned int
GeometryInfo<2>::face_to_cell_lines (const unsigned int face,
- const unsigned int line,
- const bool, const bool, const bool)
+ const unsigned int line,
+ const bool, const bool, const bool)
{
Assert (face<faces_per_cell, ExcIndexRange(face, 0, faces_per_cell));
Assert (line<lines_per_face, ExcIndexRange(line, 0, lines_per_face));
- // The face is a line itself.
+ // The face is a line itself.
return face;
}
template <>
unsigned int
GeometryInfo<3>::face_to_cell_lines (const unsigned int face,
- const unsigned int line,
- const bool face_orientation,
- const bool face_flip,
- const bool face_rotation)
+ const unsigned int line,
+ const bool face_orientation,
+ const bool face_flip,
+ const bool face_rotation)
{
Assert (face<faces_per_cell, ExcIndexRange(face, 0, faces_per_cell));
Assert (line<lines_per_face, ExcIndexRange(line, 0, lines_per_face));
static const unsigned
lines[faces_per_cell][lines_per_face] = {{8,10, 0, 4}, // left face
- {9,11, 1, 5}, // right face
- {2, 6, 8, 9}, // front face
- {3, 7,10,11}, // back face
- {0, 1, 2, 3}, // bottom face
- {4, 5, 6, 7}};// top face
+ {9,11, 1, 5}, // right face
+ {2, 6, 8, 9}, // front face
+ {3, 7,10,11}, // back face
+ {0, 1, 2, 3}, // bottom face
+ {4, 5, 6, 7}};// top face
return lines[face][real_to_standard_face_line(line,
- face_orientation,
- face_flip,
- face_rotation)];
+ face_orientation,
+ face_flip,
+ face_rotation)];
}
template<int dim>
unsigned int
GeometryInfo<dim>::face_to_cell_lines (const unsigned int,
- const unsigned int,
- const bool, const bool, const bool)
+ const unsigned int,
+ const bool, const bool, const bool)
{
Assert(false, ExcNotImplemented());
return invalid_unsigned_int;
template <int dim>
unsigned int
GeometryInfo<dim>::face_to_cell_vertices (const unsigned int face,
- const unsigned int vertex,
- const bool face_orientation,
- const bool face_flip,
- const bool face_rotation)
+ const unsigned int vertex,
+ const bool face_orientation,
+ const bool face_flip,
+ const bool face_rotation)
{
return child_cell_on_face(RefinementCase<dim>::isotropic_refinement, face, vertex,
- face_orientation, face_flip, face_rotation);
+ face_orientation, face_flip, face_rotation);
}
double
GeometryInfo<dim>::
d_linear_shape_function (const Point<dim> &xi,
- const unsigned int i)
+ const unsigned int i)
{
Assert (i < GeometryInfo<dim>::vertices_per_cell,
- ExcIndexRange (i, 0, GeometryInfo<dim>::vertices_per_cell));
+ ExcIndexRange (i, 0, GeometryInfo<dim>::vertices_per_cell));
switch (dim)
{
case 1:
{
- const double x = xi[0];
- switch (i)
- {
- case 0:
- return 1-x;
- case 1:
- return x;
- }
+ const double x = xi[0];
+ switch (i)
+ {
+ case 0:
+ return 1-x;
+ case 1:
+ return x;
+ }
}
case 2:
{
- const double x = xi[0];
- const double y = xi[1];
- switch (i)
- {
- case 0:
- return (1-x)*(1-y);
- case 1:
- return x*(1-y);
- case 2:
- return (1-x)*y;
- case 3:
- return x*y;
- }
+ const double x = xi[0];
+ const double y = xi[1];
+ switch (i)
+ {
+ case 0:
+ return (1-x)*(1-y);
+ case 1:
+ return x*(1-y);
+ case 2:
+ return (1-x)*y;
+ case 3:
+ return x*y;
+ }
}
case 3:
{
- const double x = xi[0];
- const double y = xi[1];
- const double z = xi[2];
- switch (i)
- {
- case 0:
- return (1-x)*(1-y)*(1-z);
- case 1:
- return x*(1-y)*(1-z);
- case 2:
- return (1-x)*y*(1-z);
- case 3:
- return x*y*(1-z);
- case 4:
- return (1-x)*(1-y)*z;
- case 5:
- return x*(1-y)*z;
- case 6:
- return (1-x)*y*z;
- case 7:
- return x*y*z;
- }
+ const double x = xi[0];
+ const double y = xi[1];
+ const double z = xi[2];
+ switch (i)
+ {
+ case 0:
+ return (1-x)*(1-y)*(1-z);
+ case 1:
+ return x*(1-y)*(1-z);
+ case 2:
+ return (1-x)*y*(1-z);
+ case 3:
+ return x*y*(1-z);
+ case 4:
+ return (1-x)*(1-y)*z;
+ case 5:
+ return x*(1-y)*z;
+ case 6:
+ return (1-x)*y*z;
+ case 7:
+ return x*y*z;
+ }
}
default:
- Assert (false, ExcNotImplemented());
+ Assert (false, ExcNotImplemented());
}
return -1e9;
}
Tensor<1,1>
GeometryInfo<1>::
d_linear_shape_function_gradient (const Point<1> &,
- const unsigned int i)
+ const unsigned int i)
{
Assert (i < GeometryInfo<1>::vertices_per_cell,
- ExcIndexRange (i, 0, GeometryInfo<1>::vertices_per_cell));
+ ExcIndexRange (i, 0, GeometryInfo<1>::vertices_per_cell));
switch (i)
{
case 0:
- return Point<1>(-1.);
+ return Point<1>(-1.);
case 1:
- return Point<1>(1.);
+ return Point<1>(1.);
}
return Point<1>(-1e9);
Tensor<1,2>
GeometryInfo<2>::
d_linear_shape_function_gradient (const Point<2> &xi,
- const unsigned int i)
+ const unsigned int i)
{
Assert (i < GeometryInfo<2>::vertices_per_cell,
- ExcIndexRange (i, 0, GeometryInfo<2>::vertices_per_cell));
+ ExcIndexRange (i, 0, GeometryInfo<2>::vertices_per_cell));
const double x = xi[0];
const double y = xi[1];
switch (i)
{
case 0:
- return Point<2>(-(1-y),-(1-x));
+ return Point<2>(-(1-y),-(1-x));
case 1:
- return Point<2>(1-y,-x);
+ return Point<2>(1-y,-x);
case 2:
- return Point<2>(-y, 1-x);
+ return Point<2>(-y, 1-x);
case 3:
- return Point<2>(y,x);
+ return Point<2>(y,x);
}
return Point<2> (-1e9, -1e9);
}
Tensor<1,3>
GeometryInfo<3>::
d_linear_shape_function_gradient (const Point<3> &xi,
- const unsigned int i)
+ const unsigned int i)
{
Assert (i < GeometryInfo<3>::vertices_per_cell,
- ExcIndexRange (i, 0, GeometryInfo<3>::vertices_per_cell));
+ ExcIndexRange (i, 0, GeometryInfo<3>::vertices_per_cell));
const double x = xi[0];
const double y = xi[1];
switch (i)
{
case 0:
- return Point<3>(-(1-y)*(1-z),
- -(1-x)*(1-z),
- -(1-x)*(1-y));
+ return Point<3>(-(1-y)*(1-z),
+ -(1-x)*(1-z),
+ -(1-x)*(1-y));
case 1:
- return Point<3>((1-y)*(1-z),
- -x*(1-z),
- -x*(1-y));
+ return Point<3>((1-y)*(1-z),
+ -x*(1-z),
+ -x*(1-y));
case 2:
- return Point<3>(-y*(1-z),
- (1-x)*(1-z),
- -(1-x)*y);
+ return Point<3>(-y*(1-z),
+ (1-x)*(1-z),
+ -(1-x)*y);
case 3:
- return Point<3>(y*(1-z),
- x*(1-z),
- -x*y);
+ return Point<3>(y*(1-z),
+ x*(1-z),
+ -x*y);
case 4:
- return Point<3>(-(1-y)*z,
- -(1-x)*z,
- (1-x)*(1-y));
+ return Point<3>(-(1-y)*z,
+ -(1-x)*z,
+ (1-x)*(1-y));
case 5:
- return Point<3>((1-y)*z,
- -x*z,
- x*(1-y));
+ return Point<3>((1-y)*z,
+ -x*z,
+ x*(1-y));
case 6:
- return Point<3>(-y*z,
- (1-x)*z,
- (1-x)*y);
+ return Point<3>(-y*z,
+ (1-x)*z,
+ (1-x)*y);
case 7:
- return Point<3>(y*z, x*z, x*y);
+ return Point<3>(y*z, x*z, x*y);
}
return Point<3> (-1e9, -1e9, -1e9);
Tensor<1,dim>
GeometryInfo<dim>::
d_linear_shape_function_gradient (const Point<dim> &,
- const unsigned int)
+ const unsigned int)
{
Assert (false, ExcNotImplemented());
return Tensor<1,dim>();
{
namespace GeometryInfo
{
- // wedge product of a single
- // vector in 2d: we just have to
- // rotate it by 90 degrees to the
- // right
+ // wedge product of a single
+ // vector in 2d: we just have to
+ // rotate it by 90 degrees to the
+ // right
inline
Tensor<1,2>
wedge_product (const Tensor<1,2> (&derivative)[1])
}
- // wedge product of 2 vectors in
- // 3d is the cross product
+ // wedge product of 2 vectors in
+ // 3d is the cross product
inline
Tensor<1,3>
wedge_product (const Tensor<1,3> (&derivative)[2])
}
- // wedge product of dim vectors
- // in dim-d: that's the
- // determinant of the matrix
+ // wedge product of dim vectors
+ // in dim-d: that's the
+ // determinant of the matrix
template <int dim>
inline
Tensor<0,dim>
{
Tensor<2,dim> jacobian;
for (unsigned int i=0; i<dim; ++i)
- jacobian[i] = derivative[i];
+ jacobian[i] = derivative[i];
return determinant (jacobian);
}
Tensor<spacedim-dim,spacedim> *forms)
#endif
{
- // for each of the vertices,
- // compute the alternating form
- // of the mapped unit
- // vectors. consider for
- // example the case of a quad
- // in spacedim==3: to do so, we
- // need to see how the
- // infinitesimal vectors
- // (d\xi_1,0) and (0,d\xi_2)
- // are transformed into
- // spacedim-dimensional space
- // and then form their cross
- // product (i.e. the wedge product
- // of two vectors). to this end, note
- // that
- // \vec x = sum_i \vec v_i phi_i(\vec xi)
- // so the transformed vectors are
- // [x(\xi+(d\xi_1,0))-x(\xi)]/d\xi_1
- // and
- // [x(\xi+(0,d\xi_2))-x(\xi)]/d\xi_2
- // which boils down to the columns
- // of the 3x2 matrix \grad_\xi x(\xi)
- //
- // a similar reasoning would
- // hold for all dim,spacedim
- // pairs -- we only have to
- // compute the wedge product of
- // the columns of the
- // derivatives
+ // for each of the vertices,
+ // compute the alternating form
+ // of the mapped unit
+ // vectors. consider for
+ // example the case of a quad
+ // in spacedim==3: to do so, we
+ // need to see how the
+ // infinitesimal vectors
+ // (d\xi_1,0) and (0,d\xi_2)
+ // are transformed into
+ // spacedim-dimensional space
+ // and then form their cross
+ // product (i.e. the wedge product
+ // of two vectors). to this end, note
+ // that
+ // \vec x = sum_i \vec v_i phi_i(\vec xi)
+ // so the transformed vectors are
+ // [x(\xi+(d\xi_1,0))-x(\xi)]/d\xi_1
+ // and
+ // [x(\xi+(0,d\xi_2))-x(\xi)]/d\xi_2
+ // which boils down to the columns
+ // of the 3x2 matrix \grad_\xi x(\xi)
+ //
+ // a similar reasoning would
+ // hold for all dim,spacedim
+ // pairs -- we only have to
+ // compute the wedge product of
+ // the columns of the
+ // derivatives
for (unsigned int i=0; i<vertices_per_cell; ++i)
{
Tensor<1,spacedim> derivatives[dim];
for (unsigned int j=0; j<vertices_per_cell; ++j)
- {
- const Tensor<1,dim> grad_phi_j
- = d_linear_shape_function_gradient (unit_cell_vertex(i),
- j);
- for (unsigned int l=0; l<dim; ++l)
- derivatives[l] += vertices[j] * grad_phi_j[l];
- }
+ {
+ const Tensor<1,dim> grad_phi_j
+ = d_linear_shape_function_gradient (unit_cell_vertex(i),
+ j);
+ for (unsigned int l=0; l<dim; ++l)
+ derivatives[l] += vertices[j] * grad_phi_j[l];
+ }
forms[i] = internal::GeometryInfo::wedge_product (derivatives);
}
// $Id$
// Version: $Name$
//
-// Copyright (C) 2005, 2006, 2008, 2009, 2010, 2011 by the deal.II authors
+// Copyright (C) 2005, 2006, 2008, 2009, 2010, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
void
IndexSet::do_compress () const
{
- // see if any of the
- // contiguous ranges can be
- // merged. since they are sorted by
- // their first index, determining
- // overlap isn't all that hard
+ // see if any of the
+ // contiguous ranges can be
+ // merged. since they are sorted by
+ // their first index, determining
+ // overlap isn't all that hard
for (std::vector<Range>::iterator
- i = ranges.begin();
+ i = ranges.begin();
i != ranges.end(); )
{
std::vector<Range>::iterator
- next = i;
+ next = i;
++next;
unsigned int first_index = i->begin;
unsigned int last_index = i->end;
- // see if we can merge any of
- // the following ranges
+ // see if we can merge any of
+ // the following ranges
bool can_merge = false;
while (next != ranges.end() &&
- (next->begin <= last_index))
- {
- last_index = std::max (last_index, next->end);
- ++next;
- can_merge = true;
- }
+ (next->begin <= last_index))
+ {
+ last_index = std::max (last_index, next->end);
+ ++next;
+ can_merge = true;
+ }
if (can_merge == true)
- {
- // delete the old ranges
- // and insert the new range
- // in place of the previous
- // one
- *i = Range(first_index, last_index);
- i = ranges.erase (i+1, next);
- }
+ {
+ // delete the old ranges
+ // and insert the new range
+ // in place of the previous
+ // one
+ *i = Range(first_index, last_index);
+ i = ranges.erase (i+1, next);
+ }
else
- ++i;
+ ++i;
}
- // now compute indices within set and the
- // range with most elements
+ // now compute indices within set and the
+ // range with most elements
unsigned int next_index = 0, largest_range_size = 0;
for (std::vector<Range>::iterator
- i = ranges.begin();
+ i = ranges.begin();
i != ranges.end();
++i)
{
i->nth_index_in_set = next_index;
next_index += (i->end - i->begin);
if (i->end - i->begin > largest_range_size)
- {
- largest_range_size = i->end - i->begin;
- largest_range = i - ranges.begin();
- }
+ {
+ largest_range_size = i->end - i->begin;
+ largest_range = i - ranges.begin();
+ }
}
is_compressed = true;
- // check that next_index is
- // correct. needs to be after the
- // previous statement because we
- // otherwise will get into an
- // endless loop
+ // check that next_index is
+ // correct. needs to be after the
+ // previous statement because we
+ // otherwise will get into an
+ // endless loop
Assert (next_index == n_elements(), ExcInternalError());
}
IndexSet::operator & (const IndexSet &is) const
{
Assert (size() == is.size(),
- ExcDimensionMismatch (size(), is.size()));
+ ExcDimensionMismatch (size(), is.size()));
compress ();
is.compress ();
std::vector<Range>::const_iterator r1 = ranges.begin(),
- r2 = is.ranges.begin();
+ r2 = is.ranges.begin();
IndexSet result (size());
while ((r1 != ranges.end())
- &&
- (r2 != is.ranges.end()))
+ &&
+ (r2 != is.ranges.end()))
{
- // if r1 and r2 do not overlap
- // at all, then move the
- // pointer that sits to the
- // left of the other up by one
+ // if r1 and r2 do not overlap
+ // at all, then move the
+ // pointer that sits to the
+ // left of the other up by one
if (r1->end <= r2->begin)
- ++r1;
+ ++r1;
else if (r2->end <= r1->begin)
- ++r2;
+ ++r2;
else
- {
- // the ranges must overlap
- // somehow
- Assert (((r1->begin <= r2->begin) &&
- (r1->end > r2->begin))
- ||
- ((r2->begin <= r1->begin) &&
- (r2->end > r1->begin)),
- ExcInternalError());
-
- // add the overlapping
- // range to the result
- result.add_range (std::max (r1->begin,
- r2->begin),
- std::min (r1->end,
- r2->end));
-
- // now move that iterator
- // that ends earlier one
- // up. note that it has to
- // be this one because a
- // subsequent range may
- // still have a chance of
- // overlapping with the
- // range that ends later
- if (r1->end <= r2->end)
- ++r1;
- else
- ++r2;
- }
+ {
+ // the ranges must overlap
+ // somehow
+ Assert (((r1->begin <= r2->begin) &&
+ (r1->end > r2->begin))
+ ||
+ ((r2->begin <= r1->begin) &&
+ (r2->end > r1->begin)),
+ ExcInternalError());
+
+ // add the overlapping
+ // range to the result
+ result.add_range (std::max (r1->begin,
+ r2->begin),
+ std::min (r1->end,
+ r2->end));
+
+ // now move that iterator
+ // that ends earlier one
+ // up. note that it has to
+ // be this one because a
+ // subsequent range may
+ // still have a chance of
+ // overlapping with the
+ // range that ends later
+ if (r1->end <= r2->end)
+ ++r1;
+ else
+ ++r2;
+ }
}
result.compress ();
IndexSet
IndexSet::get_view (const unsigned int begin,
- const unsigned int end) const
+ const unsigned int end) const
{
Assert (begin <= end,
- ExcMessage ("End index needs to be larger or equal to begin index!"));
+ ExcMessage ("End index needs to be larger or equal to begin index!"));
Assert (end <= size(),
- ExcMessage ("Given range exceeds index set dimension"));
+ ExcMessage ("Given range exceeds index set dimension"));
IndexSet result (end-begin);
std::vector<Range>::const_iterator r1 = ranges.begin();
while (r1 != ranges.end())
{
if ((r1->end > begin)
- &&
- (r1->begin < end))
- {
- result.add_range (std::max(r1->begin, begin)-begin,
- std::min(r1->end, end)-begin);
+ &&
+ (r1->begin < end))
+ {
+ result.add_range (std::max(r1->begin, begin)-begin,
+ std::min(r1->end, end)-begin);
- }
+ }
else
- if (r1->begin >= end)
- break;
+ if (r1->begin >= end)
+ break;
++r1;
}
{
Assert (out, ExcIO());
out.write(reinterpret_cast<const char*>(&index_space_size),
- sizeof(index_space_size));
+ sizeof(index_space_size));
size_t n_ranges = ranges.size();
out.write(reinterpret_cast<const char*>(&n_ranges),
- sizeof(n_ranges));
+ sizeof(n_ranges));
if (ranges.empty() == false)
out.write (reinterpret_cast<const char*>(&*ranges.begin()),
- ranges.size() * sizeof(Range));
+ ranges.size() * sizeof(Range));
Assert (out, ExcIO());
}
size_t n_ranges;
in.read(reinterpret_cast<char*>(&size), sizeof(size));
in.read(reinterpret_cast<char*>(&n_ranges), sizeof(n_ranges));
- // we have to clear ranges first
+ // we have to clear ranges first
ranges.clear();
set_size(size);
ranges.resize(n_ranges, Range(0,0));
if (n_ranges)
in.read(reinterpret_cast<char*>(&*ranges.begin()),
- ranges.size() * sizeof(Range));
+ ranges.size() * sizeof(Range));
}
is_compressed = false;
- // we save new ranges to be added to our
- // IndexSet in an temporary list and add
- // all of them in one go at the end. This
- // is necessary because a growing ranges
- // vector invalidates iterators.
+ // we save new ranges to be added to our
+ // IndexSet in an temporary list and add
+ // all of them in one go at the end. This
+ // is necessary because a growing ranges
+ // vector invalidates iterators.
std::list<Range> temp_list;
std::vector<Range>::iterator own_it = ranges.begin();
while (own_it != ranges.end() && other_it != other.ranges.end())
{
- //advance own iterator until we get an
- //overlap
+ //advance own iterator until we get an
+ //overlap
if (own_it->end <= other_it->begin)
- {
- ++own_it;
- continue;
- }
- //we are done with other_it, so advance
+ {
+ ++own_it;
+ continue;
+ }
+ //we are done with other_it, so advance
if (own_it->begin >= other_it->end)
- {
- ++other_it;
- continue;
- }
-
- //Now own_it and other_it overlap.
- //First save the part of own_it that is
- //before other_it (if not empty).
+ {
+ ++other_it;
+ continue;
+ }
+
+ //Now own_it and other_it overlap.
+ //First save the part of own_it that is
+ //before other_it (if not empty).
if (own_it->begin < other_it->begin)
- {
- Range r(own_it->begin, other_it->begin);
- r.nth_index_in_set = 0; //fix warning of unused variable
- temp_list.push_back(r);
- }
- // change own_it to the sub range
- // behind other_it. Do not delete
- // own_it in any case. As removal would
- // invalidate iterators, we just shrink
- // the range to an empty one.
+ {
+ Range r(own_it->begin, other_it->begin);
+ r.nth_index_in_set = 0; //fix warning of unused variable
+ temp_list.push_back(r);
+ }
+ // change own_it to the sub range
+ // behind other_it. Do not delete
+ // own_it in any case. As removal would
+ // invalidate iterators, we just shrink
+ // the range to an empty one.
own_it->begin = other_it->end;
if (own_it->begin > own_it->end)
- {
- own_it->begin = own_it->end;
- ++own_it;
- }
-
- // continue without advancing
- // iterators, the right one will be
- // advanced next.
+ {
+ own_it->begin = own_it->end;
+ ++own_it;
+ }
+
+ // continue without advancing
+ // iterators, the right one will be
+ // advanced next.
}
- // Now delete all empty ranges we might
- // have created.
+ // Now delete all empty ranges we might
+ // have created.
for (std::vector<Range>::iterator it = ranges.begin();
it != ranges.end(); )
{
if (it->begin >= it->end)
- it = ranges.erase(it);
+ it = ranges.erase(it);
else
- ++it;
+ ++it;
}
- // done, now add the temporary ranges
+ // done, now add the temporary ranges
for (std::list<Range>::iterator it = temp_list.begin();
it != temp_list.end();
++it)
Epetra_Map
IndexSet::make_trilinos_map (const MPI_Comm &communicator,
- const bool overlapping) const
+ const bool overlapping) const
{
compress ();
if ((is_contiguous() == true) && (!overlapping))
return Epetra_Map (size(),
- n_elements(),
- 0,
+ n_elements(),
+ 0,
#ifdef DEAL_II_COMPILER_SUPPORTS_MPI
- Epetra_MpiComm(communicator));
+ Epetra_MpiComm(communicator));
#else
- Epetra_SerialComm());
+ Epetra_SerialComm());
#endif
else
{
fill_index_vector(indices);
return Epetra_Map (-1,
- n_elements(),
- (n_elements() > 0
- ?
- reinterpret_cast<int*>(&indices[0])
- :
- 0),
- 0,
+ n_elements(),
+ (n_elements() > 0
+ ?
+ reinterpret_cast<int*>(&indices[0])
+ :
+ 0),
+ 0,
#ifdef DEAL_II_COMPILER_SUPPORTS_MPI
- Epetra_MpiComm(communicator));
+ Epetra_MpiComm(communicator));
#else
- Epetra_SerialComm());
+ Epetra_SerialComm());
(void)communicator;
#endif
}
// $Id$
// Version: $Name$
//
-// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2006, 2009, 2010 by the deal.II authors
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2006, 2009, 2010, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
// $Id$
// Version: $Name$
//
-// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2008, 2009, 2010, 2011 by the deal.II authors
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2008, 2009, 2010, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
LogStream::LogStream()
- :
- std_out(&std::cerr), file(0),
- std_depth(10000), file_depth(10000),
- print_utime(false), diff_utime(false),
- last_time (0.), double_threshold(0.), float_threshold(0.),
- offset(0), old_cerr(0)
+ :
+ std_out(&std::cerr), file(0),
+ std_depth(10000), file_depth(10000),
+ print_utime(false), diff_utime(false),
+ last_time (0.), double_threshold(0.), float_threshold(0.),
+ offset(0), old_cerr(0)
{
prefixes.push("DEAL:");
std_out->setf(std::ios::showpoint | std::ios::left);
LogStream::~LogStream()
{
- // if there was anything left in
- // the stream that is current to
- // this thread, make sure we flush
- // it before it gets lost
+ // if there was anything left in
+ // the stream that is current to
+ // this thread, make sure we flush
+ // it before it gets lost
{
const unsigned int id = Threads::this_thread_id();
if ((outstreams.find(id) != outstreams.end())
- &&
- (*outstreams[id] != 0)
- &&
- (outstreams[id]->str().length() > 0))
+ &&
+ (*outstreams[id] != 0)
+ &&
+ (outstreams[id]->str().length() > 0))
*this << std::endl;
}
if (old_cerr)
std::cerr.rdbuf(old_cerr);
- // on some systems, destroying the
- // outstreams objects of deallog
- // triggers some sort of memory
- // corruption, in particular when
- // we also link with Trilinos;
- // since this happens at the very
- // end of the program, we take the
- // liberty to simply not do it by
- // putting that object into a
- // deliberate memory leak and
- // instead destroying an empty
- // object
+ // on some systems, destroying the
+ // outstreams objects of deallog
+ // triggers some sort of memory
+ // corruption, in particular when
+ // we also link with Trilinos;
+ // since this happens at the very
+ // end of the program, we take the
+ // liberty to simply not do it by
+ // putting that object into a
+ // deliberate memory leak and
+ // instead destroying an empty
+ // object
#ifdef DEAL_II_USE_TRILINOS
if (this == &deallog)
{
double_threshold = 0.;
float_threshold = 0.;
offset = 0.;
- }
+ }
}
LogStream &
LogStream::operator<< (std::ostream& (*p) (std::ostream&))
{
- // do the work that is common to
- // the operator<< functions
+ // do the work that is common to
+ // the operator<< functions
print (p);
- // next check whether this is the
- // <tt>endl</tt> manipulator, and if so
- // set a flag
+ // next check whether this is the
+ // <tt>endl</tt> manipulator, and if so
+ // set a flag
std::ostream & (* const p_endl) (std::ostream&) = &std::endl;
if (p == p_endl)
{
print_line_head();
std::ostringstream& stream = get_stream();
if (prefixes.size() <= std_depth)
- *std_out << stream.str();
+ *std_out << stream.str();
if (file && (prefixes.size() <= file_depth))
- *file << stream.str() << std::flush;
+ *file << stream.str() << std::flush;
- // Start a new string
+ // Start a new string
stream.str("");
}
return *this;
Threads::ThreadMutex::ScopedLock lock(log_lock);
const unsigned int id = Threads::this_thread_id();
- // if necessary allocate a stream object
+ // if necessary allocate a stream object
if (outstreams.find (id) == outstreams.end())
{
outstreams[id].reset (new std::ostringstream());
getrusage(RUSAGE_SELF, &usage);
utime = usage.ru_utime.tv_sec + 1.e-6 * usage.ru_utime.tv_usec;
if (diff_utime)
- {
- double diff = utime - last_time;
- last_time = utime;
- utime = diff;
- }
+ {
+ double diff = utime - last_time;
+ last_time = utime;
+ utime = diff;
+ }
}
/*
static long size;
static string dummy;
ifstream stat(statname.str());
- // ignore 22 values
+ // ignore 22 values
stat >> dummy >> dummy >> dummy >> dummy >> dummy >> dummy >>
dummy >> dummy >> dummy >> dummy >> dummy >>
dummy >> dummy >> dummy >> dummy >> dummy >> dummy >>
if (prefixes.size() <= std_depth)
{
if (print_utime)
- {
- int p = std_out->width(5);
- *std_out << utime << ':';
+ {
+ int p = std_out->width(5);
+ *std_out << utime << ':';
#ifdef DEALII_MEMORY_DEBUG
- *std_out << size << ':';
+ *std_out << size << ':';
#endif
- std_out->width(p);
- }
+ std_out->width(p);
+ }
if (print_thread_id)
- *std_out << '[' << thread << ']';
+ *std_out << '[' << thread << ']';
*std_out << head << ':';
}
if (file && (prefixes.size() <= file_depth))
{
if (print_utime)
- {
- int p = file->width(6);
- *file << utime << ':';
+ {
+ int p = file->width(6);
+ *file << utime << ':';
#ifdef DEALII_MEMORY_DEBUG
- *file << size << ':';
+ *file << size << ':';
#endif
- file->width(p);
- }
+ file->width(p);
+ }
if (print_thread_id)
- *file << '[' << thread << ']';
+ *file << '[' << thread << ']';
*file << head << ':';
}
const unsigned int tick = 100;
#endif
(*this) << "Wall: " << time - reference_time_val
- << " User: " << 1./tick * (current_tms.tms_utime - reference_tms.tms_utime)
- << " System: " << 1./tick * (current_tms.tms_stime - reference_tms.tms_stime)
- << " Child-User: " << 1./tick * (current_tms.tms_cutime - reference_tms.tms_cutime)
- << " Child-System: " << 1./tick * (current_tms.tms_cstime - reference_tms.tms_cstime)
- << std::endl;
+ << " User: " << 1./tick * (current_tms.tms_utime - reference_tms.tms_utime)
+ << " System: " << 1./tick * (current_tms.tms_stime - reference_tms.tms_stime)
+ << " Child-User: " << 1./tick * (current_tms.tms_cutime - reference_tms.tms_cutime)
+ << " Child-System: " << 1./tick * (current_tms.tms_cstime - reference_tms.tms_cstime)
+ << std::endl;
}
LogStream::memory_consumption () const
{
std::size_t mem = sizeof(*this);
- // to determine size of stack
- // elements, we have to copy the
- // stack since we can't access
- // elements from further below
+ // to determine size of stack
+ // elements, we have to copy the
+ // stack since we can't access
+ // elements from further below
std::stack<std::string> tmp = prefixes;
while (tmp.empty() == false)
{
// $Id$
// Version: $Name$
//
-// Copyright (C) 2000, 2001, 2002, 2003, 2005, 2006, 2011 by the deal.II authors
+// Copyright (C) 2000, 2001, 2002, 2003, 2005, 2006, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
DEAL_II_NAMESPACE_OPEN
-namespace MemoryConsumption
+namespace MemoryConsumption
{
std::size_t
memory_consumption (const std::vector<std::string> &v)
mem += memory_consumption(v[i]);
return mem;
}
-
+
}
// $Id$
// Version: $Name$
//
-// Copyright (C) 2005, 2006, 2008, 2009, 2010, 2011 by the deal.II authors
+// Copyright (C) 2005, 2006, 2008, 2009, 2010, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
std::vector<unsigned int>
compute_point_to_point_communication_pattern (const MPI_Comm & mpi_comm,
- const std::vector<unsigned int> & destinations)
+ const std::vector<unsigned int> & destinations)
{
unsigned int myid = Utilities::MPI::this_mpi_process(mpi_comm);
unsigned int n_procs = Utilities::MPI::n_mpi_processes(mpi_comm);
for (unsigned int i=0; i<destinations.size(); ++i)
- {
- Assert (destinations[i] < n_procs,
- ExcIndexRange (destinations[i], 0, n_procs));
- Assert (destinations[i] != myid,
- ExcMessage ("There is no point in communicating with ourselves."));
- }
-
-
- // let all processors
- // communicate the maximal
- // number of destinations they
- // have
+ {
+ Assert (destinations[i] < n_procs,
+ ExcIndexRange (destinations[i], 0, n_procs));
+ Assert (destinations[i] != myid,
+ ExcMessage ("There is no point in communicating with ourselves."));
+ }
+
+
+ // let all processors
+ // communicate the maximal
+ // number of destinations they
+ // have
const unsigned int max_n_destinations
- = Utilities::MPI::max (destinations.size(), mpi_comm);
-
- // now that we know the number
- // of data packets every
- // processor wants to send, set
- // up a buffer with the maximal
- // size and copy our
- // destinations in there,
- // padded with -1's
+ = Utilities::MPI::max (destinations.size(), mpi_comm);
+
+ // now that we know the number
+ // of data packets every
+ // processor wants to send, set
+ // up a buffer with the maximal
+ // size and copy our
+ // destinations in there,
+ // padded with -1's
std::vector<unsigned int> my_destinations(max_n_destinations,
- numbers::invalid_unsigned_int);
+ numbers::invalid_unsigned_int);
std::copy (destinations.begin(), destinations.end(),
- my_destinations.begin());
-
- // now exchange these (we could
- // communicate less data if we
- // used MPI_Allgatherv, but
- // we'd have to communicate
- // my_n_destinations to all
- // processors in this case,
- // which is more expensive than
- // the reduction operation
- // above in MPI_Allreduce)
+ my_destinations.begin());
+
+ // now exchange these (we could
+ // communicate less data if we
+ // used MPI_Allgatherv, but
+ // we'd have to communicate
+ // my_n_destinations to all
+ // processors in this case,
+ // which is more expensive than
+ // the reduction operation
+ // above in MPI_Allreduce)
std::vector<unsigned int> all_destinations (max_n_destinations * n_procs);
MPI_Allgather (&my_destinations[0], max_n_destinations, MPI_UNSIGNED,
- &all_destinations[0], max_n_destinations, MPI_UNSIGNED,
- mpi_comm);
+ &all_destinations[0], max_n_destinations, MPI_UNSIGNED,
+ mpi_comm);
- // now we know who is going to
- // communicate with
- // whom. collect who is going
- // to communicate with us!
+ // now we know who is going to
+ // communicate with
+ // whom. collect who is going
+ // to communicate with us!
std::vector<unsigned int> origins;
for (unsigned int i=0; i<n_procs; ++i)
- for (unsigned int j=0; j<max_n_destinations; ++j)
- if (all_destinations[i*max_n_destinations + j] == myid)
- origins.push_back (i);
- else if (all_destinations[i*max_n_destinations + j] ==
- numbers::invalid_unsigned_int)
- break;
+ for (unsigned int j=0; j<max_n_destinations; ++j)
+ if (all_destinations[i*max_n_destinations + j] == myid)
+ origins.push_back (i);
+ else if (all_destinations[i*max_n_destinations + j] ==
+ numbers::invalid_unsigned_int)
+ break;
return origins;
}
namespace
{
- // custom MIP_Op for
- // calculate_collective_mpi_min_max_avg
+ // custom MIP_Op for
+ // calculate_collective_mpi_min_max_avg
void max_reduce ( const void * in_lhs_,
- void * inout_rhs_,
- int * len,
- MPI_Datatype * )
+ void * inout_rhs_,
+ int * len,
+ MPI_Datatype * )
{
- const MinMaxAvg * in_lhs = static_cast<const MinMaxAvg*>(in_lhs_);
- MinMaxAvg * inout_rhs = static_cast<MinMaxAvg*>(inout_rhs_);
-
- Assert(*len==1, ExcInternalError());
-
- inout_rhs->sum += in_lhs->sum;
- if (inout_rhs->min>in_lhs->min)
- {
- inout_rhs->min = in_lhs->min;
- inout_rhs->min_index = in_lhs->min_index;
- }
- else if (inout_rhs->min == in_lhs->min)
- { // choose lower cpu index when tied to make operator cumutative
- if (inout_rhs->min_index > in_lhs->min_index)
- inout_rhs->min_index = in_lhs->min_index;
- }
-
- if (inout_rhs->max < in_lhs->max)
- {
- inout_rhs->max = in_lhs->max;
- inout_rhs->max_index = in_lhs->max_index;
- }
- else if (inout_rhs->max == in_lhs->max)
- { // choose lower cpu index when tied to make operator cumutative
- if (inout_rhs->max_index > in_lhs->max_index)
- inout_rhs->max_index = in_lhs->max_index;
- }
+ const MinMaxAvg * in_lhs = static_cast<const MinMaxAvg*>(in_lhs_);
+ MinMaxAvg * inout_rhs = static_cast<MinMaxAvg*>(inout_rhs_);
+
+ Assert(*len==1, ExcInternalError());
+
+ inout_rhs->sum += in_lhs->sum;
+ if (inout_rhs->min>in_lhs->min)
+ {
+ inout_rhs->min = in_lhs->min;
+ inout_rhs->min_index = in_lhs->min_index;
+ }
+ else if (inout_rhs->min == in_lhs->min)
+ { // choose lower cpu index when tied to make operator cumutative
+ if (inout_rhs->min_index > in_lhs->min_index)
+ inout_rhs->min_index = in_lhs->min_index;
+ }
+
+ if (inout_rhs->max < in_lhs->max)
+ {
+ inout_rhs->max = in_lhs->max;
+ inout_rhs->max_index = in_lhs->max_index;
+ }
+ else if (inout_rhs->max == in_lhs->max)
+ { // choose lower cpu index when tied to make operator cumutative
+ if (inout_rhs->max_index > in_lhs->max_index)
+ inout_rhs->max_index = in_lhs->max_index;
+ }
}
}
MinMaxAvg
min_max_avg(const double my_value,
- const MPI_Comm &mpi_communicator)
+ const MPI_Comm &mpi_communicator)
{
MinMaxAvg result;
const unsigned int my_id
- = dealii::Utilities::MPI::this_mpi_process(mpi_communicator);
+ = dealii::Utilities::MPI::this_mpi_process(mpi_communicator);
const unsigned int numproc
- = dealii::Utilities::MPI::n_mpi_processes(mpi_communicator);
+ = dealii::Utilities::MPI::n_mpi_processes(mpi_communicator);
MPI_Op op;
int ierr = MPI_Op_create((MPI_User_function *)&max_reduce, true, &op);
MinMaxAvg
min_max_avg(const double my_value,
- const MPI_Comm &)
+ const MPI_Comm &)
{
MinMaxAvg result;
MPI_InitFinalize::MPI_InitFinalize (int &argc,
- char** &argv)
- :
- owns_mpi (true)
+ char** &argv)
+ :
+ owns_mpi (true)
{
static bool constructor_has_already_run = false;
Assert (constructor_has_already_run == false,
- ExcMessage ("You can only create a single object of this class "
- "in a program since it initializes the MPI system."));
+ ExcMessage ("You can only create a single object of this class "
+ "in a program since it initializes the MPI system."));
#ifdef DEAL_II_COMPILER_SUPPORTS_MPI
int MPI_has_been_started = 0;
MPI_Initialized(&MPI_has_been_started);
AssertThrow (MPI_has_been_started == 0,
- ExcMessage ("MPI error. You can only start MPI once!"));
+ ExcMessage ("MPI error. You can only start MPI once!"));
int mpi_err;
mpi_err = MPI_Init (&argc, &argv);
AssertThrow (mpi_err == 0,
- ExcMessage ("MPI could not be initialized."));
+ ExcMessage ("MPI could not be initialized."));
#else
- // make sure the compiler doesn't warn
- // about these variables
+ // make sure the compiler doesn't warn
+ // about these variables
(void)argc;
(void)argv;
#endif
#ifdef DEAL_II_COMPILER_SUPPORTS_MPI
# if defined(DEAL_II_USE_TRILINOS) && !defined(__APPLE__)
- // make memory pool release all
- // vectors that are no longer
- // used at this point. this is
- // relevant because the static
- // object destructors run for
- // these vectors at the end of
- // the program would run after
- // MPI_Finalize is called,
- // leading to errors
- //
- // TODO: On Mac OS X, shared libs can
- // only depend on other libs listed
- // later on the command line. This
- // means that libbase can't depend on
- // liblac, and we can't destroy the
- // memory pool here as long as we have
- // separate libraries. Consequently,
- // the #ifdef above. Deal will then
- // just continue to seg fault upon
- // completion of main()
+ // make memory pool release all
+ // vectors that are no longer
+ // used at this point. this is
+ // relevant because the static
+ // object destructors run for
+ // these vectors at the end of
+ // the program would run after
+ // MPI_Finalize is called,
+ // leading to errors
+ //
+ // TODO: On Mac OS X, shared libs can
+ // only depend on other libs listed
+ // later on the command line. This
+ // means that libbase can't depend on
+ // liblac, and we can't destroy the
+ // memory pool here as long as we have
+ // separate libraries. Consequently,
+ // the #ifdef above. Deal will then
+ // just continue to seg fault upon
+ // completion of main()
GrowingVectorMemory<TrilinosWrappers::MPI::Vector>
- ::release_unused_memory ();
+ ::release_unused_memory ();
GrowingVectorMemory<TrilinosWrappers::MPI::BlockVector>
- ::release_unused_memory ();
+ ::release_unused_memory ();
# endif
int mpi_err = 0;
int MPI_has_been_started = 0;
MPI_Initialized(&MPI_has_been_started);
if (Utilities::System::program_uses_mpi() == true && owns_mpi == true &&
- MPI_has_been_started != 0)
- {
- if (std::uncaught_exception())
- {
- std::cerr << "ERROR: Uncaught exception in MPI_InitFinalize on proc "
- << this_mpi_process(MPI_COMM_WORLD)
- << ". Skipping MPI_Finalize() to avoid a deadlock."
- << std::endl;
- }
- else
- mpi_err = MPI_Finalize();
- }
+ MPI_has_been_started != 0)
+ {
+ if (std::uncaught_exception())
+ {
+ std::cerr << "ERROR: Uncaught exception in MPI_InitFinalize on proc "
+ << this_mpi_process(MPI_COMM_WORLD)
+ << ". Skipping MPI_Finalize() to avoid a deadlock."
+ << std::endl;
+ }
+ else
+ mpi_err = MPI_Finalize();
+ }
AssertThrow (mpi_err == 0,
- ExcMessage ("An error occurred while calling MPI_Finalize()"));
+ ExcMessage ("An error occurred while calling MPI_Finalize()"));
#endif
}
// $Id$
// Version: $Name$
//
-// Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2011 by the deal.II authors
+// Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
unsigned int MultithreadInfo::get_n_cpus()
{
- // on linux, we simply count the
- // number of lines listing
- // individual processors when
- // reading from /proc/cpuinfo
+ // on linux, we simply count the
+ // number of lines listing
+ // individual processors when
+ // reading from /proc/cpuinfo
std::ifstream cpuinfo;
std::string search;
unsigned int nCPU = 0;
-
+
cpuinfo.open("/proc/cpuinfo");
AssertThrow(cpuinfo,ExcProcNotPresent());
-
+
while(cpuinfo)
{
cpuinfo >> search;
if (search.find("processor") != std::string::npos)
- nCPU++;
+ nCPU++;
}
cpuinfo.close();
-
+
return nCPU;
}
}
# elif defined(__MACH__) && defined(__APPLE__)
-// This is only tested on a dual G5 2.5GHz running MacOSX 10.3.6
+// This is only tested on a dual G5 2.5GHz running MacOSX 10.3.6
// and on an Intel Mac Book Pro.
// If it doesnt work please contact the mailinglist.
unsigned int MultithreadInfo::get_n_cpus()
{
- int mib[2];
- int n_cpus;
- size_t len;
-
- mib[0] = CTL_HW;
- mib[1] = HW_NCPU;
- len = sizeof(n_cpus);
- sysctl(mib, 2, &n_cpus, &len, NULL, 0);
-
- return n_cpus;
+ int mib[2];
+ int n_cpus;
+ size_t len;
+
+ mib[0] = CTL_HW;
+ mib[1] = HW_NCPU;
+ len = sizeof(n_cpus);
+ sysctl(mib, 2, &n_cpus, &len, NULL, 0);
+
+ return n_cpus;
}
# endif
-#else // not in MT mode
+#else // not in MT mode
unsigned int MultithreadInfo::get_n_cpus()
{
std::size_t
MultithreadInfo::memory_consumption ()
{
- // only simple data elements, so
- // use sizeof operator
+ // only simple data elements, so
+ // use sizeof operator
return sizeof (MultithreadInfo);
}
// $Id$
// Version: $Name$
//
-// Copyright (C) 2009 by the deal.II authors
+// Copyright (C) 2009, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
{
namespace Vector
{
- // set minimum grain size. this value is
- // roughly in accordance with the curve
- // in the TBB book (fig 3.2) that shows
- // run time as a function of grain size
- // -- there, values from 200 upward are
- // so that the scheduling overhead
- // amortizes well (for very large values
- // in that example, the grain size is too
- // large to split the work load into
- // enough chunks and the problem becomes
- // badly balanced)
+ // set minimum grain size. this value is
+ // roughly in accordance with the curve
+ // in the TBB book (fig 3.2) that shows
+ // run time as a function of grain size
+ // -- there, values from 200 upward are
+ // so that the scheduling overhead
+ // amortizes well (for very large values
+ // in that example, the grain size is too
+ // large to split the work load into
+ // enough chunks and the problem becomes
+ // badly balanced)
unsigned int minimum_parallel_grain_size = 1000;
}
namespace SparseMatrix
{
- // set this value to 1/5 of the value of
- // the minimum grain size of
- // vectors. this rests on the fact that
- // we have to do a lot more work per row
- // of a matrix than per element of a
- // vector. it could possibly be reduced
- // even further but that doesn't appear
- // worth it any more for anything but
- // very small matrices that we don't care
- // that much about anyway.
+ // set this value to 1/5 of the value of
+ // the minimum grain size of
+ // vectors. this rests on the fact that
+ // we have to do a lot more work per row
+ // of a matrix than per element of a
+ // vector. it could possibly be reduced
+ // even further but that doesn't appear
+ // worth it any more for anything but
+ // very small matrices that we don't care
+ // that much about anyway.
unsigned int minimum_parallel_grain_size = 200;
}
}
// $Id$
// Version: $Name$
//
-// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2010, 2011 by the deal.II authors
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2010, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
namespace
{
- /**
- * Read to the end of the stream and
- * return whether all there is is
- * whitespace or whether there are other
- * characters as well.
- */
+ /**
+ * Read to the end of the stream and
+ * return whether all there is is
+ * whitespace or whether there are other
+ * characters as well.
+ */
bool has_only_whitespace (std::istream &in)
{
while (in)
- {
- char c;
+ {
+ char c;
- // skip if we've reached the end of
- // the line
- if (!(in >> c))
- break;
+ // skip if we've reached the end of
+ // the line
+ if (!(in >> c))
+ break;
- if ((c != ' ') && (c != '\t'))
- return false;
- }
+ if ((c != ' ') && (c != '\t'))
+ return false;
+ }
return true;
}
}
const char* Integer::description_init = "[Integer";
Integer::Integer (const int lower_bound,
- const int upper_bound)
+ const int upper_bound)
:
- lower_bound (lower_bound),
- upper_bound (upper_bound)
+ lower_bound (lower_bound),
+ upper_bound (upper_bound)
{}
if (!has_only_whitespace (str))
return false;
- // check whether valid bounds
- // were specified, and if so
- // enforce their values
+ // check whether valid bounds
+ // were specified, and if so
+ // enforce their values
if (lower_bound <= upper_bound)
return ((lower_bound <= i) &&
- (upper_bound >= i));
+ (upper_bound >= i));
else
return true;
}
std::string Integer::description () const
{
- // check whether valid bounds
- // were specified, and if so
- // output their values
+ // check whether valid bounds
+ // were specified, and if so
+ // output their values
if (lower_bound <= upper_bound)
{
- std::ostringstream description;
+ std::ostringstream description;
- description << description_init
- <<" range "
- << lower_bound << "..." << upper_bound
- << " (inclusive)]";
- return description.str();
+ description << description_init
+ <<" range "
+ << lower_bound << "..." << upper_bound
+ << " (inclusive)]";
+ return description.str();
}
else
- // if no bounds were given, then
- // return generic string
+ // if no bounds were given, then
+ // return generic string
return "[Integer]";
}
const char* Double::description_init = "[Double";
Double::Double (const double lower_bound,
- const double upper_bound)
+ const double upper_bound)
:
- lower_bound (lower_bound),
- upper_bound (upper_bound)
+ lower_bound (lower_bound),
+ upper_bound (upper_bound)
{}
if (!has_only_whitespace (str))
return false;
- // check whether valid bounds
- // were specified, and if so
- // enforce their values
+ // check whether valid bounds
+ // were specified, and if so
+ // enforce their values
if (lower_bound <= upper_bound)
return ((lower_bound <= d) &&
- (upper_bound >= d));
+ (upper_bound >= d));
else
return true;
}
std::string Double::description () const
{
- std::ostringstream description;
+ std::ostringstream description;
- // check whether valid bounds
- // were specified, and if so
- // output their values
+ // check whether valid bounds
+ // were specified, and if so
+ // output their values
if (lower_bound <= upper_bound)
{
- description << description_init
- << " "
- << lower_bound << "..." << upper_bound
- << " (inclusive)]";
- return description.str();
+ description << description_init
+ << " "
+ << lower_bound << "..." << upper_bound
+ << " (inclusive)]";
+ return description.str();
}
else
- // if no bounds were given, then
- // return generic string
+ // if no bounds were given, then
+ // return generic string
{
- description << description_init
- << "]";
- return description.str();
+ description << description_init
+ << "]";
+ return description.str();
}
}
{
std::vector<std::string> choices;
std::string tmp(sequence);
- // check the different possibilities
+ // check the different possibilities
while (tmp.find('|') != std::string::npos)
{
- if (test_string == std::string(tmp, 0, tmp.find('|')))
- return true;
+ if (test_string == std::string(tmp, 0, tmp.find('|')))
+ return true;
- tmp.erase (0, tmp.find('|')+1);
+ tmp.erase (0, tmp.find('|')+1);
};
- // check last choice, not finished by |
+ // check last choice, not finished by |
if (test_string == tmp)
return true;
- // not found
+ // not found
return false;
}
Selection::memory_consumption () const
{
return (sizeof(PatternBase) +
- MemoryConsumption::memory_consumption(sequence));
+ MemoryConsumption::memory_consumption(sequence));
}
std::vector<std::string> split_list;
split_list.reserve (std::count (tmp.begin(), tmp.end(), ',')+1);
- // first split the input list
+ // first split the input list
while (tmp.length() != 0)
{
std::string name;
- name = tmp;
+ name = tmp;
- if (name.find(",") != std::string::npos)
- {
- name.erase (name.find(","), std::string::npos);
- tmp.erase (0, tmp.find(",")+1);
- }
- else
- tmp = "";
+ if (name.find(",") != std::string::npos)
+ {
+ name.erase (name.find(","), std::string::npos);
+ tmp.erase (0, tmp.find(",")+1);
+ }
+ else
+ tmp = "";
- while ((name.length() != 0) &&
- (std::isspace (name[0])))
- name.erase (0,1);
+ while ((name.length() != 0) &&
+ (std::isspace (name[0])))
+ name.erase (0,1);
- while (std::isspace (name[name.length()-1]))
- name.erase (name.length()-1, 1);
+ while (std::isspace (name[name.length()-1]))
+ name.erase (name.length()-1, 1);
- split_list.push_back (name);
+ split_list.push_back (name);
};
if ((split_list.size() < min_elements) ||
(split_list.size() > max_elements))
return false;
- // check the different possibilities
+ // check the different possibilities
for (std::vector<std::string>::const_iterator
test_string = split_list.begin();
- test_string != split_list.end(); ++test_string)
+ test_string != split_list.end(); ++test_string)
if (pattern->match (*test_string) == false)
return false;
List::memory_consumption () const
{
return (sizeof(PatternBase) +
- MemoryConsumption::memory_consumption(*pattern));
+ MemoryConsumption::memory_consumption(*pattern));
}
std::string tmp = test_string_list;
std::list<std::string> split_list;
- // first split the input list
+ // first split the input list
while (tmp.length() != 0)
{
- std::string name;
- name = tmp;
-
- if (name.find(",") != std::string::npos)
- {
- name.erase (name.find(","), std::string::npos);
- tmp.erase (0, tmp.find(",")+1);
- }
- else
- tmp = "";
-
- while ((name.length() != 0) &&
- (std::isspace (name[0])))
- name.erase (0,1);
- while (std::isspace (name[name.length()-1]))
- name.erase (name.length()-1, 1);
-
- split_list.push_back (name);
+ std::string name;
+ name = tmp;
+
+ if (name.find(",") != std::string::npos)
+ {
+ name.erase (name.find(","), std::string::npos);
+ tmp.erase (0, tmp.find(",")+1);
+ }
+ else
+ tmp = "";
+
+ while ((name.length() != 0) &&
+ (std::isspace (name[0])))
+ name.erase (0,1);
+ while (std::isspace (name[name.length()-1]))
+ name.erase (name.length()-1, 1);
+
+ split_list.push_back (name);
};
- // check the different possibilities
+ // check the different possibilities
for (std::list<std::string>::const_iterator test_string = split_list.begin();
- test_string != split_list.end(); ++test_string)
+ test_string != split_list.end(); ++test_string)
{
- bool string_found = false;
-
- tmp = sequence;
- while (tmp.find('|') != std::string::npos)
- {
- if (*test_string == std::string(tmp, 0, tmp.find('|')))
- {
- // string found, quit
- // loop. don't change
- // tmp, since we don't
- // need it anymore.
- string_found = true;
- break;
- };
-
- tmp.erase (0, tmp.find('|')+1);
- };
- // check last choice, not finished by |
- if (!string_found)
- if (*test_string == tmp)
- string_found = true;
-
- if (!string_found)
- return false;
+ bool string_found = false;
+
+ tmp = sequence;
+ while (tmp.find('|') != std::string::npos)
+ {
+ if (*test_string == std::string(tmp, 0, tmp.find('|')))
+ {
+ // string found, quit
+ // loop. don't change
+ // tmp, since we don't
+ // need it anymore.
+ string_found = true;
+ break;
+ };
+
+ tmp.erase (0, tmp.find('|')+1);
+ };
+ // check last choice, not finished by |
+ if (!string_found)
+ if (*test_string == tmp)
+ string_found = true;
+
+ if (!string_found)
+ return false;
};
return true;
MultipleSelection::memory_consumption () const
{
return (sizeof(PatternBase) +
- MemoryConsumption::memory_consumption(sequence));
+ MemoryConsumption::memory_consumption(sequence));
}
Bool::Bool ()
:
- Selection ("true|false")
+ Selection ("true|false")
{}
ParameterHandler::ParameterHandler ()
- :
- entries (new boost::property_tree::ptree())
+ :
+ entries (new boost::property_tree::ptree())
{}
static const std::string allowed_characters
("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789");
- // for all parts of the string, see
- // if it is an allowed character or
- // not
+ // for all parts of the string, see
+ // if it is an allowed character or
+ // not
for (unsigned int i=0; i<s.size(); ++i)
if (allowed_characters.find (s[i]) != std::string::npos)
u.push_back (s[i]);
else
{
- u.push_back ('_');
- static const char hex[16]
- = { '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
- u.push_back (hex[static_cast<unsigned char>(s[i])/16]);
- u.push_back (hex[static_cast<unsigned char>(s[i])%16]);
+ u.push_back ('_');
+ static const char hex[16]
+ = { '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
+ u.push_back (hex[static_cast<unsigned char>(s[i])/16]);
+ u.push_back (hex[static_cast<unsigned char>(s[i])%16]);
}
return u;
u.push_back (s[i]);
else
{
- Assert (i+2 < s.size(),
- ExcMessage ("Trying to demangle an invalid string."));
-
- unsigned char c = 0;
- switch (s[i+1])
- {
- case '0': c = 0 * 16; break;
- case '1': c = 1 * 16; break;
- case '2': c = 2 * 16; break;
- case '3': c = 3 * 16; break;
- case '4': c = 4 * 16; break;
- case '5': c = 5 * 16; break;
- case '6': c = 6 * 16; break;
- case '7': c = 7 * 16; break;
- case '8': c = 8 * 16; break;
- case '9': c = 9 * 16; break;
- case 'a': c = 10 * 16; break;
- case 'b': c = 11 * 16; break;
- case 'c': c = 12 * 16; break;
- case 'd': c = 13 * 16; break;
- case 'e': c = 14 * 16; break;
- case 'f': c = 15 * 16; break;
- default:
- Assert (false, ExcInternalError());
- }
- switch (s[i+2])
- {
- case '0': c += 0; break;
- case '1': c += 1; break;
- case '2': c += 2; break;
- case '3': c += 3; break;
- case '4': c += 4; break;
- case '5': c += 5; break;
- case '6': c += 6; break;
- case '7': c += 7; break;
- case '8': c += 8; break;
- case '9': c += 9; break;
- case 'a': c += 10; break;
- case 'b': c += 11; break;
- case 'c': c += 12; break;
- case 'd': c += 13; break;
- case 'e': c += 14; break;
- case 'f': c += 15; break;
- default:
- Assert (false, ExcInternalError());
- }
-
- u.push_back (static_cast<char>(c));
-
- // skip the two characters
- i += 2;
+ Assert (i+2 < s.size(),
+ ExcMessage ("Trying to demangle an invalid string."));
+
+ unsigned char c = 0;
+ switch (s[i+1])
+ {
+ case '0': c = 0 * 16; break;
+ case '1': c = 1 * 16; break;
+ case '2': c = 2 * 16; break;
+ case '3': c = 3 * 16; break;
+ case '4': c = 4 * 16; break;
+ case '5': c = 5 * 16; break;
+ case '6': c = 6 * 16; break;
+ case '7': c = 7 * 16; break;
+ case '8': c = 8 * 16; break;
+ case '9': c = 9 * 16; break;
+ case 'a': c = 10 * 16; break;
+ case 'b': c = 11 * 16; break;
+ case 'c': c = 12 * 16; break;
+ case 'd': c = 13 * 16; break;
+ case 'e': c = 14 * 16; break;
+ case 'f': c = 15 * 16; break;
+ default:
+ Assert (false, ExcInternalError());
+ }
+ switch (s[i+2])
+ {
+ case '0': c += 0; break;
+ case '1': c += 1; break;
+ case '2': c += 2; break;
+ case '3': c += 3; break;
+ case '4': c += 4; break;
+ case '5': c += 5; break;
+ case '6': c += 6; break;
+ case '7': c += 7; break;
+ case '8': c += 8; break;
+ case '9': c += 9; break;
+ case 'a': c += 10; break;
+ case 'b': c += 11; break;
+ case 'c': c += 12; break;
+ case 'd': c += 13; break;
+ case 'e': c += 14; break;
+ case 'f': c += 15; break;
+ default:
+ Assert (false, ExcInternalError());
+ }
+
+ u.push_back (static_cast<char>(c));
+
+ // skip the two characters
+ i += 2;
}
return u;
{
std::string p = mangle(subsection_path[0]);
for (unsigned int i=1; i<subsection_path.size(); ++i)
- {
- p += path_separator;
- p += mangle(subsection_path[i]);
- }
+ {
+ p += path_separator;
+ p += mangle(subsection_path[i]);
+ }
return p;
}
else
++lineno;
getline (input, line);
if (!scan_line (line, lineno))
- status = false;
+ status = false;
}
return status;
bool ParameterHandler::read_input (const std::string &filename,
- const bool optional,
- const bool write_compact)
+ const bool optional,
+ const bool write_compact)
{
PathSearch search("PARAMETERS");
catch (const PathSearch::ExcFileNotFound&)
{
std::cerr << "ParameterHandler::read_input: could not open file <"
- << filename << "> for reading." << std::endl;
+ << filename << "> for reading." << std::endl;
if (!optional)
- {
- std:: cerr << "Trying to make file <"
- << filename << "> with default values for you." << std::endl;
- std::ofstream output (filename.c_str());
- if (output)
- print_parameters (output, (write_compact ? ShortText : Text));
- }
+ {
+ std:: cerr << "Trying to make file <"
+ << filename << "> with default values for you." << std::endl;
+ std::ofstream output (filename.c_str());
+ if (output)
+ print_parameters (output, (write_compact ? ShortText : Text));
+ }
}
return false;
}
bool ParameterHandler::read_input_from_string (const char *s)
{
- // if empty std::string then exit
- // with success
+ // if empty std::string then exit
+ // with success
if ((s == 0) || ((*s) == 0)) return true;
std::string line;
std::string input (s);
int lineno=0;
- // if necessary append a newline char
- // to make all lines equal
+ // if necessary append a newline char
+ // to make all lines equal
if (input[input.length()-1] != '\n')
input += '\n';
bool status = true;
while (input.size() != 0)
{
- // get one line from Input (=s)
+ // get one line from Input (=s)
line.assign (input, 0, input.find('\n'));
- // delete this part including
- // the backspace
+ // delete this part including
+ // the backspace
input.erase (0, input.find('\n')+1);
++lineno;
if (!scan_line (line, lineno))
- status = false;
+ status = false;
}
return status;
namespace
{
- // Recursively go through the 'source' tree
- // and see if we can find corresponding
- // entries in the 'destination' tree. If
- // not, error out (i.e. we have just read
- // an XML file that has entries that
- // weren't declared in the ParameterHandler
- // object); if so, copy the value of these
- // nodes into the destination object
+ // Recursively go through the 'source' tree
+ // and see if we can find corresponding
+ // entries in the 'destination' tree. If
+ // not, error out (i.e. we have just read
+ // an XML file that has entries that
+ // weren't declared in the ParameterHandler
+ // object); if so, copy the value of these
+ // nodes into the destination object
bool
read_xml_recursively (const boost::property_tree::ptree &source,
- const std::string ¤t_path,
- const char path_separator,
- const std::vector<std_cxx1x::shared_ptr<const Patterns::PatternBase> > &
- patterns,
- boost::property_tree::ptree &destination)
+ const std::string ¤t_path,
+ const char path_separator,
+ const std::vector<std_cxx1x::shared_ptr<const Patterns::PatternBase> > &
+ patterns,
+ boost::property_tree::ptree &destination)
{
for (boost::property_tree::ptree::const_iterator p = source.begin();
- p != source.end(); ++p)
+ p != source.end(); ++p)
{
- // a sub-tree must either be a
- // parameter node or a subsection
- if (p->second.get_optional<std::string>("value"))
- {
- // make sure we have a
- // corresponding entry in the
- // destination object as well
- const std::string full_path
- = (current_path == ""
- ?
- p->first
- :
- current_path + path_separator + p->first);
- if (destination.get_optional<std::string> (full_path)
- &&
- destination.get_optional<std::string> (full_path +
- path_separator +
- "value"))
- {
- // first make sure that the
- // new entry actually
- // satisfies its constraints
- const std::string new_value
- = p->second.get<std::string>("value");
-
- const unsigned int pattern_index
- = destination.get<unsigned int> (full_path +
- path_separator +
- "pattern");
- if (patterns[pattern_index]->match(new_value) == false)
- {
- std::cerr << " The entry value" << std::endl
- << " " << new_value << std::endl
- << " for the entry named" << std::endl
- << " " << full_path << std::endl
- << " does not match the given pattern" << std::endl
- << " " << patterns[pattern_index]->description()
- << std::endl;
- return false;
- }
-
- // set the found parameter in
- // the destination argument
- destination.put (full_path + path_separator + "value",
- new_value);
-
- // this node might have
- // sub-nodes in addition to
- // "value", such as
- // "default_value",
- // "documentation", etc. we
- // might at some point in the
- // future want to make sure
- // that if they exist that
- // they match the ones in the
- // 'destination' tree
- }
- else
- {
- std::cerr << "The entry <" << full_path
- << "> with value <"
- << p->second.get<std::string>("value")
- << "> has not been declared."
- << std::endl;
- return false;
- }
- }
- else
- {
- // it must be a subsection
- const bool result
- = read_xml_recursively (p->second,
- (current_path == "" ?
- p->first :
- current_path + path_separator + p->first),
- path_separator,
- patterns,
- destination);
-
- // see if the recursive read
- // succeeded. if yes, continue,
- // otherwise exit now
- if (result == false)
- return false;
- }
+ // a sub-tree must either be a
+ // parameter node or a subsection
+ if (p->second.get_optional<std::string>("value"))
+ {
+ // make sure we have a
+ // corresponding entry in the
+ // destination object as well
+ const std::string full_path
+ = (current_path == ""
+ ?
+ p->first
+ :
+ current_path + path_separator + p->first);
+ if (destination.get_optional<std::string> (full_path)
+ &&
+ destination.get_optional<std::string> (full_path +
+ path_separator +
+ "value"))
+ {
+ // first make sure that the
+ // new entry actually
+ // satisfies its constraints
+ const std::string new_value
+ = p->second.get<std::string>("value");
+
+ const unsigned int pattern_index
+ = destination.get<unsigned int> (full_path +
+ path_separator +
+ "pattern");
+ if (patterns[pattern_index]->match(new_value) == false)
+ {
+ std::cerr << " The entry value" << std::endl
+ << " " << new_value << std::endl
+ << " for the entry named" << std::endl
+ << " " << full_path << std::endl
+ << " does not match the given pattern" << std::endl
+ << " " << patterns[pattern_index]->description()
+ << std::endl;
+ return false;
+ }
+
+ // set the found parameter in
+ // the destination argument
+ destination.put (full_path + path_separator + "value",
+ new_value);
+
+ // this node might have
+ // sub-nodes in addition to
+ // "value", such as
+ // "default_value",
+ // "documentation", etc. we
+ // might at some point in the
+ // future want to make sure
+ // that if they exist that
+ // they match the ones in the
+ // 'destination' tree
+ }
+ else
+ {
+ std::cerr << "The entry <" << full_path
+ << "> with value <"
+ << p->second.get<std::string>("value")
+ << "> has not been declared."
+ << std::endl;
+ return false;
+ }
+ }
+ else
+ {
+ // it must be a subsection
+ const bool result
+ = read_xml_recursively (p->second,
+ (current_path == "" ?
+ p->first :
+ current_path + path_separator + p->first),
+ path_separator,
+ patterns,
+ destination);
+
+ // see if the recursive read
+ // succeeded. if yes, continue,
+ // otherwise exit now
+ if (result == false)
+ return false;
+ }
}
return true;
bool ParameterHandler::read_input_from_xml (std::istream &in)
{
- // read the XML tree assuming that (as we
- // do in print_parameters(XML) it has only
- // a single top-level node called
- // "ParameterHandler"
+ // read the XML tree assuming that (as we
+ // do in print_parameters(XML) it has only
+ // a single top-level node called
+ // "ParameterHandler"
boost::property_tree::ptree single_node_tree;
try
{
catch (...)
{
std::cerr << "This input stream appears not to be valid XML"
- << std::endl;
+ << std::endl;
return false;
}
- // make sure there is a top-level element
- // called "ParameterHandler"
+ // make sure there is a top-level element
+ // called "ParameterHandler"
if (!single_node_tree.get_optional<std::string>("ParameterHandler"))
{
std::cerr << "There is no top-level XML element called \"ParameterHandler\"."
- << std::endl;
+ << std::endl;
return false;
}
- // ensure that there is only a single
- // top-level element
+ // ensure that there is only a single
+ // top-level element
if (std::distance (single_node_tree.begin(), single_node_tree.end()) != 1)
{
std::cerr << "The top-level XML element \"ParameterHandler\" is "
- << "not the only one."
- << std::endl;
+ << "not the only one."
+ << std::endl;
std::cerr << "(There are "
- << std::distance (single_node_tree.begin(),
- single_node_tree.end())
- << " top-level elements.)"
- << std::endl;
+ << std::distance (single_node_tree.begin(),
+ single_node_tree.end())
+ << " top-level elements.)"
+ << std::endl;
return false;
}
- // read the child elements recursively
+ // read the child elements recursively
const boost::property_tree::ptree
&my_entries = single_node_tree.get_child("ParameterHandler");
return read_xml_recursively (my_entries, "", path_separator, patterns,
- *entries);
+ *entries);
}
const std::string &documentation)
{
entries->put (get_current_full_path(entry) + path_separator + "value",
- default_value);
+ default_value);
entries->put (get_current_full_path(entry) + path_separator + "default_value",
- default_value);
+ default_value);
entries->put (get_current_full_path(entry) + path_separator + "documentation",
- documentation);
+ documentation);
- // clone the pattern and store its
- // index in the node
+ // clone the pattern and store its
+ // index in the node
patterns.push_back (std_cxx1x::shared_ptr<const Patterns::PatternBase>
- (pattern.clone()));
+ (pattern.clone()));
entries->put (get_current_full_path(entry) + path_separator + "pattern",
- static_cast<unsigned int>(patterns.size()-1));
- // also store the description of
- // the pattern. we do so because we
- // may wish to export the whole
- // thing as XML or any other format
- // so that external tools can work
- // on the parameter file; in that
- // case, they will have to be able
- // to re-create the patterns as far
- // as possible
+ static_cast<unsigned int>(patterns.size()-1));
+ // also store the description of
+ // the pattern. we do so because we
+ // may wish to export the whole
+ // thing as XML or any other format
+ // so that external tools can work
+ // on the parameter file; in that
+ // case, they will have to be able
+ // to re-create the patterns as far
+ // as possible
entries->put (get_current_full_path(entry) + path_separator +
- "pattern_description",
- patterns.back()->description());
+ "pattern_description",
+ patterns.back()->description());
}
{
const std::string current_path = get_current_path ();
- // if necessary create subsection
+ // if necessary create subsection
if (!entries->get_child_optional (get_current_full_path(subsection)))
entries->add_child (get_current_full_path(subsection),
- boost::property_tree::ptree());
+ boost::property_tree::ptree());
- // then enter it
+ // then enter it
subsection_path.push_back (subsection);
}
bool ParameterHandler::leave_subsection ()
{
- // assert there is a subsection that
- // we may leave
- // (use assert since this is a logical
- // error in a program. When reading input
- // the scan_line function has to check
- // whether there is a subsection to be left!)
+ // assert there is a subsection that
+ // we may leave
+ // (use assert since this is a logical
+ // error in a program. When reading input
+ // the scan_line function has to check
+ // whether there is a subsection to be left!)
Assert (subsection_path.size() != 0, ExcAlreadyAtTopLevel());
if (subsection_path.size() == 0)
std::string
ParameterHandler::get (const std::string &entry_string) const
{
- // assert that the entry is indeed
- // declared
+ // assert that the entry is indeed
+ // declared
if (boost::optional<std::string> value
= entries->get_optional<std::string> (get_current_full_path(entry_string) + path_separator + "value"))
return value.get();
std::string s = get (entry_string);
char *endptr;
long int i = std::strtol (s.c_str(), &endptr, 10);
- // assert there was no error
+ // assert there was no error
AssertThrow (*endptr == '\0', ExcConversionError(s));
return i;
std::string s = get (entry_string);
char *endptr;
double d = std::strtod (s.c_str(), &endptr);
- // assert there was no error
+ // assert there was no error
AssertThrow ((s.c_str()!='\0') || (*endptr == '\0'),
- ExcConversionError(s));
+ ExcConversionError(s));
return d;
}
ParameterHandler::set (const std::string &entry_string,
const std::string &new_value)
{
- // assert that the entry is indeed
- // declared
+ // assert that the entry is indeed
+ // declared
if (entries->get_optional<std::string>
(get_current_full_path(entry_string) + path_separator + "value"))
{
const unsigned int pattern_index
- = entries->get<unsigned int> (get_current_full_path(entry_string) + path_separator + "pattern");
+ = entries->get<unsigned int> (get_current_full_path(entry_string) + path_separator + "pattern");
AssertThrow (patterns[pattern_index]->match(new_value),
- ExcValueDoesNotMatchPattern (new_value,
- entries->get<std::string>
- (get_current_full_path(entry_string) +
- path_separator +
- "pattern_description")));
+ ExcValueDoesNotMatchPattern (new_value,
+ entries->get<std::string>
+ (get_current_full_path(entry_string) +
+ path_separator +
+ "pattern_description")));
entries->put (get_current_full_path(entry_string) + path_separator + "value",
- new_value);
+ new_value);
}
else
AssertThrow (false, ExcEntryUndeclared(entry_string));
{
case XML:
{
- // call the writer
- // function and exit as
- // there is nothing
- // further to do down in
- // this function
- //
- // XML has a requirement that
- // there can only be one
- // single top-level entry,
- // but we may have multiple
- // entries and sections. we
- // work around this by
- // creating a tree just for
- // this purpose with the
- // single top-level node
- // "ParameterHandler" and
- // assign the existing tree
- // under it
- boost::property_tree::ptree single_node_tree;
- single_node_tree.add_child("ParameterHandler",
- *entries);
-
- write_xml (out, single_node_tree);
- return out;
+ // call the writer
+ // function and exit as
+ // there is nothing
+ // further to do down in
+ // this function
+ //
+ // XML has a requirement that
+ // there can only be one
+ // single top-level entry,
+ // but we may have multiple
+ // entries and sections. we
+ // work around this by
+ // creating a tree just for
+ // this purpose with the
+ // single top-level node
+ // "ParameterHandler" and
+ // assign the existing tree
+ // under it
+ boost::property_tree::ptree single_node_tree;
+ single_node_tree.add_child("ParameterHandler",
+ *entries);
+
+ write_xml (out, single_node_tree);
+ return out;
}
case JSON:
- // call the writer
- // function and exit as
- // there is nothing
- // further to do down in
- // this function
- write_json (out, *entries);
- return out;
+ // call the writer
+ // function and exit as
+ // there is nothing
+ // further to do down in
+ // this function
+ write_json (out, *entries);
+ return out;
case Text:
- out << "# Listing of Parameters" << std::endl
- << "# ---------------------" << std::endl;
- break;
+ out << "# Listing of Parameters" << std::endl
+ << "# ---------------------" << std::endl;
+ break;
case LaTeX:
- out << "\\subsection{Global parameters}" << std::endl;
- out << "\\label{parameters:global}" << std::endl;
- out << std::endl << std::endl;
- break;
+ out << "\\subsection{Global parameters}" << std::endl;
+ out << "\\label{parameters:global}" << std::endl;
+ out << std::endl << std::endl;
+ break;
case Description:
- out << "Listing of Parameters:" << std::endl << std::endl;
- break;
+ out << "Listing of Parameters:" << std::endl << std::endl;
+ break;
case ShortText:
- break;
+ break;
default:
- Assert (false, ExcNotImplemented());
+ Assert (false, ExcNotImplemented());
};
- // dive recursively into the subsections
+ // dive recursively into the subsections
print_parameters_section (out, style, 0);
switch (style)
case Text:
case Description:
case ShortText:
- break;
+ break;
case LaTeX:
- break;
+ break;
default:
- Assert (false, ExcNotImplemented());
+ Assert (false, ExcNotImplemented());
};
return out;
case Text:
case ShortText:
{
- // first find out the longest
- // entry name to be able to
- // align the equal signs
- //
- // to do this loop over all
- // nodes of the current tree,
- // select the parameter nodes
- // (and discard sub-tree
- // nodes) and take the
- // maximum of their lengths
+ // first find out the longest
+ // entry name to be able to
+ // align the equal signs
+ //
+ // to do this loop over all
+ // nodes of the current tree,
+ // select the parameter nodes
+ // (and discard sub-tree
+ // nodes) and take the
+ // maximum of their lengths
std::size_t longest_name = 0;
- for (boost::property_tree::ptree::const_iterator
- p = current_section.begin();
- p != current_section.end(); ++p)
- if (is_parameter_node (p->second) == true)
- longest_name = std::max (longest_name,
- demangle(p->first).length());
+ for (boost::property_tree::ptree::const_iterator
+ p = current_section.begin();
+ p != current_section.end(); ++p)
+ if (is_parameter_node (p->second) == true)
+ longest_name = std::max (longest_name,
+ demangle(p->first).length());
// likewise find the longest
// actual value string to
// default and documentation
// strings
std::size_t longest_value = 0;
- for (boost::property_tree::ptree::const_iterator
- p = current_section.begin();
- p != current_section.end(); ++p)
- if (is_parameter_node (p->second) == true)
- longest_value = std::max (longest_value,
- p->second.get<std::string>("value").length());
-
-
- // print entries one by
- // one. make sure they are
- // sorted by using the
- // appropriate iterators
- bool first_entry = true;
- for (boost::property_tree::ptree::const_assoc_iterator
- p = current_section.ordered_begin();
- p != current_section.not_found(); ++p)
- if (is_parameter_node (p->second) == true)
- {
- const std::string value = p->second.get<std::string>("value");
-
- // if there is documentation,
- // then add an empty line (unless
- // this is the first entry in a
- // subsection), print the
- // documentation, and then the
- // actual entry; break the
- // documentation into readable
- // chunks such that the whole
- // thing is at most 78 characters
- // wide
- if ((!(style & 128)) &&
- !p->second.get<std::string>("documentation").empty())
- {
- if (first_entry == false)
- out << std::endl;
- else
- first_entry = false;
-
- const std::vector<std::string> doc_lines
- = Utilities::
- break_text_into_lines (p->second.get<std::string>("documentation"),
- 78 - indent_level*2 - 2);
-
- for (unsigned int i=0; i<doc_lines.size(); ++i)
- out << std::setw(indent_level*2) << ""
- << "# "
- << doc_lines[i]
- << std::endl;
- }
-
-
-
- // print name and value
- // of this entry
- out << std::setw(indent_level*2) << ""
- << "set "
- << demangle(p->first)
- << std::setw(longest_name-demangle(p->first).length()+1) << " "
- << "= " << value;
-
- // finally print the
- // default value, but
- // only if it differs
- // from the actual value
- if ((!(style & 64)) && value != p->second.get<std::string>("default_value"))
- {
- out << std::setw(longest_value-value.length()+1) << ' '
- << "# ";
- out << "default: " << p->second.get<std::string>("default_value");
- }
-
- out << std::endl;
- }
+ for (boost::property_tree::ptree::const_iterator
+ p = current_section.begin();
+ p != current_section.end(); ++p)
+ if (is_parameter_node (p->second) == true)
+ longest_value = std::max (longest_value,
+ p->second.get<std::string>("value").length());
+
+
+ // print entries one by
+ // one. make sure they are
+ // sorted by using the
+ // appropriate iterators
+ bool first_entry = true;
+ for (boost::property_tree::ptree::const_assoc_iterator
+ p = current_section.ordered_begin();
+ p != current_section.not_found(); ++p)
+ if (is_parameter_node (p->second) == true)
+ {
+ const std::string value = p->second.get<std::string>("value");
+
+ // if there is documentation,
+ // then add an empty line (unless
+ // this is the first entry in a
+ // subsection), print the
+ // documentation, and then the
+ // actual entry; break the
+ // documentation into readable
+ // chunks such that the whole
+ // thing is at most 78 characters
+ // wide
+ if ((!(style & 128)) &&
+ !p->second.get<std::string>("documentation").empty())
+ {
+ if (first_entry == false)
+ out << std::endl;
+ else
+ first_entry = false;
+
+ const std::vector<std::string> doc_lines
+ = Utilities::
+ break_text_into_lines (p->second.get<std::string>("documentation"),
+ 78 - indent_level*2 - 2);
+
+ for (unsigned int i=0; i<doc_lines.size(); ++i)
+ out << std::setw(indent_level*2) << ""
+ << "# "
+ << doc_lines[i]
+ << std::endl;
+ }
+
+
+
+ // print name and value
+ // of this entry
+ out << std::setw(indent_level*2) << ""
+ << "set "
+ << demangle(p->first)
+ << std::setw(longest_name-demangle(p->first).length()+1) << " "
+ << "= " << value;
+
+ // finally print the
+ // default value, but
+ // only if it differs
+ // from the actual value
+ if ((!(style & 64)) && value != p->second.get<std::string>("default_value"))
+ {
+ out << std::setw(longest_value-value.length()+1) << ' '
+ << "# ";
+ out << "default: " << p->second.get<std::string>("default_value");
+ }
+
+ out << std::endl;
+ }
break;
}
case LaTeX:
{
- out << "\\begin{itemize}"
- << std::endl;
-
- // print entries one by
- // one. make sure they are
- // sorted by using the
- // appropriate iterators
- for (boost::property_tree::ptree::const_assoc_iterator
- p = current_section.ordered_begin();
- p != current_section.not_found(); ++p)
- if (is_parameter_node (p->second) == true)
- {
- const std::string value = p->second.get<std::string>("value");
-
- // print name and value
- out << "\\item {\\it Parameter name:} {\\tt " << demangle(p->first) << "}\n\n"
- << std::endl
- << "{\\it Value:} " << value << "\n\n"
- << std::endl
- << "{\\it Default:} "
- << p->second.get<std::string>("default_value") << "\n\n"
- << std::endl;
-
- // if there is a
- // documenting string,
- // print it as well
- if (!p->second.get<std::string>("documentation").empty())
- out << "{\\it Description:} "
- << p->second.get<std::string>("documentation") << "\n\n"
- << std::endl;
-
- // also output possible values
- out << "{\\it Possible values:} "
- << p->second.get<std::string> ("pattern_description")
- << std::endl;
- }
- out << "\\end{itemize}" << std::endl;
+ out << "\\begin{itemize}"
+ << std::endl;
+
+ // print entries one by
+ // one. make sure they are
+ // sorted by using the
+ // appropriate iterators
+ for (boost::property_tree::ptree::const_assoc_iterator
+ p = current_section.ordered_begin();
+ p != current_section.not_found(); ++p)
+ if (is_parameter_node (p->second) == true)
+ {
+ const std::string value = p->second.get<std::string>("value");
+
+ // print name and value
+ out << "\\item {\\it Parameter name:} {\\tt " << demangle(p->first) << "}\n\n"
+ << std::endl
+ << "{\\it Value:} " << value << "\n\n"
+ << std::endl
+ << "{\\it Default:} "
+ << p->second.get<std::string>("default_value") << "\n\n"
+ << std::endl;
+
+ // if there is a
+ // documenting string,
+ // print it as well
+ if (!p->second.get<std::string>("documentation").empty())
+ out << "{\\it Description:} "
+ << p->second.get<std::string>("documentation") << "\n\n"
+ << std::endl;
+
+ // also output possible values
+ out << "{\\it Possible values:} "
+ << p->second.get<std::string> ("pattern_description")
+ << std::endl;
+ }
+ out << "\\end{itemize}" << std::endl;
break;
}
case Description:
{
- // first find out the longest
- // entry name to be able to
- // align the equal signs
+ // first find out the longest
+ // entry name to be able to
+ // align the equal signs
std::size_t longest_name = 0;
- for (boost::property_tree::ptree::const_iterator
- p = current_section.begin();
- p != current_section.end(); ++p)
- if (is_parameter_node (p->second) == true)
- longest_name = std::max (longest_name,
- demangle(p->first).length());
-
- // print entries one by
- // one. make sure they are
- // sorted by using the
- // appropriate iterators
- for (boost::property_tree::ptree::const_assoc_iterator
- p = current_section.ordered_begin();
- p != current_section.not_found(); ++p)
- if (is_parameter_node (p->second) == true)
- {
- const std::string value = p->second.get<std::string>("value");
-
- // print name and value
- out << std::setw(indent_level*2) << ""
- << "set "
- << demangle(p->first)
- << std::setw(longest_name-demangle(p->first).length()+1) << " "
- << " = ";
-
- // print possible values:
- const std::vector<std::string> description_str
- = Utilities::break_text_into_lines (p->second.get<std::string>
- ("pattern_description"),
- 78 - indent_level*2 - 2, '|');
- if (description_str.size() > 1)
- {
- out << std::endl;
- for (unsigned int i=0; i<description_str.size(); ++i)
- out << std::setw(indent_level*2+6) << ""
- << description_str[i] << std::endl;
- }
- else if (description_str.empty() == false)
- out << " " << description_str[0] << std::endl;
- else
- out << std::endl;
-
- // if there is a
- // documenting string,
- // print it as well
- if (p->second.get<std::string>("documentation").length() != 0)
- out << std::setw(indent_level*2 + longest_name + 10) << ""
- << "(" << p->second.get<std::string>("documentation") << ")" << std::endl;
- }
+ for (boost::property_tree::ptree::const_iterator
+ p = current_section.begin();
+ p != current_section.end(); ++p)
+ if (is_parameter_node (p->second) == true)
+ longest_name = std::max (longest_name,
+ demangle(p->first).length());
+
+ // print entries one by
+ // one. make sure they are
+ // sorted by using the
+ // appropriate iterators
+ for (boost::property_tree::ptree::const_assoc_iterator
+ p = current_section.ordered_begin();
+ p != current_section.not_found(); ++p)
+ if (is_parameter_node (p->second) == true)
+ {
+ const std::string value = p->second.get<std::string>("value");
+
+ // print name and value
+ out << std::setw(indent_level*2) << ""
+ << "set "
+ << demangle(p->first)
+ << std::setw(longest_name-demangle(p->first).length()+1) << " "
+ << " = ";
+
+ // print possible values:
+ const std::vector<std::string> description_str
+ = Utilities::break_text_into_lines (p->second.get<std::string>
+ ("pattern_description"),
+ 78 - indent_level*2 - 2, '|');
+ if (description_str.size() > 1)
+ {
+ out << std::endl;
+ for (unsigned int i=0; i<description_str.size(); ++i)
+ out << std::setw(indent_level*2+6) << ""
+ << description_str[i] << std::endl;
+ }
+ else if (description_str.empty() == false)
+ out << " " << description_str[0] << std::endl;
+ else
+ out << std::endl;
+
+ // if there is a
+ // documenting string,
+ // print it as well
+ if (p->second.get<std::string>("documentation").length() != 0)
+ out << std::setw(indent_level*2 + longest_name + 10) << ""
+ << "(" << p->second.get<std::string>("documentation") << ")" << std::endl;
+ }
break;
}
}
- // if there was text before and there are
+ // if there was text before and there are
// sections to come, put two newlines
// between the last entry and the first
// subsection
unsigned int n_parameters = 0;
unsigned int n_sections = 0;
for (boost::property_tree::ptree::const_iterator
- p = current_section.begin();
- p != current_section.end(); ++p)
+ p = current_section.begin();
+ p != current_section.end(); ++p)
if (is_parameter_node (p->second) == true)
- ++n_parameters;
+ ++n_parameters;
else
- ++n_sections;
+ ++n_sections;
if ((style != Description)
- &&
- (!(style & 128))
- &&
- (n_parameters != 0)
- &&
- (n_sections != 0))
+ &&
+ (!(style & 128))
+ &&
+ (n_parameters != 0)
+ &&
+ (n_sections != 0))
out << std::endl << std::endl;
}
- // now traverse subsections tree,
- // in alphabetical order
+ // now traverse subsections tree,
+ // in alphabetical order
for (boost::property_tree::ptree::const_assoc_iterator
- p = current_section.ordered_begin();
+ p = current_section.ordered_begin();
p != current_section.not_found(); ++p)
if (is_parameter_node (p->second) == false)
{
switch (style)
{
case Text:
- case Description:
- case ShortText:
+ case Description:
+ case ShortText:
out << std::setw(indent_level*2) << ""
<< "subsection " << demangle(p->first) << std::endl;
break;
case LaTeX:
- {
- out << std::endl
- << "\\subsection{Parameters in section \\tt ";
-
- // find the path to the
- // current section so that we
- // can print it in the
- // \subsection{...} heading
- for (unsigned int i=0; i<subsection_path.size(); ++i)
- out << subsection_path[i] << "/";
- out << demangle(p->first);
-
- out << "}" << std::endl;
- out << "\\label{parameters:";
- for (unsigned int i=0; i<subsection_path.size(); ++i)
- out << mangle(subsection_path[i]) << "/";
- out << p->first << "}";
- out << std::endl;
-
- out << std::endl;
- break;
- }
+ {
+ out << std::endl
+ << "\\subsection{Parameters in section \\tt ";
+
+ // find the path to the
+ // current section so that we
+ // can print it in the
+ // \subsection{...} heading
+ for (unsigned int i=0; i<subsection_path.size(); ++i)
+ out << subsection_path[i] << "/";
+ out << demangle(p->first);
+
+ out << "}" << std::endl;
+ out << "\\label{parameters:";
+ for (unsigned int i=0; i<subsection_path.size(); ++i)
+ out << mangle(subsection_path[i]) << "/";
+ out << p->first << "}";
+ out << std::endl;
+
+ out << std::endl;
+ break;
+ }
default:
Assert (false, ExcNotImplemented());
leave_subsection ();
switch (style)
{
- case Text:
- // write end of
- // subsection. one
- // blank line after
- // each subsection
- out << std::setw(indent_level*2) << ""
- << "end" << std::endl
- << std::endl;
-
- // if this is a toplevel
- // subsection, then have two
- // newlines
- if (indent_level == 0)
- out << std::endl;
-
- break;
- case Description:
- break;
- case ShortText:
- // write end of
- // subsection.
- out << std::setw(indent_level*2) << ""
- << "end" << std::endl;
+ case Text:
+ // write end of
+ // subsection. one
+ // blank line after
+ // each subsection
+ out << std::setw(indent_level*2) << ""
+ << "end" << std::endl
+ << std::endl;
+
+ // if this is a toplevel
+ // subsection, then have two
+ // newlines
+ if (indent_level == 0)
+ out << std::endl;
+
+ break;
+ case Description:
+ break;
+ case ShortText:
+ // write end of
+ // subsection.
+ out << std::setw(indent_level*2) << ""
+ << "end" << std::endl;
break;
case LaTeX:
break;
ParameterHandler::log_parameters (LogStream &out)
{
out.push("parameters");
- // dive recursively into the
- // subsections
+ // dive recursively into the
+ // subsections
log_parameters_section (out);
out.pop();
const boost::property_tree::ptree ¤t_section
= entries->get_child (get_current_path());
- // print entries one by
- // one. make sure they are
- // sorted by using the
- // appropriate iterators
+ // print entries one by
+ // one. make sure they are
+ // sorted by using the
+ // appropriate iterators
for (boost::property_tree::ptree::const_assoc_iterator
- p = current_section.ordered_begin();
+ p = current_section.ordered_begin();
p != current_section.not_found(); ++p)
if (is_parameter_node (p->second) == true)
out << demangle(p->first) << ": "
<< p->second.get<std::string>("value") << std::endl;
- // now transverse subsections tree
- // now traverse subsections tree,
- // in alphabetical order
+ // now transverse subsections tree
+ // now traverse subsections tree,
+ // in alphabetical order
for (boost::property_tree::ptree::const_assoc_iterator
- p = current_section.ordered_begin();
+ p = current_section.ordered_begin();
p != current_section.not_found(); ++p)
if (is_parameter_node (p->second) == false)
{
- out.push (demangle(p->first));
+ out.push (demangle(p->first));
enter_subsection (demangle(p->first));
log_parameters_section (out);
leave_subsection ();
- out.pop ();
+ out.pop ();
}
}
ParameterHandler::scan_line (std::string line,
const unsigned int lineno)
{
- // if there is a comment, delete it
+ // if there is a comment, delete it
if (line.find('#') != std::string::npos)
line.erase (line.find("#"), std::string::npos);
- // replace every whitespace sequence
- // by " "
+ // replace every whitespace sequence
+ // by " "
while (line.find('\t') != std::string::npos)
line.replace (line.find('\t'), 1, " ");
while (line.find(" ") != std::string::npos)
line.erase (line.find(" "), 1);
- // now every existing whitespace
- // should be exactly one ' ';
- // if at end or beginning: delete
+ // now every existing whitespace
+ // should be exactly one ' ';
+ // if at end or beginning: delete
if ((line.length() != 0) && (std::isspace (line[0]))) line.erase (0, 1);
- // if line is now empty: leave
+ // if line is now empty: leave
if (line.length() == 0) return true;
if (std::isspace (line[line.length()-1]))
line.erase (line.size()-1, 1);
- // enter subsection
+ // enter subsection
if ((line.find ("SUBSECTION ") == 0) ||
(line.find ("subsection ") == 0))
{
- // delete this prefix
+ // delete this prefix
line.erase (0, std::string("subsection").length()+1);
const std::string subsection = line;
- // check whether subsection exists
+ // check whether subsection exists
if (!entries->get_child_optional (get_current_full_path(subsection)))
- {
- std::cerr << "Line " << lineno
+ {
+ std::cerr << "Line " << lineno
<< ": There is no such subsection to be entered: "
<< demangle(get_current_full_path(subsection)) << std::endl;
- for (unsigned int i=0; i<subsection_path.size(); ++i)
- std::cerr << std::setw(i*2+4) << " "
- << "subsection " << subsection_path[i] << std::endl;
- std::cerr << std::setw(subsection_path.size()*2+4) << " "
- << "subsection " << subsection << std::endl;
- return false;
- }
-
- // subsection exists
+ for (unsigned int i=0; i<subsection_path.size(); ++i)
+ std::cerr << std::setw(i*2+4) << " "
+ << "subsection " << subsection_path[i] << std::endl;
+ std::cerr << std::setw(subsection_path.size()*2+4) << " "
+ << "subsection " << subsection << std::endl;
+ return false;
+ }
+
+ // subsection exists
subsection_path.push_back (subsection);
return true;
}
- // exit subsection
+ // exit subsection
if ((line.find ("END") == 0) ||
(line.find ("end") == 0))
{
if (subsection_path.size() == 0)
- {
- std::cerr << "Line " << lineno
- << ": There is no subsection to leave here!" << std::endl;
- return false;
- }
+ {
+ std::cerr << "Line " << lineno
+ << ": There is no subsection to leave here!" << std::endl;
+ return false;
+ }
else
- return leave_subsection ();
+ return leave_subsection ();
}
- // regular entry
+ // regular entry
if ((line.find ("SET ") == 0) ||
(line.find ("set ") == 0))
{
- // erase "set" statement and eliminate
- // spaces around the '='
+ // erase "set" statement and eliminate
+ // spaces around the '='
line.erase (0, 4);
if (line.find(" =") != std::string::npos)
- line.replace (line.find(" ="), 2, "=");
+ line.replace (line.find(" ="), 2, "=");
if (line.find("= ") != std::string::npos)
- line.replace (line.find("= "), 2, "=");
+ line.replace (line.find("= "), 2, "=");
- // extract entry name and value
+ // extract entry name and value
std::string entry_name (line, 0, line.find('='));
std::string entry_value (line, line.find('=')+1, std::string::npos);
const std::string current_path = get_current_path ();
- // assert that the entry is indeed
- // declared
+ // assert that the entry is indeed
+ // declared
if (entries->get_optional<std::string> (get_current_full_path(entry_name) + path_separator + "value"))
- {
- // if entry was declared:
- // does it match the regex? if not,
- // don't enter it into the database
- // exception: if it contains characters
- // which specify it as a multiple loop
- // entry, then ignore content
- if (entry_value.find ('{') == std::string::npos)
- {
- const unsigned int pattern_index
- = entries->get<unsigned int> (get_current_full_path(entry_name) + path_separator + "pattern");
- if (!patterns[pattern_index]->match(entry_value))
- {
- std::cerr << "Line " << lineno << ":" << std::endl
- << " The entry value" << std::endl
- << " " << entry_value << std::endl
- << " for the entry named" << std::endl
- << " " << entry_name << std::endl
- << " does not match the given pattern" << std::endl
- << " " << patterns[pattern_index]->description()
- << std::endl;
- return false;
- }
- }
-
- entries->put (get_current_full_path(entry_name) + path_separator + "value",
- entry_value);
- return true;
- }
+ {
+ // if entry was declared:
+ // does it match the regex? if not,
+ // don't enter it into the database
+ // exception: if it contains characters
+ // which specify it as a multiple loop
+ // entry, then ignore content
+ if (entry_value.find ('{') == std::string::npos)
+ {
+ const unsigned int pattern_index
+ = entries->get<unsigned int> (get_current_full_path(entry_name) + path_separator + "pattern");
+ if (!patterns[pattern_index]->match(entry_value))
+ {
+ std::cerr << "Line " << lineno << ":" << std::endl
+ << " The entry value" << std::endl
+ << " " << entry_value << std::endl
+ << " for the entry named" << std::endl
+ << " " << entry_name << std::endl
+ << " does not match the given pattern" << std::endl
+ << " " << patterns[pattern_index]->description()
+ << std::endl;
+ return false;
+ }
+ }
+
+ entries->put (get_current_full_path(entry_name) + path_separator + "value",
+ entry_value);
+ return true;
+ }
else
- {
- std::cerr << "Line " << lineno
- << ": No such entry was declared:" << std::endl
- << " " << entry_name << std::endl
- << " <Present subsection:" << std::endl;
- for (unsigned int i=0; i<subsection_path.size(); ++i)
- std::cerr << std::setw(i*2+8) << " "
- << "subsection " << subsection_path[i] << std::endl;
- std::cerr << " >" << std::endl;
-
- return false;
- }
+ {
+ std::cerr << "Line " << lineno
+ << ": No such entry was declared:" << std::endl
+ << " " << entry_name << std::endl
+ << " <Present subsection:" << std::endl;
+ for (unsigned int i=0; i<subsection_path.size(); ++i)
+ std::cerr << std::setw(i*2+8) << " "
+ << "subsection " << subsection_path[i] << std::endl;
+ std::cerr << " >" << std::endl;
+
+ return false;
+ }
}
- // this line matched nothing known
+ // this line matched nothing known
std::cerr << "Line " << lineno
<< ": This line matched nothing known ('set' or 'subsection' missing!?):" << std::endl
- << " " << line << std::endl;
+ << " " << line << std::endl;
return false;
}
if (patterns[j]->description() != prm2.patterns[j]->description())
return false;
- // instead of walking through all
- // the nodes of the two trees
- // entries and prm2.entries and
- // comparing them for equality,
- // simply dump the content of the
- // entire structure into a string
- // and compare those for equality
+ // instead of walking through all
+ // the nodes of the two trees
+ // entries and prm2.entries and
+ // comparing them for equality,
+ // simply dump the content of the
+ // entire structure into a string
+ // and compare those for equality
std::ostringstream o1, o2;
write_json (o1, *entries);
write_json (o2, *prm2.entries);
MultipleParameterLoop::MultipleParameterLoop()
:
- n_branches(0)
+ n_branches(0)
{}
bool MultipleParameterLoop::read_input (const std::string &filename,
- bool optional,
- bool write_compact)
+ bool optional,
+ bool write_compact)
{
return ParameterHandler::read_input (filename, optional, write_compact);
- // don't call init_branches, since this read_input
- // function calls
- // MultipleParameterLoop::Readinput(std::istream &, std::ostream &)
- // which itself calls init_branches.
+ // don't call init_branches, since this read_input
+ // function calls
+ // MultipleParameterLoop::Readinput(std::istream &, std::ostream &)
+ // which itself calls init_branches.
}
{
for (unsigned int run_no=0; run_no<n_branches; ++run_no)
{
- // give create_new one-based numbers
+ // give create_new one-based numbers
uc.create_new (run_no+1);
fill_entry_values (run_no);
uc.run (*this);
multiple_choices.clear ();
init_branches_current_section ();
- // split up different values
+ // split up different values
for (unsigned int i=0; i<multiple_choices.size(); ++i)
multiple_choices[i].split_different_values ();
- // finally calculate number of branches
+ // finally calculate number of branches
n_branches = 1;
for (unsigned int i=0; i<multiple_choices.size(); ++i)
if (multiple_choices[i].type == Entry::variant)
n_branches *= multiple_choices[i].different_values.size();
- // check whether array entries have the correct
- // number of entries
+ // check whether array entries have the correct
+ // number of entries
for (unsigned int i=0; i<multiple_choices.size(); ++i)
if (multiple_choices[i].type == Entry::array)
if (multiple_choices[i].different_values.size() != n_branches)
- std::cerr << " The entry value" << std::endl
- << " " << multiple_choices[i].entry_value << std::endl
- << " for the entry named" << std::endl
- << " " << multiple_choices[i].entry_name << std::endl
- << " does not have the right number of entries for the " << std::endl
- << " " << n_branches << " variant runs that will be performed."
+ std::cerr << " The entry value" << std::endl
+ << " " << multiple_choices[i].entry_value << std::endl
+ << " for the entry named" << std::endl
+ << " " << multiple_choices[i].entry_name << std::endl
+ << " does not have the right number of entries for the " << std::endl
+ << " " << n_branches << " variant runs that will be performed."
<< std::endl;
- // do a first run on filling the values to
- // check for the conformance with the regexp
- // (later on, this will be lost in the whole
- // other output)
+ // do a first run on filling the values to
+ // check for the conformance with the regexp
+ // (later on, this will be lost in the whole
+ // other output)
for (unsigned int i=0; i<n_branches; ++i)
fill_entry_values (i);
}
const boost::property_tree::ptree ¤t_section
= entries->get_child (get_current_path());
- // check all entries in the present
- // subsection whether they are
- // multiple entries
- //
- // we loop over entries in sorted
- // order to guarantee backward
- // compatibility to an earlier
- // implementation
+ // check all entries in the present
+ // subsection whether they are
+ // multiple entries
+ //
+ // we loop over entries in sorted
+ // order to guarantee backward
+ // compatibility to an earlier
+ // implementation
for (boost::property_tree::ptree::const_assoc_iterator
- p = current_section.ordered_begin();
+ p = current_section.ordered_begin();
p != current_section.not_found(); ++p)
if (is_parameter_node (p->second) == true)
{
- const std::string value = p->second.get<std::string>("value");
- if (value.find('{') != std::string::npos)
- multiple_choices.push_back (Entry(subsection_path,
- demangle(p->first),
- value));
+ const std::string value = p->second.get<std::string>("value");
+ if (value.find('{') != std::string::npos)
+ multiple_choices.push_back (Entry(subsection_path,
+ demangle(p->first),
+ value));
}
- // then loop over all subsections
+ // then loop over all subsections
for (boost::property_tree::ptree::const_iterator
- p = current_section.begin();
+ p = current_section.begin();
p != current_section.end(); ++p)
if (is_parameter_node (p->second) == false)
{
- enter_subsection (demangle(p->first));
- init_branches_current_section ();
- leave_subsection ();
+ enter_subsection (demangle(p->first));
+ init_branches_current_section ();
+ leave_subsection ();
}
}
++choice)
{
const unsigned int selection
- = (run_no/possibilities) % choice->different_values.size();
+ = (run_no/possibilities) % choice->different_values.size();
std::string entry_value;
if (choice->type == Entry::variant)
- entry_value = choice->different_values[selection];
+ entry_value = choice->different_values[selection];
else
- {
- if (run_no>=choice->different_values.size())
- {
- std::cerr << "The given array for entry <"
- << choice->entry_name
- << "> does not contain enough elements! Taking empty string instead."
+ {
+ if (run_no>=choice->different_values.size())
+ {
+ std::cerr << "The given array for entry <"
+ << choice->entry_name
+ << "> does not contain enough elements! Taking empty string instead."
<< std::endl;
- entry_value = "";
- }
- else
- entry_value = choice->different_values[run_no];
- }
-
- // temporarily enter the
- // subsection tree of this
- // multiple entry, set the
- // value, and get out
- // again. the set() operation
- // also tests for the
- // correctness of the value
- // with regard to the pattern
+ entry_value = "";
+ }
+ else
+ entry_value = choice->different_values[run_no];
+ }
+
+ // temporarily enter the
+ // subsection tree of this
+ // multiple entry, set the
+ // value, and get out
+ // again. the set() operation
+ // also tests for the
+ // correctness of the value
+ // with regard to the pattern
subsection_path.swap (choice->subsection_path);
set (choice->entry_name, entry_value);
subsection_path.swap (choice->subsection_path);
- // move ahead if it was a variant entry
+ // move ahead if it was a variant entry
if (choice->type == Entry::variant)
- possibilities *= choice->different_values.size();
+ possibilities *= choice->different_values.size();
}
}
MultipleParameterLoop::Entry::Entry (const std::vector<std::string> &ssp,
- const std::string &Name,
- const std::string &Value)
+ const std::string &Name,
+ const std::string &Value)
:
- subsection_path (ssp), entry_name(Name), entry_value(Value), type (Entry::array)
+ subsection_path (ssp), entry_name(Name), entry_value(Value), type (Entry::array)
{}
void MultipleParameterLoop::Entry::split_different_values ()
{
- // split string into three parts:
- // part before the opening "{",
- // the selection itself, final
- // part after "}"
+ // split string into three parts:
+ // part before the opening "{",
+ // the selection itself, final
+ // part after "}"
std::string prefix (entry_value, 0, entry_value.find('{'));
std::string multiple(entry_value, entry_value.find('{')+1,
- entry_value.rfind('}')-entry_value.find('{')-1);
+ entry_value.rfind('}')-entry_value.find('{')-1);
std::string postfix (entry_value, entry_value.rfind('}')+1, std::string::npos);
- // if array entry {{..}}: delete inner
- // pair of braces
+ // if array entry {{..}}: delete inner
+ // pair of braces
if (multiple[0]=='{')
multiple.erase (0,1);
if (multiple[multiple.size()-1] == '}')
multiple.erase (multiple.size()-1, 1);
- // erase leading and trailing spaces
- // in multiple
+ // erase leading and trailing spaces
+ // in multiple
while (std::isspace (multiple[0])) multiple.erase (0,1);
while (std::isspace (multiple[multiple.size()-1])) multiple.erase (multiple.size()-1,1);
- // delete spaces around '|'
+ // delete spaces around '|'
while (multiple.find(" |") != std::string::npos)
multiple.replace (multiple.find(" |"), 2, "|");
while (multiple.find("| ") != std::string::npos)
while (multiple.find('|') != std::string::npos)
{
different_values.push_back (prefix +
- std::string(multiple, 0, multiple.find('|'))+
- postfix);
+ std::string(multiple, 0, multiple.find('|'))+
+ postfix);
multiple.erase (0, multiple.find('|')+1);
};
- // make up the last selection ("while" broke
- // because there was no '|' any more
+ // make up the last selection ("while" broke
+ // because there was no '|' any more
different_values.push_back (prefix+multiple+postfix);
- // finally check whether this was a variant
- // entry ({...}) or an array ({{...}})
+ // finally check whether this was a variant
+ // entry ({...}) or an array ({{...}})
if ((entry_value.find("{{") != std::string::npos) &&
(entry_value.find("}}") != std::string::npos))
type = Entry::array;
MultipleParameterLoop::Entry::memory_consumption () const
{
return (MemoryConsumption::memory_consumption (subsection_path) +
- MemoryConsumption::memory_consumption (entry_name) +
- MemoryConsumption::memory_consumption (entry_value) +
- MemoryConsumption::memory_consumption (different_values) +
- sizeof (type));
+ MemoryConsumption::memory_consumption (entry_name) +
+ MemoryConsumption::memory_consumption (entry_value) +
+ MemoryConsumption::memory_consumption (different_values) +
+ sizeof (type));
}
DEAL_II_NAMESPACE_CLOSE
// $Id$
// Version: $Name$
//
-// Copyright (C) 2007, 2008, 2009 by the deal.II authors
+// Copyright (C) 2007, 2008, 2009, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
namespace Functions {
template <int dim>
ParsedFunction<dim>::ParsedFunction (const unsigned int n_components, const double h)
- :
- AutoDerivativeFunction<dim>(h, n_components),
- function_object(n_components)
+ :
+ AutoDerivativeFunction<dim>(h, n_components),
+ function_object(n_components)
{}
-
+
template <int dim>
void
ParsedFunction<dim>::declare_parameters(ParameterHandler &prm,
- const unsigned int n_components)
+ const unsigned int n_components)
{
Assert(n_components > 0, ExcZero());
std::string vnames;
switch (dim)
{
- case 1:
- vnames = "x,t";
- break;
- case 2:
- vnames = "x,y,t";
- break;
- case 3:
- vnames = "x,y,z,t";
- break;
- default:
- AssertThrow(false, ExcNotImplemented());
- break;
+ case 1:
+ vnames = "x,t";
+ break;
+ case 2:
+ vnames = "x,y,t";
+ break;
+ case 3:
+ vnames = "x,y,z,t";
+ break;
+ default:
+ AssertThrow(false, ExcNotImplemented());
+ break;
}
- prm.declare_entry("Variable names", vnames, Patterns::Anything(),
- "The name of the variables as they will be used in the "
- "function, separated by ','.");
+ prm.declare_entry("Variable names", vnames, Patterns::Anything(),
+ "The name of the variables as they will be used in the "
+ "function, separated by ','.");
- // The expression of the function
+ // The expression of the function
std::string expr = "0";
for (unsigned int i=1; i<n_components; ++i)
expr += "; 0";
prm.declare_entry("Function expression", expr, Patterns::Anything(),
- "Separate vector valued expressions by ';' as ',' "
- "is used internally by the function parser.");
+ "Separate vector valued expressions by ';' as ',' "
+ "is used internally by the function parser.");
prm.declare_entry("Function constants", "", Patterns::Anything(),
- "Any constant used inside the function which is not "
- "a variable name.");
+ "Any constant used inside the function which is not "
+ "a variable name.");
}
-
+
template <int dim>
- void ParsedFunction<dim>::parse_parameters(ParameterHandler &prm)
+ void ParsedFunction<dim>::parse_parameters(ParameterHandler &prm)
{
std::string vnames = prm.get("Variable names");
std::string expression = prm.get("Function expression");
std::string constants_list = prm.get("Function constants");
- std::vector<std::string> const_list =
+ std::vector<std::string> const_list =
Utilities::split_string_list(constants_list, ',');
std::map<std::string, double> constants;
for(unsigned int i = 0; i < const_list.size(); ++i)
{
- std::vector<std::string> this_c =
- Utilities::split_string_list(const_list[i], '=');
- AssertThrow(this_c.size() == 2, ExcMessage("Invalid format"));
- double tmp;
- AssertThrow( std::sscanf(this_c[1].c_str(), "%lf", &tmp),
- ExcMessage("Double number?"));
- constants[this_c[0]] = tmp;
+ std::vector<std::string> this_c =
+ Utilities::split_string_list(const_list[i], '=');
+ AssertThrow(this_c.size() == 2, ExcMessage("Invalid format"));
+ double tmp;
+ AssertThrow( std::sscanf(this_c[1].c_str(), "%lf", &tmp),
+ ExcMessage("Double number?"));
+ constants[this_c[0]] = tmp;
}
-
+
constants["pi"] = numbers::PI;
constants["Pi"] = numbers::PI;
unsigned int nn = (Utilities::split_string_list(vnames)).size();
switch (nn)
{
- case dim:
- // Time independent function
- function_object.initialize(vnames, expression, constants);
- break;
- case dim+1:
- // Time dependent function
- function_object.initialize(vnames, expression, constants, true);
- break;
- default:
- AssertThrow(false, ExcMessage("Not the correct size. Check your code."));
+ case dim:
+ // Time independent function
+ function_object.initialize(vnames, expression, constants);
+ break;
+ case dim+1:
+ // Time dependent function
+ function_object.initialize(vnames, expression, constants, true);
+ break;
+ default:
+ AssertThrow(false, ExcMessage("Not the correct size. Check your code."));
}
}
-
+
template <int dim>
void ParsedFunction<dim>::vector_value (const Point<dim> &p,
- Vector<double> &values) const
- {
+ Vector<double> &values) const
+ {
function_object.vector_value(p, values);
}
-
+
template <int dim>
double ParsedFunction<dim>::value (const Point<dim> &p,
- unsigned int comp) const
- {
+ unsigned int comp) const
+ {
return function_object.value(p, comp);
}
-
+
template <int dim>
void ParsedFunction<dim>::set_time (const double newtime)
- {
+ {
function_object.set_time(newtime);
AutoDerivativeFunction<dim>::set_time(newtime);
}
-
+
// Explicit instantiations
template class ParsedFunction<1>;
template class ParsedFunction<2>;
// $Id$
// Version: $Name$
//
-// Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by the deal.II authors
+// Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
Partitioner::Partitioner (const IndexSet &locally_owned_indices,
- const IndexSet &ghost_indices_in,
- const MPI_Comm communicator_in)
+ const IndexSet &ghost_indices_in,
+ const MPI_Comm communicator_in)
:
global_size (static_cast<types::global_dof_index>(locally_owned_indices.size())),
n_ghost_indices_data (0),
Partitioner::Partitioner (const IndexSet &locally_owned_indices,
- const MPI_Comm communicator_in)
+ const MPI_Comm communicator_in)
:
global_size (static_cast<types::global_dof_index>(locally_owned_indices.size())),
n_ghost_indices_data (0),
{
if (Utilities::System::job_supports_mpi() == true)
{
- my_pid = Utilities::MPI::this_mpi_process(communicator);
- n_procs = Utilities::MPI::n_mpi_processes(communicator);
+ my_pid = Utilities::MPI::this_mpi_process(communicator);
+ n_procs = Utilities::MPI::n_mpi_processes(communicator);
}
else
{
- my_pid = 0;
- n_procs = 1;
+ my_pid = 0;
+ n_procs = 1;
}
- // set the local range
+ // set the local range
Assert (locally_owned_indices.is_contiguous() == 1,
- ExcMessage ("The index set specified in locally_owned_indices "
- "is not contiguous."));
+ ExcMessage ("The index set specified in locally_owned_indices "
+ "is not contiguous."));
locally_owned_indices.compress();
if (locally_owned_indices.n_elements()>0)
local_range_data = std::pair<types::global_dof_index, types::global_dof_index>
- (locally_owned_indices.nth_index_in_set(0),
- locally_owned_indices.nth_index_in_set(0)+
- locally_owned_indices.n_elements());
+ (locally_owned_indices.nth_index_in_set(0),
+ locally_owned_indices.nth_index_in_set(0)+
+ locally_owned_indices.n_elements());
locally_owned_range_data.set_size (locally_owned_indices.size());
locally_owned_range_data.add_range (local_range_data.first,local_range_data.second);
locally_owned_range_data.compress();
void
Partitioner::set_ghost_indices (const IndexSet &ghost_indices_in)
{
- // Set ghost indices from input. To be sure
- // that no entries from the locally owned
- // range are present, subtract the locally
- // owned indices in any case.
+ // Set ghost indices from input. To be sure
+ // that no entries from the locally owned
+ // range are present, subtract the locally
+ // owned indices in any case.
Assert (ghost_indices_in.n_elements() == 0 ||
- ghost_indices_in.size() == locally_owned_range_data.size(),
- ExcDimensionMismatch (ghost_indices_in.size(),
- locally_owned_range_data.size()));
+ ghost_indices_in.size() == locally_owned_range_data.size(),
+ ExcDimensionMismatch (ghost_indices_in.size(),
+ locally_owned_range_data.size()));
ghost_indices_data = ghost_indices_in;
ghost_indices_data.subtract_set (locally_owned_range_data);
ghost_indices_data.compress();
n_ghost_indices_data = ghost_indices_data.n_elements();
- // In the rest of this function, we determine
- // the point-to-point communication pattern of
- // the partitioner. We make up a list with
- // both the processors the ghost indices
- // actually belong to, and the indices that
- // are locally held but ghost indices of other
- // processors. This allows then to import and
- // export data very easily.
-
- // find out the end index for each processor
- // and communicate it (this implies the start
- // index for the next processor)
+ // In the rest of this function, we determine
+ // the point-to-point communication pattern of
+ // the partitioner. We make up a list with
+ // both the processors the ghost indices
+ // actually belong to, and the indices that
+ // are locally held but ghost indices of other
+ // processors. This allows then to import and
+ // export data very easily.
+
+ // find out the end index for each processor
+ // and communicate it (this implies the start
+ // index for the next processor)
#ifdef DEAL_II_COMPILER_SUPPORTS_MPI
if (n_procs < 2)
{
- Assert (ghost_indices_data.n_elements() == 0, ExcInternalError());
- Assert (n_import_indices_data == 0, ExcInternalError());
- Assert (n_ghost_indices_data == 0, ExcInternalError());
- return;
+ Assert (ghost_indices_data.n_elements() == 0, ExcInternalError());
+ Assert (n_import_indices_data == 0, ExcInternalError());
+ Assert (n_ghost_indices_data == 0, ExcInternalError());
+ return;
}
std::vector<types::global_dof_index> first_index (n_procs+1);
first_index[0] = 0;
MPI_Allgather(&local_range_data.second, sizeof(types::global_dof_index),
- MPI_BYTE, &first_index[1], sizeof(types::global_dof_index),
- MPI_BYTE, communicator);
+ MPI_BYTE, &first_index[1], sizeof(types::global_dof_index),
+ MPI_BYTE, communicator);
first_index[n_procs] = global_size;
- // fix case when there are some processors
- // without any locally owned indices: then
- // there might be a zero in some entries
+ // fix case when there are some processors
+ // without any locally owned indices: then
+ // there might be a zero in some entries
if (global_size > 0)
{
- unsigned int first_proc_with_nonzero_dofs = 0;
- for (unsigned int i=0; i<n_procs; ++i)
- if (first_index[i+1]>0)
- {
- first_proc_with_nonzero_dofs = i;
- break;
- }
- for (unsigned int i=first_proc_with_nonzero_dofs+1; i<n_procs; ++i)
- if (first_index[i] == 0)
- first_index[i] = first_index[i-1];
-
- // correct if our processor has a wrong local
- // range
- if (first_index[my_pid] != local_range_data.first)
- {
- Assert(local_range_data.first == local_range_data.second,
- ExcInternalError());
- local_range_data.first = local_range_data.second = first_index[my_pid];
- }
+ unsigned int first_proc_with_nonzero_dofs = 0;
+ for (unsigned int i=0; i<n_procs; ++i)
+ if (first_index[i+1]>0)
+ {
+ first_proc_with_nonzero_dofs = i;
+ break;
+ }
+ for (unsigned int i=first_proc_with_nonzero_dofs+1; i<n_procs; ++i)
+ if (first_index[i] == 0)
+ first_index[i] = first_index[i-1];
+
+ // correct if our processor has a wrong local
+ // range
+ if (first_index[my_pid] != local_range_data.first)
+ {
+ Assert(local_range_data.first == local_range_data.second,
+ ExcInternalError());
+ local_range_data.first = local_range_data.second = first_index[my_pid];
+ }
}
- // Allocate memory for data that will be
- // exported
+ // Allocate memory for data that will be
+ // exported
std::vector<types::global_dof_index> expanded_ghost_indices (n_ghost_indices_data);
unsigned int n_ghost_targets = 0;
if (n_ghost_indices_data > 0)
{
- // Create first a vector of ghost_targets from
- // the list of ghost indices and then push
- // back new values. When we are done, copy the
- // data to that field of the partitioner. This
- // way, the variable ghost_targets will have
- // exactly the size we need, whereas the
- // vector filled with push_back might actually
- // be too long.
- unsigned int current_proc = 0;
- ghost_indices_data.fill_index_vector (expanded_ghost_indices);
- unsigned int current_index = expanded_ghost_indices[0];
- while(current_index >= first_index[current_proc+1])
- current_proc++;
- std::vector<std::pair<unsigned int,unsigned int> > ghost_targets_temp
- (1, std::pair<unsigned int, unsigned int>(current_proc, 0));
- n_ghost_targets++;
-
- for (unsigned int iterator=1; iterator<n_ghost_indices_data; ++iterator)
- {
- current_index = expanded_ghost_indices[iterator];
- while(current_index >= first_index[current_proc+1])
- current_proc++;
- AssertIndexRange (current_proc, n_procs);
- if( ghost_targets_temp[n_ghost_targets-1].first < current_proc)
- {
- ghost_targets_temp[n_ghost_targets-1].second =
- iterator - ghost_targets_temp[n_ghost_targets-1].second;
- ghost_targets_temp.push_back(std::pair<unsigned int,
- unsigned int>(current_proc,iterator));
- n_ghost_targets++;
- }
- }
- ghost_targets_temp[n_ghost_targets-1].second =
- n_ghost_indices_data - ghost_targets_temp[n_ghost_targets-1].second;
- ghost_targets_data = ghost_targets_temp;
+ // Create first a vector of ghost_targets from
+ // the list of ghost indices and then push
+ // back new values. When we are done, copy the
+ // data to that field of the partitioner. This
+ // way, the variable ghost_targets will have
+ // exactly the size we need, whereas the
+ // vector filled with push_back might actually
+ // be too long.
+ unsigned int current_proc = 0;
+ ghost_indices_data.fill_index_vector (expanded_ghost_indices);
+ unsigned int current_index = expanded_ghost_indices[0];
+ while(current_index >= first_index[current_proc+1])
+ current_proc++;
+ std::vector<std::pair<unsigned int,unsigned int> > ghost_targets_temp
+ (1, std::pair<unsigned int, unsigned int>(current_proc, 0));
+ n_ghost_targets++;
+
+ for (unsigned int iterator=1; iterator<n_ghost_indices_data; ++iterator)
+ {
+ current_index = expanded_ghost_indices[iterator];
+ while(current_index >= first_index[current_proc+1])
+ current_proc++;
+ AssertIndexRange (current_proc, n_procs);
+ if( ghost_targets_temp[n_ghost_targets-1].first < current_proc)
+ {
+ ghost_targets_temp[n_ghost_targets-1].second =
+ iterator - ghost_targets_temp[n_ghost_targets-1].second;
+ ghost_targets_temp.push_back(std::pair<unsigned int,
+ unsigned int>(current_proc,iterator));
+ n_ghost_targets++;
+ }
+ }
+ ghost_targets_temp[n_ghost_targets-1].second =
+ n_ghost_indices_data - ghost_targets_temp[n_ghost_targets-1].second;
+ ghost_targets_data = ghost_targets_temp;
}
- // find the processes that want to import to
- // me
+ // find the processes that want to import to
+ // me
{
std::vector<int> send_buffer (n_procs, 0);
std::vector<int> receive_buffer (n_procs, 0);
for (unsigned int i=0; i<n_ghost_targets; i++)
- send_buffer[ghost_targets_data[i].first] = ghost_targets_data[i].second;
+ send_buffer[ghost_targets_data[i].first] = ghost_targets_data[i].second;
MPI_Alltoall (&send_buffer[0], 1, MPI_INT, &receive_buffer[0], 1,
- MPI_INT, communicator);
+ MPI_INT, communicator);
- // allocate memory for import data
+ // allocate memory for import data
std::vector<std::pair<unsigned int,unsigned int> > import_targets_temp;
n_import_indices_data = 0;
for (unsigned int i=0; i<n_procs; i++)
- if (receive_buffer[i] > 0)
- {
- n_import_indices_data += receive_buffer[i];
- import_targets_temp.push_back(std::pair<unsigned int,
- unsigned int> (i, receive_buffer[i]));
- }
+ if (receive_buffer[i] > 0)
+ {
+ n_import_indices_data += receive_buffer[i];
+ import_targets_temp.push_back(std::pair<unsigned int,
+ unsigned int> (i, receive_buffer[i]));
+ }
import_targets_data = import_targets_temp;
}
- // send and receive indices for import
- // data. non-blocking receives and blocking
- // sends
+ // send and receive indices for import
+ // data. non-blocking receives and blocking
+ // sends
std::vector<types::global_dof_index> expanded_import_indices (n_import_indices_data);
{
unsigned int current_index_start = 0;
std::vector<MPI_Request> import_requests (import_targets_data.size());
for (unsigned int i=0; i<import_targets_data.size(); i++)
- {
- MPI_Irecv (&expanded_import_indices[current_index_start],
- import_targets_data[i].second*sizeof(types::global_dof_index),
- MPI_BYTE,
- import_targets_data[i].first, import_targets_data[i].first,
- communicator, &import_requests[i]);
- current_index_start += import_targets_data[i].second;
- }
+ {
+ MPI_Irecv (&expanded_import_indices[current_index_start],
+ import_targets_data[i].second*sizeof(types::global_dof_index),
+ MPI_BYTE,
+ import_targets_data[i].first, import_targets_data[i].first,
+ communicator, &import_requests[i]);
+ current_index_start += import_targets_data[i].second;
+ }
AssertDimension (current_index_start, n_import_indices_data);
- // use blocking send
+ // use blocking send
current_index_start = 0;
for (unsigned int i=0; i<n_ghost_targets; i++)
- {
- MPI_Send (&expanded_ghost_indices[current_index_start],
- ghost_targets_data[i].second*sizeof(types::global_dof_index),
- MPI_BYTE, ghost_targets_data[i].first, my_pid,
- communicator);
- current_index_start += ghost_targets_data[i].second;
- }
+ {
+ MPI_Send (&expanded_ghost_indices[current_index_start],
+ ghost_targets_data[i].second*sizeof(types::global_dof_index),
+ MPI_BYTE, ghost_targets_data[i].first, my_pid,
+ communicator);
+ current_index_start += ghost_targets_data[i].second;
+ }
AssertDimension (current_index_start, n_ghost_indices_data);
MPI_Waitall (import_requests.size(), &import_requests[0],
- MPI_STATUSES_IGNORE);
+ MPI_STATUSES_IGNORE);
- // transform import indices to local index
- // space and compress contiguous indices in
- // form of ranges
+ // transform import indices to local index
+ // space and compress contiguous indices in
+ // form of ranges
{
- unsigned int last_index = numbers::invalid_unsigned_int-1;
- std::vector<std::pair<unsigned int,unsigned int> > compressed_import_indices;
- for (unsigned int i=0;i<n_import_indices_data;i++)
- {
- Assert (expanded_import_indices[i] >= local_range_data.first &&
- expanded_import_indices[i] < local_range_data.second,
- ExcIndexRange(expanded_import_indices[i], local_range_data.first,
- local_range_data.second));
- unsigned int new_index = (expanded_import_indices[i] -
- local_range_data.first);
- if (new_index == last_index+1)
- compressed_import_indices.back().second++;
- else
- {
- compressed_import_indices.push_back
- (std::pair<unsigned int,unsigned int>(new_index,new_index+1));
- }
- last_index = new_index;
- }
- import_indices_data = compressed_import_indices;
-
- // sanity check
+ unsigned int last_index = numbers::invalid_unsigned_int-1;
+ std::vector<std::pair<unsigned int,unsigned int> > compressed_import_indices;
+ for (unsigned int i=0;i<n_import_indices_data;i++)
+ {
+ Assert (expanded_import_indices[i] >= local_range_data.first &&
+ expanded_import_indices[i] < local_range_data.second,
+ ExcIndexRange(expanded_import_indices[i], local_range_data.first,
+ local_range_data.second));
+ unsigned int new_index = (expanded_import_indices[i] -
+ local_range_data.first);
+ if (new_index == last_index+1)
+ compressed_import_indices.back().second++;
+ else
+ {
+ compressed_import_indices.push_back
+ (std::pair<unsigned int,unsigned int>(new_index,new_index+1));
+ }
+ last_index = new_index;
+ }
+ import_indices_data = compressed_import_indices;
+
+ // sanity check
#ifdef DEBUG
- const unsigned int n_local_dofs = local_range_data.second-local_range_data.first;
- for (unsigned int i=0; i<import_indices_data.size(); ++i)
- {
- AssertIndexRange (import_indices_data[i].first, n_local_dofs);
- AssertIndexRange (import_indices_data[i].second-1, n_local_dofs);
- }
+ const unsigned int n_local_dofs = local_range_data.second-local_range_data.first;
+ for (unsigned int i=0; i<import_indices_data.size(); ++i)
+ {
+ AssertIndexRange (import_indices_data[i].first, n_local_dofs);
+ AssertIndexRange (import_indices_data[i].second-1, n_local_dofs);
+ }
#endif
}
}
Partitioner::memory_consumption() const
{
std::size_t memory = (3*sizeof(types::global_dof_index)+4*sizeof(unsigned int)+
- sizeof(MPI_Comm));
+ sizeof(MPI_Comm));
memory += MemoryConsumption::memory_consumption(ghost_targets_data);
memory += MemoryConsumption::memory_consumption(import_targets_data);
memory += MemoryConsumption::memory_consumption(import_indices_data);
// $Id$
// Version: $Name$
//
-// Copyright (C) 2005, 2006, 2007, 2008, 2009 by the deal.II authors
+// Copyright (C) 2005, 2006, 2007, 2008, 2009, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
v.push_back(empty);
v.push_back(std::string(".prm"));
suffix_lists.insert(map_type(std::string("PARAMETER"), v));
-
- // We cannot use the GridIn class
- // to query the formats, since this
- // would require linking with the
- // deal.II libraries.
+
+ // We cannot use the GridIn class
+ // to query the formats, since this
+ // would require linking with the
+ // deal.II libraries.
v.clear();
v.push_back(empty);
v.push_back(std::string(".inp"));
{
if (path_lists.empty())
initialize_classes();
-
+
// Modified by Luca Heltai. If a class is not there, add it
if(path_lists.count(cls) == 0) add_class(cls);
-
+
// Assert(path_lists.count(cls) != 0, ExcNoClass(cls));
Assert(path_lists.count(cls) != 0, ExcInternalError());
-
+
return path_lists.find(cls)->second;
}
std::vector<std::string>&
PathSearch::get_suffix_list(const std::string& cls)
-{
+{
// This is redundant. The constructor should have already called the
// add_path function with the path_list bit...
// Modified by Luca Heltai. If a class is not there, add it
if(suffix_lists.count(cls) == 0) add_class(cls);
-
+
// Assert(suffix_lists.count(cls) != 0, ExcNoClass(cls));
Assert(suffix_lists.count(cls) != 0, ExcInternalError());
-
+
return suffix_lists.find(cls)->second;
}
PathSearch::PathSearch(const std::string& cls,
- const unsigned int debug)
- :
- cls(cls),
- my_path_list(get_path_list(cls)),
- my_suffix_list(get_suffix_list(cls)),
- debug(debug)
+ const unsigned int debug)
+ :
+ cls(cls),
+ my_path_list(get_path_list(cls)),
+ my_suffix_list(get_suffix_list(cls)),
+ debug(debug)
{}
std::string
PathSearch::find (const std::string& filename,
- const std::string& suffix,
- const char* open_mode)
+ const std::string& suffix,
+ const char* open_mode)
{
std::vector<std::string>::const_iterator path;
const std::vector<std::string>::const_iterator endp = my_path_list.end();
std::string real_name;
-
+
if (debug > 2)
deallog << "PathSearch[" << cls << "] "
- << my_path_list.size() << " directories "
- << std::endl;
-
- // Try to open file
+ << my_path_list.size() << " directories "
+ << std::endl;
+
+ // Try to open file
for (path = my_path_list.begin(); path != endp; ++path)
{
real_name = *path + filename + suffix;
if (debug > 1)
- deallog << "PathSearch[" << cls << "] trying "
- << real_name << std::endl;
+ deallog << "PathSearch[" << cls << "] trying "
+ << real_name << std::endl;
FILE* fp = fopen(real_name.c_str(), open_mode);
if (fp != 0)
- {
- if (debug > 0)
- deallog << "PathSearch[" << cls << "] opened "
- << real_name << std::endl;
- fclose(fp);
- return real_name;
- }
+ {
+ if (debug > 0)
+ deallog << "PathSearch[" << cls << "] opened "
+ << real_name << std::endl;
+ fclose(fp);
+ return real_name;
+ }
}
AssertThrow(false, ExcFileNotFound(filename, cls));
return std::string("");
std::string
PathSearch::find (const std::string& filename,
- const char* open_mode)
+ const char* open_mode)
{
std::vector<std::string>::const_iterator suffix;
const std::vector<std::string>::const_iterator ends = my_suffix_list.end();
if (debug > 2)
deallog << "PathSearch[" << cls << "] "
- << my_path_list.size() << " directories "
- << my_suffix_list.size() << " suffixes"
- << std::endl;
-
+ << my_path_list.size() << " directories "
+ << my_suffix_list.size() << " suffixes"
+ << std::endl;
+
for (suffix = my_suffix_list.begin(); suffix != ends; ++suffix)
{
try
- {
- return find(filename, *suffix, open_mode);
- }
+ {
+ return find(filename, *suffix, open_mode);
+ }
catch (ExcFileNotFound)
- {
- continue;
- }
-
+ {
+ continue;
+ }
+
}
AssertThrow(false, ExcFileNotFound(filename, cls));
return std::string("");
void
PathSearch::add_class (const std::string& cls)
{
- // Make sure standard classes are
- // initialized first
+ // Make sure standard classes are
+ // initialized first
if (path_lists.empty())
initialize_classes();
- // Add empty path and empty suffix
- // for new class
+ // Add empty path and empty suffix
+ // for new class
std::vector<std::string> v;
v.push_back(empty);
path_lists.insert(map_type(cls, v));
void
PathSearch::add_path (const std::string& path,
- Position pos)
+ Position pos)
{
if (pos == back)
my_path_list.push_back(path);
else if (pos == after_none)
{
std::vector<std::string>::iterator
- i = std::find(my_path_list.begin(), my_path_list.end(), empty);
+ i = std::find(my_path_list.begin(), my_path_list.end(), empty);
if (i != my_path_list.end())
- ++i;
+ ++i;
my_path_list.insert(i, path);
}
}
void
PathSearch::add_suffix (const std::string& suffix,
- Position pos)
+ Position pos)
{
if (pos == back)
my_suffix_list.push_back(suffix);
else if (pos == after_none)
{
std::vector<std::string>::iterator
- i = std::find(my_suffix_list.begin(), my_suffix_list.end(), empty);
+ i = std::find(my_suffix_list.begin(), my_suffix_list.end(), empty);
if (i != my_suffix_list.end())
- ++i;
+ ++i;
my_suffix_list.insert(i, suffix);
}
}
// $Id$
// Version: $Name$
//
-// Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2010, 2011 by the deal.II authors
+// Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2010, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
template <typename number>
Polynomial<number>::Polynomial (const std::vector<number> &a)
:
- coefficients (a),
- in_lagrange_product_form (false),
- lagrange_weight (1.)
+ coefficients (a),
+ in_lagrange_product_form (false),
+ lagrange_weight (1.)
{}
Polynomial<number>::Polynomial (const unsigned int n)
:
coefficients (n+1, 0.),
- in_lagrange_product_form (false),
- lagrange_weight (1.)
+ in_lagrange_product_form (false),
+ lagrange_weight (1.)
{}
template <typename number>
Polynomial<number>::Polynomial (const std::vector<Point<1> > &supp,
- const unsigned int center)
+ const unsigned int center)
:
in_lagrange_product_form (true)
{
number tmp_lagrange_weight = 1.;
for (unsigned int i=0; i<supp.size(); ++i)
if (i!=center)
- {
- lagrange_support_points.push_back(supp[i](0));
- tmp_lagrange_weight *= supp[center](0) - supp[i](0);
- }
+ {
+ lagrange_support_points.push_back(supp[i](0));
+ tmp_lagrange_weight *= supp[center](0) - supp[i](0);
+ }
- // check for underflow and overflow
+ // check for underflow and overflow
#ifdef HAVE_STD_NUMERIC_LIMITS
Assert (std::fabs(tmp_lagrange_weight) > std::numeric_limits<number>::min(),
- ExcMessage ("Underflow in computation of Lagrange denominator."));
+ ExcMessage ("Underflow in computation of Lagrange denominator."));
Assert (std::fabs(tmp_lagrange_weight) < std::numeric_limits<number>::max(),
- ExcMessage ("Overflow in computation of Lagrange denominator."));
+ ExcMessage ("Overflow in computation of Lagrange denominator."));
#endif
lagrange_weight = static_cast<number>(1.)/tmp_lagrange_weight;
}
Assert (values.size() > 0, ExcZero());
const unsigned int values_size=values.size();
- // evaluate Lagrange polynomial and
- // derivatives
+ // evaluate Lagrange polynomial and
+ // derivatives
if (in_lagrange_product_form == true)
{
- // to compute the value and all derivatives of
- // a polynomial of the form
- // (x-x_1)*(x-x_2)*...*(x-x_n), expand the
- // derivatives like automatic differentiation
- // does.
- const unsigned int n_supp = lagrange_support_points.size();
- switch (values_size)
- {
- default:
- values[0] = 1;
- for (unsigned int d=1; d<values_size; ++d)
- values[d] = 0;
- for (unsigned int i=0; i<n_supp; ++i)
- {
- const number v = x-lagrange_support_points[i];
-
- // multiply by (x-x_i) and compute action on
- // all derivatives, too (inspired from
- // automatic differentiation: implement the
- // product rule for the old value and the new
- // variable 'v', i.e., expand value v and
- // derivative one). since we reuse a value
- // from the next lower derivative from the
- // steps before, need to start from the
- // highest derivative
- for (unsigned int k=values_size-1; k>0; --k)
- values[k] = (values[k] * v + values[k-1]);
- values[0] *= v;
- }
- // finally, multiply by the weight in the
- // Lagrange denominator. Could be done instead
- // of setting values[0] = 1 above, but that
- // gives different accumulation of round-off
- // errors (multiplication is not associative)
- // compared to when we computed the weight,
- // and hence a basis function might not be
- // exactly one at the center point, which is
- // nice to have. We also multiply derivatives
- // by k! to transform the product p_n =
- // p^(n)(x)/k! into the actual form of the
- // derivative
- {
- number k_faculty = 1;
- for (unsigned int k=0; k<values_size; ++k)
- {
- values[k] *= k_faculty * lagrange_weight;
- k_faculty *= static_cast<number>(k+1);
- }
- }
- break;
-
- // manually implement size 1 (values only),
- // size 2 (value + first derivative), and size
- // 3 (up to second derivative) since they
- // might be called often. then, we can unroll
- // the loop.
- case 1:
- values[0] = 1;
- for (unsigned int i=0; i<n_supp; ++i)
- {
- const number v = x-lagrange_support_points[i];
- values[0] *= v;
- }
- values[0] *= lagrange_weight;
- break;
-
- case 2:
- values[0] = 1;
- values[1] = 0;
- for (unsigned int i=0; i<n_supp; ++i)
- {
- const number v = x-lagrange_support_points[i];
- values[1] = values[1] * v + values[0];
- values[0] *= v;
- }
- values[0] *= lagrange_weight;
- values[1] *= lagrange_weight;
- break;
-
- case 3:
- values[0] = 1;
- values[1] = 0;
- values[2] = 0;
- for (unsigned int i=0; i<n_supp; ++i)
- {
- const number v = x-lagrange_support_points[i];
- values[2] = values[2] * v + values[1];
- values[1] = values[1] * v + values[0];
- values[0] *= v;
- }
- values[0] *= lagrange_weight;
- values[1] *= lagrange_weight;
- values[2] *= static_cast<number>(2) * lagrange_weight;
- break;
- }
- return;
+ // to compute the value and all derivatives of
+ // a polynomial of the form
+ // (x-x_1)*(x-x_2)*...*(x-x_n), expand the
+ // derivatives like automatic differentiation
+ // does.
+ const unsigned int n_supp = lagrange_support_points.size();
+ switch (values_size)
+ {
+ default:
+ values[0] = 1;
+ for (unsigned int d=1; d<values_size; ++d)
+ values[d] = 0;
+ for (unsigned int i=0; i<n_supp; ++i)
+ {
+ const number v = x-lagrange_support_points[i];
+
+ // multiply by (x-x_i) and compute action on
+ // all derivatives, too (inspired from
+ // automatic differentiation: implement the
+ // product rule for the old value and the new
+ // variable 'v', i.e., expand value v and
+ // derivative one). since we reuse a value
+ // from the next lower derivative from the
+ // steps before, need to start from the
+ // highest derivative
+ for (unsigned int k=values_size-1; k>0; --k)
+ values[k] = (values[k] * v + values[k-1]);
+ values[0] *= v;
+ }
+ // finally, multiply by the weight in the
+ // Lagrange denominator. Could be done instead
+ // of setting values[0] = 1 above, but that
+ // gives different accumulation of round-off
+ // errors (multiplication is not associative)
+ // compared to when we computed the weight,
+ // and hence a basis function might not be
+ // exactly one at the center point, which is
+ // nice to have. We also multiply derivatives
+ // by k! to transform the product p_n =
+ // p^(n)(x)/k! into the actual form of the
+ // derivative
+ {
+ number k_faculty = 1;
+ for (unsigned int k=0; k<values_size; ++k)
+ {
+ values[k] *= k_faculty * lagrange_weight;
+ k_faculty *= static_cast<number>(k+1);
+ }
+ }
+ break;
+
+ // manually implement size 1 (values only),
+ // size 2 (value + first derivative), and size
+ // 3 (up to second derivative) since they
+ // might be called often. then, we can unroll
+ // the loop.
+ case 1:
+ values[0] = 1;
+ for (unsigned int i=0; i<n_supp; ++i)
+ {
+ const number v = x-lagrange_support_points[i];
+ values[0] *= v;
+ }
+ values[0] *= lagrange_weight;
+ break;
+
+ case 2:
+ values[0] = 1;
+ values[1] = 0;
+ for (unsigned int i=0; i<n_supp; ++i)
+ {
+ const number v = x-lagrange_support_points[i];
+ values[1] = values[1] * v + values[0];
+ values[0] *= v;
+ }
+ values[0] *= lagrange_weight;
+ values[1] *= lagrange_weight;
+ break;
+
+ case 3:
+ values[0] = 1;
+ values[1] = 0;
+ values[2] = 0;
+ for (unsigned int i=0; i<n_supp; ++i)
+ {
+ const number v = x-lagrange_support_points[i];
+ values[2] = values[2] * v + values[1];
+ values[1] = values[1] * v + values[0];
+ values[0] *= v;
+ }
+ values[0] *= lagrange_weight;
+ values[1] *= lagrange_weight;
+ values[2] *= static_cast<number>(2) * lagrange_weight;
+ break;
+ }
+ return;
}
Assert (coefficients.size() > 0, ExcEmptyObject());
void
Polynomial<number>::transform_into_standard_form ()
{
- // should only be called when the product form
- // is active
+ // should only be called when the product form
+ // is active
Assert (in_lagrange_product_form == true, ExcInternalError());
Assert (coefficients.size() == 0, ExcInternalError());
- // compute coefficients by expanding the
- // product (x-x_i) term by term
+ // compute coefficients by expanding the
+ // product (x-x_i) term by term
coefficients.resize (lagrange_support_points.size()+1);
if (lagrange_support_points.size() == 0)
coefficients[0] = 1.;
else
{
- coefficients[0] = -lagrange_support_points[0];
- coefficients[1] = 1.;
- for (unsigned int i=1; i<lagrange_support_points.size(); ++i)
- {
- coefficients[i+1] = 1.;
- for (unsigned int j=i; j>0; --j)
- coefficients[j] = (-lagrange_support_points[i]*coefficients[j] +
- coefficients[j-1]);
- coefficients[0] *= -lagrange_support_points[i];
- }
+ coefficients[0] = -lagrange_support_points[0];
+ coefficients[1] = 1.;
+ for (unsigned int i=1; i<lagrange_support_points.size(); ++i)
+ {
+ coefficients[i+1] = 1.;
+ for (unsigned int j=i; j>0; --j)
+ coefficients[j] = (-lagrange_support_points[i]*coefficients[j] +
+ coefficients[j-1]);
+ coefficients[0] *= -lagrange_support_points[i];
+ }
}
for (unsigned int i=0; i<lagrange_support_points.size()+1; ++i)
coefficients[i] *= lagrange_weight;
- // delete the product form data
+ // delete the product form data
std::vector<number> new_points;
lagrange_support_points.swap(new_points);
in_lagrange_product_form = false;
void
Polynomial<number>::scale (const number factor)
{
- // to scale (x-x_0)*(x-x_1)*...*(x-x_n), scale
- // support points by 1./factor and the weight
- // likewise
+ // to scale (x-x_0)*(x-x_1)*...*(x-x_n), scale
+ // support points by 1./factor and the weight
+ // likewise
if (in_lagrange_product_form == true)
{
- number inv_fact = number(1.)/factor;
- number accumulated_fact = 1.;
- for (unsigned int i=0; i<lagrange_support_points.size(); ++i)
- {
- lagrange_support_points[i] *= inv_fact;
- accumulated_fact *= factor;
- }
- lagrange_weight *= accumulated_fact;
+ number inv_fact = number(1.)/factor;
+ number accumulated_fact = 1.;
+ for (unsigned int i=0; i<lagrange_support_points.size(); ++i)
+ {
+ lagrange_support_points[i] *= inv_fact;
+ accumulated_fact *= factor;
+ }
+ lagrange_weight *= accumulated_fact;
}
- // otherwise, use the function above
+ // otherwise, use the function above
else
scale (coefficients, factor);
}
lagrange_weight *= s;
else
{
- for (typename std::vector<number>::iterator c = coefficients.begin();
- c != coefficients.end(); ++c)
- *c *= s;
+ for (typename std::vector<number>::iterator c = coefficients.begin();
+ c != coefficients.end(); ++c)
+ *c *= s;
}
return *this;
}
Polynomial<number>&
Polynomial<number>::operator *= (const Polynomial<number>& p)
{
- // if we are in Lagrange form, just append the
- // new points
+ // if we are in Lagrange form, just append the
+ // new points
if (in_lagrange_product_form == true && p.in_lagrange_product_form == true)
{
- lagrange_weight *= p.lagrange_weight;
- lagrange_support_points.insert (lagrange_support_points.end(),
- p.lagrange_support_points.begin(),
- p.lagrange_support_points.end());
+ lagrange_weight *= p.lagrange_weight;
+ lagrange_support_points.insert (lagrange_support_points.end(),
+ p.lagrange_support_points.begin(),
+ p.lagrange_support_points.end());
}
- // cannot retain product form, recompute...
+ // cannot retain product form, recompute...
else if (in_lagrange_product_form == true)
transform_into_standard_form();
- // need to transform p into standard form as
- // well if necessary. copy the polynomial to
- // do this
+ // need to transform p into standard form as
+ // well if necessary. copy the polynomial to
+ // do this
std_cxx1x::shared_ptr<Polynomial<number> > q_data;
const Polynomial<number> * q = 0;
if (p.in_lagrange_product_form == true)
{
- q_data.reset (new Polynomial<number>(p));
- q_data->transform_into_standard_form();
- q = q_data.get();
+ q_data.reset (new Polynomial<number>(p));
+ q_data->transform_into_standard_form();
+ q = q_data.get();
}
else
q = &p;
for (unsigned int i=0; i<q->coefficients.size(); ++i)
for (unsigned int j=0; j<this->coefficients.size(); ++j)
- new_coefficients[i+j] += this->coefficients[j]*q->coefficients[i];
+ new_coefficients[i+j] += this->coefficients[j]*q->coefficients[i];
this->coefficients = new_coefficients;
return *this;
Polynomial<number>&
Polynomial<number>::operator += (const Polynomial<number>& p)
{
- // Lagrange product form cannot reasonably be
- // retained after polynomial addition. we
- // could in theory check if either this
- // polynomial or the other is a zero
- // polynomial and retain it, but we actually
- // currently (r23974) assume that the addition
- // of a zero polynomial changes the state and
- // tests equivalence.
+ // Lagrange product form cannot reasonably be
+ // retained after polynomial addition. we
+ // could in theory check if either this
+ // polynomial or the other is a zero
+ // polynomial and retain it, but we actually
+ // currently (r23974) assume that the addition
+ // of a zero polynomial changes the state and
+ // tests equivalence.
if (in_lagrange_product_form == true)
transform_into_standard_form();
- // need to transform p into standard form as
- // well if necessary. copy the polynomial to
- // do this
+ // need to transform p into standard form as
+ // well if necessary. copy the polynomial to
+ // do this
std_cxx1x::shared_ptr<Polynomial<number> > q_data;
const Polynomial<number> * q = 0;
if (p.in_lagrange_product_form == true)
{
- q_data.reset (new Polynomial<number>(p));
- q_data->transform_into_standard_form();
- q = q_data.get();
+ q_data.reset (new Polynomial<number>(p));
+ q_data->transform_into_standard_form();
+ q = q_data.get();
}
else
q = &p;
Polynomial<number>&
Polynomial<number>::operator -= (const Polynomial<number>& p)
{
- // Lagrange product form cannot reasonably be
- // retained after polynomial addition
+ // Lagrange product form cannot reasonably be
+ // retained after polynomial addition
if (in_lagrange_product_form == true)
transform_into_standard_form();
- // need to transform p into standard form as
- // well if necessary. copy the polynomial to
- // do this
+ // need to transform p into standard form as
+ // well if necessary. copy the polynomial to
+ // do this
std_cxx1x::shared_ptr<Polynomial<number> > q_data;
const Polynomial<number> * q = 0;
if (p.in_lagrange_product_form == true)
{
- q_data.reset (new Polynomial<number>(p));
- q_data->transform_into_standard_form();
- q = q_data.get();
+ q_data.reset (new Polynomial<number>(p));
+ q_data->transform_into_standard_form();
+ q = q_data.get();
}
else
q = &p;
bool
Polynomial<number>::operator == (const Polynomial<number> & p) const
{
- // need to distinguish a few cases based on
- // whether we are in product form or not. two
- // polynomials can still be the same when they
- // are on different forms, but the expansion
- // is the same
+ // need to distinguish a few cases based on
+ // whether we are in product form or not. two
+ // polynomials can still be the same when they
+ // are on different forms, but the expansion
+ // is the same
if (in_lagrange_product_form == true &&
- p.in_lagrange_product_form == true)
+ p.in_lagrange_product_form == true)
return ((lagrange_weight == p.lagrange_weight) &&
- (lagrange_support_points == p.lagrange_support_points));
+ (lagrange_support_points == p.lagrange_support_points));
else if (in_lagrange_product_form == true)
{
- Polynomial<number> q = *this;
- q.transform_into_standard_form();
- return (q.coefficients == p.coefficients);
+ Polynomial<number> q = *this;
+ q.transform_into_standard_form();
+ return (q.coefficients == p.coefficients);
}
else if (p.in_lagrange_product_form == true)
{
- Polynomial<number> q = p;
- q.transform_into_standard_form();
- return (q.coefficients == coefficients);
+ Polynomial<number> q = p;
+ q.transform_into_standard_form();
+ return (q.coefficients == coefficients);
}
else
return (p.coefficients == coefficients);
coefficients[0] = offset;
#else
- // too many coefficients cause overflow in
- // the binomial coefficient used below
+ // too many coefficients cause overflow in
+ // the binomial coefficient used below
Assert (coefficients.size() < 31, ExcNotImplemented());
// Copy coefficients to a vector of
void
Polynomial<number>::shift (const number2 offset)
{
- // shift is simple for a polynomial in product
- // form, (x-x_0)*(x-x_1)*...*(x-x_n). just add
- // offset to all shifts
+ // shift is simple for a polynomial in product
+ // form, (x-x_0)*(x-x_1)*...*(x-x_n). just add
+ // offset to all shifts
if (in_lagrange_product_form == true)
{
- for (unsigned int i=0; i<lagrange_support_points.size(); ++i)
- lagrange_support_points[i] -= offset;
+ for (unsigned int i=0; i<lagrange_support_points.size(); ++i)
+ lagrange_support_points[i] -= offset;
}
else
- // do the shift in any case
+ // do the shift in any case
shift (coefficients, offset);
}
Polynomial<number>
Polynomial<number>::derivative () const
{
- // no simple form possible for Lagrange
- // polynomial on product form
+ // no simple form possible for Lagrange
+ // polynomial on product form
if (degree() == 0)
return Monomial<number>(0, 0.);
const Polynomial<number> * q = 0;
if (in_lagrange_product_form == true)
{
- q_data.reset (new Polynomial<number>(*this));
- q_data->transform_into_standard_form();
- q = q_data.get();
+ q_data.reset (new Polynomial<number>(*this));
+ q_data->transform_into_standard_form();
+ q = q_data.get();
}
else
q = this;
Polynomial<number>
Polynomial<number>::primitive () const
{
- // no simple form possible for Lagrange
- // polynomial on product form
+ // no simple form possible for Lagrange
+ // polynomial on product form
std_cxx1x::shared_ptr<Polynomial<number> > q_data;
const Polynomial<number> * q = 0;
if (in_lagrange_product_form == true)
{
- q_data.reset (new Polynomial<number>(*this));
- q_data->transform_into_standard_form();
- q = q_data.get();
+ q_data.reset (new Polynomial<number>(*this));
+ q_data->transform_into_standard_form();
+ q = q_data.get();
}
else
q = this;
{
if (in_lagrange_product_form == true)
{
- out << lagrange_weight;
- for (unsigned int i=0; i<lagrange_support_points.size(); ++i)
- out << " (x-" << lagrange_support_points[i] << ")";
- out << std::endl;
+ out << lagrange_weight;
+ for (unsigned int i=0; i<lagrange_support_points.size(); ++i)
+ out << " (x-" << lagrange_support_points[i] << ")";
+ out << std::endl;
}
else
for (int i=degree();i>=0;--i)
- {
- out << coefficients[i] << " x^" << i << std::endl;
- }
+ {
+ out << coefficients[i] << " x^" << i << std::endl;
+ }
}
std::vector<Point<1> >
generate_equidistant_unit_points (const unsigned int n)
{
- std::vector<Point<1> > points (n+1);
- const double one_over_n = 1./n;
+ std::vector<Point<1> > points (n+1);
+ const double one_over_n = 1./n;
for (unsigned int k=0;k<=n;++k)
- points[k](0) = static_cast<double>(k)*one_over_n;
- return points;
+ points[k](0) = static_cast<double>(k)*one_over_n;
+ return points;
}
}
}
const unsigned int support_point)
:
Polynomial<double> (internal::LagrangeEquidistant::
- generate_equidistant_unit_points (n),
- support_point)
+ generate_equidistant_unit_points (n),
+ support_point)
{
Assert (coefficients.size() == 0, ExcInternalError());
- // For polynomial order up to 3, we have
- // precomputed weights. Use these weights
- // instead of the product form
+ // For polynomial order up to 3, we have
+ // precomputed weights. Use these weights
+ // instead of the product form
if (n <= 3)
{
- this->in_lagrange_product_form = false;
- this->lagrange_weight = 1.;
- std::vector<double> new_support_points;
- this->lagrange_support_points.swap(new_support_points);
- this->coefficients.resize (n+1);
+ this->in_lagrange_product_form = false;
+ this->lagrange_weight = 1.;
+ std::vector<double> new_support_points;
+ this->lagrange_support_points.swap(new_support_points);
+ this->coefficients.resize (n+1);
compute_coefficients(n, support_point, this->coefficients);
}
}
// no, then generate the
// respective coefficients
{
- // make sure that there is enough
- // space in the array for the
- // coefficients, so we have to resize
- // it to size k+1
-
- // but it's more complicated than
- // that: we call this function
- // recursively, so if we simply
- // resize it to k+1 here, then
- // compute the coefficients for
- // degree k-1 by calling this
- // function recursively, then it will
- // reset the size to k -- not enough
- // for what we want to do below. the
- // solution therefore is to only
- // resize the size if we are going to
- // *increase* it
- if (recursive_coefficients.size() < k+1)
- recursive_coefficients.resize (k+1);
+ // make sure that there is enough
+ // space in the array for the
+ // coefficients, so we have to resize
+ // it to size k+1
+
+ // but it's more complicated than
+ // that: we call this function
+ // recursively, so if we simply
+ // resize it to k+1 here, then
+ // compute the coefficients for
+ // degree k-1 by calling this
+ // function recursively, then it will
+ // reset the size to k -- not enough
+ // for what we want to do below. the
+ // solution therefore is to only
+ // resize the size if we are going to
+ // *increase* it
+ if (recursive_coefficients.size() < k+1)
+ recursive_coefficients.resize (k+1);
if (k<=1)
{
// no, then generate the
// respective coefficients
{
- // make sure that there is enough
- // space in the array for the
- // coefficients, so we have to resize
- // it to size k+1
-
- // but it's more complicated than
- // that: we call this function
- // recursively, so if we simply
- // resize it to k+1 here, then
- // compute the coefficients for
- // degree k-1 by calling this
- // function recursively, then it will
- // reset the size to k -- not enough
- // for what we want to do below. the
- // solution therefore is to only
- // resize the size if we are going to
- // *increase* it
- if (recursive_coefficients.size() < k+1)
- recursive_coefficients.resize (k+1);
+ // make sure that there is enough
+ // space in the array for the
+ // coefficients, so we have to resize
+ // it to size k+1
+
+ // but it's more complicated than
+ // that: we call this function
+ // recursively, so if we simply
+ // resize it to k+1 here, then
+ // compute the coefficients for
+ // degree k-1 by calling this
+ // function recursively, then it will
+ // reset the size to k -- not enough
+ // for what we want to do below. the
+ // solution therefore is to only
+ // resize the size if we are going to
+ // *increase* it
+ if (recursive_coefficients.size() < k+1)
+ recursive_coefficients.resize (k+1);
if (k<=1)
{
// now make these arrays
// const
recursive_coefficients[0] =
- std_cxx1x::shared_ptr<const std::vector<double> >(c0);
+ std_cxx1x::shared_ptr<const std::vector<double> >(c0);
recursive_coefficients[1] =
- std_cxx1x::shared_ptr<const std::vector<double> >(c1);
+ std_cxx1x::shared_ptr<const std::vector<double> >(c1);
}
else if (k==2)
{
(*c2)[2] = 4.*a;
recursive_coefficients[2] =
- std_cxx1x::shared_ptr<const std::vector<double> >(c2);
+ std_cxx1x::shared_ptr<const std::vector<double> >(c2);
}
else
{
// const pointer in the
// coefficients array
recursive_coefficients[k] =
- std_cxx1x::shared_ptr<const std::vector<double> >(ck);
+ std_cxx1x::shared_ptr<const std::vector<double> >(ck);
};
};
}
// then get a pointer to the array
// of coefficients. do that in a MT
- // safe way
+ // safe way
Threads::ThreadMutex::ScopedLock lock (coefficients_lock);
return *recursive_coefficients[k];
}
// $Id$
// Version: $Name$
//
-// Copyright (C) 2002, 2003, 2004, 2005, 2006 by the deal.II authors
+// Copyright (C) 2002, 2003, 2004, 2005, 2006, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
unsigned int (&index)[1]) const
{
Assert(i<index_map.size(),
- ExcIndexRange(i,0,index_map.size()));
+ ExcIndexRange(i,0,index_map.size()));
const unsigned int n=index_map[i];
index[0] = n;
}
unsigned int (&index)[2]) const
{
Assert(i<index_map.size(),
- ExcIndexRange(i,0,index_map.size()));
+ ExcIndexRange(i,0,index_map.size()));
const unsigned int n=index_map[i];
// there should be a better way to
// write this function (not
index[0] = n-k;
index[1] = iy;
return;
- }
+ }
else
k+=n_1d-iy;
}
unsigned int (&index)[3]) const
{
Assert(i<index_map.size(),
- ExcIndexRange(i,0,index_map.size()));
+ ExcIndexRange(i,0,index_map.size()));
const unsigned int n=index_map[i];
// there should be a better way to
// write this function (not
const std::vector<unsigned int> &renumber)
{
Assert(renumber.size()==index_map.size(),
- ExcDimensionMismatch(renumber.size(), index_map.size()));
+ ExcDimensionMismatch(renumber.size(), index_map.size()));
index_map=renumber;
for (unsigned int i=0; i<index_map.size(); ++i)
{
unsigned int ix[dim];
compute_index(i,ix);
-
+
Tensor<1,dim> result;
for (unsigned int d=0; d<dim; ++d)
result[d] = 1.;
polynomials[ix[d]].value(p(d), v);
result[d] *= v[1];
for (unsigned int d1=0; d1<dim; ++d1)
- if (d1 != d)
- result[d1] *= v[0];
+ if (d1 != d)
+ result[d1] *= v[0];
}
return result;
}
{
unsigned int ix[dim];
compute_index(i,ix);
-
+
Tensor<2,dim> result;
for (unsigned int d=0; d<dim; ++d)
for (unsigned int d1=0; d1<dim; ++d1)
result[d][d1] = 1.;
-
+
// get value, first and second
// derivatives
std::vector<double> v(3);
polynomials[ix[d]].value(p(d), v);
result[d][d] *= v[2];
for (unsigned int d1=0; d1<dim; ++d1)
- {
- if (d1 != d)
- {
- result[d][d1] *= v[1];
- result[d1][d] *= v[1];
- for (unsigned int d2=0; d2<dim; ++d2)
- if (d2 != d)
- result[d1][d2] *= v[0];
- }
- }
+ {
+ if (d1 != d)
+ {
+ result[d][d1] *= v[1];
+ result[d1][d] *= v[1];
+ for (unsigned int d2=0; d2<dim; ++d2)
+ if (d2 != d)
+ result[d1][d2] *= v[0];
+ }
+ }
}
return result;
}
std::vector<Tensor<2,dim> > &grad_grads) const
{
const unsigned int n_1d=polynomials.size();
-
+
Assert(values.size()==n_pols || values.size()==0,
- ExcDimensionMismatch2(values.size(), n_pols, 0));
+ ExcDimensionMismatch2(values.size(), n_pols, 0));
Assert(grads.size()==n_pols|| grads.size()==0,
- ExcDimensionMismatch2(grads.size(), n_pols, 0));
+ ExcDimensionMismatch2(grads.size(), n_pols, 0));
Assert(grad_grads.size()==n_pols|| grad_grads.size()==0,
- ExcDimensionMismatch2(grad_grads.size(), n_pols, 0));
+ ExcDimensionMismatch2(grad_grads.size(), n_pols, 0));
unsigned int v_size=0;
bool update_values=false, update_grads=false, update_grad_grads=false;
v_size=3;
}
- // Store data in a single
- // object. Access is by
- // v[d][n][o]
- // d: coordinate direction
- // n: number of 1d polynomial
- // o: order of derivative
+ // Store data in a single
+ // object. Access is by
+ // v[d][n][o]
+ // d: coordinate direction
+ // n: number of 1d polynomial
+ // o: order of derivative
Table<2,std::vector<double> > v(dim, n_1d);
for (unsigned int d=0; d<v.size()[0]; ++d)
for (unsigned int i=0; i<v.size()[1]; ++i)
if (update_values)
{
unsigned int k = 0;
-
+
for (unsigned int iz=0;iz<((dim>2) ? n_1d : 1);++iz)
- for (unsigned int iy=0;iy<((dim>1) ? n_1d-iz : 1);++iy)
- for (unsigned int ix=0; ix<n_1d-iy-iz; ++ix)
- values[index_map_inverse[k++]] =
- v[0][ix][0]
- * ((dim>1) ? v[1][iy][0] : 1.)
- * ((dim>2) ? v[2][iz][0] : 1.);
+ for (unsigned int iy=0;iy<((dim>1) ? n_1d-iz : 1);++iy)
+ for (unsigned int ix=0; ix<n_1d-iy-iz; ++ix)
+ values[index_map_inverse[k++]] =
+ v[0][ix][0]
+ * ((dim>1) ? v[1][iy][0] : 1.)
+ * ((dim>2) ? v[2][iz][0] : 1.);
}
-
+
if (update_grads)
{
unsigned int k = 0;
-
+
for (unsigned int iz=0;iz<((dim>2) ? n_1d : 1);++iz)
- for (unsigned int iy=0;iy<((dim>1) ? n_1d-iz : 1);++iy)
- for (unsigned int ix=0; ix<n_1d-iy-iz; ++ix)
- {
- const unsigned int k2=index_map_inverse[k++];
- for (unsigned int d=0;d<dim;++d)
- grads[k2][d] = v[0][ix][(d==0) ? 1 : 0]
+ for (unsigned int iy=0;iy<((dim>1) ? n_1d-iz : 1);++iy)
+ for (unsigned int ix=0; ix<n_1d-iy-iz; ++ix)
+ {
+ const unsigned int k2=index_map_inverse[k++];
+ for (unsigned int d=0;d<dim;++d)
+ grads[k2][d] = v[0][ix][(d==0) ? 1 : 0]
* ((dim>1) ? v[1][iy][(d==1) ? 1 : 0] : 1.)
* ((dim>2) ? v[2][iz][(d==2) ? 1 : 0] : 1.);
- }
+ }
}
if (update_grad_grads)
{
unsigned int k = 0;
-
+
for (unsigned int iz=0;iz<((dim>2) ? n_1d : 1);++iz)
- for (unsigned int iy=0;iy<((dim>1) ? n_1d-iz : 1);++iy)
- for (unsigned int ix=0; ix<n_1d-iy-iz; ++ix)
- {
- const unsigned int k2=index_map_inverse[k++];
- for (unsigned int d1=0; d1<dim; ++d1)
- for (unsigned int d2=0; d2<dim; ++d2)
- {
- // Derivative
- // order for each
- // direction
- const unsigned int
- j0 = ((d1==0) ? 1 : 0) + ((d2==0) ? 1 : 0);
- const unsigned int
- j1 = ((d1==1) ? 1 : 0) + ((d2==1) ? 1 : 0);
- const unsigned int
- j2 = ((d1==2) ? 1 : 0) + ((d2==2) ? 1 : 0);
-
- grad_grads[k2][d1][d2] =
- v[0][ix][j0]
- * ((dim>1) ? v[1][iy][j1] : 1.)
- * ((dim>2) ? v[2][iz][j2] : 1.);
- }
- }
+ for (unsigned int iy=0;iy<((dim>1) ? n_1d-iz : 1);++iy)
+ for (unsigned int ix=0; ix<n_1d-iy-iz; ++ix)
+ {
+ const unsigned int k2=index_map_inverse[k++];
+ for (unsigned int d1=0; d1<dim; ++d1)
+ for (unsigned int d2=0; d2<dim; ++d2)
+ {
+ // Derivative
+ // order for each
+ // direction
+ const unsigned int
+ j0 = ((d1==0) ? 1 : 0) + ((d2==0) ? 1 : 0);
+ const unsigned int
+ j1 = ((d1==1) ? 1 : 0) + ((d2==1) ? 1 : 0);
+ const unsigned int
+ j2 = ((d1==2) ? 1 : 0) + ((d2==2) ? 1 : 0);
+
+ grad_grads[k2][d1][d2] =
+ v[0][ix][j0]
+ * ((dim>1) ? v[1][iy][j1] : 1.)
+ * ((dim>2) ? v[2][iz][j2] : 1.);
+ }
+ }
}
}
// $Id$
// Version: $Name$
//
-// Copyright (C) 2004, 2005, 2006, 2010 by the deal.II authors
+// Copyright (C) 2004, 2005, 2006, 2010, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
template <int dim>
PolynomialsABF<dim>::PolynomialsABF (const unsigned int k)
- :
- my_degree(k),
- n_pols(compute_n_pols(k))
+ :
+ my_degree(k),
+ n_pols(compute_n_pols(k))
{
std::vector<std::vector< Polynomials::Polynomial< double > > > pols(dim);
pols[0] = Polynomials::LagrangeEquidistant::generate_complete_basis(k+2);
template <int dim>
void
PolynomialsABF<dim>::compute (const Point<dim> &unit_point,
- std::vector<Tensor<1,dim> > &values,
- std::vector<Tensor<2,dim> > &grads,
- std::vector<Tensor<3,dim> > &grad_grads) const
+ std::vector<Tensor<1,dim> > &values,
+ std::vector<Tensor<2,dim> > &grads,
+ std::vector<Tensor<3,dim> > &grad_grads) const
{
Assert(values.size()==n_pols || values.size()==0,
- ExcDimensionMismatch(values.size(), n_pols));
+ ExcDimensionMismatch(values.size(), n_pols));
Assert(grads.size()==n_pols|| grads.size()==0,
- ExcDimensionMismatch(grads.size(), n_pols));
+ ExcDimensionMismatch(grads.size(), n_pols));
Assert(grad_grads.size()==n_pols|| grad_grads.size()==0,
- ExcDimensionMismatch(grad_grads.size(), n_pols));
+ ExcDimensionMismatch(grad_grads.size(), n_pols));
const unsigned int n_sub = polynomial_space->n();
- // guard access to the scratch
- // arrays in the following block
- // using a mutex to make sure they
- // are not used by multiple threads
- // at once
+ // guard access to the scratch
+ // arrays in the following block
+ // using a mutex to make sure they
+ // are not used by multiple threads
+ // at once
Threads::Mutex::ScopedLock lock(mutex);
p_values.resize((values.size() == 0) ? 0 : n_sub);
for (unsigned int d=0;d<dim;++d)
{
- // First we copy the point. The
- // polynomial space for
- // component d consists of
- // polynomials of degree k+1 in
- // x_d and degree k in the
- // other variables. in order to
- // simplify this, we use the
- // same AnisotropicPolynomial
- // space and simply rotate the
- // coordinates through all
- // directions.
+ // First we copy the point. The
+ // polynomial space for
+ // component d consists of
+ // polynomials of degree k+1 in
+ // x_d and degree k in the
+ // other variables. in order to
+ // simplify this, we use the
+ // same AnisotropicPolynomial
+ // space and simply rotate the
+ // coordinates through all
+ // directions.
Point<dim> p;
for (unsigned int c=0;c<dim;++c)
- p(c) = unit_point((c+d)%dim);
+ p(c) = unit_point((c+d)%dim);
polynomial_space->compute (p, p_values, p_grads, p_grad_grads);
for (unsigned int i=0;i<p_values.size();++i)
- values[i+d*n_sub][d] = p_values[i];
+ values[i+d*n_sub][d] = p_values[i];
for (unsigned int i=0;i<p_grads.size();++i)
- for (unsigned int d1=0;d1<dim;++d1)
- grads[i+d*n_sub][d][(d1+d)%dim] = p_grads[i][d1];
+ for (unsigned int d1=0;d1<dim;++d1)
+ grads[i+d*n_sub][d][(d1+d)%dim] = p_grads[i][d1];
for (unsigned int i=0;i<p_grad_grads.size();++i)
- for (unsigned int d1=0;d1<dim;++d1)
- for (unsigned int d2=0;d2<dim;++d2)
- grad_grads[i+d*n_sub][d][(d1+d)%dim][(d2+d)%dim]
- = p_grad_grads[i][d1][d2];
+ for (unsigned int d1=0;d1<dim;++d1)
+ for (unsigned int d2=0;d2<dim;++d2)
+ grad_grads[i+d*n_sub][d][(d1+d)%dim][(d2+d)%dim]
+ = p_grad_grads[i][d1][d2];
}
}
// $Id$
// Version: $Name$
//
-// Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009, 2010 by the deal.II authors
+// Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009, 2010, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
#include <deal.II/base/polynomials_adini.h>
-#define ENTER_COEFFICIENTS(koefs,z,a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11) \
+#define ENTER_COEFFICIENTS(koefs,z,a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11) \
koefs(0, z)= a0; koefs(1, z)=a1; koefs(2, z)=a2; koefs(3, z)=a3; koefs( 4, z)=a4 ; koefs( 5, z)=a5 ; \
koefs(6, z)= a6; koefs(7, z)=a7; koefs(8, z)=a8; koefs(9, z)=a9; koefs(10, z)=a10; koefs(11, z)=a11;
// $Id$
// Version: $Name$
//
-// Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 by the deal.II authors
+// Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
template <int dim>
PolynomialsBDM<dim>::PolynomialsBDM (const unsigned int k)
- :
- polynomial_space (Polynomials::Legendre::generate_complete_basis(k)),
- monomials((dim==2) ? (1) : (k+2)),
- n_pols(compute_n_pols(k)),
- p_values(polynomial_space.n()),
- p_grads(polynomial_space.n()),
- p_grad_grads(polynomial_space.n())
+ :
+ polynomial_space (Polynomials::Legendre::generate_complete_basis(k)),
+ monomials((dim==2) ? (1) : (k+2)),
+ n_pols(compute_n_pols(k)),
+ p_values(polynomial_space.n()),
+ p_grads(polynomial_space.n()),
+ p_grad_grads(polynomial_space.n())
{
switch(dim)
{
case 2:
- monomials[0] = Polynomials::Monomial<double> (k+1);
- break;
+ monomials[0] = Polynomials::Monomial<double> (k+1);
+ break;
case 3:
- for (unsigned int i=0;i<monomials.size();++i)
- monomials[i] = Polynomials::Monomial<double> (i);
- break;
+ for (unsigned int i=0;i<monomials.size();++i)
+ monomials[i] = Polynomials::Monomial<double> (i);
+ break;
default:
- Assert(false, ExcNotImplemented());
+ Assert(false, ExcNotImplemented());
}
}
template <int dim>
void
PolynomialsBDM<dim>::compute (const Point<dim> &unit_point,
- std::vector<Tensor<1,dim> > &values,
- std::vector<Tensor<2,dim> > &grads,
- std::vector<Tensor<3,dim> > &grad_grads) const
+ std::vector<Tensor<1,dim> > &values,
+ std::vector<Tensor<2,dim> > &grads,
+ std::vector<Tensor<3,dim> > &grad_grads) const
{
Assert(values.size()==n_pols || values.size()==0,
- ExcDimensionMismatch(values.size(), n_pols));
+ ExcDimensionMismatch(values.size(), n_pols));
Assert(grads.size()==n_pols|| grads.size()==0,
- ExcDimensionMismatch(grads.size(), n_pols));
+ ExcDimensionMismatch(grads.size(), n_pols));
Assert(grad_grads.size()==n_pols|| grad_grads.size()==0,
- ExcDimensionMismatch(grad_grads.size(), n_pols));
+ ExcDimensionMismatch(grad_grads.size(), n_pols));
const unsigned int n_sub = polynomial_space.n();
- // guard access to the scratch
- // arrays in the following block
- // using a mutex to make sure they
- // are not used by multiple threads
- // at once
+ // guard access to the scratch
+ // arrays in the following block
+ // using a mutex to make sure they
+ // are not used by multiple threads
+ // at once
{
Threads::Mutex::ScopedLock lock(mutex);
p_grads.resize((grads.size() == 0) ? 0 : n_sub);
p_grad_grads.resize((grad_grads.size() == 0) ? 0 : n_sub);
- // Compute values of complete space
- // and insert into tensors. Result
- // will have first all polynomials
- // in the x-component, then y and
- // z.
+ // Compute values of complete space
+ // and insert into tensors. Result
+ // will have first all polynomials
+ // in the x-component, then y and
+ // z.
polynomial_space.compute (unit_point, p_values, p_grads, p_grad_grads);
std::fill(values.begin(), values.end(), Tensor<1,dim>());
for (unsigned int i=0;i<p_values.size();++i)
for (unsigned int j=0;j<dim;++j)
- values[i+j*n_sub][j] = p_values[i];
+ values[i+j*n_sub][j] = p_values[i];
std::fill(grads.begin(), grads.end(), Tensor<2,dim>());
for (unsigned int i=0;i<p_grads.size();++i)
for (unsigned int j=0;j<dim;++j)
- grads[i+j*n_sub][j] = p_grads[i];
+ grads[i+j*n_sub][j] = p_grads[i];
std::fill(grad_grads.begin(), grad_grads.end(), Tensor<3,dim>());
for (unsigned int i=0;i<p_grad_grads.size();++i)
for (unsigned int j=0;j<dim;++j)
- grad_grads[i+j*n_sub][j] = p_grad_grads[i];
+ grad_grads[i+j*n_sub][j] = p_grad_grads[i];
}
- // This is the first polynomial not
- // covered by the P_k subspace
+ // This is the first polynomial not
+ // covered by the P_k subspace
unsigned int start = dim*n_sub;
- // Store values of auxiliary
- // polynomials and their three
- // derivatives
+ // Store values of auxiliary
+ // polynomials and their three
+ // derivatives
std::vector<std::vector<double> > monovali(dim, std::vector<double>(4));
std::vector<std::vector<double> > monovalk(dim, std::vector<double>(4));
if (dim == 2)
{
for (unsigned int d=0;d<dim;++d)
- monomials[0].value(unit_point(d), monovali[d]);
+ monomials[0].value(unit_point(d), monovali[d]);
if (values.size() != 0)
- {
- values[start][0] = monovali[0][0];
- values[start][1] = -unit_point(1) * monovali[0][1];
- values[start+1][0] = -unit_point(0) * monovali[1][1];
- values[start+1][1] = monovali[1][0];
- }
+ {
+ values[start][0] = monovali[0][0];
+ values[start][1] = -unit_point(1) * monovali[0][1];
+ values[start+1][0] = -unit_point(0) * monovali[1][1];
+ values[start+1][1] = monovali[1][0];
+ }
if (grads.size() != 0)
- {
- grads[start][0][0] = monovali[0][1];
- grads[start][0][1] = 0.;
- grads[start][1][0] = -unit_point(1) * monovali[0][2];
- grads[start][1][1] = -monovali[0][1];
- grads[start+1][0][0] = -monovali[1][1];
- grads[start+1][0][1] = -unit_point(0) * monovali[1][2];
- grads[start+1][1][0] = 0.;
- grads[start+1][1][1] = monovali[1][1];
- }
+ {
+ grads[start][0][0] = monovali[0][1];
+ grads[start][0][1] = 0.;
+ grads[start][1][0] = -unit_point(1) * monovali[0][2];
+ grads[start][1][1] = -monovali[0][1];
+ grads[start+1][0][0] = -monovali[1][1];
+ grads[start+1][0][1] = -unit_point(0) * monovali[1][2];
+ grads[start+1][1][0] = 0.;
+ grads[start+1][1][1] = monovali[1][1];
+ }
if (grad_grads.size() != 0)
- {
- grad_grads[start][0][0][0] = monovali[0][2];
- grad_grads[start][0][0][1] = 0.;
- grad_grads[start][0][1][0] = 0.;
- grad_grads[start][0][1][1] = 0.;
- grad_grads[start][1][0][0] = -unit_point(1) * monovali[0][3];
- grad_grads[start][1][0][1] = -monovali[0][2];
- grad_grads[start][1][1][0] = -monovali[0][2];
- grad_grads[start][1][1][1] = 0.;
- grad_grads[start+1][0][0][0] = 0;
- grad_grads[start+1][0][0][1] = -monovali[1][2];
- grad_grads[start+1][0][1][0] = -monovali[1][2];
- grad_grads[start+1][0][1][1] = -unit_point(0) * monovali[1][3];
- grad_grads[start+1][1][0][0] = 0.;
- grad_grads[start+1][1][0][1] = 0.;
- grad_grads[start+1][1][1][0] = 0.;
- grad_grads[start+1][1][1][1] = monovali[1][2];
- }
+ {
+ grad_grads[start][0][0][0] = monovali[0][2];
+ grad_grads[start][0][0][1] = 0.;
+ grad_grads[start][0][1][0] = 0.;
+ grad_grads[start][0][1][1] = 0.;
+ grad_grads[start][1][0][0] = -unit_point(1) * monovali[0][3];
+ grad_grads[start][1][0][1] = -monovali[0][2];
+ grad_grads[start][1][1][0] = -monovali[0][2];
+ grad_grads[start][1][1][1] = 0.;
+ grad_grads[start+1][0][0][0] = 0;
+ grad_grads[start+1][0][0][1] = -monovali[1][2];
+ grad_grads[start+1][0][1][0] = -monovali[1][2];
+ grad_grads[start+1][0][1][1] = -unit_point(0) * monovali[1][3];
+ grad_grads[start+1][1][0][0] = 0.;
+ grad_grads[start+1][1][0][1] = 0.;
+ grad_grads[start+1][1][1][0] = 0.;
+ grad_grads[start+1][1][1][1] = monovali[1][2];
+ }
}
else // dim == 3
{
- // The number of curls in each
- // component. Note that the
- // table in BrezziFortin91 has
- // a typo, but the text has the
- // right basis
-
- // Note that the next basis
- // function is always obtained
- // from the previous by cyclic
- // rotation of the coordinates
+ // The number of curls in each
+ // component. Note that the
+ // table in BrezziFortin91 has
+ // a typo, but the text has the
+ // right basis
+
+ // Note that the next basis
+ // function is always obtained
+ // from the previous by cyclic
+ // rotation of the coordinates
const unsigned int n_curls = monomials.size() - 1;
for (unsigned int i=0;i<n_curls;++i, start+=dim)
- {
- for (unsigned int d=0;d<dim;++d)
- {
- // p(t) = t^(i+1)
- monomials[i+1].value(unit_point(d), monovali[d]);
- // q(t) = t^(k-i)
- monomials[degree()-i].value(unit_point(d), monovalk[d]);
- }
- if (values.size() != 0)
- {
- // x p'(y) q(z)
- values[start][0] = unit_point(0) * monovali[1][1] * monovalk[2][0];
- // - p(y) q(z)
- values[start][1] = -monovali[1][0] * monovalk[2][0];
- values[start][2] = 0.;
-
- // y p'(z) q(x)
- values[start+1][1] = unit_point(1) * monovali[2][1] * monovalk[0][0];
- // - p(z) q(x)
- values[start+1][2] = -monovali[2][0] * monovalk[0][0];
- values[start+1][0] = 0.;
-
- // z p'(x) q(y)
- values[start+2][2] = unit_point(2) * monovali[0][1] * monovalk[1][0];
- // -p(x) q(y)
- values[start+2][0] = -monovali[0][0] * monovalk[1][0];
- values[start+2][1] = 0.;
- }
- if (grads.size() != 0)
- {
- grads[start][0][0] = monovali[1][1] * monovalk[2][0];
- grads[start][0][1] = unit_point(0) * monovali[1][2] * monovalk[2][0];
- grads[start][0][2] = unit_point(0) * monovali[1][1] * monovalk[2][1];
- grads[start][1][0] = 0.;
- grads[start][1][1] = -monovali[1][1] * monovalk[2][0];
- grads[start][1][2] = -monovali[1][0] * monovalk[2][1];
- grads[start+2][2][0] = 0.;
- grads[start+2][2][1] = 0.;
- grads[start+2][2][2] = 0.;
-
- grads[start+1][1][1] = monovali[2][1] * monovalk[0][0];
- grads[start+1][1][2] = unit_point(1) * monovali[2][2] * monovalk[0][0];
- grads[start+1][1][0] = unit_point(1) * monovali[2][1] * monovalk[0][1];
- grads[start+1][2][1] = 0.;
- grads[start+1][2][2] = -monovali[2][1] * monovalk[0][0];
- grads[start+1][2][0] = -monovali[2][0] * monovalk[0][1];
- grads[start+1][0][1] = 0.;
- grads[start+1][0][2] = 0.;
- grads[start+1][0][0] = 0.;
-
- grads[start+2][2][2] = monovali[0][1] * monovalk[1][0];
- grads[start+2][2][0] = unit_point(2) * monovali[0][2] * monovalk[1][0];
- grads[start+2][2][1] = unit_point(2) * monovali[0][1] * monovalk[1][1];
- grads[start+2][0][2] = 0.;
- grads[start+2][0][0] = -monovali[0][1] * monovalk[1][0];
- grads[start+2][0][1] = -monovali[0][0] * monovalk[1][1];
- grads[start+2][1][2] = 0.;
- grads[start+2][1][0] = 0.;
- grads[start+2][1][1] = 0.;
- }
- if (grad_grads.size() != 0)
- {
- Assert(false,ExcNotImplemented());
- }
- }
+ {
+ for (unsigned int d=0;d<dim;++d)
+ {
+ // p(t) = t^(i+1)
+ monomials[i+1].value(unit_point(d), monovali[d]);
+ // q(t) = t^(k-i)
+ monomials[degree()-i].value(unit_point(d), monovalk[d]);
+ }
+ if (values.size() != 0)
+ {
+ // x p'(y) q(z)
+ values[start][0] = unit_point(0) * monovali[1][1] * monovalk[2][0];
+ // - p(y) q(z)
+ values[start][1] = -monovali[1][0] * monovalk[2][0];
+ values[start][2] = 0.;
+
+ // y p'(z) q(x)
+ values[start+1][1] = unit_point(1) * monovali[2][1] * monovalk[0][0];
+ // - p(z) q(x)
+ values[start+1][2] = -monovali[2][0] * monovalk[0][0];
+ values[start+1][0] = 0.;
+
+ // z p'(x) q(y)
+ values[start+2][2] = unit_point(2) * monovali[0][1] * monovalk[1][0];
+ // -p(x) q(y)
+ values[start+2][0] = -monovali[0][0] * monovalk[1][0];
+ values[start+2][1] = 0.;
+ }
+ if (grads.size() != 0)
+ {
+ grads[start][0][0] = monovali[1][1] * monovalk[2][0];
+ grads[start][0][1] = unit_point(0) * monovali[1][2] * monovalk[2][0];
+ grads[start][0][2] = unit_point(0) * monovali[1][1] * monovalk[2][1];
+ grads[start][1][0] = 0.;
+ grads[start][1][1] = -monovali[1][1] * monovalk[2][0];
+ grads[start][1][2] = -monovali[1][0] * monovalk[2][1];
+ grads[start+2][2][0] = 0.;
+ grads[start+2][2][1] = 0.;
+ grads[start+2][2][2] = 0.;
+
+ grads[start+1][1][1] = monovali[2][1] * monovalk[0][0];
+ grads[start+1][1][2] = unit_point(1) * monovali[2][2] * monovalk[0][0];
+ grads[start+1][1][0] = unit_point(1) * monovali[2][1] * monovalk[0][1];
+ grads[start+1][2][1] = 0.;
+ grads[start+1][2][2] = -monovali[2][1] * monovalk[0][0];
+ grads[start+1][2][0] = -monovali[2][0] * monovalk[0][1];
+ grads[start+1][0][1] = 0.;
+ grads[start+1][0][2] = 0.;
+ grads[start+1][0][0] = 0.;
+
+ grads[start+2][2][2] = monovali[0][1] * monovalk[1][0];
+ grads[start+2][2][0] = unit_point(2) * monovali[0][2] * monovalk[1][0];
+ grads[start+2][2][1] = unit_point(2) * monovali[0][1] * monovalk[1][1];
+ grads[start+2][0][2] = 0.;
+ grads[start+2][0][0] = -monovali[0][1] * monovalk[1][0];
+ grads[start+2][0][1] = -monovali[0][0] * monovalk[1][1];
+ grads[start+2][1][2] = 0.;
+ grads[start+2][1][0] = 0.;
+ grads[start+2][1][1] = 0.;
+ }
+ if (grad_grads.size() != 0)
+ {
+ Assert(false,ExcNotImplemented());
+ }
+ }
Assert(start == n_pols, ExcInternalError());
}
}
{
double orientation = 1.;
if ((face==0) || (face==3))
- orientation = -1.;
+ orientation = -1.;
for (unsigned int k=0;k<qface.size();++k)
- {
- const double w = qface.weight(k) * orientation;
- const double x = qface.point(k)(0);
- Point<dim> p;
- switch (face)
- {
- case 2:
- p(1) = 1.;
- case 0:
- p(0) = x;
- break;
- case 1:
- p(0) = 1.;
- case 3:
- p(1) = x;
- break;
- }
-// std::cerr << p
-// << '\t' << moment_weight[0].value(x)
-// << '\t' << moment_weight[1].value(x)
-// ;
-
- compute (p, values, grads, grad_grads);
-
- for (unsigned int i=0;i<n();++i)
- {
-// std::cerr << '\t' << std::setw(6) << values[i][1-face%2];
- // Integrate normal component.
- // This is easy on the unit square
- for (unsigned int j=0;j<moment_weight.size();++j)
- A(moment_weight.size()*face+j,i)
- += w * values[i][1-face%2] * moment_weight[j].value(x);
- }
-// std::cerr << std::endl;
- }
+ {
+ const double w = qface.weight(k) * orientation;
+ const double x = qface.point(k)(0);
+ Point<dim> p;
+ switch (face)
+ {
+ case 2:
+ p(1) = 1.;
+ case 0:
+ p(0) = x;
+ break;
+ case 1:
+ p(0) = 1.;
+ case 3:
+ p(1) = x;
+ break;
+ }
+// std::cerr << p
+// << '\t' << moment_weight[0].value(x)
+// << '\t' << moment_weight[1].value(x)
+// ;
+
+ compute (p, values, grads, grad_grads);
+
+ for (unsigned int i=0;i<n();++i)
+ {
+// std::cerr << '\t' << std::setw(6) << values[i][1-face%2];
+ // Integrate normal component.
+ // This is easy on the unit square
+ for (unsigned int j=0;j<moment_weight.size();++j)
+ A(moment_weight.size()*face+j,i)
+ += w * values[i][1-face%2] * moment_weight[j].value(x);
+ }
+// std::cerr << std::endl;
+ }
}
- // Volume integrals are missing
- //
- // This degree is one larger
+ // Volume integrals are missing
+ //
+ // This degree is one larger
Assert (polynomial_space.degree() <= 2,
- ExcNotImplemented());
+ ExcNotImplemented());
}
*/
}
- // Compute the values, gradients
- // and double gradients of the
- // polynomial at the given point.
+ // Compute the values, gradients
+ // and double gradients of the
+ // polynomial at the given point.
template<int dim>
void
PolynomialsNedelec<dim>::compute (const Point<dim> &unit_point,
ExcDimensionMismatch(grads.size (), n_pols));
Assert(grad_grads.size () == n_pols || grad_grads.size () == 0,
ExcDimensionMismatch(grad_grads.size (), n_pols));
-
- // Declare the values, derivatives
- // and second derivatives vectors of
- // <tt>polynomial_space</tt> at
- // <tt>unit_point</tt>
+
+ // Declare the values, derivatives
+ // and second derivatives vectors of
+ // <tt>polynomial_space</tt> at
+ // <tt>unit_point</tt>
const unsigned int& n_basis = polynomial_space.n ();
std::vector<double> unit_point_values ((values.size () == 0) ? 0 : n_basis);
std::vector<Tensor<1, dim> >
{
polynomial_space.compute (unit_point, unit_point_values,
unit_point_grads, unit_point_grad_grads);
-
- // Assign the correct values to the
- // corresponding shape functions.
+
+ // Assign the correct values to the
+ // corresponding shape functions.
if (values.size () > 0)
for (unsigned int i = 0; i < unit_point_values.size (); ++i)
values[i][0] = unit_point_values[i];
{
polynomial_space.compute (unit_point, unit_point_values,
unit_point_grads, unit_point_grad_grads);
-
- // Declare the values, derivatives and
- // second derivatives vectors of
- // <tt>polynomial_space</tt> at
- // <tt>unit_point</tt> with coordinates
- // shifted one step in positive direction
+
+ // Declare the values, derivatives and
+ // second derivatives vectors of
+ // <tt>polynomial_space</tt> at
+ // <tt>unit_point</tt> with coordinates
+ // shifted one step in positive direction
Point<dim> p;
p (0) = unit_point (1);
p (1) = unit_point (0);
-
+
std::vector<double> p_values ((values.size () == 0) ? 0 : n_basis);
std::vector<Tensor<1, dim> >
p_grads ((grads.size () == 0) ? 0 : n_basis);
std::vector<Tensor<2, dim> >
p_grad_grads ((grad_grads.size () == 0) ? 0 : n_basis);
-
+
polynomial_space.compute (p, p_values, p_grads, p_grad_grads);
-
- // Assign the correct values to the
- // corresponding shape functions.
+
+ // Assign the correct values to the
+ // corresponding shape functions.
if (values.size () > 0)
{
for (unsigned int i = 0; i <= my_degree; ++i)
= unit_point_grads[i + j * (my_degree + 1)][k];
grads[i + (j + 2) * (my_degree + 1)][1][k] = 0.0;
}
-
+
grads[i + j * (my_degree + 1)][1][0]
= p_grads[i + j * (my_degree + 1)][1];
grads[i + j * (my_degree + 1)][1][1]
+ GeometryInfo<dim>::lines_per_cell)
* (my_degree + 1)][0][k] = 0.0;
}
-
+
grads[i + (j + my_degree
+ GeometryInfo<dim>::lines_per_cell)
* (my_degree + 1)][1][0]
grad_grads[i + (j + 2) * (my_degree + 1)][1][k][l]
= 0.0;
}
-
+
grad_grads[i + j * (my_degree + 1)][1][0][0]
= p_grad_grads[i + j * (my_degree + 1)][1][1];
grad_grads[i + j * (my_degree + 1)][1][0][1]
+ GeometryInfo<dim>::lines_per_cell)
* (my_degree + 1)][0][k][l] = 0.0;
}
-
+
grad_grads[i + (j + my_degree
+ GeometryInfo<dim>::lines_per_cell)
* (my_degree + 1)][1][0][0]
{
polynomial_space.compute (unit_point, unit_point_values,
unit_point_grads, unit_point_grad_grads);
-
- // Declare the values, derivatives
- // and second derivatives vectors of
- // <tt>polynomial_space</tt> at
- // <tt>unit_point</tt> with coordinates
- // shifted two steps in positive
- // direction
+
+ // Declare the values, derivatives
+ // and second derivatives vectors of
+ // <tt>polynomial_space</tt> at
+ // <tt>unit_point</tt> with coordinates
+ // shifted two steps in positive
+ // direction
Point<dim> p1, p2;
std::vector<double> p1_values ((values.size () == 0) ? 0 : n_basis);
std::vector<Tensor<1, dim> >
p2 (1) = unit_point (0);
p2 (2) = unit_point (1);
polynomial_space.compute (p2, p2_values, p2_grads, p2_grad_grads);
-
- // Assign the correct values to the
- // corresponding shape functions.
+
+ // Assign the correct values to the
+ // corresponding shape functions.
if (values.size () > 0)
{
for (unsigned int i = 0; i <= my_degree; ++i)
* my_degree + j
+ GeometryInfo<dim>::lines_per_cell][2]
= p2_values[i + (j + k * (my_degree + 2) + 2)
- * (my_degree + 1)];
+ * (my_degree + 1)];
values[i + (j + (2 * k + 5) * my_degree
+ GeometryInfo<dim>::lines_per_cell)
* (my_degree + 1)][0]
grads[i + (j + 4 * k + 2) * (my_degree + 1)][0][l]
= unit_point_grads[i + (j + k * (my_degree + 2))
* (my_degree + 1)][l];
-
+
grads[i + (j + 2 * (k + 4)) * (my_degree + 1)][2][0]
= p2_grads[i + (j + k * (my_degree + 2))
* (my_degree + 1)][1];
* (my_degree + 2) + 2)
* (my_degree + 1)][l];
}
-
+
grads[(i + (j + 2 * GeometryInfo<dim>::faces_per_cell
+ my_degree) * (my_degree + 1)
+ GeometryInfo<dim>::lines_per_cell)
for (unsigned int l = 0; l < 2; ++l)
for (unsigned int m = 0; m < dim; ++m)
{
- for (unsigned int n = 0; n < 2; ++n)
- {
+ for (unsigned int n = 0; n < 2; ++n)
+ {
grads[i + (j + (2 * (k + 2 * l) + 1)
* my_degree
+ GeometryInfo<dim>::lines_per_cell)
* (my_degree + 1)][l]
[m];
}
-
+
grad_grads[i + (j + 2 * (k + 4)) * (my_degree + 1)]
[2][0][0]
= p2_grad_grads[i + (j + k * (my_degree + 2))
+ 2) * (my_degree
+ 1)][l][m];
}
-
+
grad_grads[(i + (j + 2
* GeometryInfo<dim>::faces_per_cell
+ my_degree)
* (my_degree + 1)][2 * n][l][m]
= 0.0;
}
-
+
grad_grads[i + (j + (2 * k + 5) * my_degree
+ GeometryInfo<dim>::lines_per_cell)
* (my_degree + 1)]
}
}
}
-
+
break;
}
-
+
default:
Assert (false, ExcNotImplemented ());
}
// $Id$
// Version: $Name$
//
-// Copyright (C) 2004, 2005, 2006 by the deal.II authors
+// Copyright (C) 2004, 2005, 2006, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
template <int dim>
PolynomialsP<dim>::PolynomialsP (const unsigned int p)
- :
- PolynomialSpace<dim>(Polynomials::Monomial<double>::generate_complete_basis(p)),
- p(p)
+ :
+ PolynomialSpace<dim>(Polynomials::Monomial<double>::generate_complete_basis(p)),
+ p(p)
{
std::vector<unsigned int> index_map(this->n());
create_polynomial_ordering(index_map);
std::vector<unsigned int> &index_map) const
{
Assert(index_map.size()==this->n(),
- ExcDimensionMismatch(index_map.size(), this->n()));
+ ExcDimensionMismatch(index_map.size(), this->n()));
- // identity
+ // identity
for (unsigned int i=0; i<this->n(); ++i)
index_map[i]=i;
}
std::vector<unsigned int> &index_map) const
{
Assert(index_map.size()==this->n(),
- ExcDimensionMismatch(index_map.size(), this->n()));
+ ExcDimensionMismatch(index_map.size(), this->n()));
Assert(p<=5, ExcNotImplemented());
-
- // Given the number i of the
- // polynomial in
- // $1,x,y,xy,x2,y2,...$,
- // index_map[i] gives the number of
- // the polynomial in
- // PolynomialSpace.
+
+ // Given the number i of the
+ // polynomial in
+ // $1,x,y,xy,x2,y2,...$,
+ // index_map[i] gives the number of
+ // the polynomial in
+ // PolynomialSpace.
for (unsigned int i=0; i<this->n(); ++i)
index_map[i]=imap2[p][i];
}
std::vector<unsigned int> &index_map) const
{
Assert(index_map.size()==this->n(),
- ExcDimensionMismatch(index_map.size(), this->n()));
+ ExcDimensionMismatch(index_map.size(), this->n()));
Assert(p<=3, ExcNotImplemented());
-
- // Given the number i of the
- // polynomial in
- // $1,x,y,xy,x2,y2,...$,
- // index_map[i] gives the number of
- // the polynomial in
- // PolynomialSpace.
+
+ // Given the number i of the
+ // polynomial in
+ // $1,x,y,xy,x2,y2,...$,
+ // index_map[i] gives the number of
+ // the polynomial in
+ // PolynomialSpace.
for (unsigned int i=0; i<this->n(); ++i)
index_map[i]=imap3[p][i];
}
// $Id$
// Version: $Name$
//
-// Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 by the deal.II authors
+// Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
template <int dim>
PolynomialsRaviartThomas<dim>::PolynomialsRaviartThomas (const unsigned int k)
- :
- my_degree(k),
- polynomial_space (create_polynomials (k)),
- n_pols(compute_n_pols(k))
+ :
+ my_degree(k),
+ polynomial_space (create_polynomials (k)),
+ n_pols(compute_n_pols(k))
{}
template <int dim>
void
PolynomialsRaviartThomas<dim>::compute (const Point<dim> &unit_point,
- std::vector<Tensor<1,dim> > &values,
- std::vector<Tensor<2,dim> > &grads,
- std::vector<Tensor<3,dim> > &grad_grads) const
+ std::vector<Tensor<1,dim> > &values,
+ std::vector<Tensor<2,dim> > &grads,
+ std::vector<Tensor<3,dim> > &grad_grads) const
{
Assert(values.size()==n_pols || values.size()==0,
- ExcDimensionMismatch(values.size(), n_pols));
+ ExcDimensionMismatch(values.size(), n_pols));
Assert(grads.size()==n_pols|| grads.size()==0,
- ExcDimensionMismatch(grads.size(), n_pols));
+ ExcDimensionMismatch(grads.size(), n_pols));
Assert(grad_grads.size()==n_pols|| grad_grads.size()==0,
- ExcDimensionMismatch(grad_grads.size(), n_pols));
-
- // have a few scratch
- // arrays. because we don't want to
- // re-allocate them every time this
- // function is called, we make them
- // static. however, in return we
- // have to ensure that the calls to
- // the use of these variables is
- // locked with a mutex. if the
- // mutex is removed, several tests
- // (notably
- // deal.II/create_mass_matrix_05)
- // will start to produce random
- // results in multithread mode
+ ExcDimensionMismatch(grad_grads.size(), n_pols));
+
+ // have a few scratch
+ // arrays. because we don't want to
+ // re-allocate them every time this
+ // function is called, we make them
+ // static. however, in return we
+ // have to ensure that the calls to
+ // the use of these variables is
+ // locked with a mutex. if the
+ // mutex is removed, several tests
+ // (notably
+ // deal.II/create_mass_matrix_05)
+ // will start to produce random
+ // results in multithread mode
static Threads::ThreadMutex mutex;
Threads::ThreadMutex::ScopedLock lock(mutex);
- static std::vector<double> p_values;
+ static std::vector<double> p_values;
static std::vector<Tensor<1,dim> > p_grads;
static std::vector<Tensor<2,dim> > p_grad_grads;
- const unsigned int n_sub = polynomial_space.n();
+ const unsigned int n_sub = polynomial_space.n();
p_values.resize((values.size() == 0) ? 0 : n_sub);
p_grads.resize((grads.size() == 0) ? 0 : n_sub);
p_grad_grads.resize((grad_grads.size() == 0) ? 0 : n_sub);
-
+
for (unsigned int d=0;d<dim;++d)
{
- // First we copy the point. The
- // polynomial space for
- // component d consists of
- // polynomials of degree k+1 in
- // x_d and degree k in the
- // other variables. in order to
- // simplify this, we use the
- // same AnisotropicPolynomial
- // space and simply rotate the
- // coordinates through all
- // directions.
+ // First we copy the point. The
+ // polynomial space for
+ // component d consists of
+ // polynomials of degree k+1 in
+ // x_d and degree k in the
+ // other variables. in order to
+ // simplify this, we use the
+ // same AnisotropicPolynomial
+ // space and simply rotate the
+ // coordinates through all
+ // directions.
Point<dim> p;
for (unsigned int c=0;c<dim;++c)
- p(c) = unit_point((c+d)%dim);
-
+ p(c) = unit_point((c+d)%dim);
+
polynomial_space.compute (p, p_values, p_grads, p_grad_grads);
-
+
for (unsigned int i=0;i<p_values.size();++i)
- values[i+d*n_sub][d] = p_values[i];
-
+ values[i+d*n_sub][d] = p_values[i];
+
for (unsigned int i=0;i<p_grads.size();++i)
- for (unsigned int d1=0;d1<dim;++d1)
- grads[i+d*n_sub][d][(d1+d)%dim] = p_grads[i][d1];
-
+ for (unsigned int d1=0;d1<dim;++d1)
+ grads[i+d*n_sub][d][(d1+d)%dim] = p_grads[i][d1];
+
for (unsigned int i=0;i<p_grad_grads.size();++i)
- for (unsigned int d1=0;d1<dim;++d1)
- for (unsigned int d2=0;d2<dim;++d2)
- grad_grads[i+d*n_sub][d][(d1+d)%dim][(d2+d)%dim]
- = p_grad_grads[i][d1][d2];
+ for (unsigned int d1=0;d1<dim;++d1)
+ for (unsigned int d2=0;d2<dim;++d2)
+ grad_grads[i+d*n_sub][d][(d1+d)%dim][(d2+d)%dim]
+ = p_grad_grads[i][d1][d2];
}
}
if (dim == 1) return k+1;
if (dim == 2) return 2*(k+1)*(k+2);
if (dim == 3) return 3*(k+1)*(k+1)*(k+2);
-
+
Assert(false, ExcNotImplemented());
return 0;
}
// $Id$
// Version: $Name$
//
-// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2006, 2007, 2008, 2009, 2010, 2011 by the deal.II authors
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
template <>
Quadrature<0>::Quadrature (const unsigned int n_q)
- :
- quadrature_points (n_q),
- weights (n_q, 0)
+ :
+ quadrature_points (n_q),
+ weights (n_q, 0)
{}
template <int dim>
Quadrature<dim>::Quadrature (const unsigned int n_q)
- :
- quadrature_points (n_q, Point<dim>()),
- weights (n_q, 0)
+ :
+ quadrature_points (n_q, Point<dim>()),
+ weights (n_q, 0)
{}
template <int dim>
void
Quadrature<dim>::initialize (const std::vector<Point<dim> > &p,
- const std::vector<double> &w)
+ const std::vector<double> &w)
{
AssertDimension (w.size(), p.size());
quadrature_points = p;
template <int dim>
Quadrature<dim>::Quadrature (const std::vector<Point<dim> > &points,
- const std::vector<double> &weights)
- :
- quadrature_points(points),
- weights(weights)
+ const std::vector<double> &weights)
+ :
+ quadrature_points(points),
+ weights(weights)
{
Assert (weights.size() == points.size(),
ExcDimensionMismatch(weights.size(), points.size()));
template <int dim>
Quadrature<dim>::Quadrature (const std::vector<Point<dim> > &points)
- :
- quadrature_points(points),
- weights(points.size(), std::atof("Inf"))
+ :
+ quadrature_points(points),
+ weights(points.size(), std::atof("Inf"))
{
Assert(weights.size() == points.size(),
- ExcDimensionMismatch(weights.size(), points.size()));
+ ExcDimensionMismatch(weights.size(), points.size()));
}
template <int dim>
Quadrature<dim>::Quadrature (const Point<dim> &point)
:
- quadrature_points(std::vector<Point<dim> > (1, point)),
- weights(std::vector<double> (1, 1.))
+ quadrature_points(std::vector<Point<dim> > (1, point)),
+ weights(std::vector<double> (1, 1.))
{}
template <>
Quadrature<0>::Quadrature (const SubQuadrature&,
- const Quadrature<1>&)
+ const Quadrature<1>&)
{
Assert(false, ExcImpossibleInDim(0));
}
template <int dim>
Quadrature<dim>::Quadrature (const SubQuadrature &q1,
- const Quadrature<1> &q2)
- :
- quadrature_points (q1.size() * q2.size()),
- weights (q1.size() * q2.size())
+ const Quadrature<1> &q2)
+ :
+ quadrature_points (q1.size() * q2.size()),
+ weights (q1.size() * q2.size())
{
unsigned int present_index = 0;
for (unsigned int i2=0; i2<q2.size(); ++i2)
for (unsigned int i1=0; i1<q1.size(); ++i1)
{
- // compose coordinates of
- // new quadrature point by tensor
- // product in the last component
- for (unsigned int d=0; d<dim-1; ++d)
- quadrature_points[present_index](d)
- = q1.point(i1)(d);
- quadrature_points[present_index](dim-1)
- = q2.point(i2)(0);
-
- weights[present_index] = q1.weight(i1) * q2.weight(i2);
-
- ++present_index;
+ // compose coordinates of
+ // new quadrature point by tensor
+ // product in the last component
+ for (unsigned int d=0; d<dim-1; ++d)
+ quadrature_points[present_index](d)
+ = q1.point(i1)(d);
+ quadrature_points[present_index](dim-1)
+ = q2.point(i2)(0);
+
+ weights[present_index] = q1.weight(i1) * q2.weight(i2);
+
+ ++present_index;
};
#ifdef DEBUG
{
double sum = 0;
for (unsigned int i=0; i<size(); ++i)
- sum += weights[i];
- // we cant guarantee the sum of weights
- // to be exactly one, but it should be
- // near that.
+ sum += weights[i];
+ // we cant guarantee the sum of weights
+ // to be exactly one, but it should be
+ // near that.
Assert ((sum>0.999999) && (sum<1.000001), ExcInternalError());
}
#endif
template <>
Quadrature<1>::Quadrature (const SubQuadrature&,
- const Quadrature<1>& q2)
- :
- quadrature_points (q2.size()),
- weights (q2.size())
+ const Quadrature<1>& q2)
+ :
+ quadrature_points (q2.size()),
+ weights (q2.size())
{
unsigned int present_index = 0;
for (unsigned int i2=0; i2<q2.size(); ++i2)
{
- // compose coordinates of
- // new quadrature point by tensor
- // product in the last component
+ // compose coordinates of
+ // new quadrature point by tensor
+ // product in the last component
quadrature_points[present_index](0)
- = q2.point(i2)(0);
+ = q2.point(i2)(0);
weights[present_index] = q2.weight(i2);
{
double sum = 0;
for (unsigned int i=0; i<size(); ++i)
- sum += weights[i];
- // we cant guarantee the sum of weights
- // to be exactly one, but it should be
- // near that.
+ sum += weights[i];
+ // we cant guarantee the sum of weights
+ // to be exactly one, but it should be
+ // near that.
Assert ((sum>0.999999) && (sum<1.000001), ExcInternalError());
}
#endif
template <>
Quadrature<0>::Quadrature (const Quadrature<1> &)
- :
- Subscriptor(),
-// quadrature_points(1),
- weights(1,1.)
+ :
+ Subscriptor(),
+// quadrature_points(1),
+ weights(1,1.)
{}
template <>
Quadrature<1>::Quadrature (const Quadrature<0> &)
- :
- Subscriptor()
+ :
+ Subscriptor()
{
// this function should never be
// called -- this should be the
template <int dim>
Quadrature<dim>::Quadrature (const Quadrature<dim != 1 ? 1 : 0> &q)
- :
- Subscriptor(),
- quadrature_points (dimpow<dim>(q.size())),
- weights (dimpow<dim>(q.size()))
+ :
+ Subscriptor(),
+ quadrature_points (dimpow<dim>(q.size())),
+ weights (dimpow<dim>(q.size()))
{
Assert (dim <= 3, ExcNotImplemented());
for (unsigned int i2=0;i2<n2;++i2)
for (unsigned int i1=0;i1<n1;++i1)
for (unsigned int i0=0;i0<n0;++i0)
- {
- quadrature_points[k](0) = q.point(i0)(0);
- if (dim>1)
- quadrature_points[k](1) = q.point(i1)(0);
- if (dim>2)
- quadrature_points[k](2) = q.point(i2)(0);
- weights[k] = q.weight(i0);
- if (dim>1)
- weights[k] *= q.weight(i1);
- if (dim>2)
- weights[k] *= q.weight(i2);
- ++k;
- }
+ {
+ quadrature_points[k](0) = q.point(i0)(0);
+ if (dim>1)
+ quadrature_points[k](1) = q.point(i1)(0);
+ if (dim>2)
+ quadrature_points[k](2) = q.point(i2)(0);
+ weights[k] = q.weight(i0);
+ if (dim>1)
+ weights[k] *= q.weight(i1);
+ if (dim>2)
+ weights[k] *= q.weight(i2);
+ ++k;
+ }
}
template <int dim>
Quadrature<dim>::Quadrature (const Quadrature<dim> &q)
- :
- Subscriptor(),
- quadrature_points (q.quadrature_points),
- weights (q.weights)
+ :
+ Subscriptor(),
+ quadrature_points (q.quadrature_points),
+ weights (q.weights)
{}
Quadrature<dim>::memory_consumption () const
{
return (MemoryConsumption::memory_consumption (quadrature_points) +
- MemoryConsumption::memory_consumption (weights));
+ MemoryConsumption::memory_consumption (weights));
}
//---------------------------------------------------------------------------
template<int dim>
QAnisotropic<dim>::QAnisotropic(const Quadrature<1>& qx)
- : Quadrature<dim>(qx.size())
+ : Quadrature<dim>(qx.size())
{
Assert (dim==1, ExcImpossibleInDim(dim));
unsigned int k=0;
template<int dim>
QAnisotropic<dim>::QAnisotropic(const Quadrature<1>& qx,
- const Quadrature<1>& qy)
- : Quadrature<dim>(qx.size()
- *qy.size())
+ const Quadrature<1>& qy)
+ : Quadrature<dim>(qx.size()
+ *qy.size())
{
Assert (dim==2, ExcImpossibleInDim(dim));
unsigned int k=0;
template<int dim>
QAnisotropic<dim>::QAnisotropic(const Quadrature<1>& qx,
- const Quadrature<1>& qy,
- const Quadrature<1>& qz)
- : Quadrature<dim>(qx.size()
- *qy.size()
- *qz.size())
+ const Quadrature<1>& qy,
+ const Quadrature<1>& qz)
+ : Quadrature<dim>(qx.size()
+ *qy.size()
+ *qz.size())
{
Assert (dim==3, ExcImpossibleInDim(dim));
unsigned int k=0;
for (unsigned int k3=0;k3<qz.size();++k3)
for (unsigned int k2=0;k2<qy.size();++k2)
for (unsigned int k1=0;k1<qx.size();++k1)
- {
- this->quadrature_points[k](0) = qx.point(k1)(0);
- this->quadrature_points[k](1) = qy.point(k2)(0);
- this->quadrature_points[k](2) = qz.point(k3)(0);
- this->weights[k++] = qx.weight(k1) * qy.weight(k2) * qz.weight(k3);
- }
+ {
+ this->quadrature_points[k](0) = qx.point(k1)(0);
+ this->quadrature_points[k](1) = qy.point(k2)(0);
+ this->quadrature_points[k](2) = qz.point(k3)(0);
+ this->weights[k++] = qx.weight(k1) * qy.weight(k2) * qz.weight(k3);
+ }
Assert (k==this->size(), ExcInternalError());
}
template <int dim>
Quadrature<2>
QProjector<dim>::rotate (const Quadrature<2> &q,
- const unsigned int n_times)
+ const unsigned int n_times)
{
std::vector<Point<2> > q_points (q.size());
std::vector<double> weights (q.size());
for (unsigned int i=0; i<q.size(); ++i)
{
switch (n_times%4)
- {
- case 0:
- // 0 degree
- q_points[i][0] = q.point(i)[0];
- q_points[i][1] = q.point(i)[1];
- break;
- case 1:
- // 90 degree counterclockwise
- q_points[i][0] = 1.0 - q.point(i)[1];
- q_points[i][1] = q.point(i)[0];
- break;
- case 2:
- // 180 degree counterclockwise
- q_points[i][0] = 1.0 - q.point(i)[0];
- q_points[i][1] = 1.0 - q.point(i)[1];
- break;
- case 3:
- // 270 degree counterclockwise
- q_points[i][0] = q.point(i)[1];
- q_points[i][1] = 1.0 - q.point(i)[0];
- break;
- }
+ {
+ case 0:
+ // 0 degree
+ q_points[i][0] = q.point(i)[0];
+ q_points[i][1] = q.point(i)[1];
+ break;
+ case 1:
+ // 90 degree counterclockwise
+ q_points[i][0] = 1.0 - q.point(i)[1];
+ q_points[i][1] = q.point(i)[0];
+ break;
+ case 2:
+ // 180 degree counterclockwise
+ q_points[i][0] = 1.0 - q.point(i)[0];
+ q_points[i][1] = 1.0 - q.point(i)[1];
+ break;
+ case 3:
+ // 270 degree counterclockwise
+ q_points[i][0] = q.point(i)[1];
+ q_points[i][1] = 1.0 - q.point(i)[0];
+ break;
+ }
weights[i] = q.weight(i);
}
const unsigned int dim=2;
AssertIndexRange (face_no, GeometryInfo<dim>::faces_per_cell);
Assert (q_points.size() == quadrature.size(),
- ExcDimensionMismatch (q_points.size(), quadrature.size()));
+ ExcDimensionMismatch (q_points.size(), quadrature.size()));
for (unsigned int p=0; p<quadrature.size(); ++p)
switch (face_no)
{
- case 0:
- q_points[p] = Point<dim>(0,quadrature.point(p)(0));
- break;
- case 1:
- q_points[p] = Point<dim>(1,quadrature.point(p)(0));
- break;
- case 2:
- q_points[p] = Point<dim>(quadrature.point(p)(0),0);
- break;
- case 3:
- q_points[p] = Point<dim>(quadrature.point(p)(0),1);
- break;
- default:
- Assert (false, ExcInternalError());
+ case 0:
+ q_points[p] = Point<dim>(0,quadrature.point(p)(0));
+ break;
+ case 1:
+ q_points[p] = Point<dim>(1,quadrature.point(p)(0));
+ break;
+ case 2:
+ q_points[p] = Point<dim>(quadrature.point(p)(0),0);
+ break;
+ case 3:
+ q_points[p] = Point<dim>(quadrature.point(p)(0),1);
+ break;
+ default:
+ Assert (false, ExcInternalError());
};
}
const unsigned int dim=3;
AssertIndexRange (face_no, GeometryInfo<dim>::faces_per_cell);
Assert (q_points.size() == quadrature.size(),
- ExcDimensionMismatch (q_points.size(), quadrature.size()));
+ ExcDimensionMismatch (q_points.size(), quadrature.size()));
for (unsigned int p=0; p<quadrature.size(); ++p)
switch (face_no)
{
- case 0:
- q_points[p] = Point<dim>(0,
- quadrature.point(p)(0),
- quadrature.point(p)(1));
- break;
- case 1:
- q_points[p] = Point<dim>(1,
- quadrature.point(p)(0),
- quadrature.point(p)(1));
- break;
- case 2:
- q_points[p] = Point<dim>(quadrature.point(p)(1),
- 0,
- quadrature.point(p)(0));
- break;
- case 3:
- q_points[p] = Point<dim>(quadrature.point(p)(1),
- 1,
- quadrature.point(p)(0));
- break;
- case 4:
- q_points[p] = Point<dim>(quadrature.point(p)(0),
- quadrature.point(p)(1),
- 0);
- break;
- case 5:
- q_points[p] = Point<dim>(quadrature.point(p)(0),
- quadrature.point(p)(1),
- 1);
- break;
-
- default:
- Assert (false, ExcInternalError());
+ case 0:
+ q_points[p] = Point<dim>(0,
+ quadrature.point(p)(0),
+ quadrature.point(p)(1));
+ break;
+ case 1:
+ q_points[p] = Point<dim>(1,
+ quadrature.point(p)(0),
+ quadrature.point(p)(1));
+ break;
+ case 2:
+ q_points[p] = Point<dim>(quadrature.point(p)(1),
+ 0,
+ quadrature.point(p)(0));
+ break;
+ case 3:
+ q_points[p] = Point<dim>(quadrature.point(p)(1),
+ 1,
+ quadrature.point(p)(0));
+ break;
+ case 4:
+ q_points[p] = Point<dim>(quadrature.point(p)(0),
+ quadrature.point(p)(1),
+ 0);
+ break;
+ case 5:
+ q_points[p] = Point<dim>(quadrature.point(p)(0),
+ quadrature.point(p)(1),
+ 1);
+ break;
+
+ default:
+ Assert (false, ExcInternalError());
};
}
const unsigned int face_no,
const unsigned int,
std::vector<Point<1> >& q_points,
- const RefinementCase<0> &)
+ const RefinementCase<0> &)
{
const unsigned int dim=1;
AssertIndexRange (face_no, GeometryInfo<dim>::faces_per_cell);
const unsigned int face_no,
const unsigned int subface_no,
std::vector<Point<2> > &q_points,
- const RefinementCase<1> &)
+ const RefinementCase<1> &)
{
const unsigned int dim=2;
AssertIndexRange (face_no, GeometryInfo<dim>::faces_per_cell);
AssertIndexRange (subface_no, GeometryInfo<dim>::max_children_per_face);
Assert (q_points.size() == quadrature.size(),
- ExcDimensionMismatch (q_points.size(), quadrature.size()));
+ ExcDimensionMismatch (q_points.size(), quadrature.size()));
for (unsigned int p=0; p<quadrature.size(); ++p)
switch (face_no)
{
- case 0:
- switch (subface_no)
- {
- case 0:
- q_points[p] = Point<dim>(0,quadrature.point(p)(0)/2);
- break;
- case 1:
- q_points[p] = Point<dim>(0,quadrature.point(p)(0)/2+0.5);
- break;
- default:
- Assert (false, ExcInternalError());
- };
- break;
- case 1:
- switch (subface_no)
- {
- case 0:
- q_points[p] = Point<dim>(1,quadrature.point(p)(0)/2);
- break;
- case 1:
- q_points[p] = Point<dim>(1,quadrature.point(p)(0)/2+0.5);
- break;
- default:
- Assert (false, ExcInternalError());
- };
- break;
- case 2:
- switch (subface_no)
- {
- case 0:
- q_points[p]
- = Point<dim>(quadrature.point(p)(0)/2,0);
- break;
- case 1:
- q_points[p]
- = Point<dim>(quadrature.point(p)(0)/2+0.5,0);
- break;
- default:
- Assert (false, ExcInternalError());
- };
- break;
- case 3:
- switch (subface_no)
- {
- case 0:
- q_points[p] = Point<dim>(quadrature.point(p)(0)/2,1);
- break;
- case 1:
- q_points[p] = Point<dim>(quadrature.point(p)(0)/2+0.5,1);
- break;
- default:
- Assert (false, ExcInternalError());
- };
- break;
-
- default:
- Assert (false, ExcInternalError());
+ case 0:
+ switch (subface_no)
+ {
+ case 0:
+ q_points[p] = Point<dim>(0,quadrature.point(p)(0)/2);
+ break;
+ case 1:
+ q_points[p] = Point<dim>(0,quadrature.point(p)(0)/2+0.5);
+ break;
+ default:
+ Assert (false, ExcInternalError());
+ };
+ break;
+ case 1:
+ switch (subface_no)
+ {
+ case 0:
+ q_points[p] = Point<dim>(1,quadrature.point(p)(0)/2);
+ break;
+ case 1:
+ q_points[p] = Point<dim>(1,quadrature.point(p)(0)/2+0.5);
+ break;
+ default:
+ Assert (false, ExcInternalError());
+ };
+ break;
+ case 2:
+ switch (subface_no)
+ {
+ case 0:
+ q_points[p]
+ = Point<dim>(quadrature.point(p)(0)/2,0);
+ break;
+ case 1:
+ q_points[p]
+ = Point<dim>(quadrature.point(p)(0)/2+0.5,0);
+ break;
+ default:
+ Assert (false, ExcInternalError());
+ };
+ break;
+ case 3:
+ switch (subface_no)
+ {
+ case 0:
+ q_points[p] = Point<dim>(quadrature.point(p)(0)/2,1);
+ break;
+ case 1:
+ q_points[p] = Point<dim>(quadrature.point(p)(0)/2+0.5,1);
+ break;
+ default:
+ Assert (false, ExcInternalError());
+ };
+ break;
+
+ default:
+ Assert (false, ExcInternalError());
};
}
const unsigned int face_no,
const unsigned int subface_no,
std::vector<Point<3> > &q_points,
- const RefinementCase<2> &ref_case)
+ const RefinementCase<2> &ref_case)
{
const unsigned int dim=3;
AssertIndexRange (face_no, GeometryInfo<dim>::faces_per_cell);
AssertIndexRange (subface_no, GeometryInfo<dim>::max_children_per_face);
Assert (q_points.size() == quadrature.size(),
- ExcDimensionMismatch (q_points.size(), quadrature.size()));
+ ExcDimensionMismatch (q_points.size(), quadrature.size()));
- // one coordinate is at a const value. for
- // faces 0, 2 and 4 this value is 0.0, for
- // faces 1, 3 and 5 it is 1.0
+ // one coordinate is at a const value. for
+ // faces 0, 2 and 4 this value is 0.0, for
+ // faces 1, 3 and 5 it is 1.0
double const_value=face_no%2;
- // local 2d coordinates are xi and eta,
- // global 3d coordinates are x, y and
- // z. those have to be mapped. the following
- // indices tell, which global coordinate
- // (0->x, 1->y, 2->z) corresponds to which
- // local one
+ // local 2d coordinates are xi and eta,
+ // global 3d coordinates are x, y and
+ // z. those have to be mapped. the following
+ // indices tell, which global coordinate
+ // (0->x, 1->y, 2->z) corresponds to which
+ // local one
unsigned int xi_index = deal_II_numbers::invalid_unsigned_int,
- eta_index = deal_II_numbers::invalid_unsigned_int,
- const_index = face_no/2;
- // the xi and eta values have to be scaled
- // (by factor 0.5 or factor 1.0) depending on
- // the refinement case and translated (by 0.0
- // or 0.5) depending on the refinement case
- // and subface_no.
+ eta_index = deal_II_numbers::invalid_unsigned_int,
+ const_index = face_no/2;
+ // the xi and eta values have to be scaled
+ // (by factor 0.5 or factor 1.0) depending on
+ // the refinement case and translated (by 0.0
+ // or 0.5) depending on the refinement case
+ // and subface_no.
double xi_scale=1.0,
eta_scale=1.0,
xi_translation=0.0,
eta_translation=0.0;
- // set the index mapping between local and
- // global coordinates
+ // set the index mapping between local and
+ // global coordinates
switch(face_no/2)
{
case 0:
- xi_index=1;
- eta_index=2;
- break;
+ xi_index=1;
+ eta_index=2;
+ break;
case 1:
- xi_index=2;
- eta_index=0;
- break;
+ xi_index=2;
+ eta_index=0;
+ break;
case 2:
- xi_index=0;
- eta_index=1;
- break;
+ xi_index=0;
+ eta_index=1;
+ break;
}
- // set the scale and translation parameter
- // for individual subfaces
+ // set the scale and translation parameter
+ // for individual subfaces
switch((unsigned char)ref_case)
{
case RefinementCase<dim-1>::cut_x:
- xi_scale=0.5;
- xi_translation=subface_no%2 * 0.5;
- break;
+ xi_scale=0.5;
+ xi_translation=subface_no%2 * 0.5;
+ break;
case RefinementCase<dim-1>::cut_y:
- eta_scale=0.5;
- eta_translation=subface_no%2 * 0.5;
- break;
+ eta_scale=0.5;
+ eta_translation=subface_no%2 * 0.5;
+ break;
case RefinementCase<dim-1>::cut_xy:
- xi_scale= 0.5;
- eta_scale=0.5;
- xi_translation =subface_no%2 * 0.5;
- eta_translation=subface_no/2 * 0.5;
- break;
+ xi_scale= 0.5;
+ eta_scale=0.5;
+ xi_translation =subface_no%2 * 0.5;
+ eta_translation=subface_no/2 * 0.5;
+ break;
default:
- Assert(false,ExcInternalError());
- break;
+ Assert(false,ExcInternalError());
+ break;
}
- // finally, compute the scaled, translated,
- // projected quadrature points
+ // finally, compute the scaled, translated,
+ // projected quadrature points
for (unsigned int p=0; p<quadrature.size(); ++p)
{
q_points[p][xi_index] = xi_scale * quadrature.point(p)(0) + xi_translation;
const unsigned int dim = 1;
const unsigned int n_points = 1,
- n_faces = GeometryInfo<dim>::faces_per_cell;
+ n_faces = GeometryInfo<dim>::faces_per_cell;
- // first fix quadrature points
+ // first fix quadrature points
std::vector<Point<dim> > q_points;
q_points.reserve(n_points * n_faces);
std::vector <Point<dim> > help(n_points);
- // project to each face and append
- // results
+ // project to each face and append
+ // results
for (unsigned int face=0; face<n_faces; ++face)
{
project_to_face(quadrature, face, help);
std::back_inserter (q_points));
}
- // next copy over weights
+ // next copy over weights
std::vector<double> weights;
weights.reserve (n_points * n_faces);
for (unsigned int face=0; face<n_faces; ++face)
const unsigned int dim = 2;
const unsigned int n_points = quadrature.size(),
- n_faces = GeometryInfo<dim>::faces_per_cell;
+ n_faces = GeometryInfo<dim>::faces_per_cell;
- // first fix quadrature points
+ // first fix quadrature points
std::vector<Point<dim> > q_points;
q_points.reserve(n_points * n_faces);
std::vector <Point<dim> > help(n_points);
- // project to each face and append
- // results
+ // project to each face and append
+ // results
for (unsigned int face=0; face<n_faces; ++face)
{
project_to_face(quadrature, face, help);
std::back_inserter (q_points));
}
- // next copy over weights
+ // next copy over weights
std::vector<double> weights;
weights.reserve (n_points * n_faces);
for (unsigned int face=0; face<n_faces; ++face)
const unsigned int n_points = quadrature.size(),
- n_faces = GeometryInfo<dim>::faces_per_cell;
+ n_faces = GeometryInfo<dim>::faces_per_cell;
- // first fix quadrature points
+ // first fix quadrature points
std::vector<Point<dim> > q_points;
q_points.reserve(n_points * n_faces * 8);
std::vector <Point<dim> > help(n_points);
std::vector<double> weights;
weights.reserve (n_points * n_faces * 8);
- // do the following for all possible
- // mutations of a face (mutation==0
- // corresponds to a face with standard
- // orientation, no flip and no rotation)
+ // do the following for all possible
+ // mutations of a face (mutation==0
+ // corresponds to a face with standard
+ // orientation, no flip and no rotation)
for (unsigned int mutation=0; mutation<8; ++mutation)
{
- // project to each face and append
- // results
+ // project to each face and append
+ // results
for (unsigned int face=0; face<n_faces; ++face)
- {
- project_to_face(q[mutation], face, help);
- std::copy (help.begin(), help.end(),
- std::back_inserter (q_points));
- }
+ {
+ project_to_face(q[mutation], face, help);
+ std::copy (help.begin(), help.end(),
+ std::back_inserter (q_points));
+ }
- // next copy over weights
+ // next copy over weights
for (unsigned int face=0; face<n_faces; ++face)
- std::copy (q[mutation].get_weights().begin(),
- q[mutation].get_weights().end(),
- std::back_inserter (weights));
+ std::copy (q[mutation].get_weights().begin(),
+ q[mutation].get_weights().end(),
+ std::back_inserter (weights));
}
const unsigned int dim = 1;
const unsigned int n_points = 1,
- n_faces = GeometryInfo<dim>::faces_per_cell,
- subfaces_per_face = GeometryInfo<dim>::max_children_per_face;
+ n_faces = GeometryInfo<dim>::faces_per_cell,
+ subfaces_per_face = GeometryInfo<dim>::max_children_per_face;
- // first fix quadrature points
+ // first fix quadrature points
std::vector<Point<dim> > q_points;
q_points.reserve (n_points * n_faces * subfaces_per_face);
std::vector <Point<dim> > help(n_points);
- // project to each face and copy
- // results
+ // project to each face and copy
+ // results
for (unsigned int face=0; face<n_faces; ++face)
for (unsigned int subface=0; subface<subfaces_per_face; ++subface)
{
- project_to_subface(quadrature, face, subface, help);
- std::copy (help.begin(), help.end(),
+ project_to_subface(quadrature, face, subface, help);
+ std::copy (help.begin(), help.end(),
std::back_inserter (q_points));
};
- // next copy over weights
+ // next copy over weights
std::vector<double> weights;
weights.reserve (n_points * n_faces * subfaces_per_face);
for (unsigned int face=0; face<n_faces; ++face)
const unsigned int dim = 2;
const unsigned int n_points = quadrature.size(),
- n_faces = GeometryInfo<dim>::faces_per_cell,
- subfaces_per_face = GeometryInfo<dim>::max_children_per_face;
+ n_faces = GeometryInfo<dim>::faces_per_cell,
+ subfaces_per_face = GeometryInfo<dim>::max_children_per_face;
- // first fix quadrature points
+ // first fix quadrature points
std::vector<Point<dim> > q_points;
q_points.reserve (n_points * n_faces * subfaces_per_face);
std::vector <Point<dim> > help(n_points);
- // project to each face and copy
- // results
+ // project to each face and copy
+ // results
for (unsigned int face=0; face<n_faces; ++face)
for (unsigned int subface=0; subface<subfaces_per_face; ++subface)
{
- project_to_subface(quadrature, face, subface, help);
- std::copy (help.begin(), help.end(),
+ project_to_subface(quadrature, face, subface, help);
+ std::copy (help.begin(), help.end(),
std::back_inserter (q_points));
};
- // next copy over weights
+ // next copy over weights
std::vector<double> weights;
weights.reserve (n_points * n_faces * subfaces_per_face);
for (unsigned int face=0; face<n_faces; ++face)
rotate (q_reflected,1)};
const unsigned int n_points = quadrature.size(),
- n_faces = GeometryInfo<dim>::faces_per_cell,
- total_subfaces_per_face = 2 + 2 + 4;
+ n_faces = GeometryInfo<dim>::faces_per_cell,
+ total_subfaces_per_face = 2 + 2 + 4;
- // first fix quadrature points
+ // first fix quadrature points
std::vector<Point<dim> > q_points;
q_points.reserve (n_points * n_faces * total_subfaces_per_face * 8);
std::vector <Point<dim> > help(n_points);
std::vector<double> weights;
weights.reserve (n_points * n_faces * total_subfaces_per_face * 8);
- // do the following for all possible
- // mutations of a face (mutation==0
- // corresponds to a face with standard
- // orientation, no flip and no rotation)
+ // do the following for all possible
+ // mutations of a face (mutation==0
+ // corresponds to a face with standard
+ // orientation, no flip and no rotation)
for (unsigned int mutation=0; mutation<8; ++mutation)
{
- // project to each face and copy
- // results
+ // project to each face and copy
+ // results
for (unsigned int face=0; face<n_faces; ++face)
- for (unsigned int ref_case=RefinementCase<dim-1>::cut_xy;
- ref_case>=RefinementCase<dim-1>::cut_x;
- --ref_case)
- for (unsigned int subface=0; subface<GeometryInfo<dim-1>::n_children(RefinementCase<dim-1>(ref_case)); ++subface)
- {
- project_to_subface(q[mutation], face, subface, help,
- RefinementCase<dim-1>(ref_case));
- std::copy (help.begin(), help.end(),
- std::back_inserter (q_points));
- }
-
- // next copy over weights
+ for (unsigned int ref_case=RefinementCase<dim-1>::cut_xy;
+ ref_case>=RefinementCase<dim-1>::cut_x;
+ --ref_case)
+ for (unsigned int subface=0; subface<GeometryInfo<dim-1>::n_children(RefinementCase<dim-1>(ref_case)); ++subface)
+ {
+ project_to_subface(q[mutation], face, subface, help,
+ RefinementCase<dim-1>(ref_case));
+ std::copy (help.begin(), help.end(),
+ std::back_inserter (q_points));
+ }
+
+ // next copy over weights
for (unsigned int face=0; face<n_faces; ++face)
- for (unsigned int ref_case=RefinementCase<dim-1>::cut_xy;
- ref_case>=RefinementCase<dim-1>::cut_x;
- --ref_case)
- for (unsigned int subface=0; subface<GeometryInfo<dim-1>::n_children(RefinementCase<dim-1>(ref_case)); ++subface)
- std::copy (q[mutation].get_weights().begin(),
- q[mutation].get_weights().end(),
- std::back_inserter (weights));
+ for (unsigned int ref_case=RefinementCase<dim-1>::cut_xy;
+ ref_case>=RefinementCase<dim-1>::cut_x;
+ --ref_case)
+ for (unsigned int subface=0; subface<GeometryInfo<dim-1>::n_children(RefinementCase<dim-1>(ref_case)); ++subface)
+ std::copy (q[mutation].get_weights().begin(),
+ q[mutation].get_weights().end(),
+ std::back_inserter (weights));
}
Assert (q_points.size() == n_points * n_faces * total_subfaces_per_face * 8,
template <int dim>
Quadrature<dim>
QProjector<dim>::project_to_child (const Quadrature<dim> &quadrature,
- const unsigned int child_no)
+ const unsigned int child_no)
{
Assert (child_no < GeometryInfo<dim>::max_children_per_cell,
- ExcIndexRange (child_no, 0, GeometryInfo<dim>::max_children_per_cell));
+ ExcIndexRange (child_no, 0, GeometryInfo<dim>::max_children_per_cell));
const unsigned int n_q_points = quadrature.size();
q_points[i]=GeometryInfo<dim>::child_to_cell_coordinates(
quadrature.point(i), child_no);
- // for the weights, things are
- // equally simple: copy them and
- // scale them
+ // for the weights, things are
+ // equally simple: copy them and
+ // scale them
std::vector<double> weights = quadrature.get_weights ();
for (unsigned int i=0; i<n_q_points; ++i)
weights[i] *= (1./GeometryInfo<dim>::max_children_per_cell);
QProjector<dim>::project_to_all_children (const Quadrature<dim> &quadrature)
{
const unsigned int n_points = quadrature.size(),
- n_children = GeometryInfo<dim>::max_children_per_cell;
+ n_children = GeometryInfo<dim>::max_children_per_cell;
std::vector<Point<dim> > q_points(n_points * n_children);
std::vector<double> weights(n_points * n_children);
- // project to each child and copy
- // results
+ // project to each child and copy
+ // results
for (unsigned int child=0; child<n_children; ++child)
{
Quadrature<dim> help = project_to_child(quadrature, child);
for (unsigned int i=0;i<n_points;++i)
- {
- q_points[child*n_points+i] = help.point(i);
- weights[child*n_points+i] = help.weight(i);
- }
+ {
+ q_points[child*n_points+i] = help.point(i);
+ weights[child*n_points+i] = help.weight(i);
+ }
}
return Quadrature<dim>(q_points, weights);
}
case 3:
{
- // in 3d, we have to account for faces that
- // have non-standard face orientation, flip
- // and rotation. thus, we have to store
- // _eight_ data sets per face or subface
+ // in 3d, we have to account for faces that
+ // have non-standard face orientation, flip
+ // and rotation. thus, we have to store
+ // _eight_ data sets per face or subface
// set up a table with the according offsets
// for non-standard orientation, first index:
// stick to that (implicit) convention
static const unsigned int offset[2][2][2]=
{{{4*GeometryInfo<dim>::faces_per_cell, 5*GeometryInfo<dim>::faces_per_cell}, // face_orientation=false; face_flip=false; face_rotation=false and true
- {6*GeometryInfo<dim>::faces_per_cell, 7*GeometryInfo<dim>::faces_per_cell}}, // face_orientation=false; face_flip=true; face_rotation=false and true
- {{0*GeometryInfo<dim>::faces_per_cell, 1*GeometryInfo<dim>::faces_per_cell}, // face_orientation=true; face_flip=false; face_rotation=false and true
- {2*GeometryInfo<dim>::faces_per_cell, 3*GeometryInfo<dim>::faces_per_cell}}}; // face_orientation=true; face_flip=true; face_rotation=false and true
+ {6*GeometryInfo<dim>::faces_per_cell, 7*GeometryInfo<dim>::faces_per_cell}}, // face_orientation=false; face_flip=true; face_rotation=false and true
+ {{0*GeometryInfo<dim>::faces_per_cell, 1*GeometryInfo<dim>::faces_per_cell}, // face_orientation=true; face_flip=false; face_rotation=false and true
+ {2*GeometryInfo<dim>::faces_per_cell, 3*GeometryInfo<dim>::faces_per_cell}}}; // face_orientation=true; face_flip=true; face_rotation=false and true
return ((face_no
+ offset[face_orientation][face_flip][face_rotation])
- * n_quadrature_points);
+ * n_quadrature_points);
}
-
+
default:
Assert (false, ExcInternalError());
}
const bool,
const bool,
const unsigned int n_quadrature_points,
- const internal::SubfaceCase<1>)
+ const internal::SubfaceCase<1>)
{
Assert (face_no < GeometryInfo<1>::faces_per_cell,
ExcInternalError());
ExcInternalError());
return ((face_no * GeometryInfo<1>::max_children_per_face +
- subface_no)
- * n_quadrature_points);
+ subface_no)
+ * n_quadrature_points);
}
const bool,
const bool,
const unsigned int n_quadrature_points,
- const internal::SubfaceCase<2>)
+ const internal::SubfaceCase<2>)
{
Assert (face_no < GeometryInfo<2>::faces_per_cell,
ExcInternalError());
ExcInternalError());
return ((face_no * GeometryInfo<2>::max_children_per_face +
- subface_no)
- * n_quadrature_points);
+ subface_no)
+ * n_quadrature_points);
}
const bool face_flip,
const bool face_rotation,
const unsigned int n_quadrature_points,
- const internal::SubfaceCase<3> ref_case)
+ const internal::SubfaceCase<3> ref_case)
{
const unsigned int dim = 3;
Assert (subface_no < GeometryInfo<dim>::max_children_per_face,
ExcInternalError());
- // As the quadrature points created by
- // QProjector are on subfaces in their
- // "standard location" we have to use a
- // permutation of the equivalent subface
- // number in order to respect face
- // orientation, flip and rotation. The
- // information we need here is exactly the
- // same as the
- // GeometryInfo<3>::child_cell_on_face info
- // for the bottom face (face 4) of a hex, as
- // on this the RefineCase of the cell matches
- // that of the face and the subfaces are
- // numbered in the same way as the child
- // cells.
-
- // in 3d, we have to account for faces that
- // have non-standard face orientation, flip
- // and rotation. thus, we have to store
- // _eight_ data sets per face or subface
- // already for the isotropic
- // case. Additionally, we have three
- // different refinement cases, resulting in
- // <tt>4 + 2 + 2 = 8</tt> differnt subfaces
- // for each face.
+ // As the quadrature points created by
+ // QProjector are on subfaces in their
+ // "standard location" we have to use a
+ // permutation of the equivalent subface
+ // number in order to respect face
+ // orientation, flip and rotation. The
+ // information we need here is exactly the
+ // same as the
+ // GeometryInfo<3>::child_cell_on_face info
+ // for the bottom face (face 4) of a hex, as
+ // on this the RefineCase of the cell matches
+ // that of the face and the subfaces are
+ // numbered in the same way as the child
+ // cells.
+
+ // in 3d, we have to account for faces that
+ // have non-standard face orientation, flip
+ // and rotation. thus, we have to store
+ // _eight_ data sets per face or subface
+ // already for the isotropic
+ // case. Additionally, we have three
+ // different refinement cases, resulting in
+ // <tt>4 + 2 + 2 = 8</tt> differnt subfaces
+ // for each face.
const unsigned int total_subfaces_per_face=8;
- // set up a table with the according offsets
- // for non-standard orientation, first index:
- // face_orientation (standard true=1), second
- // index: face_flip (standard false=0), third
- // index: face_rotation (standard false=0)
- //
- // note, that normally we should use the
- // obvious offsets 0,1,2,3,4,5,6,7. However,
- // prior to the changes enabling flipped and
- // rotated faces, in many places of the
- // library the convention was used, that the
- // first dataset with offset 0 corresponds to
- // a face in standard orientation. therefore
- // we use the offsets 4,5,6,7,0,1,2,3 here to
- // stick to that (implicit) convention
+ // set up a table with the according offsets
+ // for non-standard orientation, first index:
+ // face_orientation (standard true=1), second
+ // index: face_flip (standard false=0), third
+ // index: face_rotation (standard false=0)
+ //
+ // note, that normally we should use the
+ // obvious offsets 0,1,2,3,4,5,6,7. However,
+ // prior to the changes enabling flipped and
+ // rotated faces, in many places of the
+ // library the convention was used, that the
+ // first dataset with offset 0 corresponds to
+ // a face in standard orientation. therefore
+ // we use the offsets 4,5,6,7,0,1,2,3 here to
+ // stick to that (implicit) convention
static const unsigned int orientation_offset[2][2][2]=
{{
- // face_orientation=false; face_flip=false; face_rotation=false and true
- {4*GeometryInfo<dim>::faces_per_cell*total_subfaces_per_face,
- 5*GeometryInfo<dim>::faces_per_cell*total_subfaces_per_face},
- // face_orientation=false; face_flip=true; face_rotation=false and true
- {6*GeometryInfo<dim>::faces_per_cell*total_subfaces_per_face,
- 7*GeometryInfo<dim>::faces_per_cell*total_subfaces_per_face}},
+ // face_orientation=false; face_flip=false; face_rotation=false and true
+ {4*GeometryInfo<dim>::faces_per_cell*total_subfaces_per_face,
+ 5*GeometryInfo<dim>::faces_per_cell*total_subfaces_per_face},
+ // face_orientation=false; face_flip=true; face_rotation=false and true
+ {6*GeometryInfo<dim>::faces_per_cell*total_subfaces_per_face,
+ 7*GeometryInfo<dim>::faces_per_cell*total_subfaces_per_face}},
{
- // face_orientation=true; face_flip=false; face_rotation=false and true
- {0*GeometryInfo<dim>::faces_per_cell*total_subfaces_per_face,
- 1*GeometryInfo<dim>::faces_per_cell*total_subfaces_per_face},
- // face_orientation=true; face_flip=true; face_rotation=false and true
- {2*GeometryInfo<dim>::faces_per_cell*total_subfaces_per_face,
- 3*GeometryInfo<dim>::faces_per_cell*total_subfaces_per_face}}};
-
- // set up a table with the offsets for a
- // given refinement case respecting the
- // corresponding number of subfaces. the
- // index corresponds to (RefineCase::Type - 1)
-
- // note, that normally we should use the
- // obvious offsets 0,2,6. However, prior to
- // the implementation of anisotropic
- // refinement, in many places of the library
- // the convention was used, that the first
- // dataset with offset 0 corresponds to a
- // standard (isotropic) face
- // refinement. therefore we use the offsets
- // 6,4,0 here to stick to that (implicit)
- // convention
+ // face_orientation=true; face_flip=false; face_rotation=false and true
+ {0*GeometryInfo<dim>::faces_per_cell*total_subfaces_per_face,
+ 1*GeometryInfo<dim>::faces_per_cell*total_subfaces_per_face},
+ // face_orientation=true; face_flip=true; face_rotation=false and true
+ {2*GeometryInfo<dim>::faces_per_cell*total_subfaces_per_face,
+ 3*GeometryInfo<dim>::faces_per_cell*total_subfaces_per_face}}};
+
+ // set up a table with the offsets for a
+ // given refinement case respecting the
+ // corresponding number of subfaces. the
+ // index corresponds to (RefineCase::Type - 1)
+
+ // note, that normally we should use the
+ // obvious offsets 0,2,6. However, prior to
+ // the implementation of anisotropic
+ // refinement, in many places of the library
+ // the convention was used, that the first
+ // dataset with offset 0 corresponds to a
+ // standard (isotropic) face
+ // refinement. therefore we use the offsets
+ // 6,4,0 here to stick to that (implicit)
+ // convention
static const unsigned int ref_case_offset[3]=
{
- 6, //cut_x
- 4, //cut_y
- 0 //cut_xy
+ 6, //cut_x
+ 4, //cut_y
+ 0 //cut_xy
};
- // for each subface of a given FaceRefineCase
- // there is a corresponding equivalent
- // subface number of one of the "standard"
- // RefineCases (cut_x, cut_y, cut_xy). Map
- // the given values to those equivalent
- // ones.
+ // for each subface of a given FaceRefineCase
+ // there is a corresponding equivalent
+ // subface number of one of the "standard"
+ // RefineCases (cut_x, cut_y, cut_xy). Map
+ // the given values to those equivalent
+ // ones.
- // first, define an invalid number
+ // first, define an invalid number
static const unsigned int e = deal_II_numbers::invalid_unsigned_int;
static const RefinementCase<dim-1>
equivalent_refine_case[internal::SubfaceCase<dim>::case_isotropic+1][GeometryInfo<3>::max_children_per_face]
=
{
- // case_none. there should be only
- // invalid values here. However, as
- // this function is also called (in
- // tests) for cells which have no
- // refined faces, use isotropic
- // refinement instead
- {RefinementCase<dim-1>::cut_xy,
- RefinementCase<dim-1>::cut_xy,
- RefinementCase<dim-1>::cut_xy,
- RefinementCase<dim-1>::cut_xy},
- // case_x
- {RefinementCase<dim-1>::cut_x,
- RefinementCase<dim-1>::cut_x,
- RefinementCase<dim-1>::no_refinement,
- RefinementCase<dim-1>::no_refinement},
- // case_x1y
- {RefinementCase<dim-1>::cut_xy,
- RefinementCase<dim-1>::cut_xy,
- RefinementCase<dim-1>::cut_x,
- RefinementCase<dim-1>::no_refinement},
- // case_x2y
- {RefinementCase<dim-1>::cut_x,
- RefinementCase<dim-1>::cut_xy,
- RefinementCase<dim-1>::cut_xy,
- RefinementCase<dim-1>::no_refinement},
- // case_x1y2y
- {RefinementCase<dim-1>::cut_xy,
- RefinementCase<dim-1>::cut_xy,
- RefinementCase<dim-1>::cut_xy,
- RefinementCase<dim-1>::cut_xy},
- // case_y
- {RefinementCase<dim-1>::cut_y,
- RefinementCase<dim-1>::cut_y,
- RefinementCase<dim-1>::no_refinement,
- RefinementCase<dim-1>::no_refinement},
- // case_y1x
- {RefinementCase<dim-1>::cut_xy,
- RefinementCase<dim-1>::cut_xy,
- RefinementCase<dim-1>::cut_y,
- RefinementCase<dim-1>::no_refinement},
- // case_y2x
- {RefinementCase<dim-1>::cut_y,
- RefinementCase<dim-1>::cut_xy,
- RefinementCase<dim-1>::cut_xy,
- RefinementCase<dim-1>::no_refinement},
- // case_y1x2x
- {RefinementCase<dim-1>::cut_xy,
- RefinementCase<dim-1>::cut_xy,
- RefinementCase<dim-1>::cut_xy,
- RefinementCase<dim-1>::cut_xy},
- // case_xy (case_isotropic)
- {RefinementCase<dim-1>::cut_xy,
- RefinementCase<dim-1>::cut_xy,
- RefinementCase<dim-1>::cut_xy,
- RefinementCase<dim-1>::cut_xy}
+ // case_none. there should be only
+ // invalid values here. However, as
+ // this function is also called (in
+ // tests) for cells which have no
+ // refined faces, use isotropic
+ // refinement instead
+ {RefinementCase<dim-1>::cut_xy,
+ RefinementCase<dim-1>::cut_xy,
+ RefinementCase<dim-1>::cut_xy,
+ RefinementCase<dim-1>::cut_xy},
+ // case_x
+ {RefinementCase<dim-1>::cut_x,
+ RefinementCase<dim-1>::cut_x,
+ RefinementCase<dim-1>::no_refinement,
+ RefinementCase<dim-1>::no_refinement},
+ // case_x1y
+ {RefinementCase<dim-1>::cut_xy,
+ RefinementCase<dim-1>::cut_xy,
+ RefinementCase<dim-1>::cut_x,
+ RefinementCase<dim-1>::no_refinement},
+ // case_x2y
+ {RefinementCase<dim-1>::cut_x,
+ RefinementCase<dim-1>::cut_xy,
+ RefinementCase<dim-1>::cut_xy,
+ RefinementCase<dim-1>::no_refinement},
+ // case_x1y2y
+ {RefinementCase<dim-1>::cut_xy,
+ RefinementCase<dim-1>::cut_xy,
+ RefinementCase<dim-1>::cut_xy,
+ RefinementCase<dim-1>::cut_xy},
+ // case_y
+ {RefinementCase<dim-1>::cut_y,
+ RefinementCase<dim-1>::cut_y,
+ RefinementCase<dim-1>::no_refinement,
+ RefinementCase<dim-1>::no_refinement},
+ // case_y1x
+ {RefinementCase<dim-1>::cut_xy,
+ RefinementCase<dim-1>::cut_xy,
+ RefinementCase<dim-1>::cut_y,
+ RefinementCase<dim-1>::no_refinement},
+ // case_y2x
+ {RefinementCase<dim-1>::cut_y,
+ RefinementCase<dim-1>::cut_xy,
+ RefinementCase<dim-1>::cut_xy,
+ RefinementCase<dim-1>::no_refinement},
+ // case_y1x2x
+ {RefinementCase<dim-1>::cut_xy,
+ RefinementCase<dim-1>::cut_xy,
+ RefinementCase<dim-1>::cut_xy,
+ RefinementCase<dim-1>::cut_xy},
+ // case_xy (case_isotropic)
+ {RefinementCase<dim-1>::cut_xy,
+ RefinementCase<dim-1>::cut_xy,
+ RefinementCase<dim-1>::cut_xy,
+ RefinementCase<dim-1>::cut_xy}
};
static const unsigned int
equivalent_subface_number[internal::SubfaceCase<dim>::case_isotropic+1][GeometryInfo<3>::max_children_per_face]
=
{
- // case_none, see above
- {0,1,2,3},
- // case_x
- {0,1,e,e},
- // case_x1y
- {0,2,1,e},
- // case_x2y
- {0,1,3,e},
- // case_x1y2y
- {0,2,1,3},
- // case_y
- {0,1,e,e},
- // case_y1x
- {0,1,1,e},
- // case_y2x
- {0,2,3,e},
- // case_y1x2x
- {0,1,2,3},
- // case_xy (case_isotropic)
- {0,1,2,3}
+ // case_none, see above
+ {0,1,2,3},
+ // case_x
+ {0,1,e,e},
+ // case_x1y
+ {0,2,1,e},
+ // case_x2y
+ {0,1,3,e},
+ // case_x1y2y
+ {0,2,1,3},
+ // case_y
+ {0,1,e,e},
+ // case_y1x
+ {0,1,1,e},
+ // case_y2x
+ {0,2,3,e},
+ // case_y1x2x
+ {0,1,2,3},
+ // case_xy (case_isotropic)
+ {0,1,2,3}
};
- // If face-orientation or face_rotation are
- // non-standard, cut_x and cut_y have to be
- // exchanged.
+ // If face-orientation or face_rotation are
+ // non-standard, cut_x and cut_y have to be
+ // exchanged.
static const RefinementCase<dim-1> ref_case_permutation[4]
={RefinementCase<dim-1>::no_refinement,
RefinementCase<dim-1>::cut_y,
RefinementCase<dim-1>::cut_x,
RefinementCase<dim-1>::cut_xy};
- // set a corresponding (equivalent)
- // RefineCase and subface number
+ // set a corresponding (equivalent)
+ // RefineCase and subface number
const RefinementCase<dim-1> equ_ref_case=equivalent_refine_case[ref_case][subface_no];
const unsigned int equ_subface_no=equivalent_subface_number[ref_case][subface_no];
- // make sure, that we got a valid subface and RefineCase
+ // make sure, that we got a valid subface and RefineCase
Assert(equ_ref_case!=RefinementCase<dim>::no_refinement, ExcInternalError());
Assert(equ_subface_no!=e, ExcInternalError());
- // now, finally respect non-standard faces
+ // now, finally respect non-standard faces
const RefinementCase<dim-1>
final_ref_case = (face_orientation==face_rotation
- ?
- ref_case_permutation[equ_ref_case]
- :
- equ_ref_case);
-
- // what we have now is the number of
- // the subface in the natural
- // orientation of the *face*. what we
- // need to know is the number of the
- // subface concerning the standard face
- // orientation as seen from the *cell*.
-
- // this mapping is not trivial, but we
- // have done exactly this stuff in the
- // child_cell_on_face function. in
- // order to reduce the amount of code
- // as well as to make maintaining the
- // functionality easier we want to
- // reuse that information. So we note
- // that on the bottom face (face 4) of
- // a hex cell the local x and y
- // coordinates of the face and the cell
- // coincide, thus also the refinement
- // case of the face corresponds to the
- // refinement case of the cell
- // (ignoring cell refinement along the
- // z direction). Using this knowledge
- // we can (ab)use the
- // child_cell_on_face function to do
- // exactly the transformation we are in
- // need of now
+ ?
+ ref_case_permutation[equ_ref_case]
+ :
+ equ_ref_case);
+
+ // what we have now is the number of
+ // the subface in the natural
+ // orientation of the *face*. what we
+ // need to know is the number of the
+ // subface concerning the standard face
+ // orientation as seen from the *cell*.
+
+ // this mapping is not trivial, but we
+ // have done exactly this stuff in the
+ // child_cell_on_face function. in
+ // order to reduce the amount of code
+ // as well as to make maintaining the
+ // functionality easier we want to
+ // reuse that information. So we note
+ // that on the bottom face (face 4) of
+ // a hex cell the local x and y
+ // coordinates of the face and the cell
+ // coincide, thus also the refinement
+ // case of the face corresponds to the
+ // refinement case of the cell
+ // (ignoring cell refinement along the
+ // z direction). Using this knowledge
+ // we can (ab)use the
+ // child_cell_on_face function to do
+ // exactly the transformation we are in
+ // need of now
const unsigned int
final_subface_no = GeometryInfo<dim>::child_cell_on_face(RefinementCase<dim>(final_ref_case),
- 4,
- equ_subface_no,
- face_orientation,
- face_flip,
- face_rotation,
- equ_ref_case);
+ 4,
+ equ_subface_no,
+ face_orientation,
+ face_flip,
+ face_rotation,
+ equ_ref_case);
return (((face_no * total_subfaces_per_face
- + ref_case_offset[final_ref_case-1]
- + final_subface_no)
- + orientation_offset[face_orientation][face_flip][face_rotation]
- )
- * n_quadrature_points);
+ + ref_case_offset[final_ref_case-1]
+ + final_subface_no)
+ + orientation_offset[face_orientation][face_flip][face_rotation]
+ )
+ * n_quadrature_points);
}
template <int dim>
Quadrature<dim>
QProjector<dim>::project_to_face(const SubQuadrature &quadrature,
- const unsigned int face_no)
+ const unsigned int face_no)
{
std::vector<Point<dim> > points(quadrature.size());
project_to_face(quadrature, face_no, points);
template <int dim>
Quadrature<dim>
QProjector<dim>::project_to_subface(const SubQuadrature &quadrature,
- const unsigned int face_no,
- const unsigned int subface_no,
- const RefinementCase<dim-1> &ref_case)
+ const unsigned int face_no,
+ const unsigned int subface_no,
+ const RefinementCase<dim-1> &ref_case)
{
std::vector<Point<dim> > points(quadrature.size());
project_to_subface(quadrature, face_no, subface_no, points, ref_case);
for (unsigned int i=0; i<base_quadrature.size(); ++i)
{
if (base_quadrature.point(i) == Point<1>(0.0))
- at_left = true;
+ at_left = true;
if (base_quadrature.point(i) == Point<1>(1.0))
- at_right = true;
+ at_right = true;
};
return (at_left && at_right);
// template<>
// void
// QIterated<1>::fill(Quadrature<1>& dst,
-// const Quadrature<1> &base_quadrature,
-// const unsigned int n_copies)
+// const Quadrature<1> &base_quadrature,
+// const unsigned int n_copies)
// {
// Assert (n_copies > 0, ExcZero());
// Assert (base_quadrature.size() > 0, ExcZero());
// dst.weights.resize(np);
// if (!uses_both_endpoints(base_quadrature))
-// // we don't have to skip some
-// // points in order to get a
-// // reasonable quadrature formula
+// // we don't have to skip some
+// // points in order to get a
+// // reasonable quadrature formula
// {
// unsigned int next_point = 0;
// for (unsigned int copy=0; copy<n_copies; ++copy)
-// for (unsigned int q_point=0; q_point<base_quadrature.size(); ++q_point)
-// {
-// dst.quadrature_points[next_point](0)
-// = (copy + base_quadrature.point(q_point)(0)) / n_copies;
-// dst.weights[next_point]
-// = base_quadrature.weight(q_point) / n_copies;
-// ++next_point;
-// };
+// for (unsigned int q_point=0; q_point<base_quadrature.size(); ++q_point)
+// {
+// dst.quadrature_points[next_point](0)
+// = (copy + base_quadrature.point(q_point)(0)) / n_copies;
+// dst.weights[next_point]
+// = base_quadrature.weight(q_point) / n_copies;
+// ++next_point;
+// };
// }
// else
-// // skip doubly available points
+// // skip doubly available points
// {
// unsigned int next_point = 0;
-// // first find out the weights of
-// // the left and the right boundary
-// // points. note that these usually
-// // are but need not necessarily be
-// // the same
+// // first find out the weights of
+// // the left and the right boundary
+// // points. note that these usually
+// // are but need not necessarily be
+// // the same
// double double_point_weight = 0;
// unsigned int n_end_points = 0;
// for (unsigned int i=0; i<base_quadrature.size(); ++i)
-// // add up the weight if this
-// // is an endpoint
-// if ((base_quadrature.point(i)(0) == 0.) ||
-// (base_quadrature.point(i)(0) == 1.))
-// {
-// double_point_weight += base_quadrature.weight(i);
-// ++n_end_points;
-// };
-// // scale the weight correctly
+// // add up the weight if this
+// // is an endpoint
+// if ((base_quadrature.point(i)(0) == 0.) ||
+// (base_quadrature.point(i)(0) == 1.))
+// {
+// double_point_weight += base_quadrature.weight(i);
+// ++n_end_points;
+// };
+// // scale the weight correctly
// double_point_weight /= n_copies;
-// // make sure the base quadrature formula
-// // has only one quadrature point
-// // per end point
+// // make sure the base quadrature formula
+// // has only one quadrature point
+// // per end point
// Assert (n_end_points == 2, ExcInvalidQuadratureFormula());
// for (unsigned int copy=0; copy<n_copies; ++copy)
-// for (unsigned int q_point=0; q_point<base_quadrature.size(); ++q_point)
-// {
-// // skip the left point of
-// // this copy since we
-// // have already entered
-// // it the last time
-// if ((copy > 0) &&
-// (base_quadrature.point(q_point)(0) == 0.))
-// continue;
-
-// dst.quadrature_points[next_point](0)
-// = (copy+base_quadrature.point(q_point)(0)) / n_copies;
-
-// // if this is the
-// // rightmost point of one
-// // of the non-last
-// // copies: give it the
-// // double weight
-// if ((copy != n_copies-1) &&
-// (base_quadrature.point(q_point)(0) == 1.))
-// dst.weights[next_point] = double_point_weight;
-// else
-// dst.weights[next_point] = base_quadrature.weight(q_point) /
-// n_copies;
-
-// ++next_point;
-// };
+// for (unsigned int q_point=0; q_point<base_quadrature.size(); ++q_point)
+// {
+// // skip the left point of
+// // this copy since we
+// // have already entered
+// // it the last time
+// if ((copy > 0) &&
+// (base_quadrature.point(q_point)(0) == 0.))
+// continue;
+
+// dst.quadrature_points[next_point](0)
+// = (copy+base_quadrature.point(q_point)(0)) / n_copies;
+
+// // if this is the
+// // rightmost point of one
+// // of the non-last
+// // copies: give it the
+// // double weight
+// if ((copy != n_copies-1) &&
+// (base_quadrature.point(q_point)(0) == 1.))
+// dst.weights[next_point] = double_point_weight;
+// else
+// dst.weights[next_point] = base_quadrature.weight(q_point) /
+// n_copies;
+
+// ++next_point;
+// };
// };
// #if DEBUG
// for (unsigned int i=0; i<dst.size(); ++i)
// sum_of_weights += dst.weight(i);
// Assert (std::fabs(sum_of_weights-1) < 1e-15,
-// ExcInternalError());
+// ExcInternalError());
// #endif
// }
template <>
QIterated<0>::QIterated (const Quadrature<1> &,
- const unsigned int )
- :
- Quadrature<0>()
+ const unsigned int )
+ :
+ Quadrature<0>()
{
Assert (false, ExcNotImplemented());
}
template <>
QIterated<1>::QIterated (const Quadrature<1> &base_quadrature,
- const unsigned int n_copies)
+ const unsigned int n_copies)
:
- Quadrature<1> (uses_both_endpoints(base_quadrature) ?
- (base_quadrature.size()-1) * n_copies + 1 :
- base_quadrature.size() * n_copies)
+ Quadrature<1> (uses_both_endpoints(base_quadrature) ?
+ (base_quadrature.size()-1) * n_copies + 1 :
+ base_quadrature.size() * n_copies)
{
// fill(*this, base_quadrature, n_copies);
Assert (base_quadrature.size() > 0, ExcNotInitialized());
Assert (n_copies > 0, ExcZero());
if (!uses_both_endpoints(base_quadrature))
- // we don't have to skip some
- // points in order to get a
- // reasonable quadrature formula
+ // we don't have to skip some
+ // points in order to get a
+ // reasonable quadrature formula
{
unsigned int next_point = 0;
for (unsigned int copy=0; copy<n_copies; ++copy)
- for (unsigned int q_point=0; q_point<base_quadrature.size(); ++q_point)
- {
- this->quadrature_points[next_point]
- = Point<1>(base_quadrature.point(q_point)(0) / n_copies
- +
- (1.0*copy)/n_copies);
- this->weights[next_point]
- = base_quadrature.weight(q_point) / n_copies;
-
- ++next_point;
- };
+ for (unsigned int q_point=0; q_point<base_quadrature.size(); ++q_point)
+ {
+ this->quadrature_points[next_point]
+ = Point<1>(base_quadrature.point(q_point)(0) / n_copies
+ +
+ (1.0*copy)/n_copies);
+ this->weights[next_point]
+ = base_quadrature.weight(q_point) / n_copies;
+
+ ++next_point;
+ };
}
else
- // skip doubly available points
+ // skip doubly available points
{
unsigned int next_point = 0;
- // first find out the weights of
- // the left and the right boundary
- // points. note that these usually
- // are but need not necessarily be
- // the same
+ // first find out the weights of
+ // the left and the right boundary
+ // points. note that these usually
+ // are but need not necessarily be
+ // the same
double double_point_weight = 0;
unsigned int n_end_points = 0;
for (unsigned int i=0; i<base_quadrature.size(); ++i)
- // add up the weight if this
- // is an endpoint
- if ((base_quadrature.point(i) == Point<1>(0.0)) ||
- (base_quadrature.point(i) == Point<1>(1.0)))
- {
- double_point_weight += base_quadrature.weight(i);
- ++n_end_points;
- };
- // scale the weight correctly
+ // add up the weight if this
+ // is an endpoint
+ if ((base_quadrature.point(i) == Point<1>(0.0)) ||
+ (base_quadrature.point(i) == Point<1>(1.0)))
+ {
+ double_point_weight += base_quadrature.weight(i);
+ ++n_end_points;
+ };
+ // scale the weight correctly
double_point_weight /= n_copies;
- // make sure the base quadrature formula
- // has only one quadrature point
- // per end point
+ // make sure the base quadrature formula
+ // has only one quadrature point
+ // per end point
Assert (n_end_points == 2, ExcInvalidQuadratureFormula());
for (unsigned int copy=0; copy<n_copies; ++copy)
- for (unsigned int q_point=0; q_point<base_quadrature.size(); ++q_point)
- {
- // skip the left point of
- // this copy since we
- // have already entered
- // it the last time
- if ((copy > 0) &&
- (base_quadrature.point(q_point) == Point<1>(0.0)))
- continue;
-
- this->quadrature_points[next_point]
- = Point<1>(base_quadrature.point(q_point)(0) / n_copies
- +
- (1.0*copy)/n_copies);
-
- // if this is the
- // rightmost point of one
- // of the non-last
- // copies: give it the
- // double weight
- if ((copy != n_copies-1) &&
- (base_quadrature.point(q_point) == Point<1>(1.0)))
- this->weights[next_point] = double_point_weight;
- else
- this->weights[next_point] = base_quadrature.weight(q_point) /
- n_copies;
-
- ++next_point;
- };
+ for (unsigned int q_point=0; q_point<base_quadrature.size(); ++q_point)
+ {
+ // skip the left point of
+ // this copy since we
+ // have already entered
+ // it the last time
+ if ((copy > 0) &&
+ (base_quadrature.point(q_point) == Point<1>(0.0)))
+ continue;
+
+ this->quadrature_points[next_point]
+ = Point<1>(base_quadrature.point(q_point)(0) / n_copies
+ +
+ (1.0*copy)/n_copies);
+
+ // if this is the
+ // rightmost point of one
+ // of the non-last
+ // copies: give it the
+ // double weight
+ if ((copy != n_copies-1) &&
+ (base_quadrature.point(q_point) == Point<1>(1.0)))
+ this->weights[next_point] = double_point_weight;
+ else
+ this->weights[next_point] = base_quadrature.weight(q_point) /
+ n_copies;
+
+ ++next_point;
+ };
};
#if DEBUG
for (unsigned int i=0; i<this->size(); ++i)
sum_of_weights += this->weight(i);
Assert (std::fabs(sum_of_weights-1) < 1e-13,
- ExcInternalError());
+ ExcInternalError());
#endif
}
// of lower dimensional iterated quadrature formulae
template <int dim>
QIterated<dim>::QIterated (const Quadrature<1> &base_quadrature,
- const unsigned int N)
+ const unsigned int N)
:
- Quadrature<dim> (QIterated<dim-1>(base_quadrature, N),
- QIterated<1>(base_quadrature, N))
+ Quadrature<dim> (QIterated<dim-1>(base_quadrature, N),
+ QIterated<1>(base_quadrature, N))
{}
// $Id$
// Version: $Name$
//
-// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2006, 2007, 2008, 2009, 2010, 2011 by the deal.II authors
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
template <>
QGauss<0>::QGauss (const unsigned int)
:
- // there are n_q^dim == 1
- // points
+ // there are n_q^dim == 1
+ // points
Quadrature<0> (1)
{
- // the single quadrature point gets unit
- // weight
+ // the single quadrature point gets unit
+ // weight
this->weights[0] = 1;
}
template <>
QGaussLobatto<0>::QGaussLobatto (const unsigned int)
:
- // there are n_q^dim == 1
- // points
+ // there are n_q^dim == 1
+ // points
Quadrature<0> (1)
{
- // the single quadrature point gets unit
- // weight
+ // the single quadrature point gets unit
+ // weight
this->weights[0] = 1;
}
// of the accuracy of double there,
// while on other machines we'd
// like to go further down
- //
- // the situation is complicated by
- // the fact that even if long
- // double exists and is described
- // by std::numeric_limits, we may
- // not actually get the additional
- // precision. One case where this
- // happens is on x86, where one can
- // set hardware flags that disable
- // long double precision even for
- // long double variables. these
- // flags are not usually set, but
- // for example matlab sets them and
- // this then breaks deal.II code
- // that is run as a subroutine to
- // matlab...
+ //
+ // the situation is complicated by
+ // the fact that even if long
+ // double exists and is described
+ // by std::numeric_limits, we may
+ // not actually get the additional
+ // precision. One case where this
+ // happens is on x86, where one can
+ // set hardware flags that disable
+ // long double precision even for
+ // long double variables. these
+ // flags are not usually set, but
+ // for example matlab sets them and
+ // this then breaks deal.II code
+ // that is run as a subroutine to
+ // matlab...
//
// a similar situation exists, btw,
// when running programs under
double_eps = 2.23-16;
#endif
- // now check whether long double is more
- // accurate than double, and set
- // tolerances accordingly. generate a one
- // that really is generated at run-time
- // and is not optimized away by the
- // compiler. that makes sure that the
- // tolerance is set at run-time with the
- // current behavior, not at compile-time
- // (not doing so leads to trouble with
- // valgrind for example).
+ // now check whether long double is more
+ // accurate than double, and set
+ // tolerances accordingly. generate a one
+ // that really is generated at run-time
+ // and is not optimized away by the
+ // compiler. that makes sure that the
+ // tolerance is set at run-time with the
+ // current behavior, not at compile-time
+ // (not doing so leads to trouble with
+ // valgrind for example).
volatile long double runtime_one = 1.0;
const long double tolerance
= (runtime_one + long_double_eps != runtime_one
// Newton iteration
do
- {
- // compute L_n (z)
- p1 = 1.;
- p2 = 0.;
- for (unsigned int j=0;j<n;++j)
- {
- p3 = p2;
- p2 = p1;
- p1 = ((2.*j+1.)*z*p2-j*p3)/(j+1);
- }
- pp = n*(z*p1-p2)/(z*z-1);
- z = z-p1/pp;
- }
+ {
+ // compute L_n (z)
+ p1 = 1.;
+ p2 = 0.;
+ for (unsigned int j=0;j<n;++j)
+ {
+ p3 = p2;
+ p2 = p1;
+ p1 = ((2.*j+1.)*z*p2-j*p3)/(j+1);
+ }
+ pp = n*(z*p1-p2)/(z*z-1);
+ z = z-p1/pp;
+ }
while (abs(p1/pp) > tolerance);
double x = .5*z;
template <>
QGaussLobatto<1>::QGaussLobatto (const unsigned int n)
- :
- Quadrature<1> (n)
+ :
+ Quadrature<1> (n)
{
Assert (n >= 2, ExcNotImplemented());
std::vector<long double> points = compute_quadrature_points(n, 1, 1);
std::vector<long double> w = compute_quadrature_weights(points, 0, 0);
- // scale points to the interval
- // [0.0, 1.0]:
+ // scale points to the interval
+ // [0.0, 1.0]:
for (unsigned int i=0; i<points.size(); ++i)
{
this->quadrature_points[i] = Point<1>(0.5 + 0.5*static_cast<double>(points[i]));
template <>
std::vector<long double> QGaussLobatto<1>::
compute_quadrature_points(const unsigned int q,
- const int alpha,
- const int beta) const
+ const int alpha,
+ const int beta) const
{
const unsigned int m = q-2; // no. of inner points
std::vector<long double> x(m);
- // compute quadrature points with
- // a Newton algorithm.
+ // compute quadrature points with
+ // a Newton algorithm.
- // Set tolerance. See class QGauss
- // for detailed explanation.
+ // Set tolerance. See class QGauss
+ // for detailed explanation.
#ifdef HAVE_STD_NUMERIC_LIMITS
const long double
long_double_eps = static_cast<long double>(std::numeric_limits<long double>::epsilon()),
double_eps = 2.23-16;
#endif
- // check whether long double is
- // more accurate than double, and
- // set tolerances accordingly
+ // check whether long double is
+ // more accurate than double, and
+ // set tolerances accordingly
volatile long double runtime_one = 1.0;
const long double tolerance
= (runtime_one + long_double_eps != runtime_one
double_eps * 5
);
- // The following implementation
- // follows closely the one given in
- // the appendix of the book by
- // Karniadakis and Sherwin:
- // Spectral/hp element methods for
- // computational fluid dynamics
- // (Oxford University Press, 2005)
-
- // we take the zeros of the Chebyshev
- // polynomial (alpha=beta=-0.5) as
- // initial values:
+ // The following implementation
+ // follows closely the one given in
+ // the appendix of the book by
+ // Karniadakis and Sherwin:
+ // Spectral/hp element methods for
+ // computational fluid dynamics
+ // (Oxford University Press, 2005)
+
+ // we take the zeros of the Chebyshev
+ // polynomial (alpha=beta=-0.5) as
+ // initial values:
for (unsigned int i=0; i<m; ++i)
x[i] = - std::cos( (long double) (2*i+1)/(2*m) * numbers::PI );
{
r = x[k];
if (k>0)
- r = (r + x[k-1])/2;
+ r = (r + x[k-1])/2;
do
- {
- s = 0.;
- for (unsigned int i=0; i<k; ++i)
- s += 1./(r - x[i]);
-
- J_x = 0.5*(alpha + beta + m + 1)*JacobiP(r, alpha+1, beta+1, m-1);
- f = JacobiP(r, alpha, beta, m);
- delta = f/(f*s- J_x);
- r += delta;
- }
+ {
+ s = 0.;
+ for (unsigned int i=0; i<k; ++i)
+ s += 1./(r - x[i]);
+
+ J_x = 0.5*(alpha + beta + m + 1)*JacobiP(r, alpha+1, beta+1, m-1);
+ f = JacobiP(r, alpha, beta, m);
+ delta = f/(f*s- J_x);
+ r += delta;
+ }
while (std::fabs(delta) >= tolerance);
x[k] = r;
} // for
- // add boundary points:
+ // add boundary points:
x.insert(x.begin(), -1.L);
x.push_back(+1.L);
template <>
std::vector<long double> QGaussLobatto<1>::
compute_quadrature_weights(const std::vector<long double> &x,
- const int alpha,
- const int beta) const
+ const int alpha,
+ const int beta) const
{
const unsigned int q = x.size();
std::vector<long double> w(q);
long double s = 0.L;
const long double factor = std::pow(2., alpha+beta+1) *
- gamma(alpha+q) *
- gamma(beta+q) /
- ((q-1)*gamma(q)*gamma(alpha+beta+q+1));
+ gamma(alpha+q) *
+ gamma(beta+q) /
+ ((q-1)*gamma(q)*gamma(alpha+beta+q+1));
for (unsigned int i=0; i<q; ++i)
{
s = JacobiP(x[i], alpha, beta, q-1);
template <>
long double QGaussLobatto<1>::JacobiP(const long double x,
- const int alpha,
- const int beta,
- const unsigned int n) const
+ const int alpha,
+ const int beta,
+ const unsigned int n) const
{
- // the Jacobi polynomial is evaluated
- // using a recursion formula.
+ // the Jacobi polynomial is evaluated
+ // using a recursion formula.
std::vector<long double> p(n+1);
int v, a1, a2, a3, a4;
- // initial values P_0(x), P_1(x):
+ // initial values P_0(x), P_1(x):
p[0] = 1.0L;
if (n==0) return p[0];
p[1] = ((alpha+beta+2)*x + (alpha-beta))/2;
template <>
QMidpoint<1>::QMidpoint ()
:
- Quadrature<1>(1)
+ Quadrature<1>(1)
{
this->quadrature_points[0] = Point<1>(0.5);
this->weights[0] = 1.0;
template <>
QTrapez<1>::QTrapez ()
:
- Quadrature<1> (2)
+ Quadrature<1> (2)
{
static const double xpts[] = { 0.0, 1.0 };
static const double wts[] = { 0.5, 0.5 };
template <>
QSimpson<1>::QSimpson ()
:
- Quadrature<1> (3)
+ Quadrature<1> (3)
{
static const double xpts[] = { 0.0, 0.5, 1.0 };
static const double wts[] = { 1./6., 2./3., 1./6. };
template <>
QMilne<1>::QMilne ()
:
- Quadrature<1> (5)
+ Quadrature<1> (5)
{
static const double xpts[] = { 0.0, .25, .5, .75, 1.0 };
static const double wts[] = { 7./90., 32./90., 12./90., 32./90., 7./90. };
template <>
QWeddle<1>::QWeddle ()
:
- Quadrature<1> (7)
+ Quadrature<1> (7)
{
static const double xpts[] = { 0.0, 1./6., 1./3., .5, 2./3., 5./6., 1.0 };
static const double wts[] = { 41./840., 216./840., 27./840., 272./840.,
- 27./840., 216./840., 41./840.
+ 27./840., 216./840., 41./840.
};
for (unsigned int i=0; i<this->size(); ++i)
for (unsigned int i=0; i<this->size(); ++i)
{
- // Using the change of variables x=1-t, it's possible to show
- // that int f(x)ln|1-x| = int f(1-t) ln|t|, which implies that
- // we can use this quadrature formula also with weight ln|1-x|.
- this->quadrature_points[i] = revert ? Point<1>(1-p[n-1-i]) : Point<1>(p[i]);
- this->weights[i] = revert ? w[n-1-i] : w[i];
+ // Using the change of variables x=1-t, it's possible to show
+ // that int f(x)ln|1-x| = int f(1-t) ln|t|, which implies that
+ // we can use this quadrature formula also with weight ln|1-x|.
+ this->quadrature_points[i] = revert ? Point<1>(1-p[n-1-i]) : Point<1>(p[i]);
+ this->weights[i] = revert ? w[n-1-i] : w[i];
}
}
template<>
QGaussLogR<1>::QGaussLogR(const unsigned int n,
- const Point<1> origin,
- const double alpha,
- const bool factor_out_singularity) :
+ const Point<1> origin,
+ const double alpha,
+ const bool factor_out_singularity) :
Quadrature<1>( ( (origin[0] == 0) || (origin[0] == 1) ) ?
- (alpha == 1 ? n : 2*n ) : 4*n ),
+ (alpha == 1 ? n : 2*n ) : 4*n ),
fraction( ( (origin[0] == 0) || (origin[0] == 1.) ) ? 1. : origin[0] )
{
// The three quadrature formulas that make this one up. There are
// Check that the origin is inside 0,1
Assert( (fraction >= 0) && (fraction <= 1),
- ExcMessage("Origin is outside [0,1]."));
+ ExcMessage("Origin is outside [0,1]."));
// Non singular offset. This is the start of non singular quad
// points.
unsigned int ns_offset = (fraction == 1) ? n : 2*n;
for(unsigned int i=0, j=ns_offset; i<n; ++i, ++j) {
- // The first i quadrature points are the same as quad1, and
- // are by default singular.
- this->quadrature_points[i] = quad1.point(i)*fraction;
- this->weights[i] = quad1.weight(i)*fraction;
-
- // We need to scale with -log|fraction*alpha|
- if( (alpha != 1) || (fraction != 1) ) {
- this->quadrature_points[j] = quad.point(i)*fraction;
- this->weights[j] = -std::log(alpha/fraction)*quad.weight(i)*fraction;
- }
- // In case we need the second quadrature as well, do it now.
- if(fraction != 1) {
- this->quadrature_points[i+n] = quad2.point(i)*(1-fraction)+Point<1>(fraction);
- this->weights[i+n] = quad2.weight(i)*(1-fraction);
-
- // We need to scale with -log|fraction*alpha|
- this->quadrature_points[j+n] = quad.point(i)*(1-fraction)+Point<1>(fraction);
- this->weights[j+n] = -std::log(alpha/(1-fraction))*quad.weight(i)*(1-fraction);
- }
+ // The first i quadrature points are the same as quad1, and
+ // are by default singular.
+ this->quadrature_points[i] = quad1.point(i)*fraction;
+ this->weights[i] = quad1.weight(i)*fraction;
+
+ // We need to scale with -log|fraction*alpha|
+ if( (alpha != 1) || (fraction != 1) ) {
+ this->quadrature_points[j] = quad.point(i)*fraction;
+ this->weights[j] = -std::log(alpha/fraction)*quad.weight(i)*fraction;
+ }
+ // In case we need the second quadrature as well, do it now.
+ if(fraction != 1) {
+ this->quadrature_points[i+n] = quad2.point(i)*(1-fraction)+Point<1>(fraction);
+ this->weights[i+n] = quad2.weight(i)*(1-fraction);
+
+ // We need to scale with -log|fraction*alpha|
+ this->quadrature_points[j+n] = quad.point(i)*(1-fraction)+Point<1>(fraction);
+ this->weights[j+n] = -std::log(alpha/(1-fraction))*quad.weight(i)*(1-fraction);
+ }
}
if(factor_out_singularity == true)
- for(unsigned int i=0; i<size(); ++i) {
- Assert( this->quadrature_points[i] != origin,
- ExcMessage("The singularity cannot be on a Gauss point of the same order!") );
- this->weights[i] /= std::log(std::abs( (this->quadrature_points[i]-origin)[0] )/alpha );
- }
+ for(unsigned int i=0; i<size(); ++i) {
+ Assert( this->quadrature_points[i] != origin,
+ ExcMessage("The singularity cannot be on a Gauss point of the same order!") );
+ this->weights[i] /= std::log(std::abs( (this->quadrature_points[i]-origin)[0] )/alpha );
+ }
}
template<>
unsigned int QGaussOneOverR<2>::quad_size(const Point<2> singularity,
- const unsigned int n)
+ const unsigned int n)
{
double eps=1e-8;
bool on_edge=false;
bool on_vertex=false;
for(unsigned int i=0; i<2; ++i)
if( ( std::abs(singularity[i] ) < eps ) ||
- ( std::abs(singularity[i]-1) < eps ) )
+ ( std::abs(singularity[i]-1) < eps ) )
on_edge = true;
if(on_edge && (std::abs( (singularity-Point<2>(.5, .5)).square()-.5)
- < eps) )
+ < eps) )
on_vertex = true;
if(on_vertex) return (2*n*n);
if(on_edge) return (4*n*n);
template<>
QGaussOneOverR<2>::QGaussOneOverR(const unsigned int n,
- const Point<2> singularity,
- const bool factor_out_singularity) :
- Quadrature<2>(quad_size(singularity, n))
+ const Point<2> singularity,
+ const bool factor_out_singularity) :
+ Quadrature<2>(quad_size(singularity, n))
{
- // We treat all the cases in the
- // same way. Split the element in 4
- // pieces, measure the area, if
- // it's relevant, add the
- // quadrature connected to that
- // singularity.
+ // We treat all the cases in the
+ // same way. Split the element in 4
+ // pieces, measure the area, if
+ // it's relevant, add the
+ // quadrature connected to that
+ // singularity.
std::vector<QGaussOneOverR<2> > quads;
std::vector<Point<2> > origins;
- // Id of the corner with a
- // singularity
+ // Id of the corner with a
+ // singularity
quads.push_back(QGaussOneOverR(n, 3, factor_out_singularity));
quads.push_back(QGaussOneOverR(n, 2, factor_out_singularity));
quads.push_back(QGaussOneOverR(n, 1, factor_out_singularity));
origins.push_back(Point<2>(0.,singularity[1]));
origins.push_back(singularity);
- // Lexycographical ordering.
+ // Lexycographical ordering.
double eps = 1e-8;
unsigned int q_id = 0; // Current quad point index.
dist = Point<2>(std::abs(dist[0]), std::abs(dist[1]));
area = dist[0]*dist[1];
if(area > eps)
- for(unsigned int q=0; q<quads[box].size(); ++q, ++q_id)
- {
- const Point<2> &qp = quads[box].point(q);
- this->quadrature_points[q_id] =
- origins[box]+
- Point<2>(dist[0]*qp[0], dist[1]*qp[1]);
- this->weights[q_id] = quads[box].weight(q)*area;
- }
+ for(unsigned int q=0; q<quads[box].size(); ++q, ++q_id)
+ {
+ const Point<2> &qp = quads[box].point(q);
+ this->quadrature_points[q_id] =
+ origins[box]+
+ Point<2>(dist[0]*qp[0], dist[1]*qp[1]);
+ this->weights[q_id] = quads[box].weight(q)*area;
+ }
}
}
template<>
QGaussOneOverR<2>::QGaussOneOverR(const unsigned int n,
- const unsigned int vertex_index,
- const bool factor_out_singularity) :
+ const unsigned int vertex_index,
+ const bool factor_out_singularity) :
Quadrature<2>(2*n*n)
{
- // This version of the constructor
- // works only for the 4
- // vertices. If you need a more
- // general one, you should use the
- // one with the Point<2> in the
- // constructor.
+ // This version of the constructor
+ // works only for the 4
+ // vertices. If you need a more
+ // general one, you should use the
+ // one with the Point<2> in the
+ // constructor.
Assert(vertex_index <4, ExcIndexRange(vertex_index, 0, 4));
-
+
// Start with the gauss quadrature formula on the (u,v) reference
// element.
QGauss<2> gauss(n);
//
// And we get rid of R to take into account the singularity,
// unless specified differently in the constructor.
- std::vector<Point<2> > &ps = this->quadrature_points;
- std::vector<double> &ws = this->weights;
+ std::vector<Point<2> > &ps = this->quadrature_points;
+ std::vector<double> &ws = this->weights;
double pi4 = numbers::PI/4;
for(unsigned int q=0; q<gauss.size(); ++q) {
- const Point<2> &gp = gauss.point(q);
- ps[q][0] = gp[0];
- ps[q][1] = gp[0] * std::tan(pi4*gp[1]);
- ws[q] = gauss.weight(q)*pi4/std::cos(pi4 *gp[1]);
- if(factor_out_singularity)
- ws[q] *= (ps[q]-GeometryInfo<2>::unit_cell_vertex(0)).norm();
- // The other half of the quadrilateral is symmetric with
- // respect to xy plane.
- ws[gauss.size()+q] = ws[q];
- ps[gauss.size()+q][0] = ps[q][1];
- ps[gauss.size()+q][1] = ps[q][0];
+ const Point<2> &gp = gauss.point(q);
+ ps[q][0] = gp[0];
+ ps[q][1] = gp[0] * std::tan(pi4*gp[1]);
+ ws[q] = gauss.weight(q)*pi4/std::cos(pi4 *gp[1]);
+ if(factor_out_singularity)
+ ws[q] *= (ps[q]-GeometryInfo<2>::unit_cell_vertex(0)).norm();
+ // The other half of the quadrilateral is symmetric with
+ // respect to xy plane.
+ ws[gauss.size()+q] = ws[q];
+ ps[gauss.size()+q][0] = ps[q][1];
+ ps[gauss.size()+q][1] = ps[q][0];
}
// Now we distribute these vertices in the correct manner
double theta = 0;
switch(vertex_index) {
case 0:
- theta = 0;
- break;
+ theta = 0;
+ break;
case 1:
- //
- theta = numbers::PI/2;
- break;
+ //
+ theta = numbers::PI/2;
+ break;
case 2:
- theta = -numbers::PI/2;
- break;
+ theta = -numbers::PI/2;
+ break;
case 3:
- theta = numbers::PI;
- break;
+ theta = numbers::PI;
+ break;
}
double R00 = std::cos(theta), R01 = -std::sin(theta);
double R10 = std::sin(theta), R11 = std::cos(theta);
if(vertex_index != 0)
- for(unsigned int q=0; q<size(); ++q) {
- double x = ps[q][0]-.5, y = ps[q][1]-.5;
+ for(unsigned int q=0; q<size(); ++q) {
+ double x = ps[q][0]-.5, y = ps[q][1]-.5;
- ps[q][0] = R00*x + R01*y + .5;
- ps[q][1] = R10*x + R11*y + .5;
- }
+ ps[q][0] = R00*x + R01*y + .5;
+ ps[q][1] = R10*x + R11*y + .5;
+ }
}
template <int dim>
QMidpoint<dim>::QMidpoint ()
:
- Quadrature<dim> (QMidpoint<dim-1>(), QMidpoint<1>())
+ Quadrature<dim> (QMidpoint<dim-1>(), QMidpoint<1>())
{}
template <int dim>
QTrapez<dim>::QTrapez ()
:
- Quadrature<dim> (QTrapez<dim-1>(), QTrapez<1>())
+ Quadrature<dim> (QTrapez<dim-1>(), QTrapez<1>())
{}
template <int dim>
QSimpson<dim>::QSimpson ()
:
- Quadrature<dim> (QSimpson<dim-1>(), QSimpson<1>())
+ Quadrature<dim> (QSimpson<dim-1>(), QSimpson<1>())
{}
template <int dim>
QMilne<dim>::QMilne ()
:
- Quadrature<dim> (QMilne<dim-1>(), QMilne<1>())
+ Quadrature<dim> (QMilne<dim-1>(), QMilne<1>())
{}
template <int dim>
QWeddle<dim>::QWeddle ()
:
- Quadrature<dim> (QWeddle<dim-1>(), QWeddle<1>())
+ Quadrature<dim> (QWeddle<dim-1>(), QWeddle<1>())
{}
// $Id$
// Version: $Name$
//
-// Copyright (C) 2003, 2005, 2006, 2010 by the deal.II authors
+// Copyright (C) 2003, 2005, 2006, 2010, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
Quadrature<dim>
QuadratureSelector<dim>::
create_quadrature (const std::string &s,
- const unsigned int order)
+ const unsigned int order)
{
if(s == "gauss")
{
else if (s == "weddle") return QWeddle<dim>();
}
- // we didn't find this name
+ // we didn't find this name
AssertThrow (false, ExcInvalidQuadrature(s));
- // return something to suppress
- // stupid warnings by some
- // compilers
+ // return something to suppress
+ // stupid warnings by some
+ // compilers
return Quadrature<dim>();
}
template <int dim>
QuadratureSelector<dim>::QuadratureSelector (const std::string &s,
- const unsigned int order)
- :
- Quadrature<dim> (create_quadrature(s, order).get_points(),
- create_quadrature(s, order).get_weights())
-{
+ const unsigned int order)
+ :
+ Quadrature<dim> (create_quadrature(s, order).get_points(),
+ create_quadrature(s, order).get_weights())
+{
}
// $Id$
// Version: $Name$
//
-// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2006, 2007, 2008, 2010 by the deal.II authors
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2006, 2007, 2008, 2010, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
DEAL_II_NAMESPACE_OPEN
-namespace
+namespace
{
// create a lock that might be used to control subscription to and
// unsubscription from objects, as that might happen in parallel.
Subscriptor::Subscriptor ()
:
- counter (0),
- object_info (0)
+ counter (0),
+ object_info (0)
{}
Subscriptor::Subscriptor (const Subscriptor &)
:
- counter (0),
- object_info (0)
+ counter (0),
+ object_info (0)
{}
Subscriptor::~Subscriptor ()
{
- // check whether there are still
- // subscriptions to this object. if
- // so, output the actual name of
- // the class to which this object
- // belongs, i.e. the most derived
- // class. note that the name may be
- // mangled, so it need not be the
- // clear-text class name. however,
- // you can obtain the latter by
- // running the c++filt program over
- // the output.
+ // check whether there are still
+ // subscriptions to this object. if
+ // so, output the actual name of
+ // the class to which this object
+ // belongs, i.e. the most derived
+ // class. note that the name may be
+ // mangled, so it need not be the
+ // clear-text class name. however,
+ // you can obtain the latter by
+ // running the c++filt program over
+ // the output.
#ifdef DEBUG
std::string infostring;
for (map_iterator it = counter_map.begin(); it != counter_map.end(); ++it)
{
if (it->second > 0)
- infostring += std::string("\n from Subscriber ")
- + std::string(it->first);
+ infostring += std::string("\n from Subscriber ")
+ + std::string(it->first);
}
- // if there are still active pointers, show
- // a message and kill the program. However,
- // under some circumstances, this is not so
- // desirable. For example, in code like this
- //
- // Triangulation tria;
- // DoFHandler *dh = new DoFHandler(tria);
- // ...some function that throws an exception
- //
- // the exception will lead to the
- // destruction of the triangulation, but
- // since the dof_handler is on the heap it
- // will not be destroyed. This will trigger
- // an assertion in the triangulation. If we
- // kill the program at this point, we will
- // never be able to learn what caused the
- // problem. In this situation, just display
- // a message and continue the program.
+ // if there are still active pointers, show
+ // a message and kill the program. However,
+ // under some circumstances, this is not so
+ // desirable. For example, in code like this
+ //
+ // Triangulation tria;
+ // DoFHandler *dh = new DoFHandler(tria);
+ // ...some function that throws an exception
+ //
+ // the exception will lead to the
+ // destruction of the triangulation, but
+ // since the dof_handler is on the heap it
+ // will not be destroyed. This will trigger
+ // an assertion in the triangulation. If we
+ // kill the program at this point, we will
+ // never be able to learn what caused the
+ // problem. In this situation, just display
+ // a message and continue the program.
if (counter != 0)
{
if (std::uncaught_exception() == false)
- {
- Assert (counter == 0,
- ExcInUse (counter, object_info->name(), infostring));
- }
+ {
+ Assert (counter == 0,
+ ExcInUse (counter, object_info->name(), infostring));
+ }
else
- {
- std::cerr << "---------------------------------------------------------"
- << std::endl
- << "An object pointed to by a SmartPointer is being destroyed."
- << std::endl
- << "Under normal circumstances, this would abort the program."
- << std::endl
- << "However, another exception is being processed at the"
- << std::endl
- << "moment, so the program will continue to run to allow"
- << std::endl
- << "this exception to be processed."
- << std::endl
- << "---------------------------------------------------------"
- << std::endl;
- }
+ {
+ std::cerr << "---------------------------------------------------------"
+ << std::endl
+ << "An object pointed to by a SmartPointer is being destroyed."
+ << std::endl
+ << "Under normal circumstances, this would abort the program."
+ << std::endl
+ << "However, another exception is being processed at the"
+ << std::endl
+ << "moment, so the program will continue to run to allow"
+ << std::endl
+ << "this exception to be processed."
+ << std::endl
+ << "---------------------------------------------------------"
+ << std::endl;
+ }
}
- // In case we do not abort
- // on error, this will tell
- // do_unsubscribe below that the
- // object is unused now.
+ // In case we do not abort
+ // on error, this will tell
+ // do_unsubscribe below that the
+ // object is unused now.
counter = 0;
#endif
}
object_info = &typeid(*this);
Threads::ThreadMutex::ScopedLock lock (subscription_lock);
++counter;
-
+
#if DEAL_USE_MT == 0
const char* const name = (id != 0) ? id : unknown_subscriber;
-
+
map_iterator it = counter_map.find(name);
if (it == counter_map.end())
counter_map.insert(map_value_type(name, 1U));
-
+
else
it->second++;
#endif
#ifdef DEBUG
const char* name = (id != 0) ? id : unknown_subscriber;
Assert (counter>0, ExcNoSubscriber(object_info->name(), name));
- // This is for the case that we do
- // not abort after the exception
+ // This is for the case that we do
+ // not abort after the exception
if (counter == 0)
return;
-
+
Threads::ThreadMutex::ScopedLock lock (subscription_lock);
--counter;
-
+
#if DEAL_USE_MT == 0
map_iterator it = counter_map.find(name);
Assert (it != counter_map.end(), ExcNoSubscriber(object_info->name(), name));
Assert (it->second > 0, ExcNoSubscriber(object_info->name(), name));
-
+
it->second--;
#endif
#endif
for (map_iterator it = counter_map.begin();
it != counter_map.end(); ++it)
deallog << it->second << '/'
- << counter << " subscriptions from \""
- << it->first << '\"' << std::endl;
+ << counter << " subscriptions from \""
+ << it->first << '\"' << std::endl;
#else
deallog << "No subscriber listing with multithreading" << std::endl;
#endif
// $Id$
// Version: $Name$
//
-// Copyright (C) 2005, 2006 by the deal.II authors
+// Copyright (C) 2005, 2006, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
// references between libbase and liblac
const unsigned int N = 6;
- // first get an estimate of the
- // size of the elements of this
- // matrix, for later checks whether
- // the pivot element is large
- // enough, or whether we have to
- // fear that the matrix is not
- // regular
+ // first get an estimate of the
+ // size of the elements of this
+ // matrix, for later checks whether
+ // the pivot element is large
+ // enough, or whether we have to
+ // fear that the matrix is not
+ // regular
double diagonal_sum = 0;
for (unsigned int i=0; i<N; ++i)
diagonal_sum += std::fabs(tmp.data[i][i]);
for (unsigned int j=0; j<N; ++j)
{
- // pivot search: search that
- // part of the line on and
- // right of the diagonal for
- // the largest element
+ // pivot search: search that
+ // part of the line on and
+ // right of the diagonal for
+ // the largest element
double max = std::fabs(tmp.data[j][j]);
unsigned int r = j;
for (unsigned int i=j+1; i<N; ++i)
max = std::fabs(tmp.data[i][j]);
r = i;
}
- // check whether the pivot is
- // too small
+ // check whether the pivot is
+ // too small
Assert(max > 1.e-16*typical_diagonal_element,
- ExcMessage("This tensor seems to be noninvertible"));
+ ExcMessage("This tensor seems to be noninvertible"));
- // row interchange
+ // row interchange
if (r>j)
- {
- for (unsigned int k=0; k<N; ++k)
- std::swap (tmp.data[j][k], tmp.data[r][k]);
+ {
+ for (unsigned int k=0; k<N; ++k)
+ std::swap (tmp.data[j][k], tmp.data[r][k]);
- std::swap (p[j], p[r]);
- }
+ std::swap (p[j], p[r]);
+ }
- // transformation
+ // transformation
const double hr = 1./tmp.data[j][j];
tmp.data[j][j] = hr;
for (unsigned int k=0; k<N; ++k)
- {
- if (k==j) continue;
- for (unsigned int i=0; i<N; ++i)
- {
- if (i==j) continue;
- tmp.data[i][k] -= tmp.data[i][j]*tmp.data[j][k]*hr;
- }
- }
+ {
+ if (k==j) continue;
+ for (unsigned int i=0; i<N; ++i)
+ {
+ if (i==j) continue;
+ tmp.data[i][k] -= tmp.data[i][j]*tmp.data[j][k]*hr;
+ }
+ }
for (unsigned int i=0; i<N; ++i)
- {
- tmp.data[i][j] *= hr;
- tmp.data[j][i] *= -hr;
- }
+ {
+ tmp.data[i][j] *= hr;
+ tmp.data[j][i] *= -hr;
+ }
tmp.data[j][j] = hr;
}
- // column interchange
+ // column interchange
double hv[N];
for (unsigned int i=0; i<N; ++i)
{
for (unsigned int k=0; k<N; ++k)
- hv[p[k]] = tmp.data[i][k];
+ hv[p[k]] = tmp.data[i][k];
for (unsigned int k=0; k<N; ++k)
- tmp.data[i][k] = hv[k];
+ tmp.data[i][k] = hv[k];
}
// scale rows and columns. the mult matrix
template <typename T>
void operator()( T & operand ) const
{
- operand = T();
+ operand = T();
}
};
}
TableHandler::Column::Column(const std::string &tex_caption)
:
- tex_caption(tex_caption),
- tex_format("c"),
- precision(4),
- scientific(0),
- flag(0)
+ tex_caption(tex_caption),
+ tex_format("c"),
+ precision(4),
+ scientific(0),
+ flag(0)
{}
TableHandler::Column::Column()
:
- tex_caption(),
- tex_format("c"),
- precision(4),
- scientific(0),
- flag(0)
+ tex_caption(),
+ tex_format("c"),
+ precision(4),
+ scientific(0),
+ flag(0)
{}
void TableHandler::add_column_to_supercolumn (const std::string &key,
- const std::string &superkey)
+ const std::string &superkey)
{
Assert(columns.count(key), ExcColumnNotExistent(key));
std::pair<std::string, std::vector<std::string> >
new_column(superkey, std::vector<std::string>());
supercolumns.insert(new_column);
- // replace key in column_order
- // by superkey
+ // replace key in column_order
+ // by superkey
for (unsigned int j=0; j<column_order.size(); ++j)
- if (column_order[j]==key)
- {
- column_order[j]=superkey;
- break;
- }
+ if (column_order[j]==key)
+ {
+ column_order[j]=superkey;
+ break;
+ }
}
else
{
- // remove key from column_order
- // for erase we need an iterator
+ // remove key from column_order
+ // for erase we need an iterator
for (std::vector<std::string>::iterator order_iter=column_order.begin();
- order_iter!=column_order.end(); ++order_iter)
- if (*order_iter==key)
- {
- column_order.erase(order_iter);
- break;
- }
+ order_iter!=column_order.end(); ++order_iter)
+ if (*order_iter==key)
+ {
+ column_order.erase(order_iter);
+ break;
+ }
}
if (supercolumns.count(superkey))
{
supercolumns[superkey].push_back(key);
- // By default set the
- // tex_supercaption to superkey
+ // By default set the
+ // tex_supercaption to superkey
std::pair<std::string, std::string> new_tex_supercaption(superkey, superkey);
tex_supercaptions.insert(new_tex_supercaption);
}
{
for (unsigned int j=0; j<new_order.size(); ++j)
Assert(supercolumns.count(new_order[j]) || columns.count(new_order[j]),
- ExcColumnOrSuperColumnNotExistent(new_order[j]));
+ ExcColumnOrSuperColumnNotExistent(new_order[j]));
column_order=new_order;
}
void TableHandler::set_tex_caption (const std::string &key,
- const std::string &tex_caption)
+ const std::string &tex_caption)
{
Assert(columns.count(key), ExcColumnNotExistent(key));
columns[key].tex_caption=tex_caption;
void TableHandler::set_tex_supercaption (const std::string &superkey,
- const std::string &tex_supercaption)
+ const std::string &tex_supercaption)
{
Assert(supercolumns.count(superkey), ExcSuperColumnNotExistent(superkey));
Assert(tex_supercaptions.count(superkey), ExcInternalError());
void TableHandler::set_tex_format (const std::string &key,
- const std::string &tex_format)
+ const std::string &tex_format)
{
Assert(columns.count(key), ExcColumnNotExistent(key));
Assert(tex_format=="l" || tex_format=="c" || tex_format=="r",
- ExcUndefinedTexFormat(tex_format));
+ ExcUndefinedTexFormat(tex_format));
columns[key].tex_format=tex_format;
}
void TableHandler::set_precision (const std::string &key,
- const unsigned int precision)
+ const unsigned int precision)
{
Assert(columns.count(key), ExcColumnNotExistent(key));
columns[key].precision=precision;
void TableHandler::set_scientific (const std::string &key,
- const bool scientific)
+ const bool scientific)
{
Assert(columns.count(key), ExcColumnNotExistent(key));
columns[key].scientific=scientific;
void TableHandler::write_text(std::ostream &out,
- const TextOutputFormat format) const
+ const TextOutputFormat format) const
{
AssertThrow (out, ExcIO());
{
unsigned int max_rows = 0;
for (std::map<std::string, Column>::const_iterator p = columns.begin();
- p != columns.end(); ++p)
+ p != columns.end(); ++p)
max_rows = std::max<unsigned int>(max_rows, p->second.entries.size());
for (std::map<std::string, Column>::iterator p = columns.begin();
- p != columns.end(); ++p)
+ p != columns.end(); ++p)
p->second.pad_column_below (max_rows);
}
const unsigned int nrows = n_rows();
const unsigned int n_cols = sel_columns.size();
- // first compute the widths of each
- // entry of the table, in order to
- // have a nicer alignement
+ // first compute the widths of each
+ // entry of the table, in order to
+ // have a nicer alignement
Table<2,unsigned int> entry_widths (nrows, n_cols);
for (unsigned int i=0; i<nrows; ++i)
for (unsigned int j=0; j<n_cols; ++j)
{
- // get key and entry here
- std::string key = sel_columns[j];
- const std::map<std::string, Column>::const_iterator
- col_iter = columns.find(key);
- Assert(col_iter!=columns.end(), ExcInternalError());
-
- const Column & column = col_iter->second;
-
- // write it into a dummy
- // stream, just to get its
- // size upon output
- std::ostringstream dummy_out;
-
- dummy_out << std::setprecision(column.precision);
-
- if (col_iter->second.scientific)
- dummy_out.setf (std::ios::scientific, std::ios::floatfield);
- else
- dummy_out.setf (std::ios::fixed, std::ios::floatfield);
-
- dummy_out << column.entries[i].value;
-
- // get size. as a side note, if the
- // text printed is in fact the empty
- // string, then we get into a bit of
- // trouble since readers would skip
- // over the resulting whitespaces. as
- // a consequence, we'll print ""
- // instead in that case.
- const unsigned int size = dummy_out.str().length();
- if (size > 0)
- entry_widths[i][j] = size;
- else
- entry_widths[i][j] = 2;
+ // get key and entry here
+ std::string key = sel_columns[j];
+ const std::map<std::string, Column>::const_iterator
+ col_iter = columns.find(key);
+ Assert(col_iter!=columns.end(), ExcInternalError());
+
+ const Column & column = col_iter->second;
+
+ // write it into a dummy
+ // stream, just to get its
+ // size upon output
+ std::ostringstream dummy_out;
+
+ dummy_out << std::setprecision(column.precision);
+
+ if (col_iter->second.scientific)
+ dummy_out.setf (std::ios::scientific, std::ios::floatfield);
+ else
+ dummy_out.setf (std::ios::fixed, std::ios::floatfield);
+
+ dummy_out << column.entries[i].value;
+
+ // get size. as a side note, if the
+ // text printed is in fact the empty
+ // string, then we get into a bit of
+ // trouble since readers would skip
+ // over the resulting whitespaces. as
+ // a consequence, we'll print ""
+ // instead in that case.
+ const unsigned int size = dummy_out.str().length();
+ if (size > 0)
+ entry_widths[i][j] = size;
+ else
+ entry_widths[i][j] = 2;
}
- // next compute the width each row
- // has to have to suit all entries
+ // next compute the width each row
+ // has to have to suit all entries
std::vector<unsigned int> column_widths (n_cols, 0);
for (unsigned int i=0; i<nrows; ++i)
for (unsigned int j=0; j<n_cols; ++j)
column_widths[j] = std::max(entry_widths[i][j],
- column_widths[j]);
+ column_widths[j]);
- // write the captions
+ // write the captions
for (unsigned int j=0; j<column_order.size(); ++j)
{
const std::string & key = column_order[j];
switch (format)
{
- case table_with_headers:
- {
- // if the key of this column is
- // wider than the widest entry,
- // then adjust
- if (key.length() > column_widths[j])
- column_widths[j] = key.length();
-
- // now write key. try to center
- // it somehow
- const unsigned int front_padding = (column_widths[j]-key.length())/2,
- rear_padding = (column_widths[j]-key.length()) -
- front_padding;
+ case table_with_headers:
+ {
+ // if the key of this column is
+ // wider than the widest entry,
+ // then adjust
+ if (key.length() > column_widths[j])
+ column_widths[j] = key.length();
+
+ // now write key. try to center
+ // it somehow
+ const unsigned int front_padding = (column_widths[j]-key.length())/2,
+ rear_padding = (column_widths[j]-key.length()) -
+ front_padding;
for (unsigned int i=0; i<front_padding; ++i)
- out << ' ';
- out << key;
- for (unsigned int i=0; i<rear_padding; ++i)
- out << ' ';
-
- // finally column break
- out << ' ';
-
- break;
- }
-
- case table_with_separate_column_description:
- {
- // print column key with column number. enumerate
- // columns starting with 1
- out << "# " << j+1 << ": " << key << std::endl;
- break;
- }
-
- default:
- Assert (false, ExcInternalError());
+ out << ' ';
+ out << key;
+ for (unsigned int i=0; i<rear_padding; ++i)
+ out << ' ';
+
+ // finally column break
+ out << ' ';
+
+ break;
+ }
+
+ case table_with_separate_column_description:
+ {
+ // print column key with column number. enumerate
+ // columns starting with 1
+ out << "# " << j+1 << ": " << key << std::endl;
+ break;
+ }
+
+ default:
+ Assert (false, ExcInternalError());
}
}
if (format == table_with_headers)
for (unsigned int i=0; i<nrows; ++i)
{
for (unsigned int j=0; j<n_cols; ++j)
- {
- std::string key=sel_columns[j];
- const std::map<std::string, Column>::const_iterator
- col_iter=columns.find(key);
- Assert(col_iter!=columns.end(), ExcInternalError());
-
- const Column &column=col_iter->second;
-
- out << std::setprecision(column.precision);
-
- if (col_iter->second.scientific)
- out.setf(std::ios::scientific, std::ios::floatfield);
- else
- out.setf(std::ios::fixed, std::ios::floatfield);
- out << std::setw(column_widths[j]);
-
- // get the string to write into the
- // table. we could simply << it
- // into the stream but we have to
- // be a bit careful about the case
- // where the string may be empty,
- // in which case we'll print it as
- // "". note that ultimately we
- // still just << it into the stream
- // since we want to use the flags
- // of that stream, and the first
- // test is only used to determine
- // whether the size of the string
- // representation is zero
- {
- std::ostringstream text;
- text << column.entries[i].value;
- if (text.str().size() > 0)
- out << column.entries[i].value;
- else
- out << "\"\"";
- }
-
- // pad after this column
- out << " ";
- }
+ {
+ std::string key=sel_columns[j];
+ const std::map<std::string, Column>::const_iterator
+ col_iter=columns.find(key);
+ Assert(col_iter!=columns.end(), ExcInternalError());
+
+ const Column &column=col_iter->second;
+
+ out << std::setprecision(column.precision);
+
+ if (col_iter->second.scientific)
+ out.setf(std::ios::scientific, std::ios::floatfield);
+ else
+ out.setf(std::ios::fixed, std::ios::floatfield);
+ out << std::setw(column_widths[j]);
+
+ // get the string to write into the
+ // table. we could simply << it
+ // into the stream but we have to
+ // be a bit careful about the case
+ // where the string may be empty,
+ // in which case we'll print it as
+ // "". note that ultimately we
+ // still just << it into the stream
+ // since we want to use the flags
+ // of that stream, and the first
+ // test is only used to determine
+ // whether the size of the string
+ // representation is zero
+ {
+ std::ostringstream text;
+ text << column.entries[i].value;
+ if (text.str().size() > 0)
+ out << column.entries[i].value;
+ else
+ out << "\"\"";
+ }
+
+ // pad after this column
+ out << " ";
+ }
out << std::endl;
}
}
AssertThrow (out, ExcIO());
if (with_header)
out << "\\documentclass[10pt]{report}" << std::endl
- << "\\usepackage{float}" << std::endl << std::endl << std::endl
- << "\\begin{document}" << std::endl;
+ << "\\usepackage{float}" << std::endl << std::endl << std::endl
+ << "\\begin{document}" << std::endl;
out << "\\begin{table}[H]" << std::endl
<< "\\begin{center}" << std::endl
{
unsigned int max_rows = 0;
for (std::map<std::string, Column>::const_iterator p = columns.begin();
- p != columns.end(); ++p)
+ p != columns.end(); ++p)
max_rows = std::max<unsigned int>(max_rows, p->second.entries.size());
for (std::map<std::string, Column>::iterator p = columns.begin();
- p != columns.end(); ++p)
+ p != columns.end(); ++p)
p->second.pad_column_below (max_rows);
}
std::vector<std::string> sel_columns;
get_selected_columns(sel_columns);
- // write the column formats
+ // write the column formats
for (unsigned int j=0; j<column_order.size(); ++j)
{
std::string key=column_order[j];
- // avoid `supercolumns[key]'
+ // avoid `supercolumns[key]'
const std::map<std::string, std::vector<std::string> >::const_iterator
- super_iter=supercolumns.find(key);
+ super_iter=supercolumns.find(key);
if (super_iter!=supercolumns.end())
- {
- const unsigned int n_subcolumns=super_iter->second.size();
- for (unsigned int k=0; k<n_subcolumns; ++k)
- {
- // avoid `columns[supercolumns[key]]'
- const std::map<std::string, Column>::const_iterator
- col_iter=columns.find(super_iter->second[k]);
- Assert(col_iter!=columns.end(), ExcInternalError());
-
- out << col_iter->second.tex_format << "|";
- }
- }
+ {
+ const unsigned int n_subcolumns=super_iter->second.size();
+ for (unsigned int k=0; k<n_subcolumns; ++k)
+ {
+ // avoid `columns[supercolumns[key]]'
+ const std::map<std::string, Column>::const_iterator
+ col_iter=columns.find(super_iter->second[k]);
+ Assert(col_iter!=columns.end(), ExcInternalError());
+
+ out << col_iter->second.tex_format << "|";
+ }
+ }
else
- {
- // avoid `columns[key]';
- const std::map<std::string, Column>::const_iterator
- col_iter=columns.find(key);
- Assert(col_iter!=columns.end(), ExcInternalError());
- out << col_iter->second.tex_format << "|";
- }
+ {
+ // avoid `columns[key]';
+ const std::map<std::string, Column>::const_iterator
+ col_iter=columns.find(key);
+ Assert(col_iter!=columns.end(), ExcInternalError());
+ out << col_iter->second.tex_format << "|";
+ }
}
out << "} \\hline" << std::endl;
- // write the caption line of the table
+ // write the caption line of the table
for (unsigned int j=0; j<column_order.size(); ++j)
{
std::string key=column_order[j];
const std::map<std::string, std::vector<std::string> >::const_iterator
- super_iter=supercolumns.find(key);
+ super_iter=supercolumns.find(key);
if (super_iter!=supercolumns.end())
- {
- const unsigned int n_subcolumns=super_iter->second.size();
- // avoid use of `tex_supercaptions[key]'
- std::map<std::string,std::string>::const_iterator
- tex_super_cap_iter=tex_supercaptions.find(key);
- out << std::endl << "\\multicolumn{" << n_subcolumns << "}{|c|}{"
- << tex_super_cap_iter->second << "}";
- }
+ {
+ const unsigned int n_subcolumns=super_iter->second.size();
+ // avoid use of `tex_supercaptions[key]'
+ std::map<std::string,std::string>::const_iterator
+ tex_super_cap_iter=tex_supercaptions.find(key);
+ out << std::endl << "\\multicolumn{" << n_subcolumns << "}{|c|}{"
+ << tex_super_cap_iter->second << "}";
+ }
else
- {
- // col_iter->second=columns[col];
- const std::map<std::string, Column>::const_iterator
- col_iter=columns.find(key);
- Assert(col_iter!=columns.end(), ExcInternalError());
- out << col_iter->second.tex_caption;
- }
+ {
+ // col_iter->second=columns[col];
+ const std::map<std::string, Column>::const_iterator
+ col_iter=columns.find(key);
+ Assert(col_iter!=columns.end(), ExcInternalError());
+ out << col_iter->second.tex_caption;
+ }
if (j<column_order.size()-1)
- out << " & ";
+ out << " & ";
}
out << "\\\\ \\hline" << std::endl;
- // write the n rows
+ // write the n rows
const unsigned int nrows=n_rows();
for (unsigned int i=0; i<nrows; ++i)
{
const unsigned int n_cols=sel_columns.size();
for (unsigned int j=0; j<n_cols; ++j)
- {
- std::string key=sel_columns[j];
- // avoid `column[key]'
- const std::map<std::string, Column>::const_iterator
- col_iter=columns.find(key);
- Assert(col_iter!=columns.end(), ExcInternalError());
+ {
+ std::string key=sel_columns[j];
+ // avoid `column[key]'
+ const std::map<std::string, Column>::const_iterator
+ col_iter=columns.find(key);
+ Assert(col_iter!=columns.end(), ExcInternalError());
- const Column &column=col_iter->second;
+ const Column &column=col_iter->second;
- out << std::setprecision(column.precision);
+ out << std::setprecision(column.precision);
- if (col_iter->second.scientific)
- out.setf(std::ios::scientific, std::ios::floatfield);
- else
- out.setf(std::ios::fixed, std::ios::floatfield);
+ if (col_iter->second.scientific)
+ out.setf(std::ios::scientific, std::ios::floatfield);
+ else
+ out.setf(std::ios::fixed, std::ios::floatfield);
- out << column.entries[i].value;
+ out << column.entries[i].value;
- if (j<n_cols-1)
- out << " & ";
- }
+ if (j<n_cols-1)
+ out << " & ";
+ }
out << "\\\\ \\hline" << std::endl;
}
out << "\\end{tabular}" << std::endl
- << "\\end{center}" << std::endl;
+ << "\\end{center}" << std::endl;
if(tex_table_caption!="")
out << "\\caption{" << tex_table_caption << "}" << std::endl;
if(tex_table_label!="")
for (++col_iter; col_iter!=columns.end(); ++col_iter)
Assert(col_iter->second.entries.size()==n,
- ExcWrongNumberOfDataEntries(col_iter->first,
- col_iter->second.entries.size(),
- first_name, n));
+ ExcWrongNumberOfDataEntries(col_iter->first,
+ col_iter->second.entries.size(),
+ first_name, n));
return n;
}
{
std::string key=column_order[j];
const std::map<std::string, std::vector<std::string> >::const_iterator
- super_iter=supercolumns.find(key);
+ super_iter=supercolumns.find(key);
if (super_iter!=supercolumns.end())
- {
- // i.e. key is a supercolumn key
- const unsigned int n_subcolumns=super_iter->second.size();
- for (unsigned int j=0; j<n_subcolumns; ++j)
- {
- const std::string subkey=super_iter->second[j];
- Assert(columns.count(subkey), ExcInternalError());
- sel_columns.push_back(subkey);
- }
- }
+ {
+ // i.e. key is a supercolumn key
+ const unsigned int n_subcolumns=super_iter->second.size();
+ for (unsigned int j=0; j<n_subcolumns; ++j)
+ {
+ const std::string subkey=super_iter->second[j];
+ Assert(columns.count(subkey), ExcInternalError());
+ sel_columns.push_back(subkey);
+ }
+ }
else
- {
- Assert(columns.count(key), ExcInternalError());
- // i.e. key is a column key
- sel_columns.push_back(key);
- }
+ {
+ Assert(columns.count(key), ExcInternalError());
+ // i.e. key is a column key
+ sel_columns.push_back(key);
+ }
}
}
// $Id$
// Version: $Name$
//
-// Copyright (C) 1999, 2000, 2001, 2002, 2003, 2005, 2006 by the deal.II authors
+// Copyright (C) 1999, 2000, 2001, 2002, 2003, 2005, 2006, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
template <int rank, int dim>
TensorFunction<rank, dim>::TensorFunction (const double initial_time)
- :
- FunctionTime (initial_time)
+ :
+ FunctionTime (initial_time)
{}
template <int rank, int dim>
void
TensorFunction<rank, dim>::value_list (const std::vector<Point<dim> > &points,
- std::vector<value_type> &values) const
+ std::vector<value_type> &values) const
{
Assert (values.size() == points.size(),
- ExcDimensionMismatch(values.size(), points.size()));
+ ExcDimensionMismatch(values.size(), points.size()));
for (unsigned int i=0; i<points.size(); ++i)
values[i] = this->value (points[i]);
template <int rank, int dim>
void
TensorFunction<rank, dim>::gradient_list (const std::vector<Point<dim> > &points,
- std::vector<gradient_type> &gradients) const
+ std::vector<gradient_type> &gradients) const
{
Assert (gradients.size() == points.size(),
- ExcDimensionMismatch(gradients.size(), points.size()));
+ ExcDimensionMismatch(gradients.size(), points.size()));
for (unsigned int i=0; i<points.size(); ++i)
gradients[i] = gradient(points[i]);
// $Id$
// Version: $Name$
//
-// Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2010 by the deal.II authors
+// Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2010, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
compute_index(i,ix);
out << i << "\t";
for (unsigned int d=0; d<dim; ++d)
- out << ix[d] << " ";
+ out << ix[d] << " ";
out << std::endl;
}
}
const std::vector<unsigned int> &renumber)
{
Assert(renumber.size()==index_map.size(),
- ExcDimensionMismatch(renumber.size(), index_map.size()));
+ ExcDimensionMismatch(renumber.size(), index_map.size()));
index_map=renumber;
for (unsigned int i=0; i<index_map.size(); ++i)
template <>
double
TensorProductPolynomials<0>::compute_value (const unsigned int ,
- const Point<0> &) const
+ const Point<0> &) const
{
Assert (false, ExcNotImplemented());
return 0.;
std::vector<double> tmp (2);
for (unsigned int d=0; d<dim; ++d)
{
- polynomials[indices[d]].value (p(d), tmp);
- v[d][0] = tmp[0];
- v[d][1] = tmp[1];
+ polynomials[indices[d]].value (p(d), tmp);
+ v[d][0] = tmp[0];
+ v[d][1] = tmp[1];
}
}
std::vector<double> tmp (3);
for (unsigned int d=0; d<dim; ++d)
{
- polynomials[indices[d]].value (p(d), tmp);
- v[d][0] = tmp[0];
- v[d][1] = tmp[1];
- v[d][2] = tmp[2];
+ polynomials[indices[d]].value (p(d), tmp);
+ v[d][0] = tmp[0];
+ v[d][1] = tmp[1];
+ v[d][2] = tmp[2];
}
}
std::vector<double> tmp (n_values_and_derivatives);
for (unsigned int d=0; d<dim; ++d)
for (unsigned int i=0; i<polynomials.size(); ++i)
- {
- polynomials[i].value(p(d), tmp);
- for (unsigned int e=0; e<n_values_and_derivatives; ++e)
- v(d,i)[e] = tmp[e];
- };
+ {
+ polynomials[i].value(p(d), tmp);
+ for (unsigned int e=0; e<n_values_and_derivatives; ++e)
+ v(d,i)[e] = tmp[e];
+ };
}
for (unsigned int i=0; i<n_tensor_pols; ++i)
template <int dim>
AnisotropicPolynomials<dim>::
AnisotropicPolynomials(const std::vector<std::vector<Polynomials::Polynomial<double> > > &pols)
- :
- polynomials (pols),
- n_tensor_pols(get_n_tensor_pols(pols))
+ :
+ polynomials (pols),
+ n_tensor_pols(get_n_tensor_pols(pols))
{
Assert (pols.size() == dim, ExcDimensionMismatch(pols.size(), dim));
for (unsigned int d=0; d<dim; ++d)
// $Id$
// Version: $Name$
//
-// Copyright (C) 2000, 2001, 2002, 2003, 2005, 2006, 2007, 2008, 2009, 2010 by the deal.II authors
+// Copyright (C) 2000, 2001, 2002, 2003, 2005, 2006, 2007, 2008, 2009, 2010, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
void handle_std_exception (const std::exception &exc)
{
- // lock the following context
- // to ensure that we don't
- // print things over each other
- // if we have trouble from
- // multiple threads. release
- // the lock before calling
- // std::abort, though
+ // lock the following context
+ // to ensure that we don't
+ // print things over each other
+ // if we have trouble from
+ // multiple threads. release
+ // the lock before calling
+ // std::abort, though
static Mutex mutex;
{
- Mutex::ScopedLock lock(mutex);
-
- std::cerr << std::endl << std::endl
- << "---------------------------------------------------------"
- << std::endl
- << "In one of the sub-threads of this program, an exception\n"
- << "was thrown and not caught. Since exceptions do not\n"
- << "propagate to the main thread, the library has caught it.\n"
- << "The information carried by this exception is given below.\n"
- << std::endl
- << "---------------------------------------------------------"
- << std::endl;
- std::cerr << "Exception message: " << std::endl
- << " " << exc.what() << std::endl
- << "Exception type: " << std::endl
- << " " << typeid(exc).name() << std::endl;
- std::cerr << "Aborting!" << std::endl
- << "---------------------------------------------------------"
- << std::endl;
+ Mutex::ScopedLock lock(mutex);
+
+ std::cerr << std::endl << std::endl
+ << "---------------------------------------------------------"
+ << std::endl
+ << "In one of the sub-threads of this program, an exception\n"
+ << "was thrown and not caught. Since exceptions do not\n"
+ << "propagate to the main thread, the library has caught it.\n"
+ << "The information carried by this exception is given below.\n"
+ << std::endl
+ << "---------------------------------------------------------"
+ << std::endl;
+ std::cerr << "Exception message: " << std::endl
+ << " " << exc.what() << std::endl
+ << "Exception type: " << std::endl
+ << " " << typeid(exc).name() << std::endl;
+ std::cerr << "Aborting!" << std::endl
+ << "---------------------------------------------------------"
+ << std::endl;
}
std::abort ();
void handle_unknown_exception ()
{
- // lock the following context
- // to ensure that we don't
- // print things over each other
- // if we have trouble from
- // multiple threads. release
- // the lock before calling
- // std::abort, though
+ // lock the following context
+ // to ensure that we don't
+ // print things over each other
+ // if we have trouble from
+ // multiple threads. release
+ // the lock before calling
+ // std::abort, though
static Mutex mutex;
{
- Mutex::ScopedLock lock(mutex);
-
- std::cerr << std::endl << std::endl
- << "---------------------------------------------------------"
- << std::endl
- << "In one of the sub-threads of this program, an exception\n"
- << "was thrown and not caught. Since exceptions do not\n"
- << "propagate to the main thread, the library has caught it.\n"
- << std::endl
- << "---------------------------------------------------------"
- << std::endl;
- std::cerr << "Type of exception is unknown, but not std::exception.\n"
- << "No additional information is available.\n"
- << "---------------------------------------------------------"
- << std::endl;
+ Mutex::ScopedLock lock(mutex);
+
+ std::cerr << std::endl << std::endl
+ << "---------------------------------------------------------"
+ << std::endl
+ << "In one of the sub-threads of this program, an exception\n"
+ << "was thrown and not caught. Since exceptions do not\n"
+ << "propagate to the main thread, the library has caught it.\n"
+ << std::endl
+ << "---------------------------------------------------------"
+ << std::endl;
+ std::cerr << "Type of exception is unknown, but not std::exception.\n"
+ << "No additional information is available.\n"
+ << "---------------------------------------------------------"
+ << std::endl;
}
std::abort ();
}
#if DEAL_II_USE_MT != 1
DummyBarrier::DummyBarrier (const unsigned int count,
- const char *,
- void *)
+ const char *,
+ void *)
{
Assert (count == 1, ExcBarrierSizeNotUseful(count));
}
#ifndef DEAL_II_USE_MT_POSIX_NO_BARRIERS
PosixThreadBarrier::PosixThreadBarrier (const unsigned int count,
- const char *,
- void *)
+ const char *,
+ void *)
{
pthread_barrier_init (&barrier, 0, count);
}
#else
PosixThreadBarrier::PosixThreadBarrier (const unsigned int count,
- const char *,
- void *)
+ const char *,
+ void *)
: count (count)
{
// throw an exception unless we
// a no-op, and we don't need the
// POSIX functionality
AssertThrow (count == 1,
- ExcMessage ("Your local POSIX installation does not support\n"
- "POSIX barriers. You will not be able to use\n"
- "this class, but the rest of the threading\n"
- "functionality is available."));
+ ExcMessage ("Your local POSIX installation does not support\n"
+ "POSIX barriers. You will not be able to use\n"
+ "this class, but the rest of the threading\n"
+ "functionality is available."));
}
#endif
std::vector<std::pair<unsigned int,unsigned int> >
split_interval (const unsigned int begin,
- const unsigned int end,
- const unsigned int n_intervals)
+ const unsigned int end,
+ const unsigned int n_intervals)
{
Assert (end >= begin, ExcInternalError());
return_values[0].first = begin;
for (unsigned int i=0; i<n_intervals; ++i)
{
- if (i != n_intervals-1)
- {
- return_values[i].second = (return_values[i].first
- + n_elements_per_interval);
- // distribute residual in
- // division equally among
- // the first few
- // subintervals
- if (i < residual)
- ++return_values[i].second;
- return_values[i+1].first = return_values[i].second;
- }
- else
- return_values[i].second = end;
+ if (i != n_intervals-1)
+ {
+ return_values[i].second = (return_values[i].first
+ + n_elements_per_interval);
+ // distribute residual in
+ // division equally among
+ // the first few
+ // subintervals
+ if (i < residual)
+ ++return_values[i].second;
+ return_values[i+1].first = return_values[i].second;
+ }
+ else
+ return_values[i].second = end;
};
return return_values;
}
// $Id$
// Version: $Name$
//
-// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2006, 2009, 2010, 2011 by the deal.II authors
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2006, 2009, 2010, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
- // in case we use an MPI compiler, need
- // to create a communicator just for the
- // current process
+ // in case we use an MPI compiler, need
+ // to create a communicator just for the
+ // current process
Timer::Timer()
:
cumulative_time (0.),
- cumulative_wall_time (0.)
+ cumulative_wall_time (0.)
#ifdef DEAL_II_COMPILER_SUPPORTS_MPI
- , mpi_communicator (MPI_COMM_SELF)
- , sync_wall_time (false)
+ , mpi_communicator (MPI_COMM_SELF)
+ , sync_wall_time (false)
#endif
{
start();
- // in case we use an MPI compiler, use
- // the communicator given from input
+ // in case we use an MPI compiler, use
+ // the communicator given from input
#ifdef DEAL_II_COMPILER_SUPPORTS_MPI
Timer::Timer(MPI_Comm mpi_communicator,
- bool sync_wall_time_)
+ bool sync_wall_time_)
:
cumulative_time (0.),
- cumulative_wall_time (0.),
- mpi_communicator (mpi_communicator),
- sync_wall_time(sync_wall_time_)
+ cumulative_wall_time (0.),
+ mpi_communicator (mpi_communicator),
+ sync_wall_time(sync_wall_time_)
{
start();
}
rusage usage_children;
getrusage (RUSAGE_CHILDREN, &usage_children);
const double dtime_children =
- usage_children.ru_utime.tv_sec + 1.e-6 * usage_children.ru_utime.tv_usec;
+ usage_children.ru_utime.tv_sec + 1.e-6 * usage_children.ru_utime.tv_usec;
cumulative_time += dtime_children - start_time_children;
struct timeval wall_timer;
gettimeofday(&wall_timer, NULL);
double time = wall_timer.tv_sec + 1.e-6 * wall_timer.tv_usec
- - start_wall_time;
+ - start_wall_time;
#ifdef DEAL_II_COMPILER_USE_MPI
if (sync_wall_time && Utilities::System::job_supports_mpi())
- {
- this->mpi_data
- = Utilities::MPI::min_max_avg (time, mpi_communicator);
+ {
+ this->mpi_data
+ = Utilities::MPI::min_max_avg (time, mpi_communicator);
- cumulative_wall_time += this->mpi_data.max;
- }
+ cumulative_wall_time += this->mpi_data.max;
+ }
else
#endif
- cumulative_wall_time += time;
+ cumulative_wall_time += time;
}
return cumulative_time;
}
rusage usage_children;
getrusage (RUSAGE_CHILDREN, &usage_children);
const double dtime_children =
- usage_children.ru_utime.tv_sec + 1.e-6 * usage_children.ru_utime.tv_usec;
+ usage_children.ru_utime.tv_sec + 1.e-6 * usage_children.ru_utime.tv_usec;
const double running_time = dtime - start_time + dtime_children
- - start_time_children + cumulative_time;
+ - start_time_children + cumulative_time;
if (Utilities::System::job_supports_mpi())
- // in case of MPI, need to get the time
- // passed by summing the time over all
- // processes in the network. works also
- // in case we just want to have the time
- // of a single thread, since then the
- // communicator is MPI_COMM_SELF
- return Utilities::MPI::sum (running_time, mpi_communicator);
+ // in case of MPI, need to get the time
+ // passed by summing the time over all
+ // processes in the network. works also
+ // in case we just want to have the time
+ // of a single thread, since then the
+ // communicator is MPI_COMM_SELF
+ return Utilities::MPI::sum (running_time, mpi_communicator);
else
- return running_time;
+ return running_time;
}
else
{
if (Utilities::System::job_supports_mpi())
- return Utilities::MPI::sum (cumulative_time, mpi_communicator);
+ return Utilities::MPI::sum (cumulative_time, mpi_communicator);
else
- return cumulative_time;
+ return cumulative_time;
}
}
struct timeval wall_timer;
gettimeofday(&wall_timer, NULL);
return wall_timer.tv_sec + 1.e-6 * wall_timer.tv_usec - start_wall_time +
- cumulative_wall_time;
+ cumulative_wall_time;
}
else
return cumulative_wall_time;
/* ---------------------------- TimerOutput -------------------------- */
TimerOutput::TimerOutput (std::ostream &stream,
- const enum OutputFrequency output_frequency,
- const enum OutputType output_type)
+ const enum OutputFrequency output_frequency,
+ const enum OutputType output_type)
:
output_frequency (output_frequency),
- output_type (output_type),
+ output_type (output_type),
out_stream (stream, true),
- output_is_enabled (true)
+ output_is_enabled (true)
#ifdef DEAL_II_COMPILER_SUPPORTS_MPI
- , mpi_communicator (MPI_COMM_SELF)
+ , mpi_communicator (MPI_COMM_SELF)
#endif
{}
TimerOutput::TimerOutput (ConditionalOStream &stream,
- const enum OutputFrequency output_frequency,
- const enum OutputType output_type)
+ const enum OutputFrequency output_frequency,
+ const enum OutputType output_type)
:
output_frequency (output_frequency),
- output_type (output_type),
+ output_type (output_type),
out_stream (stream),
- output_is_enabled (true)
+ output_is_enabled (true)
#ifdef DEAL_II_COMPILER_SUPPORTS_MPI
- , mpi_communicator (MPI_COMM_SELF)
+ , mpi_communicator (MPI_COMM_SELF)
#endif
{}
#ifdef DEAL_II_COMPILER_SUPPORTS_MPI
TimerOutput::TimerOutput (MPI_Comm mpi_communicator,
- std::ostream &stream,
- const enum OutputFrequency output_frequency,
- const enum OutputType output_type)
+ std::ostream &stream,
+ const enum OutputFrequency output_frequency,
+ const enum OutputType output_type)
:
output_frequency (output_frequency),
- output_type (output_type),
+ output_type (output_type),
out_stream (stream, true),
- output_is_enabled (true),
- mpi_communicator (mpi_communicator)
+ output_is_enabled (true),
+ mpi_communicator (mpi_communicator)
{}
TimerOutput::TimerOutput (MPI_Comm mpi_communicator,
- ConditionalOStream &stream,
- const enum OutputFrequency output_frequency,
- const enum OutputType output_type)
+ ConditionalOStream &stream,
+ const enum OutputFrequency output_frequency,
+ const enum OutputType output_type)
:
output_frequency (output_frequency),
- output_type (output_type),
+ output_type (output_type),
out_stream (stream),
- output_is_enabled (true),
- mpi_communicator (mpi_communicator)
+ output_is_enabled (true),
+ mpi_communicator (mpi_communicator)
{}
#endif
Threads::ThreadMutex::ScopedLock lock (mutex);
Assert (section_name.empty() == false,
- ExcMessage ("Section string is empty."));
+ ExcMessage ("Section string is empty."));
Assert (std::find (active_sections.begin(), active_sections.end(),
- section_name) == active_sections.end(),
- ExcMessage ("Cannot enter the already active section."));
+ section_name) == active_sections.end(),
+ ExcMessage ("Cannot enter the already active section."));
if (sections.find (section_name) == sections.end())
{
TimerOutput::leave_subsection (const std::string §ion_name)
{
Assert (!active_sections.empty(),
- ExcMessage("Cannot exit any section because none has been entered!"));
+ ExcMessage("Cannot exit any section because none has been entered!"));
Threads::ThreadMutex::ScopedLock lock (mutex);
if (section_name != "")
{
Assert (sections.find (section_name) != sections.end(),
- ExcMessage ("Cannot delete a section that was never created."));
+ ExcMessage ("Cannot delete a section that was never created."));
Assert (std::find (active_sections.begin(), active_sections.end(),
- section_name) != active_sections.end(),
- ExcMessage ("Cannot delete a section that has not been entered."));
+ section_name) != active_sections.end(),
+ ExcMessage ("Cannot delete a section that has not been entered."));
}
- // if no string is given, exit the last
- // active section.
+ // if no string is given, exit the last
+ // active section.
const std::string actual_section_name = (section_name == "" ?
- active_sections.back () :
- section_name);
+ active_sections.back () :
+ section_name);
sections[actual_section_name].timer.stop();
sections[actual_section_name].total_wall_time
+= sections[actual_section_name].timer.wall_time();
- // get cpu time. on MPI systems, add
- // the local contributions. we could
- // do that also in the Timer class
- // itself, but we didn't initialize
- // the Timers here according to that
+ // get cpu time. on MPI systems, add
+ // the local contributions. we could
+ // do that also in the Timer class
+ // itself, but we didn't initialize
+ // the Timers here according to that
double cpu_time = sections[actual_section_name].timer();
sections[actual_section_name].total_cpu_time
+= Utilities::MPI::sum (cpu_time, mpi_communicator);
- // in case we have to print out
- // something, do that here...
+ // in case we have to print out
+ // something, do that here...
if (output_frequency != summary && output_is_enabled == true)
{
std::string output_time;
std::ostringstream wall;
wall << sections[actual_section_name].timer.wall_time() << "s";
if (output_type == cpu_times)
- output_time = ", CPU time: " + cpu.str();
+ output_time = ", CPU time: " + cpu.str();
else if (output_type == wall_times)
- output_time = ", wall time: " + wall.str() + ".";
+ output_time = ", wall time: " + wall.str() + ".";
else
- output_time = ", CPU/wall time: " + cpu.str() + " / " + wall.str() + ".";
+ output_time = ", CPU/wall time: " + cpu.str() + " / " + wall.str() + ".";
out_stream << actual_section_name << output_time
- << std::endl;
+ << std::endl;
}
- // delete the index from the list of
- // active ones
+ // delete the index from the list of
+ // active ones
active_sections.erase (std::find (active_sections.begin(), active_sections.end(),
- actual_section_name));
+ actual_section_name));
}
void
TimerOutput::print_summary () const
{
- // we are going to change the
- // precision and width of output
- // below. store the old values so we
- // can restore it later on
+ // we are going to change the
+ // precision and width of output
+ // below. store the old values so we
+ // can restore it later on
const std::istream::fmtflags old_flags = out_stream.get_stream().flags();
const std::streamsize old_precision = out_stream.get_stream().precision ();
const std::streamsize old_width = out_stream.get_stream().width ();
- // in case we want to write CPU times
+ // in case we want to write CPU times
if (output_type != wall_times)
{
double total_cpu_time = Utilities::MPI::sum (timer_all(),
- mpi_communicator);
+ mpi_communicator);
- // check that the sum of all times is
- // less or equal than the total
- // time. otherwise, we might have
- // generated a lot of overhead in this
- // function.
+ // check that the sum of all times is
+ // less or equal than the total
+ // time. otherwise, we might have
+ // generated a lot of overhead in this
+ // function.
double check_time = 0.;
for (std::map<std::string, Section>::const_iterator
- i = sections.begin(); i!=sections.end(); ++i)
- check_time += i->second.total_cpu_time;
+ i = sections.begin(); i!=sections.end(); ++i)
+ check_time += i->second.total_cpu_time;
if (check_time > total_cpu_time)
- total_cpu_time = check_time;
+ total_cpu_time = check_time;
- // generate a nice table
+ // generate a nice table
out_stream << "\n\n"
- << "+---------------------------------------------+------------"
- << "+------------+\n"
- << "| Total CPU time elapsed since start |";
+ << "+---------------------------------------------+------------"
+ << "+------------+\n"
+ << "| Total CPU time elapsed since start |";
out_stream << std::setw(10) << std::setprecision(3) << std::right;
out_stream << total_cpu_time << "s | |\n";
out_stream << "| | "
- << "| |\n";
+ << "| |\n";
out_stream << "| Section | no. calls |";
out_stream << std::setw(10);
out_stream << std::setprecision(3);
out_stream << " CPU time " << " | % of total |\n";
out_stream << "+---------------------------------+-----------+------------"
- << "+------------+";
+ << "+------------+";
for (std::map<std::string, Section>::const_iterator
- i = sections.begin(); i!=sections.end(); ++i)
- {
- std::string name_out = i->first;
-
- // resize the array so that it is always
- // of the same size
- unsigned int pos_non_space = name_out.find_first_not_of (" ");
- name_out.erase(0, pos_non_space);
- name_out.resize (32, ' ');
- out_stream << std::endl;
- out_stream << "| " << name_out;
- out_stream << "| ";
- out_stream << std::setw(9);
- out_stream << i->second.n_calls << " |";
- out_stream << std::setw(10);
- out_stream << std::setprecision(3);
- out_stream << i->second.total_cpu_time << "s |";
- out_stream << std::setw(10);
- out_stream << std::setprecision(2);
- out_stream << i->second.total_cpu_time/total_cpu_time * 100 << "% |";
- }
+ i = sections.begin(); i!=sections.end(); ++i)
+ {
+ std::string name_out = i->first;
+
+ // resize the array so that it is always
+ // of the same size
+ unsigned int pos_non_space = name_out.find_first_not_of (" ");
+ name_out.erase(0, pos_non_space);
+ name_out.resize (32, ' ');
+ out_stream << std::endl;
+ out_stream << "| " << name_out;
+ out_stream << "| ";
+ out_stream << std::setw(9);
+ out_stream << i->second.n_calls << " |";
+ out_stream << std::setw(10);
+ out_stream << std::setprecision(3);
+ out_stream << i->second.total_cpu_time << "s |";
+ out_stream << std::setw(10);
+ out_stream << std::setprecision(2);
+ out_stream << i->second.total_cpu_time/total_cpu_time * 100 << "% |";
+ }
out_stream << std::endl
- << "+---------------------------------+-----------+"
- << "------------+------------+\n"
- << std::endl;
+ << "+---------------------------------+-----------+"
+ << "------------+------------+\n"
+ << std::endl;
if (check_time > total_cpu_time)
- out_stream << std::endl
- << "Note: The sum of counted times is larger than the total time.\n"
- << "(Timer function may have introduced too much overhead, or different\n"
- << "section timers may have run at the same time.)" << std::endl;
+ out_stream << std::endl
+ << "Note: The sum of counted times is larger than the total time.\n"
+ << "(Timer function may have introduced too much overhead, or different\n"
+ << "section timers may have run at the same time.)" << std::endl;
}
- // in case we want to write out wallclock times
+ // in case we want to write out wallclock times
if (output_type != cpu_times)
{
double total_wall_time = timer_all.wall_time();
- // check that the sum of all times is
- // less or equal than the total
- // time. otherwise, we might have
- // generated a lot of overhead in this
- // function.
+ // check that the sum of all times is
+ // less or equal than the total
+ // time. otherwise, we might have
+ // generated a lot of overhead in this
+ // function.
double check_time = 0.;
for (std::map<std::string, Section>::const_iterator
- i = sections.begin(); i!=sections.end(); ++i)
- check_time += i->second.total_wall_time;
+ i = sections.begin(); i!=sections.end(); ++i)
+ check_time += i->second.total_wall_time;
if (check_time > total_wall_time)
- total_wall_time = check_time;
+ total_wall_time = check_time;
- // now generate a nice table
+ // now generate a nice table
out_stream << "\n\n"
- << "+---------------------------------------------+------------"
- << "+------------+\n"
- << "| Total wallclock time elapsed since start |";
+ << "+---------------------------------------------+------------"
+ << "+------------+\n"
+ << "| Total wallclock time elapsed since start |";
out_stream << std::setw(10) << std::setprecision(3) << std::right;
out_stream << total_wall_time << "s | |\n";
out_stream << "| | "
- << "| |\n";
+ << "| |\n";
out_stream << "| Section | no. calls |";
out_stream << std::setw(10);
out_stream << std::setprecision(3);
out_stream << " wall time | % of total |\n";
out_stream << "+---------------------------------+-----------+------------"
- << "+------------+";
+ << "+------------+";
for (std::map<std::string, Section>::const_iterator
- i = sections.begin(); i!=sections.end(); ++i)
- {
- std::string name_out = i->first;
-
- // resize the array so that it is always
- // of the same size
- unsigned int pos_non_space = name_out.find_first_not_of (" ");
- name_out.erase(0, pos_non_space);
- name_out.resize (32, ' ');
- out_stream << std::endl;
- out_stream << "| " << name_out;
- out_stream << "| ";
- out_stream << std::setw(9);
- out_stream << i->second.n_calls << " |";
- out_stream << std::setw(10);
- out_stream << std::setprecision(3);
- out_stream << i->second.total_wall_time << "s |";
- out_stream << std::setw(10);
- out_stream << std::setprecision(2);
- out_stream << i->second.total_wall_time/total_wall_time * 100 << "% |";
- }
+ i = sections.begin(); i!=sections.end(); ++i)
+ {
+ std::string name_out = i->first;
+
+ // resize the array so that it is always
+ // of the same size
+ unsigned int pos_non_space = name_out.find_first_not_of (" ");
+ name_out.erase(0, pos_non_space);
+ name_out.resize (32, ' ');
+ out_stream << std::endl;
+ out_stream << "| " << name_out;
+ out_stream << "| ";
+ out_stream << std::setw(9);
+ out_stream << i->second.n_calls << " |";
+ out_stream << std::setw(10);
+ out_stream << std::setprecision(3);
+ out_stream << i->second.total_wall_time << "s |";
+ out_stream << std::setw(10);
+ out_stream << std::setprecision(2);
+ out_stream << i->second.total_wall_time/total_wall_time * 100 << "% |";
+ }
out_stream << std::endl
- << "+---------------------------------+-----------+"
- << "------------+------------+\n"
- << std::endl;
+ << "+---------------------------------+-----------+"
+ << "------------+------------+\n"
+ << std::endl;
if (check_time > total_wall_time)
- out_stream << std::endl
- << "Note: The sum of counted times is larger than the total time.\n"
- << "(Timer function may have introduced too much overhead, or different\n"
- << "section timers may have run at the same time.)" << std::endl;
+ out_stream << std::endl
+ << "Note: The sum of counted times is larger than the total time.\n"
+ << "(Timer function may have introduced too much overhead, or different\n"
+ << "section timers may have run at the same time.)" << std::endl;
}
- // restore previous precision and width
+ // restore previous precision and width
out_stream.get_stream().precision (old_precision);
out_stream.get_stream().width (old_width);
out_stream.get_stream().flags (old_flags);
// $Id$
// Version: $Name$
//
-// Copyright (C) 2005, 2006, 2008, 2009, 2010, 2011 by the deal.II authors
+// Copyright (C) 2005, 2006, 2008, 2009, 2010, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
DeclException2 (ExcInvalidNumber2StringConversersion,
- unsigned int, unsigned int,
- << "When trying to convert " << arg1
- << " to a string with " << arg2 << " digits");
+ unsigned int, unsigned int,
+ << "When trying to convert " << arg1
+ << " to a string with " << arg2 << " digits");
DeclException1 (ExcInvalidNumber,
- unsigned int,
- << "Invalid number " << arg1);
+ unsigned int,
+ << "Invalid number " << arg1);
DeclException1 (ExcCantConvertString,
- std::string,
- << "Can't convert the string " << arg1
+ std::string,
+ << "Can't convert the string " << arg1
<< " to the desired type");
std::string
int_to_string (const unsigned int i,
- const unsigned int digits)
+ const unsigned int digits)
{
- // if second argument is invalid, then do
- // not pad the resulting string at all
+ // if second argument is invalid, then do
+ // not pad the resulting string at all
if (digits == numbers::invalid_unsigned_int)
return int_to_string (i, needed_digits(i));
AssertThrow ( ! ((digits==1 && i>=10) ||
- (digits==2 && i>=100) ||
- (digits==3 && i>=1000) ||
- (digits==4 && i>=10000)||
- (digits==5 && i>=100000)||
- (i>=1000000)),
- ExcInvalidNumber2StringConversersion(i, digits));
+ (digits==2 && i>=100) ||
+ (digits==3 && i>=1000) ||
+ (digits==4 && i>=10000)||
+ (digits==5 && i>=100000)||
+ (i>=1000000)),
+ ExcInvalidNumber2StringConversersion(i, digits));
std::string s;
switch (digits)
{
- case 6:
- s += '0' + i/100000;
- case 5:
- s += '0' + (i%100000)/10000;
- case 4:
- s += '0' + (i%10000)/1000;
- case 3:
- s += '0' + (i%1000)/100;
- case 2:
- s += '0' + (i%100)/10;
- case 1:
- s += '0' + i%10;
- break;
- default:
- s += "invalid digits information";
+ case 6:
+ s += '0' + i/100000;
+ case 5:
+ s += '0' + (i%100000)/10000;
+ case 4:
+ s += '0' + (i%10000)/1000;
+ case 3:
+ s += '0' + (i%1000)/100;
+ case 2:
+ s += '0' + (i%100)/10;
+ case 1:
+ s += '0' + i%10;
+ break;
+ default:
+ s += "invalid digits information";
};
return s;
}
std::vector<std::string> split_list;
split_list.reserve (std::count (tmp.begin(), tmp.end(), delimiter)+1);
- // split the input list
+ // split the input list
while (tmp.length() != 0)
{
std::string name;
- name = tmp;
+ name = tmp;
- if (name.find(delimiter) != std::string::npos)
- {
- name.erase (name.find(delimiter), std::string::npos);
- tmp.erase (0, tmp.find(delimiter)+1);
- }
- else
- tmp = "";
+ if (name.find(delimiter) != std::string::npos)
+ {
+ name.erase (name.find(delimiter), std::string::npos);
+ tmp.erase (0, tmp.find(delimiter)+1);
+ }
+ else
+ tmp = "";
- while ((name.length() != 0) &&
- (name[0] == ' '))
- name.erase (0,1);
+ while ((name.length() != 0) &&
+ (name[0] == ' '))
+ name.erase (0,1);
- while (name[name.length()-1] == ' ')
- name.erase (name.length()-1, 1);
+ while (name[name.length()-1] == ' ')
+ name.erase (name.length()-1, 1);
- split_list.push_back (name);
+ split_list.push_back (name);
}
return split_list;
while ((text.length() != 0) && (text[0] == delimiter))
text.erase(0, 1);
- std::size_t pos_newline = text.find_first_of("\n", 0);
- if (pos_newline != std::string::npos && pos_newline <= width)
- {
- std::string line (text, 0, pos_newline);
- while ((line.length() != 0) && (line[line.length()-1] == delimiter))
- line.erase(line.length()-1,1);
- lines.push_back (line);
+ std::size_t pos_newline = text.find_first_of("\n", 0);
+ if (pos_newline != std::string::npos && pos_newline <= width)
+ {
+ std::string line (text, 0, pos_newline);
+ while ((line.length() != 0) && (line[line.length()-1] == delimiter))
+ line.erase(line.length()-1,1);
+ lines.push_back (line);
text.erase (0, pos_newline+1);
- continue;
- }
-
+ continue;
+ }
+
// if we can fit everything into one
// line, then do so. otherwise, we have
// to keep breaking
if (text.length() < width)
{
- // remove trailing spaces
- while ((text.length() != 0) && (text[text.length()-1] == delimiter))
- text.erase(text.length()-1,1);
+ // remove trailing spaces
+ while ((text.length() != 0) && (text[text.length()-1] == delimiter))
+ text.erase(text.length()-1,1);
lines.push_back (text);
text = "";
}
// now take the text up to the found
// location and put it into a single
// line, and remove it from 'text'
- std::string line (text, 0, location);
- while ((line.length() != 0) && (line[line.length()-1] == delimiter))
- line.erase(line.length()-1,1);
+ std::string line (text, 0, location);
+ while ((line.length() != 0) && (line[line.length()-1] == delimiter))
+ line.erase(line.length()-1,1);
lines.push_back (line);
text.erase (0, location);
}
bool
match_at_string_start (const std::string &name,
- const std::string &pattern)
+ const std::string &pattern)
{
if (pattern.size() > name.size())
return false;
for (unsigned int i=0; i<pattern.size(); ++i)
if (pattern[i] != name[i])
- return false;
+ return false;
return true;
}
std::pair<int, unsigned int>
get_integer_at_position (const std::string &name,
- const unsigned int position)
+ const unsigned int position)
{
Assert (position < name.size(), ExcInternalError());
const std::string test_string (name.begin()+position,
- name.end());
+ name.end());
std::istringstream str(test_string);
int i;
if (str >> i)
{
- // compute the number of
- // digits of i. assuming it
- // is less than 8 is likely
- // ok
- if (i<10)
- return std::make_pair (i, 1U);
- else if (i<100)
- return std::make_pair (i, 2U);
- else if (i<1000)
- return std::make_pair (i, 3U);
- else if (i<10000)
- return std::make_pair (i, 4U);
- else if (i<100000)
- return std::make_pair (i, 5U);
- else if (i<1000000)
- return std::make_pair (i, 6U);
- else if (i<10000000)
- return std::make_pair (i, 7U);
- else
- {
- Assert (false, ExcNotImplemented());
- return std::make_pair (-1, numbers::invalid_unsigned_int);
- }
+ // compute the number of
+ // digits of i. assuming it
+ // is less than 8 is likely
+ // ok
+ if (i<10)
+ return std::make_pair (i, 1U);
+ else if (i<100)
+ return std::make_pair (i, 2U);
+ else if (i<1000)
+ return std::make_pair (i, 3U);
+ else if (i<10000)
+ return std::make_pair (i, 4U);
+ else if (i<100000)
+ return std::make_pair (i, 5U);
+ else if (i<1000000)
+ return std::make_pair (i, 6U);
+ else if (i<10000000)
+ return std::make_pair (i, 7U);
+ else
+ {
+ Assert (false, ExcNotImplemented());
+ return std::make_pair (-1, numbers::invalid_unsigned_int);
+ }
}
else
return std::make_pair (-1, numbers::invalid_unsigned_int);
double
generate_normal_random_number (const double a,
- const double sigma)
+ const double sigma)
{
- // if no noise: return now
+ // if no noise: return now
if (sigma == 0)
return a;
const double y = 1.0*rand()/RAND_MAX;
#endif
- // find x such that y=erf(x). do so
- // using a Newton method to find
- // the zero of F(x)=erf(x)-y. start
- // at x=0
+ // find x such that y=erf(x). do so
+ // using a Newton method to find
+ // the zero of F(x)=erf(x)-y. start
+ // at x=0
double x = 0;
unsigned int iteration = 0;
while (true)
{
- const double residual = 0.5+erf(x/std::sqrt(2.)/sigma)/2-y;
- if (std::fabs(residual) < 1e-7)
- break;
- const double F_prime = 1./std::sqrt(2*3.1415926536)/sigma *
- std::exp(-x*x/sigma/sigma/2);
- x += -residual / F_prime;
-
- // make sure that we don't
- // recurse endlessly
- ++iteration;
- Assert (iteration < 20, ExcInternalError());
+ const double residual = 0.5+erf(x/std::sqrt(2.)/sigma)/2-y;
+ if (std::fabs(residual) < 1e-7)
+ break;
+ const double F_prime = 1./std::sqrt(2*3.1415926536)/sigma *
+ std::exp(-x*x/sigma/sigma/2);
+ x += -residual / F_prime;
+
+ // make sure that we don't
+ // recurse endlessly
+ ++iteration;
+ Assert (iteration < 20, ExcInternalError());
};
return x+a;
}
for (unsigned int i=0; i<n; ++i)
{
- Assert (permutation[i] < n, ExcIndexRange (permutation[i], 0, n));
- out[permutation[i]] = i;
+ Assert (permutation[i] < n, ExcIndexRange (permutation[i], 0, n));
+ out[permutation[i]] = i;
}
- // check that we have actually reached
- // all indices
+ // check that we have actually reached
+ // all indices
for (unsigned int i=0; i<n; ++i)
Assert (out[i] != numbers::invalid_unsigned_int,
- ExcMessage ("The given input permutation had duplicate entries!"));
+ ExcMessage ("The given input permutation had duplicate entries!"));
return out;
}
{
stats.VmPeak = stats.VmSize = stats.VmHWM = stats.VmRSS = 0;
- // parsing /proc/self/stat would be a
- // lot easier, but it does not contain
- // VmHWM, so we use /status instead.
+ // parsing /proc/self/stat would be a
+ // lot easier, but it does not contain
+ // VmHWM, so we use /status instead.
#if defined(__linux__)
std::ifstream file("/proc/self/status");
std::string line;
std::string name;
while (!file.eof())
- {
- file >> name;
- if (name == "VmPeak:")
- file >> stats.VmPeak;
- else if (name == "VmSize:")
- file >> stats.VmSize;
- else if (name == "VmHWM:")
- file >> stats.VmHWM;
- else if (name == "VmRSS:")
- {
- file >> stats.VmRSS;
- break; //this is always the last entry
- }
-
- getline(file, line);
- }
+ {
+ file >> name;
+ if (name == "VmPeak:")
+ file >> stats.VmPeak;
+ else if (name == "VmSize:")
+ file >> stats.VmSize;
+ else if (name == "VmHWM:")
+ file >> stats.VmHWM;
+ else if (name == "VmRSS:")
+ {
+ file >> stats.VmRSS;
+ break; //this is always the last entry
+ }
+
+ getline(file, line);
+ }
#endif
}
void calculate_collective_mpi_min_max_avg(const MPI_Comm &mpi_communicator,
- double my_value,
- MinMaxAvg & result)
+ double my_value,
+ MinMaxAvg & result)
{
result = Utilities::MPI::min_max_avg (my_value,
- mpi_communicator);
+ mpi_communicator);
}
{
#ifdef DEAL_II_COMPILER_SUPPORTS_MPI
static Teuchos::RCP<Epetra_MpiComm>
- communicator = Teuchos::rcp (new Epetra_MpiComm (MPI_COMM_WORLD), true);
+ communicator = Teuchos::rcp (new Epetra_MpiComm (MPI_COMM_WORLD), true);
#else
static Teuchos::RCP<Epetra_SerialComm>
- communicator = Teuchos::rcp (new Epetra_SerialComm (), true);
+ communicator = Teuchos::rcp (new Epetra_SerialComm (), true);
#endif
return *communicator;
{
#ifdef DEAL_II_COMPILER_SUPPORTS_MPI
static Teuchos::RCP<Epetra_MpiComm>
- communicator = Teuchos::rcp (new Epetra_MpiComm (MPI_COMM_SELF), true);
+ communicator = Teuchos::rcp (new Epetra_MpiComm (MPI_COMM_SELF), true);
#else
static Teuchos::RCP<Epetra_SerialComm>
- communicator = Teuchos::rcp (new Epetra_SerialComm (), true);
+ communicator = Teuchos::rcp (new Epetra_SerialComm (), true);
#endif
return *communicator;
{
#ifdef DEAL_II_COMPILER_SUPPORTS_MPI
- // see if the communicator is in fact a
- // parallel MPI communicator; if so,
- // return a duplicate of it
+ // see if the communicator is in fact a
+ // parallel MPI communicator; if so,
+ // return a duplicate of it
const Epetra_MpiComm
- *mpi_comm = dynamic_cast<const Epetra_MpiComm *>(&communicator);
+ *mpi_comm = dynamic_cast<const Epetra_MpiComm *>(&communicator);
if (mpi_comm != 0)
- return new Epetra_MpiComm(Utilities::System::
- duplicate_communicator(mpi_comm->GetMpiComm()));
+ return new Epetra_MpiComm(Utilities::System::
+ duplicate_communicator(mpi_comm->GetMpiComm()));
#endif
- // if we don't support MPI, or if the
- // communicator in question was in fact
- // not an MPI communicator, return a
- // copy of the same object again
+ // if we don't support MPI, or if the
+ // communicator in question was in fact
+ // not an MPI communicator, return a
+ // copy of the same object again
Assert (dynamic_cast<const Epetra_SerialComm*>(&communicator)
- != 0,
- ExcInternalError());
+ != 0,
+ ExcInternalError());
return new Epetra_SerialComm(dynamic_cast<const Epetra_SerialComm&>(communicator));
}
{
Assert (&communicator != 0, ExcInternalError());
- // save the communicator, reset
- // the map, and delete the
- // communicator if this whole
- // thing was created as an MPI
- // communicator
+ // save the communicator, reset
+ // the map, and delete the
+ // communicator if this whole
+ // thing was created as an MPI
+ // communicator
#ifdef DEAL_II_COMPILER_SUPPORTS_MPI
Epetra_MpiComm
- *mpi_comm = dynamic_cast<Epetra_MpiComm *>(&communicator);
+ *mpi_comm = dynamic_cast<Epetra_MpiComm *>(&communicator);
if (mpi_comm != 0)
- {
- MPI_Comm comm = mpi_comm->GetMpiComm();
- *mpi_comm = Epetra_MpiComm(MPI_COMM_SELF);
- MPI_Comm_free (&comm);
- }
+ {
+ MPI_Comm comm = mpi_comm->GetMpiComm();
+ *mpi_comm = Epetra_MpiComm(MPI_COMM_SELF);
+ MPI_Comm_free (&comm);
+ }
#endif
}
Epetra_Map
duplicate_map (const Epetra_BlockMap &map,
- const Epetra_Comm &comm)
+ const Epetra_Comm &comm)
{
if (map.LinearMap() == true)
- {
- // each processor stores a
- // contiguous range of
- // elements in the
- // following constructor
- // call
- return Epetra_Map (map.NumGlobalElements(),
- map.NumMyElements(),
- map.IndexBase(),
- comm);
- }
+ {
+ // each processor stores a
+ // contiguous range of
+ // elements in the
+ // following constructor
+ // call
+ return Epetra_Map (map.NumGlobalElements(),
+ map.NumMyElements(),
+ map.IndexBase(),
+ comm);
+ }
else
- {
- // the range is not
- // contiguous
- return Epetra_Map (map.NumGlobalElements(),
- map.NumMyElements(),
- map.MyGlobalElements (),
- 0,
- comm);
- }
+ {
+ // the range is not
+ // contiguous
+ return Epetra_Map (map.NumGlobalElements(),
+ map.NumMyElements(),
+ map.MyGlobalElements (),
+ 0,
+ comm);
+ }
}
}
// $Id$
// Version: $Name$
//
-// Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 by the deal.II authors
+// Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
max_element (const Vector<number> &criteria)
{
return (criteria.size()>0)
- ?
- (*std::max_element(criteria.begin(), criteria.end()))
- :
- std::numeric_limits<number>::min();
+ ?
+ (*std::max_element(criteria.begin(), criteria.end()))
+ :
+ std::numeric_limits<number>::min();
}
min_element (const Vector<number> &criteria)
{
return (criteria.size()>0)
- ?
- (*std::min_element(criteria.begin(), criteria.end()))
- :
- std::numeric_limits<number>::max();
+ ?
+ (*std::min_element(criteria.begin(), criteria.end()))
+ :
+ std::numeric_limits<number>::max();
}
- /**
- * Compute the global max and min
- * of the criteria vector. These
- * are returned only on the
- * processor with rank zero, all
- * others get a pair of zeros.
- */
+ /**
+ * Compute the global max and min
+ * of the criteria vector. These
+ * are returned only on the
+ * processor with rank zero, all
+ * others get a pair of zeros.
+ */
template <typename number>
std::pair<double,double>
compute_global_min_and_max_at_root (const Vector<number> &criteria,
- MPI_Comm mpi_communicator)
+ MPI_Comm mpi_communicator)
{
- // we'd like to compute the
- // global max and min from the
- // local ones in one MPI
- // communication. we can do that
- // by taking the elementwise
- // minimum of the local min and
- // the negative maximum over all
- // processors
+ // we'd like to compute the
+ // global max and min from the
+ // local ones in one MPI
+ // communication. we can do that
+ // by taking the elementwise
+ // minimum of the local min and
+ // the negative maximum over all
+ // processors
const double local_min = min_element (criteria),
- local_max = max_element (criteria);
+ local_max = max_element (criteria);
double comp[2] = { local_min, -local_max };
double result[2] = { 0, 0 };
- // compute the minimum on
- // processor zero
+ // compute the minimum on
+ // processor zero
MPI_Reduce (&comp, &result, 2, MPI_DOUBLE,
- MPI_MIN, 0, mpi_communicator);
+ MPI_MIN, 0, mpi_communicator);
- // make sure only processor zero
- // got something
+ // make sure only processor zero
+ // got something
if (Utilities::MPI::this_mpi_process (mpi_communicator) != 0)
Assert ((result[0] == 0) && (result[1] == 0),
- ExcInternalError());
+ ExcInternalError());
return std::make_pair (result[0], -result[1]);
}
- /**
- * Compute the global sum over the elements
- * of the vectors passed to this function
- * on all processors. This number is
- * returned only on the processor with rank
- * zero, all others get zero.
- */
+ /**
+ * Compute the global sum over the elements
+ * of the vectors passed to this function
+ * on all processors. This number is
+ * returned only on the processor with rank
+ * zero, all others get zero.
+ */
template <typename number>
double
compute_global_sum (const Vector<number> &criteria,
- MPI_Comm mpi_communicator)
+ MPI_Comm mpi_communicator)
{
double my_sum = std::accumulate (criteria.begin(),
- criteria.end(),
- /* do accumulation in the correct data type: */
- number());
+ criteria.end(),
+ /* do accumulation in the correct data type: */
+ number());
double result = 0;
- // compute the minimum on
- // processor zero
+ // compute the minimum on
+ // processor zero
MPI_Reduce (&my_sum, &result, 1, MPI_DOUBLE,
- MPI_SUM, 0, mpi_communicator);
+ MPI_SUM, 0, mpi_communicator);
- // make sure only processor zero
- // got something
+ // make sure only processor zero
+ // got something
if (Utilities::MPI::this_mpi_process (mpi_communicator) != 0)
Assert (result == 0, ExcInternalError());
- /**
- * Given a vector of refinement criteria
- * for all cells of a mesh (locally owned
- * or not), extract those that pertain to
- * locally owned cells.
- */
+ /**
+ * Given a vector of refinement criteria
+ * for all cells of a mesh (locally owned
+ * or not), extract those that pertain to
+ * locally owned cells.
+ */
template <int dim, int spacedim, class Vector>
void
get_locally_owned_indicators (const parallel::distributed::Triangulation<dim,spacedim> &tria,
- const Vector &criteria,
- dealii::Vector<float> &locally_owned_indicators)
+ const Vector &criteria,
+ dealii::Vector<float> &locally_owned_indicators)
{
Assert (locally_owned_indicators.size() == tria.n_locally_owned_active_cells(),
- ExcInternalError());
+ ExcInternalError());
unsigned int active_index = 0;
unsigned int owned_index = 0;
for (typename Triangulation<dim,spacedim>::active_cell_iterator
- cell = tria.begin_active();
- cell != tria.end(); ++cell, ++active_index)
+ cell = tria.begin_active();
+ cell != tria.end(); ++cell, ++active_index)
if (cell->subdomain_id() == tria.locally_owned_subdomain())
- {
- locally_owned_indicators(owned_index)
- = criteria(active_index);
- ++owned_index;
- }
+ {
+ locally_owned_indicators(owned_index)
+ = criteria(active_index);
+ ++owned_index;
+ }
Assert (owned_index == tria.n_locally_owned_active_cells(),
- ExcInternalError());
+ ExcInternalError());
Assert ((active_index == tria.dealii::Triangulation<dim,spacedim>::n_active_cells()),
- ExcInternalError());
+ ExcInternalError());
}
- // we compute refinement
- // thresholds by bisection of the
- // interval spanned by the
- // smallest and largest error
- // indicator. this leads to a
- // small problem: if, for
- // example, we want to coarsen
- // zero per cent of the cells,
- // then we need to pick a
- // threshold equal to the
- // smallest indicator, but of
- // course the bisection algorithm
- // can never find a threshold
- // equal to one of the end points
- // of the interval. So we
- // slightly increase the interval
- // before we even start
+ // we compute refinement
+ // thresholds by bisection of the
+ // interval spanned by the
+ // smallest and largest error
+ // indicator. this leads to a
+ // small problem: if, for
+ // example, we want to coarsen
+ // zero per cent of the cells,
+ // then we need to pick a
+ // threshold equal to the
+ // smallest indicator, but of
+ // course the bisection algorithm
+ // can never find a threshold
+ // equal to one of the end points
+ // of the interval. So we
+ // slightly increase the interval
+ // before we even start
void adjust_interesting_range (double (&interesting_range)[2])
{
Assert (interesting_range[0] <= interesting_range[1],
- ExcInternalError());
+ ExcInternalError());
if (interesting_range[0] > 0)
interesting_range[0] *= 0.99;
else
interesting_range[0]
- -= 0.01 * (interesting_range[1] - interesting_range[0]);
+ -= 0.01 * (interesting_range[1] - interesting_range[0]);
if (interesting_range[1] > 0)
interesting_range[1] *= 1.01;
else
interesting_range[1]
- += 0.01 * (interesting_range[1] - interesting_range[0]);
+ += 0.01 * (interesting_range[1] - interesting_range[0]);
}
- /**
- * Given a vector of criteria and bottom
- * and top thresholds for coarsening and
- * refinement, mark all those cells that we
- * locally own as appropriate for
- * coarsening or refinement.
- */
+ /**
+ * Given a vector of criteria and bottom
+ * and top thresholds for coarsening and
+ * refinement, mark all those cells that we
+ * locally own as appropriate for
+ * coarsening or refinement.
+ */
template <int dim, int spacedim, class Vector>
void
mark_cells (parallel::distributed::Triangulation<dim,spacedim> &tria,
- const Vector &criteria,
- const double top_threshold,
- const double bottom_threshold)
+ const Vector &criteria,
+ const double top_threshold,
+ const double bottom_threshold)
{
dealii::GridRefinement::refine (tria, criteria, top_threshold);
dealii::GridRefinement::coarsen (tria, criteria, bottom_threshold);
- // as a final good measure,
- // delete all flags again
- // from cells that we don't
- // locally own
+ // as a final good measure,
+ // delete all flags again
+ // from cells that we don't
+ // locally own
for (typename Triangulation<dim,spacedim>::active_cell_iterator
- cell = tria.begin_active();
- cell != tria.end(); ++cell)
+ cell = tria.begin_active();
+ cell != tria.end(); ++cell)
if (cell->subdomain_id() != tria.locally_owned_subdomain())
- {
- cell->clear_refine_flag ();
- cell->clear_coarsen_flag ();
- }
+ {
+ cell->clear_refine_flag ();
+ cell->clear_coarsen_flag ();
+ }
}
namespace RefineAndCoarsenFixedNumber
{
- /**
- * Compute a threshold value so
- * that exactly n_target_cells have
- * a value that is larger.
- */
+ /**
+ * Compute a threshold value so
+ * that exactly n_target_cells have
+ * a value that is larger.
+ */
template <typename number>
number
master_compute_threshold (const Vector<number> &criteria,
- const std::pair<double,double> global_min_and_max,
- const unsigned int n_target_cells,
- MPI_Comm mpi_communicator)
+ const std::pair<double,double> global_min_and_max,
+ const unsigned int n_target_cells,
+ MPI_Comm mpi_communicator)
{
double interesting_range[2] = { global_min_and_max.first,
- global_min_and_max.second };
+ global_min_and_max.second };
adjust_interesting_range (interesting_range);
unsigned int iteration = 0;
do
- {
- MPI_Bcast (&interesting_range[0], 2, MPI_DOUBLE,
- 0, mpi_communicator);
-
- if (interesting_range[0] == interesting_range[1])
- return interesting_range[0];
-
- const double test_threshold
- = (interesting_range[0] > 0
- ?
- std::sqrt(interesting_range[0] *
- interesting_range[1])
- :
- (interesting_range[0] + interesting_range[1]) / 2);
-
- // count how many of our own
- // elements would be above
- // this threshold and then
- // add to it the number for
- // all the others
- unsigned int
- my_count = std::count_if (criteria.begin(),
- criteria.end(),
- std::bind2nd (std::greater<double>(),
- test_threshold));
-
- unsigned int total_count;
- MPI_Reduce (&my_count, &total_count, 1, MPI_UNSIGNED,
- MPI_SUM, 0, mpi_communicator);
-
- // now adjust the range. if
- // we have to many cells, we
- // take the upper half of the
- // previous range, otherwise
- // the lower half. if we have
- // hit the right number, then
- // set the range to the exact
- // value
- if (total_count > n_target_cells)
- interesting_range[0] = test_threshold;
- else if (total_count < n_target_cells)
- interesting_range[1] = test_threshold;
- else
- interesting_range[0] = interesting_range[1] = test_threshold;
-
- // terminate the iteration
- // after 10 go-arounds. this
- // is necessary because
- // oftentimes error
- // indicators on cells have
- // exactly the same value,
- // and so there may not be a
- // particular value that cuts
- // the indicators in such a
- // way that we can achieve
- // the desired number of
- // cells. using a max of 10
- // iterations means that we
- // terminate the iteration
- // after 10 steps if the
- // indicators were perfectly
- // badly distributed, and we
- // make at most a mistake of
- // 1/2^10 in the number of
- // cells flagged if
- // indicators are perfectly
- // equidistributed
- ++iteration;
- if (iteration == 25)
- interesting_range[0] = interesting_range[1] = test_threshold;
- }
+ {
+ MPI_Bcast (&interesting_range[0], 2, MPI_DOUBLE,
+ 0, mpi_communicator);
+
+ if (interesting_range[0] == interesting_range[1])
+ return interesting_range[0];
+
+ const double test_threshold
+ = (interesting_range[0] > 0
+ ?
+ std::sqrt(interesting_range[0] *
+ interesting_range[1])
+ :
+ (interesting_range[0] + interesting_range[1]) / 2);
+
+ // count how many of our own
+ // elements would be above
+ // this threshold and then
+ // add to it the number for
+ // all the others
+ unsigned int
+ my_count = std::count_if (criteria.begin(),
+ criteria.end(),
+ std::bind2nd (std::greater<double>(),
+ test_threshold));
+
+ unsigned int total_count;
+ MPI_Reduce (&my_count, &total_count, 1, MPI_UNSIGNED,
+ MPI_SUM, 0, mpi_communicator);
+
+ // now adjust the range. if
+ // we have to many cells, we
+ // take the upper half of the
+ // previous range, otherwise
+ // the lower half. if we have
+ // hit the right number, then
+ // set the range to the exact
+ // value
+ if (total_count > n_target_cells)
+ interesting_range[0] = test_threshold;
+ else if (total_count < n_target_cells)
+ interesting_range[1] = test_threshold;
+ else
+ interesting_range[0] = interesting_range[1] = test_threshold;
+
+ // terminate the iteration
+ // after 10 go-arounds. this
+ // is necessary because
+ // oftentimes error
+ // indicators on cells have
+ // exactly the same value,
+ // and so there may not be a
+ // particular value that cuts
+ // the indicators in such a
+ // way that we can achieve
+ // the desired number of
+ // cells. using a max of 10
+ // iterations means that we
+ // terminate the iteration
+ // after 10 steps if the
+ // indicators were perfectly
+ // badly distributed, and we
+ // make at most a mistake of
+ // 1/2^10 in the number of
+ // cells flagged if
+ // indicators are perfectly
+ // equidistributed
+ ++iteration;
+ if (iteration == 25)
+ interesting_range[0] = interesting_range[1] = test_threshold;
+ }
while (true);
Assert (false, ExcInternalError());
}
- /**
- * The corresponding function to
- * the one above, to be run on the
- * slaves.
- */
+ /**
+ * The corresponding function to
+ * the one above, to be run on the
+ * slaves.
+ */
template <typename number>
number
slave_compute_threshold (const Vector<number> &criteria,
- MPI_Comm mpi_communicator)
+ MPI_Comm mpi_communicator)
{
do
- {
- double interesting_range[2] = { -1, -1 };
- MPI_Bcast (&interesting_range[0], 2, MPI_DOUBLE,
- 0, mpi_communicator);
-
- if (interesting_range[0] == interesting_range[1])
- return interesting_range[0];
-
- // count how many elements
- // there are that are bigger
- // than the following trial
- // threshold
- const double test_threshold
- = (interesting_range[0] > 0
- ?
- std::exp((std::log(interesting_range[0]) +
- std::log(interesting_range[1])) / 2)
- :
- (interesting_range[0] + interesting_range[1]) / 2);
- unsigned int
- my_count = std::count_if (criteria.begin(),
- criteria.end(),
- std::bind2nd (std::greater<double>(),
- test_threshold));
-
- MPI_Reduce (&my_count, 0, 1, MPI_UNSIGNED,
- MPI_SUM, 0, mpi_communicator);
- }
+ {
+ double interesting_range[2] = { -1, -1 };
+ MPI_Bcast (&interesting_range[0], 2, MPI_DOUBLE,
+ 0, mpi_communicator);
+
+ if (interesting_range[0] == interesting_range[1])
+ return interesting_range[0];
+
+ // count how many elements
+ // there are that are bigger
+ // than the following trial
+ // threshold
+ const double test_threshold
+ = (interesting_range[0] > 0
+ ?
+ std::exp((std::log(interesting_range[0]) +
+ std::log(interesting_range[1])) / 2)
+ :
+ (interesting_range[0] + interesting_range[1]) / 2);
+ unsigned int
+ my_count = std::count_if (criteria.begin(),
+ criteria.end(),
+ std::bind2nd (std::greater<double>(),
+ test_threshold));
+
+ MPI_Reduce (&my_count, 0, 1, MPI_UNSIGNED,
+ MPI_SUM, 0, mpi_communicator);
+ }
while (true);
Assert (false, ExcInternalError());
namespace RefineAndCoarsenFixedFraction
{
- /**
- * Compute a threshold value so
- * that exactly n_target_cells have
- * a value that is larger.
- */
+ /**
+ * Compute a threshold value so
+ * that exactly n_target_cells have
+ * a value that is larger.
+ */
template <typename number>
number
master_compute_threshold (const Vector<number> &criteria,
- const std::pair<double,double> global_min_and_max,
- const double target_error,
- MPI_Comm mpi_communicator)
+ const std::pair<double,double> global_min_and_max,
+ const double target_error,
+ MPI_Comm mpi_communicator)
{
double interesting_range[2] = { global_min_and_max.first,
- global_min_and_max.second };
+ global_min_and_max.second };
adjust_interesting_range (interesting_range);
unsigned int iteration = 0;
do
- {
- MPI_Bcast (&interesting_range[0], 2, MPI_DOUBLE,
- 0, mpi_communicator);
-
- if (interesting_range[0] == interesting_range[1])
- return interesting_range[0];
-
- const double test_threshold
- = (interesting_range[0] > 0
- ?
- std::exp((std::log(interesting_range[0]) +
- std::log(interesting_range[1])) / 2)
- :
- (interesting_range[0] + interesting_range[1]) / 2);
-
- // accumulate the error of those
- // our own elements above this
- // threshold and then add to it the
- // number for all the others
- double my_error = 0;
- for (unsigned int i=0; i<criteria.size(); ++i)
- if (criteria(i) > test_threshold)
- my_error += criteria(i);
-
- double total_error;
- MPI_Reduce (&my_error, &total_error, 1, MPI_DOUBLE,
- MPI_SUM, 0, mpi_communicator);
-
- // now adjust the range. if
- // we have to many cells, we
- // take the upper half of the
- // previous range, otherwise
- // the lower half. if we have
- // hit the right number, then
- // set the range to the exact
- // value
- if (total_error > target_error)
- interesting_range[0] = test_threshold;
- else if (total_error < target_error)
- interesting_range[1] = test_threshold;
- else
- interesting_range[0] = interesting_range[1] = test_threshold;
-
- // terminate the iteration
- // after 10 go-arounds. this
- // is necessary because
- // oftentimes error
- // indicators on cells have
- // exactly the same value,
- // and so there may not be a
- // particular value that cuts
- // the indicators in such a
- // way that we can achieve
- // the desired number of
- // cells. using a max of 10
- // iterations means that we
- // terminate the iteration
- // after 10 steps if the
- // indicators were perfectly
- // badly distributed, and we
- // make at most a mistake of
- // 1/2^10 in the number of
- // cells flagged if
- // indicators are perfectly
- // equidistributed
- ++iteration;
- if (iteration == 25)
- interesting_range[0] = interesting_range[1] = test_threshold;
- }
+ {
+ MPI_Bcast (&interesting_range[0], 2, MPI_DOUBLE,
+ 0, mpi_communicator);
+
+ if (interesting_range[0] == interesting_range[1])
+ return interesting_range[0];
+
+ const double test_threshold
+ = (interesting_range[0] > 0
+ ?
+ std::exp((std::log(interesting_range[0]) +
+ std::log(interesting_range[1])) / 2)
+ :
+ (interesting_range[0] + interesting_range[1]) / 2);
+
+ // accumulate the error of those
+ // our own elements above this
+ // threshold and then add to it the
+ // number for all the others
+ double my_error = 0;
+ for (unsigned int i=0; i<criteria.size(); ++i)
+ if (criteria(i) > test_threshold)
+ my_error += criteria(i);
+
+ double total_error;
+ MPI_Reduce (&my_error, &total_error, 1, MPI_DOUBLE,
+ MPI_SUM, 0, mpi_communicator);
+
+ // now adjust the range. if
+ // we have to many cells, we
+ // take the upper half of the
+ // previous range, otherwise
+ // the lower half. if we have
+ // hit the right number, then
+ // set the range to the exact
+ // value
+ if (total_error > target_error)
+ interesting_range[0] = test_threshold;
+ else if (total_error < target_error)
+ interesting_range[1] = test_threshold;
+ else
+ interesting_range[0] = interesting_range[1] = test_threshold;
+
+ // terminate the iteration
+ // after 10 go-arounds. this
+ // is necessary because
+ // oftentimes error
+ // indicators on cells have
+ // exactly the same value,
+ // and so there may not be a
+ // particular value that cuts
+ // the indicators in such a
+ // way that we can achieve
+ // the desired number of
+ // cells. using a max of 10
+ // iterations means that we
+ // terminate the iteration
+ // after 10 steps if the
+ // indicators were perfectly
+ // badly distributed, and we
+ // make at most a mistake of
+ // 1/2^10 in the number of
+ // cells flagged if
+ // indicators are perfectly
+ // equidistributed
+ ++iteration;
+ if (iteration == 25)
+ interesting_range[0] = interesting_range[1] = test_threshold;
+ }
while (true);
Assert (false, ExcInternalError());
}
- /**
- * The corresponding function to
- * the one above, to be run on the
- * slaves.
- */
+ /**
+ * The corresponding function to
+ * the one above, to be run on the
+ * slaves.
+ */
template <typename number>
number
slave_compute_threshold (const Vector<number> &criteria,
- MPI_Comm mpi_communicator)
+ MPI_Comm mpi_communicator)
{
do
- {
- double interesting_range[2] = { -1, -1 };
- MPI_Bcast (&interesting_range[0], 2, MPI_DOUBLE,
- 0, mpi_communicator);
-
- if (interesting_range[0] == interesting_range[1])
- return interesting_range[0];
-
- // count how many elements
- // there are that are bigger
- // than the following trial
- // threshold
- const double test_threshold
- = (interesting_range[0] > 0
- ?
- std::exp((std::log(interesting_range[0]) +
- std::log(interesting_range[1])) / 2)
- :
- (interesting_range[0] + interesting_range[1]) / 2);
-
- double my_error = 0;
- for (unsigned int i=0; i<criteria.size(); ++i)
- if (criteria(i) > test_threshold)
- my_error += criteria(i);
-
- MPI_Reduce (&my_error, 0, 1, MPI_DOUBLE,
- MPI_SUM, 0, mpi_communicator);
- }
+ {
+ double interesting_range[2] = { -1, -1 };
+ MPI_Bcast (&interesting_range[0], 2, MPI_DOUBLE,
+ 0, mpi_communicator);
+
+ if (interesting_range[0] == interesting_range[1])
+ return interesting_range[0];
+
+ // count how many elements
+ // there are that are bigger
+ // than the following trial
+ // threshold
+ const double test_threshold
+ = (interesting_range[0] > 0
+ ?
+ std::exp((std::log(interesting_range[0]) +
+ std::log(interesting_range[1])) / 2)
+ :
+ (interesting_range[0] + interesting_range[1]) / 2);
+
+ double my_error = 0;
+ for (unsigned int i=0; i<criteria.size(); ++i)
+ if (criteria(i) > test_threshold)
+ my_error += criteria(i);
+
+ MPI_Reduce (&my_error, 0, 1, MPI_DOUBLE,
+ MPI_SUM, 0, mpi_communicator);
+ }
while (true);
Assert (false, ExcInternalError());
template <int dim, class Vector, int spacedim>
void
refine_and_coarsen_fixed_number (
- parallel::distributed::Triangulation<dim,spacedim> &tria,
- const Vector &criteria,
- const double top_fraction_of_cells,
- const double bottom_fraction_of_cells)
+ parallel::distributed::Triangulation<dim,spacedim> &tria,
+ const Vector &criteria,
+ const double top_fraction_of_cells,
+ const double bottom_fraction_of_cells)
{
- Assert ((top_fraction_of_cells>=0) && (top_fraction_of_cells<=1),
- dealii::GridRefinement::ExcInvalidParameterValue());
- Assert ((bottom_fraction_of_cells>=0) && (bottom_fraction_of_cells<=1),
- dealii::GridRefinement::ExcInvalidParameterValue());
- Assert (top_fraction_of_cells+bottom_fraction_of_cells <= 1,
- dealii::GridRefinement::ExcInvalidParameterValue());
- Assert (criteria.is_non_negative (),
- dealii::GridRefinement::ExcNegativeCriteria());
-
- // first extract from the
- // vector of indicators the
- // ones that correspond to
- // cells that we locally own
- dealii::Vector<float>
- locally_owned_indicators (tria.n_locally_owned_active_cells());
- get_locally_owned_indicators (tria,
- criteria,
- locally_owned_indicators);
-
- MPI_Comm mpi_communicator = tria.get_communicator ();
-
- // figure out the global
- // max and min of the
- // indicators. we don't
- // need it here, but it's a
- // collective communication
- // call
- const std::pair<double,double> global_min_and_max
- = compute_global_min_and_max_at_root (locally_owned_indicators,
- mpi_communicator);
-
- // from here on designate a
- // master and slaves
- double top_threshold, bottom_threshold;
- if (Utilities::MPI::this_mpi_process (mpi_communicator) == 0)
- {
- // this is the master
- // processor
- top_threshold
- =
- RefineAndCoarsenFixedNumber::
- master_compute_threshold (locally_owned_indicators,
- global_min_and_max,
- static_cast<unsigned int>
- (top_fraction_of_cells *
- tria.n_global_active_cells()),
- mpi_communicator);
-
- // compute bottom
- // threshold only if
- // necessary. otherwise
- // use a threshold lower
- // than the smallest
- // value we have locally
- if (bottom_fraction_of_cells > 0)
- bottom_threshold
- =
- RefineAndCoarsenFixedNumber::
- master_compute_threshold (locally_owned_indicators,
- global_min_and_max,
- static_cast<unsigned int>
- ((1-bottom_fraction_of_cells) *
- tria.n_global_active_cells()),
- mpi_communicator);
- else
- {
- bottom_threshold = *std::min_element (criteria.begin(),
- criteria.end());
- bottom_threshold -= std::fabs(bottom_threshold);
- }
- }
- else
- {
- // this is a slave
- // processor
- top_threshold
- =
- RefineAndCoarsenFixedNumber::
- slave_compute_threshold (locally_owned_indicators,
- mpi_communicator);
- // compute bottom
- // threshold only if
- // necessary
- if (bottom_fraction_of_cells > 0)
- bottom_threshold
- =
- RefineAndCoarsenFixedNumber::
- slave_compute_threshold (locally_owned_indicators,
- mpi_communicator);
- else
- {
- bottom_threshold = *std::min_element (criteria.begin(),
- criteria.end());
- bottom_threshold -= std::fabs(bottom_threshold);
- }
- }
-
- // now refine the mesh
- mark_cells (tria, criteria, top_threshold, bottom_threshold);
+ Assert ((top_fraction_of_cells>=0) && (top_fraction_of_cells<=1),
+ dealii::GridRefinement::ExcInvalidParameterValue());
+ Assert ((bottom_fraction_of_cells>=0) && (bottom_fraction_of_cells<=1),
+ dealii::GridRefinement::ExcInvalidParameterValue());
+ Assert (top_fraction_of_cells+bottom_fraction_of_cells <= 1,
+ dealii::GridRefinement::ExcInvalidParameterValue());
+ Assert (criteria.is_non_negative (),
+ dealii::GridRefinement::ExcNegativeCriteria());
+
+ // first extract from the
+ // vector of indicators the
+ // ones that correspond to
+ // cells that we locally own
+ dealii::Vector<float>
+ locally_owned_indicators (tria.n_locally_owned_active_cells());
+ get_locally_owned_indicators (tria,
+ criteria,
+ locally_owned_indicators);
+
+ MPI_Comm mpi_communicator = tria.get_communicator ();
+
+ // figure out the global
+ // max and min of the
+ // indicators. we don't
+ // need it here, but it's a
+ // collective communication
+ // call
+ const std::pair<double,double> global_min_and_max
+ = compute_global_min_and_max_at_root (locally_owned_indicators,
+ mpi_communicator);
+
+ // from here on designate a
+ // master and slaves
+ double top_threshold, bottom_threshold;
+ if (Utilities::MPI::this_mpi_process (mpi_communicator) == 0)
+ {
+ // this is the master
+ // processor
+ top_threshold
+ =
+ RefineAndCoarsenFixedNumber::
+ master_compute_threshold (locally_owned_indicators,
+ global_min_and_max,
+ static_cast<unsigned int>
+ (top_fraction_of_cells *
+ tria.n_global_active_cells()),
+ mpi_communicator);
+
+ // compute bottom
+ // threshold only if
+ // necessary. otherwise
+ // use a threshold lower
+ // than the smallest
+ // value we have locally
+ if (bottom_fraction_of_cells > 0)
+ bottom_threshold
+ =
+ RefineAndCoarsenFixedNumber::
+ master_compute_threshold (locally_owned_indicators,
+ global_min_and_max,
+ static_cast<unsigned int>
+ ((1-bottom_fraction_of_cells) *
+ tria.n_global_active_cells()),
+ mpi_communicator);
+ else
+ {
+ bottom_threshold = *std::min_element (criteria.begin(),
+ criteria.end());
+ bottom_threshold -= std::fabs(bottom_threshold);
+ }
+ }
+ else
+ {
+ // this is a slave
+ // processor
+ top_threshold
+ =
+ RefineAndCoarsenFixedNumber::
+ slave_compute_threshold (locally_owned_indicators,
+ mpi_communicator);
+ // compute bottom
+ // threshold only if
+ // necessary
+ if (bottom_fraction_of_cells > 0)
+ bottom_threshold
+ =
+ RefineAndCoarsenFixedNumber::
+ slave_compute_threshold (locally_owned_indicators,
+ mpi_communicator);
+ else
+ {
+ bottom_threshold = *std::min_element (criteria.begin(),
+ criteria.end());
+ bottom_threshold -= std::fabs(bottom_threshold);
+ }
+ }
+
+ // now refine the mesh
+ mark_cells (tria, criteria, top_threshold, bottom_threshold);
}
template <int dim, class Vector, int spacedim>
void
refine_and_coarsen_fixed_fraction (
- parallel::distributed::Triangulation<dim,spacedim> &tria,
- const Vector &criteria,
- const double top_fraction_of_error,
- const double bottom_fraction_of_error)
+ parallel::distributed::Triangulation<dim,spacedim> &tria,
+ const Vector &criteria,
+ const double top_fraction_of_error,
+ const double bottom_fraction_of_error)
{
- Assert ((top_fraction_of_error>=0) && (top_fraction_of_error<=1),
- dealii::GridRefinement::ExcInvalidParameterValue());
- Assert ((bottom_fraction_of_error>=0) && (bottom_fraction_of_error<=1),
- dealii::GridRefinement::ExcInvalidParameterValue());
- Assert (top_fraction_of_error+bottom_fraction_of_error <= 1,
- dealii::GridRefinement::ExcInvalidParameterValue());
- Assert (criteria.is_non_negative (),
- dealii::GridRefinement::ExcNegativeCriteria());
-
- // first extract from the
- // vector of indicators the
- // ones that correspond to
- // cells that we locally own
- dealii::Vector<float>
- locally_owned_indicators (tria.n_locally_owned_active_cells());
- get_locally_owned_indicators (tria,
- criteria,
- locally_owned_indicators);
-
- MPI_Comm mpi_communicator = tria.get_communicator ();
-
- // figure out the global
- // max and min of the
- // indicators. we don't
- // need it here, but it's a
- // collective communication
- // call
- const std::pair<double,double> global_min_and_max
- = compute_global_min_and_max_at_root (locally_owned_indicators,
- mpi_communicator);
-
- const double total_error
- = compute_global_sum (locally_owned_indicators,
- mpi_communicator);
-
- // from here on designate a
- // master and slaves
- double top_threshold, bottom_threshold;
- if (Utilities::MPI::this_mpi_process (mpi_communicator) == 0)
- {
- // this is the master
- // processor
- top_threshold
- =
- RefineAndCoarsenFixedFraction::
- master_compute_threshold (locally_owned_indicators,
- global_min_and_max,
- top_fraction_of_error *
- total_error,
- mpi_communicator);
-
- // compute bottom
- // threshold only if
- // necessary. otherwise
- // use a threshold lower
- // than the smallest
- // value we have locally
- if (bottom_fraction_of_error > 0)
- bottom_threshold
- =
- RefineAndCoarsenFixedFraction::
- master_compute_threshold (locally_owned_indicators,
- global_min_and_max,
- (1-bottom_fraction_of_error) *
- total_error,
- mpi_communicator);
- else
- {
- bottom_threshold = *std::min_element (criteria.begin(),
- criteria.end());
- bottom_threshold -= std::fabs(bottom_threshold);
- }
- }
- else
- {
- // this is a slave
- // processor
- top_threshold
- =
- RefineAndCoarsenFixedFraction::
- slave_compute_threshold (locally_owned_indicators,
- mpi_communicator);
-
- // compute bottom
- // threshold only if
- // necessary. otherwise
- // use a threshold lower
- // than the smallest
- // value we have locally
- if (bottom_fraction_of_error > 0)
- bottom_threshold
- =
- RefineAndCoarsenFixedFraction::
- slave_compute_threshold (locally_owned_indicators,
- mpi_communicator);
- else
- {
- bottom_threshold = *std::min_element (criteria.begin(),
- criteria.end());
- bottom_threshold -= std::fabs(bottom_threshold);
- }
- }
-
- // now refine the mesh
- mark_cells (tria, criteria, top_threshold, bottom_threshold);
+ Assert ((top_fraction_of_error>=0) && (top_fraction_of_error<=1),
+ dealii::GridRefinement::ExcInvalidParameterValue());
+ Assert ((bottom_fraction_of_error>=0) && (bottom_fraction_of_error<=1),
+ dealii::GridRefinement::ExcInvalidParameterValue());
+ Assert (top_fraction_of_error+bottom_fraction_of_error <= 1,
+ dealii::GridRefinement::ExcInvalidParameterValue());
+ Assert (criteria.is_non_negative (),
+ dealii::GridRefinement::ExcNegativeCriteria());
+
+ // first extract from the
+ // vector of indicators the
+ // ones that correspond to
+ // cells that we locally own
+ dealii::Vector<float>
+ locally_owned_indicators (tria.n_locally_owned_active_cells());
+ get_locally_owned_indicators (tria,
+ criteria,
+ locally_owned_indicators);
+
+ MPI_Comm mpi_communicator = tria.get_communicator ();
+
+ // figure out the global
+ // max and min of the
+ // indicators. we don't
+ // need it here, but it's a
+ // collective communication
+ // call
+ const std::pair<double,double> global_min_and_max
+ = compute_global_min_and_max_at_root (locally_owned_indicators,
+ mpi_communicator);
+
+ const double total_error
+ = compute_global_sum (locally_owned_indicators,
+ mpi_communicator);
+
+ // from here on designate a
+ // master and slaves
+ double top_threshold, bottom_threshold;
+ if (Utilities::MPI::this_mpi_process (mpi_communicator) == 0)
+ {
+ // this is the master
+ // processor
+ top_threshold
+ =
+ RefineAndCoarsenFixedFraction::
+ master_compute_threshold (locally_owned_indicators,
+ global_min_and_max,
+ top_fraction_of_error *
+ total_error,
+ mpi_communicator);
+
+ // compute bottom
+ // threshold only if
+ // necessary. otherwise
+ // use a threshold lower
+ // than the smallest
+ // value we have locally
+ if (bottom_fraction_of_error > 0)
+ bottom_threshold
+ =
+ RefineAndCoarsenFixedFraction::
+ master_compute_threshold (locally_owned_indicators,
+ global_min_and_max,
+ (1-bottom_fraction_of_error) *
+ total_error,
+ mpi_communicator);
+ else
+ {
+ bottom_threshold = *std::min_element (criteria.begin(),
+ criteria.end());
+ bottom_threshold -= std::fabs(bottom_threshold);
+ }
+ }
+ else
+ {
+ // this is a slave
+ // processor
+ top_threshold
+ =
+ RefineAndCoarsenFixedFraction::
+ slave_compute_threshold (locally_owned_indicators,
+ mpi_communicator);
+
+ // compute bottom
+ // threshold only if
+ // necessary. otherwise
+ // use a threshold lower
+ // than the smallest
+ // value we have locally
+ if (bottom_fraction_of_error > 0)
+ bottom_threshold
+ =
+ RefineAndCoarsenFixedFraction::
+ slave_compute_threshold (locally_owned_indicators,
+ mpi_communicator);
+ else
+ {
+ bottom_threshold = *std::min_element (criteria.begin(),
+ criteria.end());
+ bottom_threshold -= std::fabs(bottom_threshold);
+ }
+ }
+
+ // now refine the mesh
+ mark_cells (tria, criteria, top_threshold, bottom_threshold);
}
}
}
// $Id: solution_transfer.cc 23752 2011-05-30 00:16:00Z bangerth $
// Version: $Name$
//
-// Copyright (C) 2009, 2010, 2011 by the deal.II authors
+// Copyright (C) 2009, 2010, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
template <class VECTOR>
void compress_vector_insert(VECTOR & vec)
{
- vec.compress();
+ vec.compress();
}
#ifdef DEAL_II_USE_TRILINOS
void compress_vector_insert(TrilinosWrappers::Vector & vec)
{
- vec.compress(Insert);
+ vec.compress(Insert);
}
void compress_vector_insert(TrilinosWrappers::BlockVector & vec)
{
- for (unsigned int i=0;i<vec.n_blocks();++i)
- vec.block(i).compress(Insert);
+ for (unsigned int i=0;i<vec.n_blocks();++i)
+ vec.block(i).compress(Insert);
}
void compress_vector_insert(TrilinosWrappers::MPI::Vector & vec)
{
- vec.compress(Insert);
+ vec.compress(Insert);
}
void compress_vector_insert(TrilinosWrappers::MPI::BlockVector & vec)
{
- for (unsigned int i=0;i<vec.n_blocks();++i)
- vec.block(i).compress(Insert);
+ for (unsigned int i=0;i<vec.n_blocks();++i)
+ vec.block(i).compress(Insert);
}
#endif
}
template<int dim, typename VECTOR, class DH>
SolutionTransfer<dim, VECTOR, DH>::SolutionTransfer(const DH &dof)
- :
- dof_handler(&dof, typeid(*this).name())
+ :
+ dof_handler(&dof, typeid(*this).name())
{}
//TODO: casting away constness is bad
parallel::distributed::Triangulation<dim> * tria
- = (dynamic_cast<parallel::distributed::Triangulation<dim>*>
- (const_cast<dealii::Triangulation<dim>*>
- (&dof_handler->get_tria())));
+ = (dynamic_cast<parallel::distributed::Triangulation<dim>*>
+ (const_cast<dealii::Triangulation<dim>*>
+ (&dof_handler->get_tria())));
Assert (tria != 0, ExcInternalError());
offset
- = tria->register_data_attach(size,
- std_cxx1x::bind(&SolutionTransfer<dim, VECTOR, DH>::pack_callback,
- this,
- std_cxx1x::_1,
- std_cxx1x::_2,
- std_cxx1x::_3));
+ = tria->register_data_attach(size,
+ std_cxx1x::bind(&SolutionTransfer<dim, VECTOR, DH>::pack_callback,
+ this,
+ std_cxx1x::_1,
+ std_cxx1x::_2,
+ std_cxx1x::_3));
}
template<int dim, typename VECTOR, class DH>
void
SolutionTransfer<dim, VECTOR, DH>::
- prepare_serialization(const VECTOR &in)
- {
+ prepare_serialization(const VECTOR &in)
+ {
std::vector<const VECTOR*> all_in(1, &in);
prepare_serialization(all_in);
- }
+ }
- template<int dim, typename VECTOR, class DH>
+ template<int dim, typename VECTOR, class DH>
void
SolutionTransfer<dim, VECTOR, DH>::
- prepare_serialization(const std::vector<const VECTOR*> &all_in)
- {
- prepare_for_coarsening_and_refinement (all_in);
- }
+ prepare_serialization(const std::vector<const VECTOR*> &all_in)
+ {
+ prepare_for_coarsening_and_refinement (all_in);
+ }
template<int dim, typename VECTOR, class DH>
void
SolutionTransfer<dim, VECTOR, DH>::
- deserialize(VECTOR &in)
- {
+ deserialize(VECTOR &in)
+ {
std::vector<VECTOR*> all_in(1, &in);
deserialize(all_in);
- }
+ }
- template<int dim, typename VECTOR, class DH>
+ template<int dim, typename VECTOR, class DH>
void
SolutionTransfer<dim, VECTOR, DH>::
- deserialize(std::vector<VECTOR*> &all_in)
- {
- register_data_attach( get_data_size() * all_in.size() );
+ deserialize(std::vector<VECTOR*> &all_in)
+ {
+ register_data_attach( get_data_size() * all_in.size() );
- // this makes interpolate() happy
- input_vectors.resize(all_in.size());
+ // this makes interpolate() happy
+ input_vectors.resize(all_in.size());
- interpolate(all_in);
- }
+ interpolate(all_in);
+ }
template<int dim, typename VECTOR, class DH>
interpolate (std::vector<VECTOR*> &all_out)
{
Assert(input_vectors.size()==all_out.size(),
- ExcDimensionMismatch(input_vectors.size(), all_out.size()) );
+ ExcDimensionMismatch(input_vectors.size(), all_out.size()) );
//TODO: casting away constness is bad
parallel::distributed::Triangulation<dim> * tria
- = (dynamic_cast<parallel::distributed::Triangulation<dim>*>
- (const_cast<dealii::Triangulation<dim>*>
- (&dof_handler->get_tria())));
+ = (dynamic_cast<parallel::distributed::Triangulation<dim>*>
+ (const_cast<dealii::Triangulation<dim>*>
+ (&dof_handler->get_tria())));
Assert (tria != 0, ExcInternalError());
tria->notify_ready_to_unpack(offset,
- std_cxx1x::bind(&SolutionTransfer<dim, VECTOR, DH>::unpack_callback,
- this,
- std_cxx1x::_1,
- std_cxx1x::_2,
- std_cxx1x::_3,
- std_cxx1x::ref(all_out)));
+ std_cxx1x::bind(&SolutionTransfer<dim, VECTOR, DH>::unpack_callback,
+ this,
+ std_cxx1x::_1,
+ std_cxx1x::_2,
+ std_cxx1x::_3,
+ std_cxx1x::ref(all_out)));
for (typename std::vector<VECTOR*>::iterator it=all_out.begin();
- it !=all_out.end();
- ++it)
- compress_vector_insert(*(*it));
+ it !=all_out.end();
+ ++it)
+ compress_vector_insert(*(*it));
input_vectors.clear();
}
void
SolutionTransfer<dim, VECTOR, DH>::
pack_callback(const typename Triangulation<dim,dim>::cell_iterator & cell_,
- const typename Triangulation<dim,dim>::CellStatus /*status*/,
- void* data)
+ const typename Triangulation<dim,dim>::CellStatus /*status*/,
+ void* data)
{
double *data_store = reinterpret_cast<double *>(data);
const unsigned int dofs_per_cell=cell->get_fe().dofs_per_cell;
::dealii::Vector<double> dofvalues(dofs_per_cell);
for (typename std::vector<const VECTOR*>::iterator it=input_vectors.begin();
- it !=input_vectors.end();
- ++it)
- {
- cell->get_interpolated_dof_values(*(*it), dofvalues);
- std::memcpy(data_store, &dofvalues(0), sizeof(double)*dofs_per_cell);
- data_store += dofs_per_cell;
- }
+ it !=input_vectors.end();
+ ++it)
+ {
+ cell->get_interpolated_dof_values(*(*it), dofvalues);
+ std::memcpy(data_store, &dofvalues(0), sizeof(double)*dofs_per_cell);
+ data_store += dofs_per_cell;
+ }
}
void
SolutionTransfer<dim, VECTOR, DH>::
unpack_callback(const typename Triangulation<dim,dim>::cell_iterator & cell_,
- const typename Triangulation<dim,dim>::CellStatus /*status*/,
- const void* data,
- std::vector<VECTOR*> &all_out)
+ const typename Triangulation<dim,dim>::CellStatus /*status*/,
+ const void* data,
+ std::vector<VECTOR*> &all_out)
{
typename DH::cell_iterator
- cell(&dof_handler->get_tria(), cell_->level(), cell_->index(), dof_handler);
+ cell(&dof_handler->get_tria(), cell_->level(), cell_->index(), dof_handler);
const unsigned int dofs_per_cell=cell->get_fe().dofs_per_cell;
::dealii::Vector<double> dofvalues(dofs_per_cell);
const double *data_store = reinterpret_cast<const double *>(data);
for (typename std::vector<VECTOR*>::iterator it = all_out.begin();
- it != all_out.end();
- ++it)
- {
- std::memcpy(&dofvalues(0), data_store, sizeof(double)*dofs_per_cell);
- cell->set_dof_values_by_interpolation(dofvalues, *(*it));
- data_store += dofs_per_cell;
- }
+ it != all_out.end();
+ ++it)
+ {
+ std::memcpy(&dofvalues(0), data_store, sizeof(double)*dofs_per_cell);
+ cell->set_dof_values_by_interpolation(dofvalues, *(*it));
+ data_store += dofs_per_cell;
+ }
}
{
namespace p4est
{
- /**
- * A structure whose explicit
- * specializations contain
- * pointers to the relevant
- * p4est_* and p8est_*
- * functions. Using this
- * structure, for example by
- * saying
- * functions<dim>::quadrant_compare,
- * we can write code in a
- * dimension independent way,
- * either calling
- * p4est_quadrant_compare or
- * p8est_quadrant_compare,
- * depending on template
- * argument.
- */
+ /**
+ * A structure whose explicit
+ * specializations contain
+ * pointers to the relevant
+ * p4est_* and p8est_*
+ * functions. Using this
+ * structure, for example by
+ * saying
+ * functions<dim>::quadrant_compare,
+ * we can write code in a
+ * dimension independent way,
+ * either calling
+ * p4est_quadrant_compare or
+ * p8est_quadrant_compare,
+ * depending on template
+ * argument.
+ */
template <int dim> struct functions;
template <> struct functions<2>
{
- static
- int (&quadrant_compare) (const void *v1, const void *v2);
-
- static
- void (&quadrant_childrenv) (const types<2>::quadrant * q,
- types<2>::quadrant c[]);
-
- static
- int (&quadrant_overlaps_tree) (types<2>::tree * tree,
- const types<2>::quadrant * q);
-
- static
- void (&quadrant_set_morton) (types<2>::quadrant * quadrant,
- int level,
- uint64_t id);
-
- static
- int (&quadrant_is_equal) (const types<2>::quadrant * q1,
- const types<2>::quadrant * q2);
-
- static
- int (&quadrant_is_sibling) (const types<2>::quadrant * q1,
- const types<2>::quadrant * q2);
-
- static
- int (&quadrant_is_ancestor) (const types<2>::quadrant * q1,
- const types<2>::quadrant * q2);
-
- static
- types<2>::connectivity * (&connectivity_new) (types<2>::topidx num_vertices,
- types<2>::topidx num_trees,
- types<2>::topidx num_corners,
- types<2>::topidx num_vtt);
-
- static
- void (&connectivity_destroy) (p4est_connectivity_t *connectivity);
-
- static
- types<2>::forest * (&new_forest) (MPI_Comm mpicomm,
- types<2>::connectivity * connectivity,
- types<2>::locidx min_quadrants,
+ static
+ int (&quadrant_compare) (const void *v1, const void *v2);
+
+ static
+ void (&quadrant_childrenv) (const types<2>::quadrant * q,
+ types<2>::quadrant c[]);
+
+ static
+ int (&quadrant_overlaps_tree) (types<2>::tree * tree,
+ const types<2>::quadrant * q);
+
+ static
+ void (&quadrant_set_morton) (types<2>::quadrant * quadrant,
+ int level,
+ uint64_t id);
+
+ static
+ int (&quadrant_is_equal) (const types<2>::quadrant * q1,
+ const types<2>::quadrant * q2);
+
+ static
+ int (&quadrant_is_sibling) (const types<2>::quadrant * q1,
+ const types<2>::quadrant * q2);
+
+ static
+ int (&quadrant_is_ancestor) (const types<2>::quadrant * q1,
+ const types<2>::quadrant * q2);
+
+ static
+ types<2>::connectivity * (&connectivity_new) (types<2>::topidx num_vertices,
+ types<2>::topidx num_trees,
+ types<2>::topidx num_corners,
+ types<2>::topidx num_vtt);
+
+ static
+ void (&connectivity_destroy) (p4est_connectivity_t *connectivity);
+
+ static
+ types<2>::forest * (&new_forest) (MPI_Comm mpicomm,
+ types<2>::connectivity * connectivity,
+ types<2>::locidx min_quadrants,
int min_level,
int fill_uniform,
- size_t data_size,
- p4est_init_t init_fn,
- void *user_pointer);
-
- static
- void (&destroy) (types<2>::forest * p4est);
-
- static
- void (&refine) (types<2>::forest * p4est,
- int refine_recursive,
- p4est_refine_t refine_fn,
- p4est_init_t init_fn);
-
- static
- void (&coarsen) (types<2>::forest * p4est,
- int coarsen_recursive,
- p4est_coarsen_t coarsen_fn,
- p4est_init_t init_fn);
-
- static
- void (&balance) (types<2>::forest * p4est,
- types<2>::balance_type btype,
- p4est_init_t init_fn);
-
- static
- void (&partition) (types<2>::forest * p4est,
+ size_t data_size,
+ p4est_init_t init_fn,
+ void *user_pointer);
+
+ static
+ void (&destroy) (types<2>::forest * p4est);
+
+ static
+ void (&refine) (types<2>::forest * p4est,
+ int refine_recursive,
+ p4est_refine_t refine_fn,
+ p4est_init_t init_fn);
+
+ static
+ void (&coarsen) (types<2>::forest * p4est,
+ int coarsen_recursive,
+ p4est_coarsen_t coarsen_fn,
+ p4est_init_t init_fn);
+
+ static
+ void (&balance) (types<2>::forest * p4est,
+ types<2>::balance_type btype,
+ p4est_init_t init_fn);
+
+ static
+ void (&partition) (types<2>::forest * p4est,
int partition_for_coarsening,
- p4est_weight_t weight_fn);
-
- static
- void (&save) (const char *filename,
- types<2>::forest * p4est,
- int save_data);
-
- static
- types<2>::forest * (&load) (const char *filename,
- MPI_Comm mpicomm,
- size_t data_size,
- int load_data,
- void *user_pointer,
- types<2>::connectivity ** p4est);
-
- static
- void (&connectivity_save) (const char *filename,
- types<2>::connectivity * connectivity);
-
- static
- types<2>::connectivity * (&connectivity_load) (const char *filename,
- long *length);
-
- static
- unsigned (&checksum) (types<2>::forest * p4est);
-
- static
- void (&vtk_write_file) (types<2>::forest * p4est,
- p4est_geometry_t*,
- const char *baseName);
-
- static
- types<2>::ghost* (&ghost_new) (types<2>::forest * p4est,
- types<2>::balance_type btype);
-
- static
- void (&ghost_destroy) (types<2>::ghost * ghost);
-
- static
- void (&reset_data) (types<2>::forest * p4est,
- size_t data_size,
- p4est_init_t init_fn,
+ p4est_weight_t weight_fn);
+
+ static
+ void (&save) (const char *filename,
+ types<2>::forest * p4est,
+ int save_data);
+
+ static
+ types<2>::forest * (&load) (const char *filename,
+ MPI_Comm mpicomm,
+ size_t data_size,
+ int load_data,
+ void *user_pointer,
+ types<2>::connectivity ** p4est);
+
+ static
+ void (&connectivity_save) (const char *filename,
+ types<2>::connectivity * connectivity);
+
+ static
+ types<2>::connectivity * (&connectivity_load) (const char *filename,
+ long *length);
+
+ static
+ unsigned (&checksum) (types<2>::forest * p4est);
+
+ static
+ void (&vtk_write_file) (types<2>::forest * p4est,
+ p4est_geometry_t*,
+ const char *baseName);
+
+ static
+ types<2>::ghost* (&ghost_new) (types<2>::forest * p4est,
+ types<2>::balance_type btype);
+
+ static
+ void (&ghost_destroy) (types<2>::ghost * ghost);
+
+ static
+ void (&reset_data) (types<2>::forest * p4est,
+ size_t data_size,
+ p4est_init_t init_fn,
void *user_pointer);
- static
- size_t (&forest_memory_used) (types<2>::forest * p4est);
+ static
+ size_t (&forest_memory_used) (types<2>::forest * p4est);
- static
- size_t (&connectivity_memory_used) (types<2>::connectivity * p4est);
+ static
+ size_t (&connectivity_memory_used) (types<2>::connectivity * p4est);
};
int (&functions<2>::quadrant_compare) (const void *v1, const void *v2)
= p4est_quadrant_compare;
void (&functions<2>::quadrant_childrenv) (const types<2>::quadrant * q,
- types<2>::quadrant c[])
+ types<2>::quadrant c[])
= p4est_quadrant_childrenv;
int (&functions<2>::quadrant_overlaps_tree) (types<2>::tree * tree,
- const types<2>::quadrant * q)
+ const types<2>::quadrant * q)
= p4est_quadrant_overlaps_tree;
void (&functions<2>::quadrant_set_morton) (types<2>::quadrant * quadrant,
- int level,
- uint64_t id)
+ int level,
+ uint64_t id)
= p4est_quadrant_set_morton;
int (&functions<2>::quadrant_is_equal) (const types<2>::quadrant * q1,
- const types<2>::quadrant * q2)
+ const types<2>::quadrant * q2)
= p4est_quadrant_is_equal;
int (&functions<2>::quadrant_is_sibling) (const types<2>::quadrant * q1,
- const types<2>::quadrant * q2)
+ const types<2>::quadrant * q2)
= p4est_quadrant_is_sibling;
int (&functions<2>::quadrant_is_ancestor) (const types<2>::quadrant * q1,
- const types<2>::quadrant * q2)
+ const types<2>::quadrant * q2)
= p4est_quadrant_is_ancestor;
types<2>::connectivity * (&functions<2>::connectivity_new) (types<2>::topidx num_vertices,
- types<2>::topidx num_trees,
- types<2>::topidx num_corners,
- types<2>::topidx num_vtt)
+ types<2>::topidx num_trees,
+ types<2>::topidx num_corners,
+ types<2>::topidx num_vtt)
= p4est_connectivity_new;
void (&functions<2>::connectivity_destroy) (p4est_connectivity_t *connectivity)
= p4est_connectivity_destroy;
types<2>::forest * (&functions<2>::new_forest) (MPI_Comm mpicomm,
- types<2>::connectivity * connectivity,
- types<2>::locidx min_quadrants,
+ types<2>::connectivity * connectivity,
+ types<2>::locidx min_quadrants,
int min_level,
int fill_uniform,
- size_t data_size,
- p4est_init_t init_fn,
- void *user_pointer)
+ size_t data_size,
+ p4est_init_t init_fn,
+ void *user_pointer)
= p4est_new_ext;
void (&functions<2>::destroy) (types<2>::forest * p4est)
= p4est_destroy;
void (&functions<2>::refine) (types<2>::forest * p4est,
- int refine_recursive,
- p4est_refine_t refine_fn,
- p4est_init_t init_fn)
+ int refine_recursive,
+ p4est_refine_t refine_fn,
+ p4est_init_t init_fn)
= p4est_refine;
void (&functions<2>::coarsen) (types<2>::forest * p4est,
- int coarsen_recursive,
- p4est_coarsen_t coarsen_fn,
- p4est_init_t init_fn)
+ int coarsen_recursive,
+ p4est_coarsen_t coarsen_fn,
+ p4est_init_t init_fn)
= p4est_coarsen;
void (&functions<2>::balance) (types<2>::forest * p4est,
- types<2>::balance_type btype,
- p4est_init_t init_fn)
+ types<2>::balance_type btype,
+ p4est_init_t init_fn)
= p4est_balance;
void (&functions<2>::partition) (types<2>::forest * p4est,
int partition_for_coarsening,
- p4est_weight_t weight_fn)
+ p4est_weight_t weight_fn)
= p4est_partition_ext;
void (&functions<2>::save) (const char *filename,
- types<2>::forest * p4est,
- int save_data)
+ types<2>::forest * p4est,
+ int save_data)
= p4est_save;
types<2>::forest *
(&functions<2>::load) (const char *filename,
- MPI_Comm mpicomm,
- std::size_t data_size,
- int load_data,
- void *user_pointer,
- types<2>::connectivity ** p4est)
+ MPI_Comm mpicomm,
+ std::size_t data_size,
+ int load_data,
+ void *user_pointer,
+ types<2>::connectivity ** p4est)
= p4est_load;
void (&functions<2>::connectivity_save) (const char *filename,
- types<2>::connectivity *connectivity)
+ types<2>::connectivity *connectivity)
= p4est_connectivity_save;
types<2>::connectivity *
(&functions<2>::connectivity_load) (const char *filename,
- long *length)
+ long *length)
= p4est_connectivity_load;
unsigned (&functions<2>::checksum) (types<2>::forest * p4est)
= p4est_checksum;
void (&functions<2>::vtk_write_file) (types<2>::forest * p4est,
- p4est_geometry_t*,
- const char *baseName)
+ p4est_geometry_t*,
+ const char *baseName)
= p4est_vtk_write_file;
types<2>::ghost* (&functions<2>::ghost_new) (types<2>::forest * p4est,
- types<2>::balance_type btype)
+ types<2>::balance_type btype)
= p4est_ghost_new;
void (&functions<2>::ghost_destroy) (types<2>::ghost * ghost)
= p4est_ghost_destroy;
void (&functions<2>::reset_data) (types<2>::forest * p4est,
- size_t data_size,
- p4est_init_t init_fn,
- void *user_pointer)
+ size_t data_size,
+ p4est_init_t init_fn,
+ void *user_pointer)
= p4est_reset_data;
size_t (&functions<2>::forest_memory_used) (types<2>::forest * p4est)
template <> struct functions<3>
{
- static
- int (&quadrant_compare) (const void *v1, const void *v2);
-
- static
- void (&quadrant_childrenv) (const types<3>::quadrant * q,
- types<3>::quadrant c[]);
-
- static
- int (&quadrant_overlaps_tree) (types<3>::tree * tree,
- const types<3>::quadrant * q);
-
- static
- void (&quadrant_set_morton) (types<3>::quadrant * quadrant,
- int level,
- uint64_t id);
-
- static
- int (&quadrant_is_equal) (const types<3>::quadrant * q1,
- const types<3>::quadrant * q2);
-
- static
- int (&quadrant_is_sibling) (const types<3>::quadrant * q1,
- const types<3>::quadrant * q2);
-
- static
- int (&quadrant_is_ancestor) (const types<3>::quadrant * q1,
- const types<3>::quadrant * q2);
-
- static
- types<3>::connectivity * (&connectivity_new) (types<3>::topidx num_vertices,
- types<3>::topidx num_trees,
- types<3>::topidx num_edges,
- types<3>::topidx num_ett,
- types<3>::topidx num_corners,
- types<3>::topidx num_ctt);
-
- static
- void (&connectivity_destroy) (p8est_connectivity_t *connectivity);
-
- static
- types<3>::forest * (&new_forest) (MPI_Comm mpicomm,
- types<3>::connectivity * connectivity,
- types<3>::locidx min_quadrants,
+ static
+ int (&quadrant_compare) (const void *v1, const void *v2);
+
+ static
+ void (&quadrant_childrenv) (const types<3>::quadrant * q,
+ types<3>::quadrant c[]);
+
+ static
+ int (&quadrant_overlaps_tree) (types<3>::tree * tree,
+ const types<3>::quadrant * q);
+
+ static
+ void (&quadrant_set_morton) (types<3>::quadrant * quadrant,
+ int level,
+ uint64_t id);
+
+ static
+ int (&quadrant_is_equal) (const types<3>::quadrant * q1,
+ const types<3>::quadrant * q2);
+
+ static
+ int (&quadrant_is_sibling) (const types<3>::quadrant * q1,
+ const types<3>::quadrant * q2);
+
+ static
+ int (&quadrant_is_ancestor) (const types<3>::quadrant * q1,
+ const types<3>::quadrant * q2);
+
+ static
+ types<3>::connectivity * (&connectivity_new) (types<3>::topidx num_vertices,
+ types<3>::topidx num_trees,
+ types<3>::topidx num_edges,
+ types<3>::topidx num_ett,
+ types<3>::topidx num_corners,
+ types<3>::topidx num_ctt);
+
+ static
+ void (&connectivity_destroy) (p8est_connectivity_t *connectivity);
+
+ static
+ types<3>::forest * (&new_forest) (MPI_Comm mpicomm,
+ types<3>::connectivity * connectivity,
+ types<3>::locidx min_quadrants,
int min_level,
int fill_uniform,
- size_t data_size,
- p8est_init_t init_fn,
- void *user_pointer);
-
- static
- void (&destroy) (types<3>::forest * p8est);
-
- static
- void (&refine) (types<3>::forest * p8est,
- int refine_recursive,
- p8est_refine_t refine_fn,
- p8est_init_t init_fn);
-
- static
- void (&coarsen) (types<3>::forest * p8est,
- int coarsen_recursive,
- p8est_coarsen_t coarsen_fn,
- p8est_init_t init_fn);
-
- static
- void (&balance) (types<3>::forest * p8est,
- types<3>::balance_type btype,
- p8est_init_t init_fn);
-
- static
- void (&partition) (types<3>::forest * p8est,
+ size_t data_size,
+ p8est_init_t init_fn,
+ void *user_pointer);
+
+ static
+ void (&destroy) (types<3>::forest * p8est);
+
+ static
+ void (&refine) (types<3>::forest * p8est,
+ int refine_recursive,
+ p8est_refine_t refine_fn,
+ p8est_init_t init_fn);
+
+ static
+ void (&coarsen) (types<3>::forest * p8est,
+ int coarsen_recursive,
+ p8est_coarsen_t coarsen_fn,
+ p8est_init_t init_fn);
+
+ static
+ void (&balance) (types<3>::forest * p8est,
+ types<3>::balance_type btype,
+ p8est_init_t init_fn);
+
+ static
+ void (&partition) (types<3>::forest * p8est,
int partition_for_coarsening,
- p8est_weight_t weight_fn);
-
- static
- void (&save) (const char *filename,
- types<3>::forest * p4est,
- int save_data);
-
- static
- types<3>::forest * (&load) (const char *filename,
- MPI_Comm mpicomm,
- std::size_t data_size,
- int load_data,
- void *user_pointer,
- types<3>::connectivity ** p4est);
-
- static
- void (&connectivity_save) (const char *filename,
- types<3>::connectivity * connectivity);
-
- static
- types<3>::connectivity * (&connectivity_load) (const char *filename,
- long *length);
-
- static
- unsigned (&checksum) (types<3>::forest * p8est);
-
- static
- void (&vtk_write_file) (types<3>::forest * p8est,
- p8est_geometry_t*,
- const char *baseName);
-
- static
- types<3>::ghost* (&ghost_new) (types<3>::forest * p4est,
- types<3>::balance_type btype);
-
- static
- void (&ghost_destroy) (types<3>::ghost * ghost);
-
- static
- void (&reset_data) (types<3>::forest * p4est,
- size_t data_size,
- p8est_init_t init_fn,
+ p8est_weight_t weight_fn);
+
+ static
+ void (&save) (const char *filename,
+ types<3>::forest * p4est,
+ int save_data);
+
+ static
+ types<3>::forest * (&load) (const char *filename,
+ MPI_Comm mpicomm,
+ std::size_t data_size,
+ int load_data,
+ void *user_pointer,
+ types<3>::connectivity ** p4est);
+
+ static
+ void (&connectivity_save) (const char *filename,
+ types<3>::connectivity * connectivity);
+
+ static
+ types<3>::connectivity * (&connectivity_load) (const char *filename,
+ long *length);
+
+ static
+ unsigned (&checksum) (types<3>::forest * p8est);
+
+ static
+ void (&vtk_write_file) (types<3>::forest * p8est,
+ p8est_geometry_t*,
+ const char *baseName);
+
+ static
+ types<3>::ghost* (&ghost_new) (types<3>::forest * p4est,
+ types<3>::balance_type btype);
+
+ static
+ void (&ghost_destroy) (types<3>::ghost * ghost);
+
+ static
+ void (&reset_data) (types<3>::forest * p4est,
+ size_t data_size,
+ p8est_init_t init_fn,
void *user_pointer);
- static
- size_t (&forest_memory_used) (types<3>::forest * p4est);
+ static
+ size_t (&forest_memory_used) (types<3>::forest * p4est);
- static
- size_t (&connectivity_memory_used) (types<3>::connectivity * p4est);
+ static
+ size_t (&connectivity_memory_used) (types<3>::connectivity * p4est);
};
= p8est_quadrant_compare;
void (&functions<3>::quadrant_childrenv) (const types<3>::quadrant * q,
- types<3>::quadrant c[])
+ types<3>::quadrant c[])
= p8est_quadrant_childrenv;
int (&functions<3>::quadrant_overlaps_tree) (types<3>::tree * tree,
- const types<3>::quadrant * q)
+ const types<3>::quadrant * q)
= p8est_quadrant_overlaps_tree;
void (&functions<3>::quadrant_set_morton) (types<3>::quadrant * quadrant,
- int level,
- uint64_t id)
+ int level,
+ uint64_t id)
= p8est_quadrant_set_morton;
int (&functions<3>::quadrant_is_equal) (const types<3>::quadrant * q1,
- const types<3>::quadrant * q2)
+ const types<3>::quadrant * q2)
= p8est_quadrant_is_equal;
int (&functions<3>::quadrant_is_sibling) (const types<3>::quadrant * q1,
- const types<3>::quadrant * q2)
+ const types<3>::quadrant * q2)
= p8est_quadrant_is_sibling;
int (&functions<3>::quadrant_is_ancestor) (const types<3>::quadrant * q1,
- const types<3>::quadrant * q2)
+ const types<3>::quadrant * q2)
= p8est_quadrant_is_ancestor;
types<3>::connectivity * (&functions<3>::connectivity_new) (types<3>::topidx num_vertices,
- types<3>::topidx num_trees,
- types<3>::topidx num_edges,
- types<3>::topidx num_ett,
- types<3>::topidx num_corners,
- types<3>::topidx num_ctt)
+ types<3>::topidx num_trees,
+ types<3>::topidx num_edges,
+ types<3>::topidx num_ett,
+ types<3>::topidx num_corners,
+ types<3>::topidx num_ctt)
= p8est_connectivity_new;
void (&functions<3>::connectivity_destroy) (p8est_connectivity_t *connectivity)
= p8est_connectivity_destroy;
types<3>::forest * (&functions<3>::new_forest) (MPI_Comm mpicomm,
- types<3>::connectivity * connectivity,
- types<3>::locidx min_quadrants,
+ types<3>::connectivity * connectivity,
+ types<3>::locidx min_quadrants,
int min_level,
int fill_uniform,
- size_t data_size,
- p8est_init_t init_fn,
- void *user_pointer)
+ size_t data_size,
+ p8est_init_t init_fn,
+ void *user_pointer)
= p8est_new_ext;
void (&functions<3>::destroy) (types<3>::forest * p8est)
= p8est_destroy;
void (&functions<3>::refine) (types<3>::forest * p8est,
- int refine_recursive,
- p8est_refine_t refine_fn,
- p8est_init_t init_fn)
+ int refine_recursive,
+ p8est_refine_t refine_fn,
+ p8est_init_t init_fn)
= p8est_refine;
void (&functions<3>::coarsen) (types<3>::forest * p8est,
- int coarsen_recursive,
- p8est_coarsen_t coarsen_fn,
- p8est_init_t init_fn)
+ int coarsen_recursive,
+ p8est_coarsen_t coarsen_fn,
+ p8est_init_t init_fn)
= p8est_coarsen;
void (&functions<3>::balance) (types<3>::forest * p8est,
- types<3>::balance_type btype,
- p8est_init_t init_fn)
+ types<3>::balance_type btype,
+ p8est_init_t init_fn)
= p8est_balance;
void (&functions<3>::partition) (types<3>::forest * p8est,
int partition_for_coarsening,
- p8est_weight_t weight_fn)
+ p8est_weight_t weight_fn)
= p8est_partition_ext;
void (&functions<3>::save) (const char *filename,
- types<3>::forest * p4est,
- int save_data)
+ types<3>::forest * p4est,
+ int save_data)
= p8est_save;
types<3>::forest *
(&functions<3>::load) (const char *filename,
- MPI_Comm mpicomm,
- std::size_t data_size,
- int load_data,
- void *user_pointer,
- types<3>::connectivity ** p4est)
+ MPI_Comm mpicomm,
+ std::size_t data_size,
+ int load_data,
+ void *user_pointer,
+ types<3>::connectivity ** p4est)
= p8est_load;
void (&functions<3>::connectivity_save) (const char *filename,
- types<3>::connectivity *connectivity)
+ types<3>::connectivity *connectivity)
= p8est_connectivity_save;
types<3>::connectivity *
(&functions<3>::connectivity_load) (const char *filename,
- long *length)
+ long *length)
= p8est_connectivity_load;
unsigned (&functions<3>::checksum) (types<3>::forest * p8est)
= p8est_checksum;
void (&functions<3>::vtk_write_file) (types<3>::forest * p8est,
- p8est_geometry_t*,
- const char *baseName)
+ p8est_geometry_t*,
+ const char *baseName)
= p8est_vtk_write_file;
types<3>::ghost* (&functions<3>::ghost_new) (types<3>::forest * p4est,
- types<3>::balance_type btype)
+ types<3>::balance_type btype)
= p8est_ghost_new;
void (&functions<3>::ghost_destroy) (types<3>::ghost * ghost)
= p8est_ghost_destroy;
void (&functions<3>::reset_data) (types<3>::forest * p4est,
- size_t data_size,
- p8est_init_t init_fn,
- void *user_pointer)
+ size_t data_size,
+ p8est_init_t init_fn,
+ void *user_pointer)
= p8est_reset_data;
size_t (&functions<3>::forest_memory_used) (types<3>::forest * p4est)
{
for (unsigned int c=0;
- c<GeometryInfo<dim>::max_children_per_cell; ++c)
- switch (dim)
- {
- case 2:
- P4EST_QUADRANT_INIT(&p4est_children[c]);
- break;
- case 3:
- P8EST_QUADRANT_INIT(&p4est_children[c]);
- break;
- default:
- Assert (false, ExcNotImplemented());
- }
+ c<GeometryInfo<dim>::max_children_per_cell; ++c)
+ switch (dim)
+ {
+ case 2:
+ P4EST_QUADRANT_INIT(&p4est_children[c]);
+ break;
+ case 3:
+ P8EST_QUADRANT_INIT(&p4est_children[c]);
+ break;
+ default:
+ Assert (false, ExcNotImplemented());
+ }
functions<dim>::quadrant_childrenv (&p4est_cell,
- p4est_children);
+ p4est_children);
}
init_coarse_quadrant(typename types<dim>::quadrant & quad)
{
switch (dim)
- {
- case 2:
- P4EST_QUADRANT_INIT(&quad);
- break;
- case 3:
- P8EST_QUADRANT_INIT(&quad);
- break;
- default:
- Assert (false, ExcNotImplemented());
- }
+ {
+ case 2:
+ P4EST_QUADRANT_INIT(&quad);
+ break;
+ case 3:
+ P8EST_QUADRANT_INIT(&quad);
+ break;
+ default:
+ Assert (false, ExcNotImplemented());
+ }
functions<dim>::quadrant_set_morton (&quad,
- /*level=*/0,
- /*index=*/0);
+ /*level=*/0,
+ /*index=*/0);
}
template <int dim>
bool
quadrant_is_equal (const typename types<dim>::quadrant & q1,
- const typename types<dim>::quadrant & q2)
+ const typename types<dim>::quadrant & q2)
{
return functions<dim>::quadrant_is_equal(&q1, &q2);
}
template <int dim>
bool
quadrant_is_ancestor (const typename types<dim>::quadrant & q1,
- const typename types<dim>::quadrant & q2)
+ const typename types<dim>::quadrant & q2)
{
return functions<dim>::quadrant_is_ancestor(&q1, &q2);
}
template <int dim, int spacedim>
void
get_vertex_to_cell_mappings (const Triangulation<dim,spacedim> &triangulation,
- std::vector<unsigned int> &vertex_touch_count,
- std::vector<std::list<
- std::pair<typename Triangulation<dim,spacedim>::active_cell_iterator,unsigned int> > >
- & vertex_to_cell)
+ std::vector<unsigned int> &vertex_touch_count,
+ std::vector<std::list<
+ std::pair<typename Triangulation<dim,spacedim>::active_cell_iterator,unsigned int> > >
+ & vertex_to_cell)
{
vertex_touch_count.resize (triangulation.n_vertices());
vertex_to_cell.resize (triangulation.n_vertices());
for (typename Triangulation<dim,spacedim>::active_cell_iterator
- cell = triangulation.begin_active();
- cell != triangulation.end(); ++cell)
+ cell = triangulation.begin_active();
+ cell != triangulation.end(); ++cell)
for (unsigned int v=0; v<GeometryInfo<dim>::vertices_per_cell; ++v)
- {
- ++vertex_touch_count[cell->vertex_index(v)];
- vertex_to_cell[cell->vertex_index(v)]
- .push_back (std::make_pair (cell, v));
- }
+ {
+ ++vertex_touch_count[cell->vertex_index(v)];
+ vertex_to_cell[cell->vertex_index(v)]
+ .push_back (std::make_pair (cell, v));
+ }
}
template <int dim, int spacedim>
void
get_edge_to_cell_mappings (const Triangulation<dim,spacedim> &triangulation,
- std::vector<unsigned int> &edge_touch_count,
- std::vector<std::list<
- std::pair<typename Triangulation<dim,spacedim>::active_cell_iterator,unsigned int> > >
- & edge_to_cell)
+ std::vector<unsigned int> &edge_touch_count,
+ std::vector<std::list<
+ std::pair<typename Triangulation<dim,spacedim>::active_cell_iterator,unsigned int> > >
+ & edge_to_cell)
{
Assert (triangulation.n_levels() == 1, ExcInternalError());
edge_to_cell.resize (triangulation.n_active_lines());
for (typename Triangulation<dim,spacedim>::active_cell_iterator
- cell = triangulation.begin_active();
- cell != triangulation.end(); ++cell)
+ cell = triangulation.begin_active();
+ cell != triangulation.end(); ++cell)
for (unsigned int l=0; l<GeometryInfo<dim>::lines_per_cell; ++l)
- {
- ++edge_touch_count[cell->line(l)->index()];
- edge_to_cell[cell->line(l)->index()]
- .push_back (std::make_pair (cell, l));
- }
+ {
+ ++edge_touch_count[cell->line(l)->index()];
+ edge_to_cell[cell->line(l)->index()]
+ .push_back (std::make_pair (cell, l));
+ }
}
- /**
- * Set all vertex and cell
- * related information in the
- * p4est connectivity structure.
- */
+ /**
+ * Set all vertex and cell
+ * related information in the
+ * p4est connectivity structure.
+ */
template <int dim, int spacedim>
void
set_vertex_and_cell_info (const Triangulation<dim,spacedim> &triangulation,
- const std::vector<unsigned int> &vertex_touch_count,
- const std::vector<std::list<
- std::pair<typename Triangulation<dim,spacedim>::active_cell_iterator,unsigned int> > >
- & vertex_to_cell,
- const std::vector<unsigned int> &coarse_cell_to_p4est_tree_permutation,
- const bool set_vertex_info,
- typename internal::p4est::types<dim>::connectivity *connectivity)
+ const std::vector<unsigned int> &vertex_touch_count,
+ const std::vector<std::list<
+ std::pair<typename Triangulation<dim,spacedim>::active_cell_iterator,unsigned int> > >
+ & vertex_to_cell,
+ const std::vector<unsigned int> &coarse_cell_to_p4est_tree_permutation,
+ const bool set_vertex_info,
+ typename internal::p4est::types<dim>::connectivity *connectivity)
{
- // copy the vertices into the
- // connectivity structure. the
- // triangulation exports the array of
- // vertices, but some of the entries are
- // sometimes unused; this shouldn't be
- // the case for a newly created
- // triangulation, but make sure
- //
- // note that p4est stores coordinates as
- // a triplet of values even in 2d
+ // copy the vertices into the
+ // connectivity structure. the
+ // triangulation exports the array of
+ // vertices, but some of the entries are
+ // sometimes unused; this shouldn't be
+ // the case for a newly created
+ // triangulation, but make sure
+ //
+ // note that p4est stores coordinates as
+ // a triplet of values even in 2d
Assert (triangulation.get_used_vertices().size() ==
- triangulation.get_vertices().size(),
- ExcInternalError());
+ triangulation.get_vertices().size(),
+ ExcInternalError());
Assert (std::find (triangulation.get_used_vertices().begin(),
- triangulation.get_used_vertices().end(),
- false)
- == triangulation.get_used_vertices().end(),
- ExcInternalError());
+ triangulation.get_used_vertices().end(),
+ false)
+ == triangulation.get_used_vertices().end(),
+ ExcInternalError());
if (set_vertex_info == true)
for (unsigned int v=0; v<triangulation.n_vertices(); ++v)
- {
- connectivity->vertices[3*v ] = triangulation.get_vertices()[v][0];
- connectivity->vertices[3*v+1] = triangulation.get_vertices()[v][1];
- connectivity->vertices[3*v+2] = (spacedim == 2 ?
- 0
- :
- triangulation.get_vertices()[v][2]);
- }
-
- // next store the tree_to_vertex indices
- // (each tree is here only a single cell
- // in the coarse mesh). p4est requires
- // vertex numbering in clockwise
- // orientation
- //
- // while we're at it, also copy the
- // neighborship information between cells
+ {
+ connectivity->vertices[3*v ] = triangulation.get_vertices()[v][0];
+ connectivity->vertices[3*v+1] = triangulation.get_vertices()[v][1];
+ connectivity->vertices[3*v+2] = (spacedim == 2 ?
+ 0
+ :
+ triangulation.get_vertices()[v][2]);
+ }
+
+ // next store the tree_to_vertex indices
+ // (each tree is here only a single cell
+ // in the coarse mesh). p4est requires
+ // vertex numbering in clockwise
+ // orientation
+ //
+ // while we're at it, also copy the
+ // neighborship information between cells
typename Triangulation<dim>::active_cell_iterator
cell = triangulation.begin_active(),
endc = triangulation.end();
for (; cell != endc; ++cell)
{
- const unsigned int
- index = coarse_cell_to_p4est_tree_permutation[cell->index()];
-
- for (unsigned int v=0; v<GeometryInfo<dim>::vertices_per_cell; ++v)
- {
- if (set_vertex_info == true)
- connectivity->tree_to_vertex[index*GeometryInfo<dim>::vertices_per_cell+v] = cell->vertex_index(v);
- connectivity->tree_to_corner[index*GeometryInfo<dim>::vertices_per_cell+v] = cell->vertex_index(v);
- }
-
- // neighborship information. if a
- // cell is at a boundary, then enter
- // the index of the cell itself here
- for (unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell; ++f)
- if (cell->face(f)->at_boundary() == false)
- connectivity->tree_to_tree[index*GeometryInfo<dim>::faces_per_cell + f]
- = coarse_cell_to_p4est_tree_permutation[cell->neighbor(f)->index()];
- else
- connectivity->tree_to_tree[index*GeometryInfo<dim>::faces_per_cell + f]
- = coarse_cell_to_p4est_tree_permutation[cell->index()];
-
- // fill tree_to_face, which is
- // essentially neighbor_to_neighbor;
- // however, we have to remap the
- // resulting face number as well
- for (unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell; ++f)
- if (cell->face(f)->at_boundary() == false)
- {
- switch (dim)
- {
- case 2:
- {
- connectivity->tree_to_face[index*GeometryInfo<dim>::faces_per_cell + f]
- = cell->neighbor_of_neighbor (f);
- break;
- }
-
- case 3:
- {
- /*
- * The values for
- * tree_to_face are in
- * 0..23 where ttf % 6
- * gives the face
- * number and ttf / 6
- * the face orientation
- * code. The
- * orientation is
- * determined as
- * follows. Let
- * my_face and
- * other_face be the
- * two face numbers of
- * the connecting trees
- * in 0..5. Then the
- * first face vertex of
- * the lower of my_face
- * and other_face
- * connects to a face
- * vertex numbered 0..3
- * in the higher of
- * my_face and
- * other_face. The
- * face orientation is
- * defined as this
- * number. If my_face
- * == other_face,
- * treating either of
- * both faces as the
- * lower one leads to
- * the same result.
- */
-
- connectivity->tree_to_face[index*6 + f]
- = cell->neighbor_of_neighbor (f);
-
- unsigned int face_idx_list[2] =
- {f, cell->neighbor_of_neighbor (f)};
- typename Triangulation<dim>::active_cell_iterator
- cell_list[2] = {cell, cell->neighbor(f)};
- unsigned int smaller_idx = 0;
-
- if (f>cell->neighbor_of_neighbor (f))
- smaller_idx = 1;
-
- unsigned larger_idx = (smaller_idx+1) % 2;
- //smaller = *_list[smaller_idx]
- //larger = *_list[larger_idx]
-
- unsigned int v = 0;
-
- // global vertex index of
- // vertex 0 on face of
- // cell with smaller
- // local face index
- unsigned int g_idx =
- cell_list[smaller_idx]->vertex_index(
- GeometryInfo<dim>::face_to_cell_vertices(
- face_idx_list[smaller_idx],
- 0,
- cell_list[smaller_idx]->face_orientation(face_idx_list[smaller_idx]),
- cell_list[smaller_idx]->face_flip(face_idx_list[smaller_idx]),
- cell_list[smaller_idx]->face_rotation(face_idx_list[smaller_idx]))
- );
-
- // loop over vertices on
- // face from other cell
- // and compare global
- // vertex numbers
- for (unsigned int i=0; i<GeometryInfo<dim>::vertices_per_face; ++i)
- {
- unsigned int idx
- =
- cell_list[larger_idx]->vertex_index(
- GeometryInfo<dim>::face_to_cell_vertices(
- face_idx_list[larger_idx],
- i)
- );
-
- if (idx==g_idx)
- {
- v = i;
- break;
- }
- }
-
- connectivity->tree_to_face[index*6 + f] += 6*v;
- break;
- }
-
- default:
- Assert (false, ExcNotImplemented());
- }
- }
- else
- connectivity->tree_to_face[index*GeometryInfo<dim>::faces_per_cell + f] = f;
+ const unsigned int
+ index = coarse_cell_to_p4est_tree_permutation[cell->index()];
+
+ for (unsigned int v=0; v<GeometryInfo<dim>::vertices_per_cell; ++v)
+ {
+ if (set_vertex_info == true)
+ connectivity->tree_to_vertex[index*GeometryInfo<dim>::vertices_per_cell+v] = cell->vertex_index(v);
+ connectivity->tree_to_corner[index*GeometryInfo<dim>::vertices_per_cell+v] = cell->vertex_index(v);
+ }
+
+ // neighborship information. if a
+ // cell is at a boundary, then enter
+ // the index of the cell itself here
+ for (unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell; ++f)
+ if (cell->face(f)->at_boundary() == false)
+ connectivity->tree_to_tree[index*GeometryInfo<dim>::faces_per_cell + f]
+ = coarse_cell_to_p4est_tree_permutation[cell->neighbor(f)->index()];
+ else
+ connectivity->tree_to_tree[index*GeometryInfo<dim>::faces_per_cell + f]
+ = coarse_cell_to_p4est_tree_permutation[cell->index()];
+
+ // fill tree_to_face, which is
+ // essentially neighbor_to_neighbor;
+ // however, we have to remap the
+ // resulting face number as well
+ for (unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell; ++f)
+ if (cell->face(f)->at_boundary() == false)
+ {
+ switch (dim)
+ {
+ case 2:
+ {
+ connectivity->tree_to_face[index*GeometryInfo<dim>::faces_per_cell + f]
+ = cell->neighbor_of_neighbor (f);
+ break;
+ }
+
+ case 3:
+ {
+ /*
+ * The values for
+ * tree_to_face are in
+ * 0..23 where ttf % 6
+ * gives the face
+ * number and ttf / 6
+ * the face orientation
+ * code. The
+ * orientation is
+ * determined as
+ * follows. Let
+ * my_face and
+ * other_face be the
+ * two face numbers of
+ * the connecting trees
+ * in 0..5. Then the
+ * first face vertex of
+ * the lower of my_face
+ * and other_face
+ * connects to a face
+ * vertex numbered 0..3
+ * in the higher of
+ * my_face and
+ * other_face. The
+ * face orientation is
+ * defined as this
+ * number. If my_face
+ * == other_face,
+ * treating either of
+ * both faces as the
+ * lower one leads to
+ * the same result.
+ */
+
+ connectivity->tree_to_face[index*6 + f]
+ = cell->neighbor_of_neighbor (f);
+
+ unsigned int face_idx_list[2] =
+ {f, cell->neighbor_of_neighbor (f)};
+ typename Triangulation<dim>::active_cell_iterator
+ cell_list[2] = {cell, cell->neighbor(f)};
+ unsigned int smaller_idx = 0;
+
+ if (f>cell->neighbor_of_neighbor (f))
+ smaller_idx = 1;
+
+ unsigned larger_idx = (smaller_idx+1) % 2;
+ //smaller = *_list[smaller_idx]
+ //larger = *_list[larger_idx]
+
+ unsigned int v = 0;
+
+ // global vertex index of
+ // vertex 0 on face of
+ // cell with smaller
+ // local face index
+ unsigned int g_idx =
+ cell_list[smaller_idx]->vertex_index(
+ GeometryInfo<dim>::face_to_cell_vertices(
+ face_idx_list[smaller_idx],
+ 0,
+ cell_list[smaller_idx]->face_orientation(face_idx_list[smaller_idx]),
+ cell_list[smaller_idx]->face_flip(face_idx_list[smaller_idx]),
+ cell_list[smaller_idx]->face_rotation(face_idx_list[smaller_idx]))
+ );
+
+ // loop over vertices on
+ // face from other cell
+ // and compare global
+ // vertex numbers
+ for (unsigned int i=0; i<GeometryInfo<dim>::vertices_per_face; ++i)
+ {
+ unsigned int idx
+ =
+ cell_list[larger_idx]->vertex_index(
+ GeometryInfo<dim>::face_to_cell_vertices(
+ face_idx_list[larger_idx],
+ i)
+ );
+
+ if (idx==g_idx)
+ {
+ v = i;
+ break;
+ }
+ }
+
+ connectivity->tree_to_face[index*6 + f] += 6*v;
+ break;
+ }
+
+ default:
+ Assert (false, ExcNotImplemented());
+ }
+ }
+ else
+ connectivity->tree_to_face[index*GeometryInfo<dim>::faces_per_cell + f] = f;
}
- // now fill the vertex information
+ // now fill the vertex information
connectivity->ctt_offset[0] = 0;
std::partial_sum (vertex_touch_count.begin(),
- vertex_touch_count.end(),
- &connectivity->ctt_offset[1]);
+ vertex_touch_count.end(),
+ &connectivity->ctt_offset[1]);
const typename internal::p4est::types<dim>::locidx
num_vtt = std::accumulate (vertex_touch_count.begin(),
- vertex_touch_count.end(),
- 0);
+ vertex_touch_count.end(),
+ 0);
Assert (connectivity->ctt_offset[triangulation.n_vertices()] ==
- num_vtt,
- ExcInternalError());
+ num_vtt,
+ ExcInternalError());
for (unsigned int v=0; v<triangulation.n_vertices(); ++v)
{
- Assert (vertex_to_cell[v].size() == vertex_touch_count[v],
- ExcInternalError());
-
- typename std::list<std::pair
- <typename Triangulation<dim,spacedim>::active_cell_iterator,
- unsigned int> >::const_iterator
- p = vertex_to_cell[v].begin();
- for (unsigned int c=0; c<vertex_touch_count[v]; ++c, ++p)
- {
- connectivity->corner_to_tree[connectivity->ctt_offset[v]+c]
- = coarse_cell_to_p4est_tree_permutation[p->first->index()];
- connectivity->corner_to_corner[connectivity->ctt_offset[v]+c]
- = p->second;
- }
+ Assert (vertex_to_cell[v].size() == vertex_touch_count[v],
+ ExcInternalError());
+
+ typename std::list<std::pair
+ <typename Triangulation<dim,spacedim>::active_cell_iterator,
+ unsigned int> >::const_iterator
+ p = vertex_to_cell[v].begin();
+ for (unsigned int c=0; c<vertex_touch_count[v]; ++c, ++p)
+ {
+ connectivity->corner_to_tree[connectivity->ctt_offset[v]+c]
+ = coarse_cell_to_p4est_tree_permutation[p->first->index()];
+ connectivity->corner_to_corner[connectivity->ctt_offset[v]+c]
+ = p->second;
+ }
}
}
template <int dim, int spacedim>
bool
tree_exists_locally (const typename internal::p4est::types<dim>::forest *parallel_forest,
- const typename internal::p4est::types<dim>::topidx coarse_grid_cell)
+ const typename internal::p4est::types<dim>::topidx coarse_grid_cell)
{
Assert (coarse_grid_cell < parallel_forest->connectivity->num_trees,
- ExcInternalError());
+ ExcInternalError());
return ((coarse_grid_cell >= parallel_forest->first_local_tree)
- &&
- (coarse_grid_cell <= parallel_forest->last_local_tree));
+ &&
+ (coarse_grid_cell <= parallel_forest->last_local_tree));
}
{
if (cell->has_children())
for (unsigned int c=0; c<cell->n_children(); ++c)
- delete_all_children_and_self<dim,spacedim> (cell->child(c));
+ delete_all_children_and_self<dim,spacedim> (cell->child(c));
else
cell->set_coarsen_flag ();
}
{
if (cell->has_children())
for (unsigned int c=0; c<cell->n_children(); ++c)
- delete_all_children_and_self<dim,spacedim> (cell->child(c));
+ delete_all_children_and_self<dim,spacedim> (cell->child(c));
}
template <int dim, int spacedim>
void
match_tree_recursively (const typename internal::p4est::types<dim>::tree &tree,
- const typename Triangulation<dim,spacedim>::cell_iterator &dealii_cell,
- const typename internal::p4est::types<dim>::quadrant &p4est_cell,
- const typename internal::p4est::types<dim>::forest &forest,
- const types::subdomain_id_t my_subdomain)
+ const typename Triangulation<dim,spacedim>::cell_iterator &dealii_cell,
+ const typename internal::p4est::types<dim>::quadrant &p4est_cell,
+ const typename internal::p4est::types<dim>::forest &forest,
+ const types::subdomain_id_t my_subdomain)
{
- // check if this cell exists in
- // the local p4est cell
+ // check if this cell exists in
+ // the local p4est cell
if (sc_array_bsearch(const_cast<sc_array_t*>(&tree.quadrants),
- &p4est_cell,
- internal::p4est::functions<dim>::quadrant_compare)
- != -1)
+ &p4est_cell,
+ internal::p4est::functions<dim>::quadrant_compare)
+ != -1)
{
- // yes, cell found in local part of p4est
- delete_all_children<dim,spacedim> (dealii_cell);
- dealii_cell->set_subdomain_id(my_subdomain);
+ // yes, cell found in local part of p4est
+ delete_all_children<dim,spacedim> (dealii_cell);
+ dealii_cell->set_subdomain_id(my_subdomain);
}
else
{
- // no, cell not found in
- // local part of
- // p4est. this means that
- // the local part is more
- // refined than the current
- // cell. if this cell has
- // no children of its own,
- // we need to refine it,
- // and if it does already
- // have children then loop
- // over all children and
- // see if they are locally
- // available as well
- if (dealii_cell->has_children () == false)
- dealii_cell->set_refine_flag ();
- else
- {
- typename internal::p4est::types<dim>::quadrant
- p4est_child[GeometryInfo<dim>::max_children_per_cell];
- for (unsigned int c=0;
- c<GeometryInfo<dim>::max_children_per_cell; ++c)
- switch (dim)
- {
- case 2:
- P4EST_QUADRANT_INIT(&p4est_child[c]);
- break;
- case 3:
- P8EST_QUADRANT_INIT(&p4est_child[c]);
- break;
- default:
- Assert (false, ExcNotImplemented());
- }
-
-
- internal::p4est::functions<dim>::
- quadrant_childrenv (&p4est_cell,
- p4est_child);
-
- for (unsigned int c=0;
- c<GeometryInfo<dim>::max_children_per_cell; ++c)
- if (internal::p4est::functions<dim>::
- quadrant_overlaps_tree (const_cast<typename internal::p4est::types<dim>::tree*>(&tree),
- &p4est_child[c])
- == false)
- {
- // no, this child
- // is locally not
- // available in
- // the p4est.
- // delete all
- // its children
- // but, because this
- // may not be successfull,
- // make sure to mark all
- // children recursively as
- // not local.
- delete_all_children<dim,spacedim> (dealii_cell->child(c));
- dealii_cell->child(c)
- ->recursively_set_subdomain_id(types::artificial_subdomain_id);
- }
- else
- {
- // at least some
- // part of the
- // tree rooted in
- // this child is
- // locally
- // available
- match_tree_recursively<dim,spacedim> (tree,
- dealii_cell->child(c),
- p4est_child[c],
- forest,
- my_subdomain);
- }
- }
+ // no, cell not found in
+ // local part of
+ // p4est. this means that
+ // the local part is more
+ // refined than the current
+ // cell. if this cell has
+ // no children of its own,
+ // we need to refine it,
+ // and if it does already
+ // have children then loop
+ // over all children and
+ // see if they are locally
+ // available as well
+ if (dealii_cell->has_children () == false)
+ dealii_cell->set_refine_flag ();
+ else
+ {
+ typename internal::p4est::types<dim>::quadrant
+ p4est_child[GeometryInfo<dim>::max_children_per_cell];
+ for (unsigned int c=0;
+ c<GeometryInfo<dim>::max_children_per_cell; ++c)
+ switch (dim)
+ {
+ case 2:
+ P4EST_QUADRANT_INIT(&p4est_child[c]);
+ break;
+ case 3:
+ P8EST_QUADRANT_INIT(&p4est_child[c]);
+ break;
+ default:
+ Assert (false, ExcNotImplemented());
+ }
+
+
+ internal::p4est::functions<dim>::
+ quadrant_childrenv (&p4est_cell,
+ p4est_child);
+
+ for (unsigned int c=0;
+ c<GeometryInfo<dim>::max_children_per_cell; ++c)
+ if (internal::p4est::functions<dim>::
+ quadrant_overlaps_tree (const_cast<typename internal::p4est::types<dim>::tree*>(&tree),
+ &p4est_child[c])
+ == false)
+ {
+ // no, this child
+ // is locally not
+ // available in
+ // the p4est.
+ // delete all
+ // its children
+ // but, because this
+ // may not be successfull,
+ // make sure to mark all
+ // children recursively as
+ // not local.
+ delete_all_children<dim,spacedim> (dealii_cell->child(c));
+ dealii_cell->child(c)
+ ->recursively_set_subdomain_id(types::artificial_subdomain_id);
+ }
+ else
+ {
+ // at least some
+ // part of the
+ // tree rooted in
+ // this child is
+ // locally
+ // available
+ match_tree_recursively<dim,spacedim> (tree,
+ dealii_cell->child(c),
+ p4est_child[c],
+ forest,
+ my_subdomain);
+ }
+ }
}
}
template <int dim, int spacedim>
void
match_quadrant_recursively (const typename internal::p4est::types<dim>::quadrant &this_quadrant,
- const typename Triangulation<dim,spacedim>::cell_iterator &dealii_cell,
- const typename internal::p4est::types<dim>::quadrant &ghost_quadrant,
- const typename internal::p4est::types<dim>::forest &forest,
- unsigned int ghost_owner)
+ const typename Triangulation<dim,spacedim>::cell_iterator &dealii_cell,
+ const typename internal::p4est::types<dim>::quadrant &ghost_quadrant,
+ const typename internal::p4est::types<dim>::forest &forest,
+ unsigned int ghost_owner)
{
if (internal::p4est::functions<dim>::quadrant_is_equal(&this_quadrant, &ghost_quadrant))
{
- // this is the ghostcell
- dealii_cell->set_subdomain_id(ghost_owner);
-
- if (dealii_cell->has_children())
- delete_all_children<dim,spacedim> (dealii_cell);
- else
- dealii_cell->clear_coarsen_flag();
- return;
+ // this is the ghostcell
+ dealii_cell->set_subdomain_id(ghost_owner);
+
+ if (dealii_cell->has_children())
+ delete_all_children<dim,spacedim> (dealii_cell);
+ else
+ dealii_cell->clear_coarsen_flag();
+ return;
}
if (! internal::p4est::functions<dim>::quadrant_is_ancestor ( &this_quadrant, &ghost_quadrant))
{
- return;
+ return;
}
if (dealii_cell->has_children () == false)
{
- dealii_cell->clear_coarsen_flag();
- dealii_cell->set_refine_flag ();
- return;
+ dealii_cell->clear_coarsen_flag();
+ dealii_cell->set_refine_flag ();
+ return;
}
typename internal::p4est::types<dim>::quadrant
p4est_child[GeometryInfo<dim>::max_children_per_cell];
for (unsigned int c=0;
- c<GeometryInfo<dim>::max_children_per_cell; ++c)
+ c<GeometryInfo<dim>::max_children_per_cell; ++c)
switch (dim)
- {
- case 2:
- P4EST_QUADRANT_INIT(&p4est_child[c]);
- break;
- case 3:
- P8EST_QUADRANT_INIT(&p4est_child[c]);
- break;
- default:
- Assert (false, ExcNotImplemented());
- }
+ {
+ case 2:
+ P4EST_QUADRANT_INIT(&p4est_child[c]);
+ break;
+ case 3:
+ P8EST_QUADRANT_INIT(&p4est_child[c]);
+ break;
+ default:
+ Assert (false, ExcNotImplemented());
+ }
internal::p4est::functions<dim>::
quadrant_childrenv (&this_quadrant, p4est_child);
for (unsigned int c=0;
- c<GeometryInfo<dim>::max_children_per_cell; ++c)
+ c<GeometryInfo<dim>::max_children_per_cell; ++c)
{
- match_quadrant_recursively<dim,spacedim> (p4est_child[c], dealii_cell->child(c), ghost_quadrant, forest, ghost_owner);
+ match_quadrant_recursively<dim,spacedim> (p4est_child[c], dealii_cell->child(c), ghost_quadrant, forest, ghost_owner);
}
template <int dim, int spacedim>
void
attach_mesh_data_recursively (const typename internal::p4est::types<dim>::tree &tree,
- const typename Triangulation<dim,spacedim>::cell_iterator &dealii_cell,
- const typename internal::p4est::types<dim>::quadrant &p4est_cell,
- const typename std::list<std::pair<unsigned int, typename std_cxx1x::function<
- void(typename parallel::distributed::Triangulation<dim,spacedim>::cell_iterator,
- typename parallel::distributed::Triangulation<dim,spacedim>::CellStatus,
- void*)
- > > > &attached_data_pack_callbacks)
+ const typename Triangulation<dim,spacedim>::cell_iterator &dealii_cell,
+ const typename internal::p4est::types<dim>::quadrant &p4est_cell,
+ const typename std::list<std::pair<unsigned int, typename std_cxx1x::function<
+ void(typename parallel::distributed::Triangulation<dim,spacedim>::cell_iterator,
+ typename parallel::distributed::Triangulation<dim,spacedim>::CellStatus,
+ void*)
+ > > > &attached_data_pack_callbacks)
{
typedef std::list<std::pair<unsigned int, typename std_cxx1x::function<
void(typename parallel::distributed::Triangulation<dim,spacedim>::cell_iterator,
- typename parallel::distributed::Triangulation<dim,spacedim>::CellStatus,
- void*)
+ typename parallel::distributed::Triangulation<dim,spacedim>::CellStatus,
+ void*)
> > > callback_list_t;
int idx = sc_array_bsearch(const_cast<sc_array_t*>(&tree.quadrants),
- &p4est_cell,
- internal::p4est::functions<dim>::quadrant_compare);
+ &p4est_cell,
+ internal::p4est::functions<dim>::quadrant_compare);
if (idx == -1 && (internal::p4est::functions<dim>::
- quadrant_overlaps_tree (const_cast<typename internal::p4est::types<dim>::tree*>(&tree),
- &p4est_cell)
- == false))
+ quadrant_overlaps_tree (const_cast<typename internal::p4est::types<dim>::tree*>(&tree),
+ &p4est_cell)
+ == false))
return; //this quadrant and none of it's childs belongs to us.
bool p4est_has_children = (idx == -1);
if (p4est_has_children && dealii_cell->has_children())
{
- //recurse further
- typename internal::p4est::types<dim>::quadrant
- p4est_child[GeometryInfo<dim>::max_children_per_cell];
- for (unsigned int c=0; c<GeometryInfo<dim>::max_children_per_cell; ++c)
- switch (dim)
- {
- case 2:
- P4EST_QUADRANT_INIT(&p4est_child[c]);
- break;
- case 3:
- P8EST_QUADRANT_INIT(&p4est_child[c]);
- break;
- default:
- Assert (false, ExcNotImplemented());
- }
-
- internal::p4est::functions<dim>::
- quadrant_childrenv (&p4est_cell, p4est_child);
-
- for (unsigned int c=0;
- c<GeometryInfo<dim>::max_children_per_cell; ++c)
- {
- attach_mesh_data_recursively<dim,spacedim> (tree,
- dealii_cell->child(c),
- p4est_child[c],
- attached_data_pack_callbacks);
- }
+ //recurse further
+ typename internal::p4est::types<dim>::quadrant
+ p4est_child[GeometryInfo<dim>::max_children_per_cell];
+ for (unsigned int c=0; c<GeometryInfo<dim>::max_children_per_cell; ++c)
+ switch (dim)
+ {
+ case 2:
+ P4EST_QUADRANT_INIT(&p4est_child[c]);
+ break;
+ case 3:
+ P8EST_QUADRANT_INIT(&p4est_child[c]);
+ break;
+ default:
+ Assert (false, ExcNotImplemented());
+ }
+
+ internal::p4est::functions<dim>::
+ quadrant_childrenv (&p4est_cell, p4est_child);
+
+ for (unsigned int c=0;
+ c<GeometryInfo<dim>::max_children_per_cell; ++c)
+ {
+ attach_mesh_data_recursively<dim,spacedim> (tree,
+ dealii_cell->child(c),
+ p4est_child[c],
+ attached_data_pack_callbacks);
+ }
}
else if (!p4est_has_children && !dealii_cell->has_children())
{
- //this active cell didn't change
- typename internal::p4est::types<dim>::quadrant *q;
- q = static_cast<typename internal::p4est::types<dim>::quadrant*> (
- sc_array_index (const_cast<sc_array_t*>(&tree.quadrants), idx)
- );
- *static_cast<typename parallel::distributed::Triangulation<dim,spacedim>::CellStatus*>(q->p.user_data) = parallel::distributed::Triangulation<dim,spacedim>::CELL_PERSIST;
-
- for(typename callback_list_t::const_iterator it = attached_data_pack_callbacks.begin();
- it != attached_data_pack_callbacks.end();
- ++it)
- {
- void * ptr = static_cast<char*>(q->p.user_data) + (*it).first; //add offset
- ((*it).second)(dealii_cell,
- parallel::distributed::Triangulation<dim,spacedim>::CELL_PERSIST,
- ptr);
- }
+ //this active cell didn't change
+ typename internal::p4est::types<dim>::quadrant *q;
+ q = static_cast<typename internal::p4est::types<dim>::quadrant*> (
+ sc_array_index (const_cast<sc_array_t*>(&tree.quadrants), idx)
+ );
+ *static_cast<typename parallel::distributed::Triangulation<dim,spacedim>::CellStatus*>(q->p.user_data) = parallel::distributed::Triangulation<dim,spacedim>::CELL_PERSIST;
+
+ for(typename callback_list_t::const_iterator it = attached_data_pack_callbacks.begin();
+ it != attached_data_pack_callbacks.end();
+ ++it)
+ {
+ void * ptr = static_cast<char*>(q->p.user_data) + (*it).first; //add offset
+ ((*it).second)(dealii_cell,
+ parallel::distributed::Triangulation<dim,spacedim>::CELL_PERSIST,
+ ptr);
+ }
}
else if (p4est_has_children)
{
- //this cell got refined
-
- //attach to the first child, because
- // we can only attach to active
- // quadrants
- typename internal::p4est::types<dim>::quadrant
- p4est_child[GeometryInfo<dim>::max_children_per_cell];
- for (unsigned int c=0; c<GeometryInfo<dim>::max_children_per_cell; ++c)
- switch (dim)
- {
- case 2:
- P4EST_QUADRANT_INIT(&p4est_child[c]);
- break;
- case 3:
- P8EST_QUADRANT_INIT(&p4est_child[c]);
- break;
- default:
- Assert (false, ExcNotImplemented());
- }
-
- internal::p4est::functions<dim>::
- quadrant_childrenv (&p4est_cell, p4est_child);
- int child0_idx = sc_array_bsearch(const_cast<sc_array_t*>(&tree.quadrants),
- &p4est_child[0],
- internal::p4est::functions<dim>::quadrant_compare);
- Assert(child0_idx != -1, ExcMessage("the first child should exist as an active quadrant!"));
-
- typename internal::p4est::types<dim>::quadrant *q;
- q = static_cast<typename internal::p4est::types<dim>::quadrant*> (
- sc_array_index (const_cast<sc_array_t*>(&tree.quadrants), child0_idx)
- );
- *static_cast<typename parallel::distributed::Triangulation<dim,spacedim>::CellStatus*>(q->p.user_data) = parallel::distributed::Triangulation<dim,spacedim>::CELL_REFINE;
-
- for(typename callback_list_t::const_iterator it = attached_data_pack_callbacks.begin();
- it != attached_data_pack_callbacks.end();
- ++it)
- {
- void * ptr = static_cast<char*>(q->p.user_data) + (*it).first; //add offset
-
- ((*it).second)(dealii_cell,
- parallel::distributed::Triangulation<dim,spacedim>::CELL_REFINE,
- ptr);
- }
-
- //mark other childs as invalid, so that unpack only happens once
- for (unsigned int i=1;i<GeometryInfo<dim>::max_children_per_cell; ++i)
- {
- int child_idx = sc_array_bsearch(const_cast<sc_array_t*>(&tree.quadrants),
- &p4est_child[i],
- internal::p4est::functions<dim>::quadrant_compare);
- q = static_cast<typename internal::p4est::types<dim>::quadrant*> (
- sc_array_index (const_cast<sc_array_t*>(&tree.quadrants), child_idx)
- );
- *static_cast<typename parallel::distributed::Triangulation<dim,spacedim>::CellStatus*>(q->p.user_data) = parallel::distributed::Triangulation<dim,spacedim>::CELL_INVALID;
- }
+ //this cell got refined
+
+ //attach to the first child, because
+ // we can only attach to active
+ // quadrants
+ typename internal::p4est::types<dim>::quadrant
+ p4est_child[GeometryInfo<dim>::max_children_per_cell];
+ for (unsigned int c=0; c<GeometryInfo<dim>::max_children_per_cell; ++c)
+ switch (dim)
+ {
+ case 2:
+ P4EST_QUADRANT_INIT(&p4est_child[c]);
+ break;
+ case 3:
+ P8EST_QUADRANT_INIT(&p4est_child[c]);
+ break;
+ default:
+ Assert (false, ExcNotImplemented());
+ }
+
+ internal::p4est::functions<dim>::
+ quadrant_childrenv (&p4est_cell, p4est_child);
+ int child0_idx = sc_array_bsearch(const_cast<sc_array_t*>(&tree.quadrants),
+ &p4est_child[0],
+ internal::p4est::functions<dim>::quadrant_compare);
+ Assert(child0_idx != -1, ExcMessage("the first child should exist as an active quadrant!"));
+
+ typename internal::p4est::types<dim>::quadrant *q;
+ q = static_cast<typename internal::p4est::types<dim>::quadrant*> (
+ sc_array_index (const_cast<sc_array_t*>(&tree.quadrants), child0_idx)
+ );
+ *static_cast<typename parallel::distributed::Triangulation<dim,spacedim>::CellStatus*>(q->p.user_data) = parallel::distributed::Triangulation<dim,spacedim>::CELL_REFINE;
+
+ for(typename callback_list_t::const_iterator it = attached_data_pack_callbacks.begin();
+ it != attached_data_pack_callbacks.end();
+ ++it)
+ {
+ void * ptr = static_cast<char*>(q->p.user_data) + (*it).first; //add offset
+
+ ((*it).second)(dealii_cell,
+ parallel::distributed::Triangulation<dim,spacedim>::CELL_REFINE,
+ ptr);
+ }
+
+ //mark other childs as invalid, so that unpack only happens once
+ for (unsigned int i=1;i<GeometryInfo<dim>::max_children_per_cell; ++i)
+ {
+ int child_idx = sc_array_bsearch(const_cast<sc_array_t*>(&tree.quadrants),
+ &p4est_child[i],
+ internal::p4est::functions<dim>::quadrant_compare);
+ q = static_cast<typename internal::p4est::types<dim>::quadrant*> (
+ sc_array_index (const_cast<sc_array_t*>(&tree.quadrants), child_idx)
+ );
+ *static_cast<typename parallel::distributed::Triangulation<dim,spacedim>::CellStatus*>(q->p.user_data) = parallel::distributed::Triangulation<dim,spacedim>::CELL_INVALID;
+ }
}
else
{
- //it's children got coarsened into
- //this cell
- typename internal::p4est::types<dim>::quadrant *q;
- q = static_cast<typename internal::p4est::types<dim>::quadrant*> (
- sc_array_index (const_cast<sc_array_t*>(&tree.quadrants), idx)
- );
- *static_cast<typename parallel::distributed::Triangulation<dim,spacedim>::CellStatus*>(q->p.user_data) = parallel::distributed::Triangulation<dim,spacedim>::CELL_COARSEN;
-
- for(typename callback_list_t::const_iterator it = attached_data_pack_callbacks.begin();
- it != attached_data_pack_callbacks.end();
- ++it)
- {
- void * ptr = static_cast<char*>(q->p.user_data) + (*it).first; //add offset
- ((*it).second)(dealii_cell,
- parallel::distributed::Triangulation<dim,spacedim>::CELL_COARSEN,
- ptr);
- }
+ //it's children got coarsened into
+ //this cell
+ typename internal::p4est::types<dim>::quadrant *q;
+ q = static_cast<typename internal::p4est::types<dim>::quadrant*> (
+ sc_array_index (const_cast<sc_array_t*>(&tree.quadrants), idx)
+ );
+ *static_cast<typename parallel::distributed::Triangulation<dim,spacedim>::CellStatus*>(q->p.user_data) = parallel::distributed::Triangulation<dim,spacedim>::CELL_COARSEN;
+
+ for(typename callback_list_t::const_iterator it = attached_data_pack_callbacks.begin();
+ it != attached_data_pack_callbacks.end();
+ ++it)
+ {
+ void * ptr = static_cast<char*>(q->p.user_data) + (*it).first; //add offset
+ ((*it).second)(dealii_cell,
+ parallel::distributed::Triangulation<dim,spacedim>::CELL_COARSEN,
+ ptr);
+ }
}
}
template <int dim, int spacedim>
void
post_mesh_data_recursively (const typename internal::p4est::types<dim>::tree &tree,
- const typename Triangulation<dim,spacedim>::cell_iterator &dealii_cell,
- const typename Triangulation<dim,spacedim>::cell_iterator &parent_cell,
- const typename internal::p4est::types<dim>::quadrant &p4est_cell,
- const unsigned int offset,
- const typename std_cxx1x::function<
- void(typename parallel::distributed::Triangulation<dim,spacedim>::cell_iterator, typename parallel::distributed::Triangulation<dim,spacedim>::CellStatus, void*)
- > &unpack_callback)
+ const typename Triangulation<dim,spacedim>::cell_iterator &dealii_cell,
+ const typename Triangulation<dim,spacedim>::cell_iterator &parent_cell,
+ const typename internal::p4est::types<dim>::quadrant &p4est_cell,
+ const unsigned int offset,
+ const typename std_cxx1x::function<
+ void(typename parallel::distributed::Triangulation<dim,spacedim>::cell_iterator, typename parallel::distributed::Triangulation<dim,spacedim>::CellStatus, void*)
+ > &unpack_callback)
{
int idx = sc_array_bsearch(const_cast<sc_array_t*>(&tree.quadrants),
- &p4est_cell,
- internal::p4est::functions<dim>::quadrant_compare);
+ &p4est_cell,
+ internal::p4est::functions<dim>::quadrant_compare);
if (idx == -1 && (internal::p4est::functions<dim>::
- quadrant_overlaps_tree (const_cast<typename internal::p4est::types<dim>::tree*>(&tree),
- &p4est_cell)
- == false))
- // this quadrant and none of
- // it's children belong to us.
+ quadrant_overlaps_tree (const_cast<typename internal::p4est::types<dim>::tree*>(&tree),
+ &p4est_cell)
+ == false))
+ // this quadrant and none of
+ // it's children belong to us.
return;
const bool p4est_has_children = (idx == -1);
if (p4est_has_children)
{
- Assert(dealii_cell->has_children(), ExcInternalError());
-
- //recurse further
- typename internal::p4est::types<dim>::quadrant
- p4est_child[GeometryInfo<dim>::max_children_per_cell];
- for (unsigned int c=0; c<GeometryInfo<dim>::max_children_per_cell; ++c)
- switch (dim)
- {
- case 2:
- P4EST_QUADRANT_INIT(&p4est_child[c]);
- break;
- case 3:
- P8EST_QUADRANT_INIT(&p4est_child[c]);
- break;
- default:
- Assert (false, ExcNotImplemented());
- }
-
- internal::p4est::functions<dim>::
- quadrant_childrenv (&p4est_cell, p4est_child);
-
- for (unsigned int c=0;
- c<GeometryInfo<dim>::max_children_per_cell; ++c)
- {
- post_mesh_data_recursively<dim,spacedim> (tree,
- dealii_cell->child(c),
- dealii_cell,
- p4est_child[c],
- offset,
- unpack_callback);
- }
+ Assert(dealii_cell->has_children(), ExcInternalError());
+
+ //recurse further
+ typename internal::p4est::types<dim>::quadrant
+ p4est_child[GeometryInfo<dim>::max_children_per_cell];
+ for (unsigned int c=0; c<GeometryInfo<dim>::max_children_per_cell; ++c)
+ switch (dim)
+ {
+ case 2:
+ P4EST_QUADRANT_INIT(&p4est_child[c]);
+ break;
+ case 3:
+ P8EST_QUADRANT_INIT(&p4est_child[c]);
+ break;
+ default:
+ Assert (false, ExcNotImplemented());
+ }
+
+ internal::p4est::functions<dim>::
+ quadrant_childrenv (&p4est_cell, p4est_child);
+
+ for (unsigned int c=0;
+ c<GeometryInfo<dim>::max_children_per_cell; ++c)
+ {
+ post_mesh_data_recursively<dim,spacedim> (tree,
+ dealii_cell->child(c),
+ dealii_cell,
+ p4est_child[c],
+ offset,
+ unpack_callback);
+ }
}
else
{
- Assert(! dealii_cell->has_children(), ExcInternalError());
-
- typename internal::p4est::types<dim>::quadrant *q;
- q = static_cast<typename internal::p4est::types<dim>::quadrant*> (
- sc_array_index (const_cast<sc_array_t*>(&tree.quadrants), idx)
- );
-
- void * ptr = static_cast<char*>(q->p.user_data) + offset;
- typename parallel::distributed::Triangulation<dim,spacedim>::CellStatus
- status = * static_cast<
- typename parallel::distributed::Triangulation<dim,spacedim>::CellStatus*
- >(q->p.user_data);
- switch (status)
- {
- case parallel::distributed::Triangulation<dim,spacedim>::CELL_PERSIST:
- {
- unpack_callback(dealii_cell, status, ptr);
- break;
- }
- case parallel::distributed::Triangulation<dim,spacedim>::CELL_REFINE:
- {
- unpack_callback(parent_cell, status, ptr);
- break;
- }
- case parallel::distributed::Triangulation<dim,spacedim>::CELL_COARSEN:
- {
- unpack_callback(dealii_cell, status, ptr);
- break;
- }
- case parallel::distributed::Triangulation<dim,spacedim>::CELL_INVALID:
- {
- break;
- }
- default:
- AssertThrow (false, ExcInternalError());
- }
+ Assert(! dealii_cell->has_children(), ExcInternalError());
+
+ typename internal::p4est::types<dim>::quadrant *q;
+ q = static_cast<typename internal::p4est::types<dim>::quadrant*> (
+ sc_array_index (const_cast<sc_array_t*>(&tree.quadrants), idx)
+ );
+
+ void * ptr = static_cast<char*>(q->p.user_data) + offset;
+ typename parallel::distributed::Triangulation<dim,spacedim>::CellStatus
+ status = * static_cast<
+ typename parallel::distributed::Triangulation<dim,spacedim>::CellStatus*
+ >(q->p.user_data);
+ switch (status)
+ {
+ case parallel::distributed::Triangulation<dim,spacedim>::CELL_PERSIST:
+ {
+ unpack_callback(dealii_cell, status, ptr);
+ break;
+ }
+ case parallel::distributed::Triangulation<dim,spacedim>::CELL_REFINE:
+ {
+ unpack_callback(parent_cell, status, ptr);
+ break;
+ }
+ case parallel::distributed::Triangulation<dim,spacedim>::CELL_COARSEN:
+ {
+ unpack_callback(dealii_cell, status, ptr);
+ break;
+ }
+ case parallel::distributed::Triangulation<dim,spacedim>::CELL_INVALID:
+ {
+ break;
+ }
+ default:
+ AssertThrow (false, ExcInternalError());
+ }
}
}
- /**
- * A data structure that we use to store
- * which cells (indicated by
- * internal::p4est::types<dim>::quadrant objects) shall be
- * refined and which shall be coarsened.
- */
+ /**
+ * A data structure that we use to store
+ * which cells (indicated by
+ * internal::p4est::types<dim>::quadrant objects) shall be
+ * refined and which shall be coarsened.
+ */
template <int dim, int spacedim>
class RefineAndCoarsenList
{
public:
RefineAndCoarsenList (const Triangulation<dim,spacedim> &triangulation,
- const std::vector<unsigned int> &p4est_tree_to_coarse_cell_permutation,
- const types::subdomain_id_t my_subdomain,
- typename internal::p4est::types<dim>::forest &forest);
-
- /**
- * A callback function that we
- * pass to the p4est data
- * structures when a forest is
- * to be refined. The p4est
- * functions call it back with
- * a tree (the index of the
- * tree that grows out of a
- * given coarse cell) and a
- * refinement path from that
- * coarse cell to a
- * terminal/leaf cell. The
- * function returns whether the
- * corresponding cell in the
- * deal.II triangulation has
- * the refined flag set.
- */
+ const std::vector<unsigned int> &p4est_tree_to_coarse_cell_permutation,
+ const types::subdomain_id_t my_subdomain,
+ typename internal::p4est::types<dim>::forest &forest);
+
+ /**
+ * A callback function that we
+ * pass to the p4est data
+ * structures when a forest is
+ * to be refined. The p4est
+ * functions call it back with
+ * a tree (the index of the
+ * tree that grows out of a
+ * given coarse cell) and a
+ * refinement path from that
+ * coarse cell to a
+ * terminal/leaf cell. The
+ * function returns whether the
+ * corresponding cell in the
+ * deal.II triangulation has
+ * the refined flag set.
+ */
static
int
refine_callback (typename internal::p4est::types<dim>::forest *forest,
- typename internal::p4est::types<dim>::topidx coarse_cell_index,
- typename internal::p4est::types<dim>::quadrant *quadrant);
-
- /**
- * Same as the refine_callback
- * function, but return whether
- * all four of the given
- * children of a non-terminal
- * cell are to be coarsened
- * away.
- */
+ typename internal::p4est::types<dim>::topidx coarse_cell_index,
+ typename internal::p4est::types<dim>::quadrant *quadrant);
+
+ /**
+ * Same as the refine_callback
+ * function, but return whether
+ * all four of the given
+ * children of a non-terminal
+ * cell are to be coarsened
+ * away.
+ */
static
int
coarsen_callback (typename internal::p4est::types<dim>::forest *forest,
- typename internal::p4est::types<dim>::topidx coarse_cell_index,
- typename internal::p4est::types<dim>::quadrant *children[]);
+ typename internal::p4est::types<dim>::topidx coarse_cell_index,
+ typename internal::p4est::types<dim>::quadrant *children[]);
bool pointers_are_at_end () const;
typename internal::p4est::types<dim>::forest forest;
void build_lists (const typename Triangulation<dim,spacedim>::cell_iterator &cell,
- const typename internal::p4est::types<dim>::quadrant &p4est_cell,
- const unsigned int myid);
+ const typename internal::p4est::types<dim>::quadrant &p4est_cell,
+ const unsigned int myid);
};
pointers_are_at_end () const
{
return ((current_refine_pointer == refine_list.end())
- &&
- (current_coarsen_pointer == coarsen_list.end()));
+ &&
+ (current_coarsen_pointer == coarsen_list.end()));
}
template <int dim, int spacedim>
RefineAndCoarsenList<dim,spacedim>::
RefineAndCoarsenList (const Triangulation<dim,spacedim> &triangulation,
- const std::vector<unsigned int> &p4est_tree_to_coarse_cell_permutation,
- const types::subdomain_id_t my_subdomain,
- typename internal::p4est::types<dim>::forest &forest)
- :
- forest(forest)
+ const std::vector<unsigned int> &p4est_tree_to_coarse_cell_permutation,
+ const types::subdomain_id_t my_subdomain,
+ typename internal::p4est::types<dim>::forest &forest)
+ :
+ forest(forest)
{
- // count how many flags are set and
- // allocate that much memory
+ // count how many flags are set and
+ // allocate that much memory
unsigned int n_refine_flags = 0,
- n_coarsen_flags = 0;
+ n_coarsen_flags = 0;
for (typename Triangulation<dim,spacedim>::active_cell_iterator
- cell = triangulation.begin_active();
- cell != triangulation.end(); ++cell)
+ cell = triangulation.begin_active();
+ cell != triangulation.end(); ++cell)
{
- //skip cells that are not local
- if (cell->subdomain_id() != my_subdomain)
- continue;
-
- if (cell->refine_flag_set())
- ++n_refine_flags;
- else if (cell->coarsen_flag_set())
- ++n_coarsen_flags;
+ //skip cells that are not local
+ if (cell->subdomain_id() != my_subdomain)
+ continue;
+
+ if (cell->refine_flag_set())
+ ++n_refine_flags;
+ else if (cell->coarsen_flag_set())
+ ++n_coarsen_flags;
}
refine_list.reserve (n_refine_flags);
coarsen_list.reserve (n_coarsen_flags);
- // now build the lists of cells that
- // are flagged. note that p4est will
- // traverse its cells in the order in
- // which trees appear in the
- // forest. this order is not the same
- // as the order of coarse cells in the
- // deal.II Triangulation because we
- // have translated everything by the
- // coarse_cell_to_p4est_tree_permutation
- // permutation. in order to make sure
- // that the output array is already in
- // the correct order, traverse our
- // coarse cells in the same order in
- // which p4est will:
+ // now build the lists of cells that
+ // are flagged. note that p4est will
+ // traverse its cells in the order in
+ // which trees appear in the
+ // forest. this order is not the same
+ // as the order of coarse cells in the
+ // deal.II Triangulation because we
+ // have translated everything by the
+ // coarse_cell_to_p4est_tree_permutation
+ // permutation. in order to make sure
+ // that the output array is already in
+ // the correct order, traverse our
+ // coarse cells in the same order in
+ // which p4est will:
for (unsigned int c=0; c<triangulation.n_cells(0); ++c)
{
- unsigned int coarse_cell_index =
- p4est_tree_to_coarse_cell_permutation[c];
-
- const typename Triangulation<dim,spacedim>::cell_iterator
- cell (&triangulation, 0, coarse_cell_index);
-
- typename internal::p4est::types<dim>::quadrant p4est_cell;
- internal::p4est::functions<dim>::
- quadrant_set_morton (&p4est_cell,
- /*level=*/0,
- /*index=*/0);
- p4est_cell.p.which_tree = c;
- build_lists (cell, p4est_cell, my_subdomain);
+ unsigned int coarse_cell_index =
+ p4est_tree_to_coarse_cell_permutation[c];
+
+ const typename Triangulation<dim,spacedim>::cell_iterator
+ cell (&triangulation, 0, coarse_cell_index);
+
+ typename internal::p4est::types<dim>::quadrant p4est_cell;
+ internal::p4est::functions<dim>::
+ quadrant_set_morton (&p4est_cell,
+ /*level=*/0,
+ /*index=*/0);
+ p4est_cell.p.which_tree = c;
+ build_lists (cell, p4est_cell, my_subdomain);
}
Assert(refine_list.size() == n_refine_flags,
- ExcInternalError());
+ ExcInternalError());
Assert(coarsen_list.size() == n_coarsen_flags,
- ExcInternalError());
+ ExcInternalError());
- // make sure that our ordering in fact
- // worked
+ // make sure that our ordering in fact
+ // worked
for (unsigned int i=1; i<refine_list.size(); ++i)
Assert (refine_list[i].p.which_tree >=
- refine_list[i-1].p.which_tree,
- ExcInternalError());
+ refine_list[i-1].p.which_tree,
+ ExcInternalError());
for (unsigned int i=1; i<coarsen_list.size(); ++i)
Assert (coarsen_list[i].p.which_tree >=
- coarsen_list[i-1].p.which_tree,
- ExcInternalError());
+ coarsen_list[i-1].p.which_tree,
+ ExcInternalError());
current_refine_pointer = refine_list.begin();
current_coarsen_pointer = coarsen_list.begin();
void
RefineAndCoarsenList<dim,spacedim>::
build_lists (const typename Triangulation<dim,spacedim>::cell_iterator &cell,
- const typename internal::p4est::types<dim>::quadrant &p4est_cell,
- const types::subdomain_id_t my_subdomain)
+ const typename internal::p4est::types<dim>::quadrant &p4est_cell,
+ const types::subdomain_id_t my_subdomain)
{
if (!cell->has_children())
{
- if (cell->subdomain_id() == my_subdomain)
- {
- if (cell->refine_flag_set())
- refine_list.push_back (p4est_cell);
- else if (cell->coarsen_flag_set())
- coarsen_list.push_back (p4est_cell);
- }
+ if (cell->subdomain_id() == my_subdomain)
+ {
+ if (cell->refine_flag_set())
+ refine_list.push_back (p4est_cell);
+ else if (cell->coarsen_flag_set())
+ coarsen_list.push_back (p4est_cell);
+ }
}
else
{
- typename internal::p4est::types<dim>::quadrant
- p4est_child[GeometryInfo<dim>::max_children_per_cell];
- for (unsigned int c=0; c<GeometryInfo<dim>::max_children_per_cell; ++c)
- switch (dim)
- {
- case 2:
- P4EST_QUADRANT_INIT(&p4est_child[c]);
- break;
- case 3:
- P8EST_QUADRANT_INIT(&p4est_child[c]);
- break;
- default:
- Assert (false, ExcNotImplemented());
- }
- internal::p4est::functions<dim>::
- quadrant_childrenv (&p4est_cell,
- p4est_child);
- for (unsigned int c=0;
- c<GeometryInfo<dim>::max_children_per_cell; ++c)
- {
- p4est_child[c].p.which_tree = p4est_cell.p.which_tree;
- build_lists (cell->child(c),
- p4est_child[c],
- my_subdomain);
- }
+ typename internal::p4est::types<dim>::quadrant
+ p4est_child[GeometryInfo<dim>::max_children_per_cell];
+ for (unsigned int c=0; c<GeometryInfo<dim>::max_children_per_cell; ++c)
+ switch (dim)
+ {
+ case 2:
+ P4EST_QUADRANT_INIT(&p4est_child[c]);
+ break;
+ case 3:
+ P8EST_QUADRANT_INIT(&p4est_child[c]);
+ break;
+ default:
+ Assert (false, ExcNotImplemented());
+ }
+ internal::p4est::functions<dim>::
+ quadrant_childrenv (&p4est_cell,
+ p4est_child);
+ for (unsigned int c=0;
+ c<GeometryInfo<dim>::max_children_per_cell; ++c)
+ {
+ p4est_child[c].p.which_tree = p4est_cell.p.which_tree;
+ build_lists (cell->child(c),
+ p4est_child[c],
+ my_subdomain);
+ }
}
}
int
RefineAndCoarsenList<dim,spacedim>::
refine_callback (typename internal::p4est::types<dim>::forest *forest,
- typename internal::p4est::types<dim>::topidx coarse_cell_index,
- typename internal::p4est::types<dim>::quadrant *quadrant)
+ typename internal::p4est::types<dim>::topidx coarse_cell_index,
+ typename internal::p4est::types<dim>::quadrant *quadrant)
{
RefineAndCoarsenList<dim,spacedim> *this_object
= reinterpret_cast<RefineAndCoarsenList<dim,spacedim>*>(forest->user_pointer);
- // if there are no more cells in our
- // list the current cell can't be
- // flagged for refinement
+ // if there are no more cells in our
+ // list the current cell can't be
+ // flagged for refinement
if (this_object->current_refine_pointer == this_object->refine_list.end())
return false;
Assert (coarse_cell_index <=
- this_object->current_refine_pointer->p.which_tree,
- ExcInternalError());
+ this_object->current_refine_pointer->p.which_tree,
+ ExcInternalError());
- // if p4est hasn't yet reached the tree
- // of the next flagged cell the current
- // cell can't be flagged for refinement
+ // if p4est hasn't yet reached the tree
+ // of the next flagged cell the current
+ // cell can't be flagged for refinement
if (coarse_cell_index <
- this_object->current_refine_pointer->p.which_tree)
+ this_object->current_refine_pointer->p.which_tree)
return false;
- // now we're in the right tree in the
- // forest
+ // now we're in the right tree in the
+ // forest
Assert (coarse_cell_index <=
- this_object->current_refine_pointer->p.which_tree,
- ExcInternalError());
+ this_object->current_refine_pointer->p.which_tree,
+ ExcInternalError());
- // make sure that the p4est loop over
- // cells hasn't gotten ahead of our own
- // pointer
+ // make sure that the p4est loop over
+ // cells hasn't gotten ahead of our own
+ // pointer
Assert (internal::p4est::functions<dim>::
- quadrant_compare (quadrant,
- &*this_object->current_refine_pointer) <= 0,
- ExcInternalError());
+ quadrant_compare (quadrant,
+ &*this_object->current_refine_pointer) <= 0,
+ ExcInternalError());
- // now, if the p4est cell is one in the
- // list, it is supposed to be refined
+ // now, if the p4est cell is one in the
+ // list, it is supposed to be refined
if (internal::p4est::functions<dim>::
- quadrant_is_equal (quadrant, &*this_object->current_refine_pointer))
+ quadrant_is_equal (quadrant, &*this_object->current_refine_pointer))
{
- ++this_object->current_refine_pointer;
- return true;
+ ++this_object->current_refine_pointer;
+ return true;
}
- // p4est cell is not in list
+ // p4est cell is not in list
return false;
}
int
RefineAndCoarsenList<dim,spacedim>::
coarsen_callback (typename internal::p4est::types<dim>::forest *forest,
- typename internal::p4est::types<dim>::topidx coarse_cell_index,
- typename internal::p4est::types<dim>::quadrant *children[])
+ typename internal::p4est::types<dim>::topidx coarse_cell_index,
+ typename internal::p4est::types<dim>::quadrant *children[])
{
RefineAndCoarsenList<dim,spacedim> *this_object
= reinterpret_cast<RefineAndCoarsenList<dim,spacedim>*>(forest->user_pointer);
- // if there are no more cells in our
- // list the current cell can't be
- // flagged for coarsening
+ // if there are no more cells in our
+ // list the current cell can't be
+ // flagged for coarsening
if (this_object->current_coarsen_pointer ==
- this_object->coarsen_list.end())
+ this_object->coarsen_list.end())
return false;
Assert (coarse_cell_index <=
- this_object->current_coarsen_pointer->p.which_tree,
- ExcInternalError());
+ this_object->current_coarsen_pointer->p.which_tree,
+ ExcInternalError());
- // if p4est hasn't yet reached the tree
- // of the next flagged cell the current
- // cell can't be flagged for coarsening
+ // if p4est hasn't yet reached the tree
+ // of the next flagged cell the current
+ // cell can't be flagged for coarsening
if (coarse_cell_index <
- this_object->current_coarsen_pointer->p.which_tree)
+ this_object->current_coarsen_pointer->p.which_tree)
return false;
- // now we're in the right tree in the
- // forest
+ // now we're in the right tree in the
+ // forest
Assert (coarse_cell_index <=
- this_object->current_coarsen_pointer->p.which_tree,
- ExcInternalError());
+ this_object->current_coarsen_pointer->p.which_tree,
+ ExcInternalError());
- // make sure that the p4est loop over
- // cells hasn't gotten ahead of our own
- // pointer
+ // make sure that the p4est loop over
+ // cells hasn't gotten ahead of our own
+ // pointer
Assert (internal::p4est::functions<dim>::
- quadrant_compare (children[0],
- &*this_object->current_coarsen_pointer) <= 0,
- ExcInternalError());
+ quadrant_compare (children[0],
+ &*this_object->current_coarsen_pointer) <= 0,
+ ExcInternalError());
- // now, if the p4est cell is one in the
- // list, it is supposed to be coarsened
+ // now, if the p4est cell is one in the
+ // list, it is supposed to be coarsened
if (internal::p4est::functions<dim>::
- quadrant_is_equal (children[0],
- &*this_object->current_coarsen_pointer))
+ quadrant_is_equal (children[0],
+ &*this_object->current_coarsen_pointer))
{
- // move current pointer one up
- ++this_object->current_coarsen_pointer;
-
- // note that the next 3 cells in
- // our list need to correspond to
- // the other siblings of the cell
- // we have just found
- for (unsigned int c=1; c<GeometryInfo<dim>::max_children_per_cell; ++c)
- {
- Assert (internal::p4est::functions<dim>::
- quadrant_is_equal (children[c],
- &*this_object->current_coarsen_pointer),
- ExcInternalError());
- ++this_object->current_coarsen_pointer;
- }
-
- return true;
+ // move current pointer one up
+ ++this_object->current_coarsen_pointer;
+
+ // note that the next 3 cells in
+ // our list need to correspond to
+ // the other siblings of the cell
+ // we have just found
+ for (unsigned int c=1; c<GeometryInfo<dim>::max_children_per_cell; ++c)
+ {
+ Assert (internal::p4est::functions<dim>::
+ quadrant_is_equal (children[c],
+ &*this_object->current_coarsen_pointer),
+ ExcInternalError());
+ ++this_object->current_coarsen_pointer;
+ }
+
+ return true;
}
- // p4est cell is not in list
+ // p4est cell is not in list
return false;
}
}
struct InitFinalize
{
private:
- struct Singleton
- {
- Singleton ()
- {
- // ensure that the
- // initialization
- // code is run only
- // once, even if we
- // link with 1d, 2d,
- // and 3d libraries
- static bool initialized = false;
-
- if (initialized == false)
- {
- sc_init (MPI_COMM_WORLD,
- 0, 0, 0, SC_LP_SILENT);
- p4est_init (0, SC_LP_SILENT);
-
- initialized = true;
- }
- }
-
- ~Singleton ()
- {
- // same here
- static bool deinitialized = false;
-
- if (deinitialized == false)
- {
- // p4est has no
- // p4est_finalize
- // function
- sc_finalize ();
-
- deinitialized = true;
- }
- }
- };
+ struct Singleton
+ {
+ Singleton ()
+ {
+ // ensure that the
+ // initialization
+ // code is run only
+ // once, even if we
+ // link with 1d, 2d,
+ // and 3d libraries
+ static bool initialized = false;
+
+ if (initialized == false)
+ {
+ sc_init (MPI_COMM_WORLD,
+ 0, 0, 0, SC_LP_SILENT);
+ p4est_init (0, SC_LP_SILENT);
+
+ initialized = true;
+ }
+ }
+
+ ~Singleton ()
+ {
+ // same here
+ static bool deinitialized = false;
+
+ if (deinitialized == false)
+ {
+ // p4est has no
+ // p4est_finalize
+ // function
+ sc_finalize ();
+
+ deinitialized = true;
+ }
+ }
+ };
public:
- // do run the initialization code, at least the first time around we
- // get to this function
+ // do run the initialization code, at least the first time around we
+ // get to this function
static void do_initialize ()
- {
- static Singleton singleton;
- }
+ {
+ static Singleton singleton;
+ }
};
}
}
template <int dim, int spacedim>
Triangulation<dim,spacedim>::
Triangulation (MPI_Comm mpi_communicator,
- const typename dealii::Triangulation<dim,spacedim>::MeshSmoothing smooth_grid,
- const Settings settings_)
- :
- // do not check
- // for distorted
- // cells
- dealii::Triangulation<dim,spacedim>
- (smooth_grid,
- false),
- mpi_communicator (Utilities::MPI::
- duplicate_communicator(mpi_communicator)),
- settings(settings_),
- my_subdomain (Utilities::MPI::this_mpi_process (this->mpi_communicator)),
- triangulation_has_content (false),
- connectivity (0),
- parallel_forest (0),
- refinement_in_progress (false),
- attached_data_size(0),
- n_attached_datas(0),
- n_attached_deserialize(0)
+ const typename dealii::Triangulation<dim,spacedim>::MeshSmoothing smooth_grid,
+ const Settings settings_)
+ :
+ // do not check
+ // for distorted
+ // cells
+ dealii::Triangulation<dim,spacedim>
+ (smooth_grid,
+ false),
+ mpi_communicator (Utilities::MPI::
+ duplicate_communicator(mpi_communicator)),
+ settings(settings_),
+ my_subdomain (Utilities::MPI::this_mpi_process (this->mpi_communicator)),
+ triangulation_has_content (false),
+ connectivity (0),
+ parallel_forest (0),
+ refinement_in_progress (false),
+ attached_data_size(0),
+ n_attached_datas(0),
+ n_attached_deserialize(0)
{
- // initialize p4est. do this in a separate function since it has
- // to happen only once, even if we have triangulation objects
- // for several different space dimensions
+ // initialize p4est. do this in a separate function since it has
+ // to happen only once, even if we have triangulation objects
+ // for several different space dimensions
dealii::internal::p4est::InitFinalize::do_initialize ();
number_cache.n_locally_owned_active_cells
- .resize (Utilities::MPI::n_mpi_processes (mpi_communicator));
+ .resize (Utilities::MPI::n_mpi_processes (mpi_communicator));
}
clear ();
Assert (triangulation_has_content == false,
- ExcInternalError());
+ ExcInternalError());
Assert (connectivity == 0, ExcInternalError());
Assert (parallel_forest == 0, ExcInternalError());
Assert (refinement_in_progress == false, ExcInternalError());
- // get rid of the unique
- // communicator used here again
+ // get rid of the unique
+ // communicator used here again
MPI_Comm_free (&mpi_communicator);
}
void
Triangulation<dim,spacedim>::
create_triangulation (const std::vector<Point<spacedim> > &vertices,
- const std::vector<CellData<dim> > &cells,
- const SubCellData &subcelldata)
+ const std::vector<CellData<dim> > &cells,
+ const SubCellData &subcelldata)
{
try
- {
- dealii::Triangulation<dim,spacedim>::
- create_triangulation (vertices, cells, subcelldata);
- }
+ {
+ dealii::Triangulation<dim,spacedim>::
+ create_triangulation (vertices, cells, subcelldata);
+ }
catch (const typename dealii::Triangulation<dim,spacedim>::DistortedCellList &)
- {
- // the underlying
- // triangulation should not
- // be checking for
- // distorted cells
- AssertThrow (false, ExcInternalError());
- }
-
- // note that now we have some content in
- // the p4est objects and call the
- // functions that do the actual work
- // (which are dimension dependent, so
- // separate)
+ {
+ // the underlying
+ // triangulation should not
+ // be checking for
+ // distorted cells
+ AssertThrow (false, ExcInternalError());
+ }
+
+ // note that now we have some content in
+ // the p4est objects and call the
+ // functions that do the actual work
+ // (which are dimension dependent, so
+ // separate)
triangulation_has_content = true;
setup_coarse_cell_to_p4est_tree_permutation ();
copy_new_triangulation_to_p4est (dealii::internal::int2type<dim>());
try
- {
- copy_local_forest_to_triangulation ();
- }
+ {
+ copy_local_forest_to_triangulation ();
+ }
catch (const typename Triangulation<dim>::DistortedCellList &)
- {
- // the underlying
- // triangulation should not
- // be checking for
- // distorted cells
- AssertThrow (false, ExcInternalError());
- }
+ {
+ // the underlying
+ // triangulation should not
+ // be checking for
+ // distorted cells
+ AssertThrow (false, ExcInternalError());
+ }
update_number_cache ();
}
triangulation_has_content = false;
if (parallel_forest != 0)
- {
- dealii::internal::p4est::functions<dim>::destroy (parallel_forest);
- parallel_forest = 0;
- }
+ {
+ dealii::internal::p4est::functions<dim>::destroy (parallel_forest);
+ parallel_forest = 0;
+ }
if (connectivity != 0)
- {
- dealii::internal::p4est::functions<dim>::connectivity_destroy (connectivity);
- connectivity = 0;
- }
+ {
+ dealii::internal::p4est::functions<dim>::connectivity_destroy (connectivity);
+ connectivity = 0;
+ }
coarse_cell_to_p4est_tree_permutation.resize (0);
p4est_tree_to_coarse_cell_permutation.resize (0);
GridTools::get_face_connectivity_of_cells (*this, cell_connectivity);
coarse_cell_to_p4est_tree_permutation.resize (this->n_cells(0));
SparsityTools::
- reorder_Cuthill_McKee (cell_connectivity,
- coarse_cell_to_p4est_tree_permutation);
+ reorder_Cuthill_McKee (cell_connectivity,
+ coarse_cell_to_p4est_tree_permutation);
p4est_tree_to_coarse_cell_permutation
- = Utilities::invert_permutation (coarse_cell_to_p4est_tree_permutation);
+ = Utilities::invert_permutation (coarse_cell_to_p4est_tree_permutation);
}
Triangulation<dim,spacedim>::write_mesh_vtk (const char *file_basename) const
{
Assert (parallel_forest != 0,
- ExcMessage ("Can't produce output when no forest is created yet."));
+ ExcMessage ("Can't produce output when no forest is created yet."));
dealii::internal::p4est::functions<dim>::
- vtk_write_file (parallel_forest, 0, file_basename);
+ vtk_write_file (parallel_forest, 0, file_basename);
}
save(const char* filename) const
{
Assert(n_attached_deserialize==0,
- ExcMessage ("not all SolutionTransfer's got deserialized after the last load()"));
+ ExcMessage ("not all SolutionTransfer's got deserialized after the last load()"));
int real_data_size = 0;
if (attached_data_size>0)
- real_data_size = attached_data_size+sizeof(CellStatus);
+ real_data_size = attached_data_size+sizeof(CellStatus);
if (my_subdomain==0)
- {
- std::string fname=std::string(filename)+".info";
- std::ofstream f(fname.c_str());
- f << Utilities::System::get_n_mpi_processes (mpi_communicator) << " "
- << real_data_size << " "
- << attached_data_pack_callbacks.size() << std::endl;
- }
+ {
+ std::string fname=std::string(filename)+".info";
+ std::ofstream f(fname.c_str());
+ f << Utilities::System::get_n_mpi_processes (mpi_communicator) << " "
+ << real_data_size << " "
+ << attached_data_pack_callbacks.size() << std::endl;
+ }
if (attached_data_size>0)
- {
- const_cast<dealii::parallel::distributed::Triangulation<dim, spacedim>*>(this)
- ->attach_mesh_data();
- }
+ {
+ const_cast<dealii::parallel::distributed::Triangulation<dim, spacedim>*>(this)
+ ->attach_mesh_data();
+ }
dealii::internal::p4est::functions<dim>::save(filename, parallel_forest, attached_data_size>0);
dealii::parallel::distributed::Triangulation<dim, spacedim>* tria
- = const_cast<dealii::parallel::distributed::Triangulation<dim, spacedim>*>(this);
+ = const_cast<dealii::parallel::distributed::Triangulation<dim, spacedim>*>(this);
tria->n_attached_datas = 0;
tria->attached_data_size = 0;
tria->attached_data_pack_callbacks.clear();
- // and release the data
+ // and release the data
void * userptr = parallel_forest->user_pointer;
dealii::internal::p4est::functions<dim>::reset_data (parallel_forest, 0, NULL, NULL);
parallel_forest->user_pointer = userptr;
unsigned int numcpus, attached_size, attached_count;
{
- std::string fname=std::string(filename)+".info";
- std::ifstream f(fname.c_str());
- f >> numcpus >> attached_size >> attached_count;
- if (numcpus != Utilities::System::get_n_mpi_processes (mpi_communicator))
- throw ExcInternalError();
+ std::string fname=std::string(filename)+".info";
+ std::ifstream f(fname.c_str());
+ f >> numcpus >> attached_size >> attached_count;
+ if (numcpus != Utilities::System::get_n_mpi_processes (mpi_communicator))
+ throw ExcInternalError();
}
attached_data_size = 0;
n_attached_deserialize = attached_count;
parallel_forest = dealii::internal::p4est::functions<dim>::load (
- filename, mpi_communicator,
- attached_size, attached_size>0,
- this,
- &connectivity);
+ filename, mpi_communicator,
+ attached_size, attached_size>0,
+ this,
+ &connectivity);
try
- {
- copy_local_forest_to_triangulation ();
- }
+ {
+ copy_local_forest_to_triangulation ();
+ }
catch (const typename Triangulation<dim>::DistortedCellList &)
- {
- // the underlying
- // triangulation should not
- // be checking for
- // distorted cells
- AssertThrow (false, ExcInternalError());
- }
+ {
+ // the underlying
+ // triangulation should not
+ // be checking for
+ // distorted cells
+ AssertThrow (false, ExcInternalError());
+ }
update_number_cache ();
}
Triangulation<dim,spacedim>::get_checksum () const
{
Assert (parallel_forest != 0,
- ExcMessage ("Can't produce a check sum when no forest is created yet."));
+ ExcMessage ("Can't produce a check sum when no forest is created yet."));
return dealii::internal::p4est::functions<dim>::checksum (parallel_forest);
}
init_tree(const int dealii_coarse_cell_index) const
{
const unsigned int tree_index
- = coarse_cell_to_p4est_tree_permutation[dealii_coarse_cell_index];
+ = coarse_cell_to_p4est_tree_permutation[dealii_coarse_cell_index];
typename dealii::internal::p4est::types<dim>::tree *tree
- = static_cast<typename dealii::internal::p4est::types<dim>::tree*>
- (sc_array_index (parallel_forest->trees,
- tree_index));
+ = static_cast<typename dealii::internal::p4est::types<dim>::tree*>
+ (sc_array_index (parallel_forest->trees,
+ tree_index));
return tree;
}
Assert (this->n_cells(0) > 0, ExcInternalError());
Assert (this->n_levels() == 1, ExcInternalError());
- // data structures that counts how many
- // cells touch each vertex
- // (vertex_touch_count), and which cells
- // touch a given vertex (together with
- // the local numbering of that vertex
- // within the cells that touch it)
+ // data structures that counts how many
+ // cells touch each vertex
+ // (vertex_touch_count), and which cells
+ // touch a given vertex (together with
+ // the local numbering of that vertex
+ // within the cells that touch it)
std::vector<unsigned int> vertex_touch_count;
std::vector<
- std::list<
- std::pair<Triangulation<dim,spacedim>::active_cell_iterator,
- unsigned int> > >
- vertex_to_cell;
+ std::list<
+ std::pair<Triangulation<dim,spacedim>::active_cell_iterator,
+ unsigned int> > >
+ vertex_to_cell;
get_vertex_to_cell_mappings (*this,
- vertex_touch_count,
- vertex_to_cell);
+ vertex_touch_count,
+ vertex_to_cell);
const dealii::internal::p4est::types<2>::locidx
- num_vtt = std::accumulate (vertex_touch_count.begin(),
- vertex_touch_count.end(),
- 0);
-
- // now create a connectivity
- // object with the right sizes
- // for all arrays. set vertex
- // information only in debug
- // mode (saves a few bytes in
- // optimized mode)
+ num_vtt = std::accumulate (vertex_touch_count.begin(),
+ vertex_touch_count.end(),
+ 0);
+
+ // now create a connectivity
+ // object with the right sizes
+ // for all arrays. set vertex
+ // information only in debug
+ // mode (saves a few bytes in
+ // optimized mode)
const bool set_vertex_info
#ifdef DEBUG
- = true
+ = true
#else
- = false
+ = false
#endif
- ;
+ ;
connectivity
- = dealii::internal::p4est::functions<2>::
- connectivity_new ((set_vertex_info == true ? this->n_vertices() : 0),
- this->n_cells(0),
- this->n_vertices(),
- num_vtt);
+ = dealii::internal::p4est::functions<2>::
+ connectivity_new ((set_vertex_info == true ? this->n_vertices() : 0),
+ this->n_cells(0),
+ this->n_vertices(),
+ num_vtt);
set_vertex_and_cell_info (*this,
- vertex_touch_count,
- vertex_to_cell,
- coarse_cell_to_p4est_tree_permutation,
- set_vertex_info,
- connectivity);
+ vertex_touch_count,
+ vertex_to_cell,
+ coarse_cell_to_p4est_tree_permutation,
+ set_vertex_info,
+ connectivity);
Assert (p4est_connectivity_is_valid (connectivity) == 1,
- ExcInternalError());
+ ExcInternalError());
- // now create a forest out of the
- // connectivity data structure
+ // now create a forest out of the
+ // connectivity data structure
parallel_forest
- = dealii::internal::p4est::functions<2>::
- new_forest (mpi_communicator,
- connectivity,
- /* minimum initial number of quadrants per tree */ 0,
+ = dealii::internal::p4est::functions<2>::
+ new_forest (mpi_communicator,
+ connectivity,
+ /* minimum initial number of quadrants per tree */ 0,
/* minimum level of upfront refinement */ 0,
/* use uniform upfront refinement */ 1,
- /* user_data_size = */ 0,
- /* user_data_constructor = */ NULL,
- /* user_pointer */ this);
+ /* user_data_size = */ 0,
+ /* user_data_constructor = */ NULL,
+ /* user_pointer */ this);
}
- // TODO: This is a verbatim copy of the 2,2
- // case. However, we can't just specialize the
- // dim template argument, but let spacedim open
+ // TODO: This is a verbatim copy of the 2,2
+ // case. However, we can't just specialize the
+ // dim template argument, but let spacedim open
template <>
void
Triangulation<2,3>::copy_new_triangulation_to_p4est (dealii::internal::int2type<2>)
Assert (this->n_cells(0) > 0, ExcInternalError());
Assert (this->n_levels() == 1, ExcInternalError());
- // data structures that counts how many
- // cells touch each vertex
- // (vertex_touch_count), and which cells
- // touch a given vertex (together with
- // the local numbering of that vertex
- // within the cells that touch it)
+ // data structures that counts how many
+ // cells touch each vertex
+ // (vertex_touch_count), and which cells
+ // touch a given vertex (together with
+ // the local numbering of that vertex
+ // within the cells that touch it)
std::vector<unsigned int> vertex_touch_count;
std::vector<
- std::list<
- std::pair<Triangulation<dim,spacedim>::active_cell_iterator,
- unsigned int> > >
- vertex_to_cell;
+ std::list<
+ std::pair<Triangulation<dim,spacedim>::active_cell_iterator,
+ unsigned int> > >
+ vertex_to_cell;
get_vertex_to_cell_mappings (*this,
- vertex_touch_count,
- vertex_to_cell);
+ vertex_touch_count,
+ vertex_to_cell);
const dealii::internal::p4est::types<2>::locidx
- num_vtt = std::accumulate (vertex_touch_count.begin(),
- vertex_touch_count.end(),
- 0);
-
- // now create a connectivity
- // object with the right sizes
- // for all arrays. set vertex
- // information only in debug
- // mode (saves a few bytes in
- // optimized mode)
+ num_vtt = std::accumulate (vertex_touch_count.begin(),
+ vertex_touch_count.end(),
+ 0);
+
+ // now create a connectivity
+ // object with the right sizes
+ // for all arrays. set vertex
+ // information only in debug
+ // mode (saves a few bytes in
+ // optimized mode)
const bool set_vertex_info
#ifdef DEBUG
- = true
+ = true
#else
- = false
+ = false
#endif
- ;
+ ;
connectivity
- = dealii::internal::p4est::functions<2>::
- connectivity_new ((set_vertex_info == true ? this->n_vertices() : 0),
- this->n_cells(0),
- this->n_vertices(),
- num_vtt);
+ = dealii::internal::p4est::functions<2>::
+ connectivity_new ((set_vertex_info == true ? this->n_vertices() : 0),
+ this->n_cells(0),
+ this->n_vertices(),
+ num_vtt);
set_vertex_and_cell_info (*this,
- vertex_touch_count,
- vertex_to_cell,
- coarse_cell_to_p4est_tree_permutation,
- set_vertex_info,
- connectivity);
+ vertex_touch_count,
+ vertex_to_cell,
+ coarse_cell_to_p4est_tree_permutation,
+ set_vertex_info,
+ connectivity);
Assert (p4est_connectivity_is_valid (connectivity) == 1,
- ExcInternalError());
+ ExcInternalError());
- // now create a forest out of the
- // connectivity data structure
+ // now create a forest out of the
+ // connectivity data structure
parallel_forest
- = dealii::internal::p4est::functions<2>::
- new_forest (mpi_communicator,
- connectivity,
- /* minimum initial number of quadrants per tree */ 0,
+ = dealii::internal::p4est::functions<2>::
+ new_forest (mpi_communicator,
+ connectivity,
+ /* minimum initial number of quadrants per tree */ 0,
/* minimum level of upfront refinement */ 0,
/* use uniform upfront refinement */ 1,
- /* user_data_size = */ 0,
- /* user_data_constructor = */ NULL,
- /* user_pointer */ this);
+ /* user_data_size = */ 0,
+ /* user_data_constructor = */ NULL,
+ /* user_pointer */ this);
}
Assert (this->n_cells(0) > 0, ExcInternalError());
Assert (this->n_levels() == 1, ExcInternalError());
- // data structures that counts how many
- // cells touch each vertex
- // (vertex_touch_count), and which cells
- // touch a given vertex (together with
- // the local numbering of that vertex
- // within the cells that touch it)
+ // data structures that counts how many
+ // cells touch each vertex
+ // (vertex_touch_count), and which cells
+ // touch a given vertex (together with
+ // the local numbering of that vertex
+ // within the cells that touch it)
std::vector<unsigned int> vertex_touch_count;
std::vector<
- std::list<
- std::pair<Triangulation<3>::active_cell_iterator,
- unsigned int> > >
- vertex_to_cell;
+ std::list<
+ std::pair<Triangulation<3>::active_cell_iterator,
+ unsigned int> > >
+ vertex_to_cell;
get_vertex_to_cell_mappings (*this,
- vertex_touch_count,
- vertex_to_cell);
+ vertex_touch_count,
+ vertex_to_cell);
const dealii::internal::p4est::types<2>::locidx
- num_vtt = std::accumulate (vertex_touch_count.begin(),
- vertex_touch_count.end(),
- 0);
+ num_vtt = std::accumulate (vertex_touch_count.begin(),
+ vertex_touch_count.end(),
+ 0);
std::vector<unsigned int> edge_touch_count;
std::vector<
- std::list<
- std::pair<Triangulation<3>::active_cell_iterator,
- unsigned int> > >
- edge_to_cell;
+ std::list<
+ std::pair<Triangulation<3>::active_cell_iterator,
+ unsigned int> > >
+ edge_to_cell;
get_edge_to_cell_mappings (*this,
- edge_touch_count,
- edge_to_cell);
+ edge_touch_count,
+ edge_to_cell);
const dealii::internal::p4est::types<2>::locidx
- num_ett = std::accumulate (edge_touch_count.begin(),
- edge_touch_count.end(),
- 0);
- // now create a connectivity object with
- // the right sizes for all arrays
+ num_ett = std::accumulate (edge_touch_count.begin(),
+ edge_touch_count.end(),
+ 0);
+ // now create a connectivity object with
+ // the right sizes for all arrays
const bool set_vertex_info
#ifdef DEBUG
- = true
+ = true
#else
- = false
+ = false
#endif
- ;
+ ;
connectivity
- = dealii::internal::p4est::functions<3>::
- connectivity_new ((set_vertex_info == true ? this->n_vertices() : 0),
- this->n_cells(0),
- this->n_active_lines(),
- num_ett,
- this->n_vertices(),
- num_vtt);
+ = dealii::internal::p4est::functions<3>::
+ connectivity_new ((set_vertex_info == true ? this->n_vertices() : 0),
+ this->n_cells(0),
+ this->n_active_lines(),
+ num_ett,
+ this->n_vertices(),
+ num_vtt);
set_vertex_and_cell_info (*this,
- vertex_touch_count,
- vertex_to_cell,
- coarse_cell_to_p4est_tree_permutation,
- set_vertex_info,
- connectivity);
-
- // next to tree-to-edge
- // data. note that in p4est lines
- // are ordered as follows
- // *---3---* *---3---*
- // /| | / /|
- // 6 | 11 6 7 11
- // / 10 | / / |
- // * | | *---2---* |
- // | *---1---* | | *
- // | / / | 9 /
- // 8 4 5 8 | 5
- // |/ / | |/
- // *---0---* *---0---*
- // whereas in deal.II they are like this:
- // *---7---* *---7---*
- // /| | / /|
- // 4 | 11 4 5 11
- // / 10 | / / |
- // * | | *---6---* |
- // | *---3---* | | *
- // | / / | 9 /
- // 8 0 1 8 | 1
- // |/ / | |/
- // *---2---* *---2---*
+ vertex_touch_count,
+ vertex_to_cell,
+ coarse_cell_to_p4est_tree_permutation,
+ set_vertex_info,
+ connectivity);
+
+ // next to tree-to-edge
+ // data. note that in p4est lines
+ // are ordered as follows
+ // *---3---* *---3---*
+ // /| | / /|
+ // 6 | 11 6 7 11
+ // / 10 | / / |
+ // * | | *---2---* |
+ // | *---1---* | | *
+ // | / / | 9 /
+ // 8 4 5 8 | 5
+ // |/ / | |/
+ // *---0---* *---0---*
+ // whereas in deal.II they are like this:
+ // *---7---* *---7---*
+ // /| | / /|
+ // 4 | 11 4 5 11
+ // / 10 | / / |
+ // * | | *---6---* |
+ // | *---3---* | | *
+ // | / / | 9 /
+ // 8 0 1 8 | 1
+ // |/ / | |/
+ // *---2---* *---2---*
const unsigned int deal_to_p4est_line_index[12]
- = { 4, 5, 0, 1, 6, 7, 2, 3, 8, 9, 10, 11 } ;
+ = { 4, 5, 0, 1, 6, 7, 2, 3, 8, 9, 10, 11 } ;
for (Triangulation<dim,spacedim>::active_cell_iterator
- cell = this->begin_active();
- cell != this->end(); ++cell)
- {
- const unsigned int
- index = coarse_cell_to_p4est_tree_permutation[cell->index()];
- for (unsigned int e=0; e<GeometryInfo<3>::lines_per_cell; ++e)
- connectivity->tree_to_edge[index*GeometryInfo<3>::lines_per_cell+
- deal_to_p4est_line_index[e]]
- = cell->line(e)->index();
- }
-
- // now also set edge-to-tree
- // information
+ cell = this->begin_active();
+ cell != this->end(); ++cell)
+ {
+ const unsigned int
+ index = coarse_cell_to_p4est_tree_permutation[cell->index()];
+ for (unsigned int e=0; e<GeometryInfo<3>::lines_per_cell; ++e)
+ connectivity->tree_to_edge[index*GeometryInfo<3>::lines_per_cell+
+ deal_to_p4est_line_index[e]]
+ = cell->line(e)->index();
+ }
+
+ // now also set edge-to-tree
+ // information
connectivity->ett_offset[0] = 0;
std::partial_sum (edge_touch_count.begin(),
- edge_touch_count.end(),
- &connectivity->ett_offset[1]);
+ edge_touch_count.end(),
+ &connectivity->ett_offset[1]);
Assert (connectivity->ett_offset[this->n_active_lines()] ==
- num_ett,
- ExcInternalError());
+ num_ett,
+ ExcInternalError());
for (unsigned int v=0; v<this->n_active_lines(); ++v)
- {
- Assert (edge_to_cell[v].size() == edge_touch_count[v],
- ExcInternalError());
-
- std::list<std::pair
- <Triangulation<dim,spacedim>::active_cell_iterator,
- unsigned int> >::const_iterator
- p = edge_to_cell[v].begin();
- for (unsigned int c=0; c<edge_touch_count[v]; ++c, ++p)
- {
- connectivity->edge_to_tree[connectivity->ett_offset[v]+c]
- = coarse_cell_to_p4est_tree_permutation[p->first->index()];
- connectivity->edge_to_edge[connectivity->ett_offset[v]+c]
- = deal_to_p4est_line_index[p->second];
- }
- }
+ {
+ Assert (edge_to_cell[v].size() == edge_touch_count[v],
+ ExcInternalError());
+
+ std::list<std::pair
+ <Triangulation<dim,spacedim>::active_cell_iterator,
+ unsigned int> >::const_iterator
+ p = edge_to_cell[v].begin();
+ for (unsigned int c=0; c<edge_touch_count[v]; ++c, ++p)
+ {
+ connectivity->edge_to_tree[connectivity->ett_offset[v]+c]
+ = coarse_cell_to_p4est_tree_permutation[p->first->index()];
+ connectivity->edge_to_edge[connectivity->ett_offset[v]+c]
+ = deal_to_p4est_line_index[p->second];
+ }
+ }
Assert (p8est_connectivity_is_valid (connectivity) == 1,
- ExcInternalError());
+ ExcInternalError());
- // now create a forest out of the
- // connectivity data structure
+ // now create a forest out of the
+ // connectivity data structure
parallel_forest
- = dealii::internal::p4est::functions<3>::
- new_forest (mpi_communicator,
- connectivity,
- /* minimum initial number of quadrants per tree */ 0,
+ = dealii::internal::p4est::functions<3>::
+ new_forest (mpi_communicator,
+ connectivity,
+ /* minimum initial number of quadrants per tree */ 0,
/* minimum level of upfront refinement */ 0,
/* use uniform upfront refinement */ 1,
- /* user_data_size = */ 0,
- /* user_data_constructor = */ NULL,
- /* user_pointer */ this);
+ /* user_data_size = */ 0,
+ /* user_data_constructor = */ NULL,
+ /* user_pointer */ this);
}
void
Triangulation<dim,spacedim>::copy_local_forest_to_triangulation ()
{
- // disable mesh smoothing for
- // recreating the deal.II
- // triangulation, otherwise we might
- // not be able to reproduce the p4est
- // mesh exactly. We restore the
- // original smoothing at the end of
- // this function. Note that the
- // smoothing flag is used in the normal
- // refinement process.
+ // disable mesh smoothing for
+ // recreating the deal.II
+ // triangulation, otherwise we might
+ // not be able to reproduce the p4est
+ // mesh exactly. We restore the
+ // original smoothing at the end of
+ // this function. Note that the
+ // smoothing flag is used in the normal
+ // refinement process.
typename Triangulation<dim,spacedim>::MeshSmoothing
- save_smooth = this->smooth_grid;
+ save_smooth = this->smooth_grid;
this->smooth_grid = dealii::Triangulation<dim,spacedim>::none;
bool mesh_changed = false;
- // remove all deal.II refinements. Note that we could skip this and
- // start from our current state, because the algorithm later coarsens as
- // necessary. This has the advantage of being faster when large parts
- // of the local partition changes (likely) and gives a deterministic
- // ordering of the cells (useful for snapshot/resume).
- // TODO: is there a more efficient way to do this?
+ // remove all deal.II refinements. Note that we could skip this and
+ // start from our current state, because the algorithm later coarsens as
+ // necessary. This has the advantage of being faster when large parts
+ // of the local partition changes (likely) and gives a deterministic
+ // ordering of the cells (useful for snapshot/resume).
+ // TODO: is there a more efficient way to do this?
if (settings & mesh_reconstruction_after_repartitioning)
while (this->begin_active()->level() > 0)
{
for (typename Triangulation<dim, spacedim>::active_cell_iterator
- cell = this->begin_active();
+ cell = this->begin_active();
cell != this->end();
++cell)
{
}
catch (const typename Triangulation<dim, spacedim>::DistortedCellList &)
{
- // the underlying
- // triangulation should not
- // be checking for
- // distorted cells
+ // the underlying
+ // triangulation should not
+ // be checking for
+ // distorted cells
AssertThrow (false, ExcInternalError());
}
}
- // query p4est for the ghost cells
+ // query p4est for the ghost cells
typename dealii::internal::p4est::types<dim>::ghost * ghostlayer;
ghostlayer = dealii::internal::p4est::functions<dim>::ghost_new (parallel_forest,
- (dim == 2
- ?
- typename dealii::internal::p4est::types<dim>::
- balance_type(P4EST_BALANCE_CORNER)
- :
- typename dealii::internal::p4est::types<dim>::
- balance_type(P8EST_BALANCE_CORNER)));
+ (dim == 2
+ ?
+ typename dealii::internal::p4est::types<dim>::
+ balance_type(P4EST_BALANCE_CORNER)
+ :
+ typename dealii::internal::p4est::types<dim>::
+ balance_type(P8EST_BALANCE_CORNER)));
Assert (ghostlayer, ExcInternalError());
- //set all cells to artificial
+ //set all cells to artificial
for (typename Triangulation<dim,spacedim>::cell_iterator
- cell = this->begin(0);
- cell != this->end(0);
- ++cell)
- cell->recursively_set_subdomain_id(types::artificial_subdomain_id);
+ cell = this->begin(0);
+ cell != this->end(0);
+ ++cell)
+ cell->recursively_set_subdomain_id(types::artificial_subdomain_id);
do
- {
- for (typename Triangulation<dim,spacedim>::cell_iterator
- cell = this->begin(0);
- cell != this->end(0);
- ++cell)
- {
- // if this processor
- // stores no part of the
- // forest that comes out
- // of this coarse grid
- // cell, then we need to
- // delete all children of
- // this cell (the coarse
- // grid cell remains)
- if (tree_exists_locally<dim,spacedim>(parallel_forest,
- coarse_cell_to_p4est_tree_permutation[cell->index()])
- == false)
- {
- delete_all_children<dim,spacedim> (cell);
- cell->set_subdomain_id (types::artificial_subdomain_id);
- }
-
- else
- {
-
- // this processor
- // stores at least a
- // part of the tree
- // that comes out of
- // this cell.
-
-
- typename dealii::internal::p4est::types<dim>::quadrant p4est_coarse_cell;
- typename dealii::internal::p4est::types<dim>::tree *tree =
- init_tree(cell->index());
-
- dealii::internal::p4est::init_coarse_quadrant<dim>(p4est_coarse_cell);
-
- match_tree_recursively<dim,spacedim> (*tree, cell,
- p4est_coarse_cell,
- *parallel_forest,
- my_subdomain);
- }
- }
-
- // check mesh for ghostcells,
- // refine as neccessary.
- // iterate over every ghostquadrant,
- // find corresponding deal coarsecell
- // and recurse.
- typename dealii::internal::p4est::types<dim>::quadrant * quadr;
- unsigned int ghost_owner=0;
-
- for (unsigned int g_idx=0;g_idx<ghostlayer->ghosts.elem_count;++g_idx)
- {
- while (g_idx >= (unsigned int)ghostlayer->proc_offsets[ghost_owner+1])
- ++ghost_owner;
-
- quadr = static_cast<typename dealii::internal::p4est::types<dim>::quadrant *>
- ( sc_array_index(&ghostlayer->ghosts, g_idx) );
-
- unsigned int coarse_cell_index =
- p4est_tree_to_coarse_cell_permutation[quadr->p.piggy3.which_tree];
-
- const typename Triangulation<dim,spacedim>::cell_iterator
- cell (this, 0U, coarse_cell_index);
-
- typename dealii::internal::p4est::types<dim>::quadrant p4est_coarse_cell;
- dealii::internal::p4est::init_coarse_quadrant<dim> (p4est_coarse_cell);
-
- match_quadrant_recursively<dim,spacedim> (p4est_coarse_cell, cell, *quadr,
- *parallel_forest, ghost_owner);
- }
-
- // fix all the flags to make
- // sure we have a consistent
- // mesh
- this->prepare_coarsening_and_refinement ();
-
- // see if any flags are still set
- mesh_changed = false;
- for (typename Triangulation<dim,spacedim>::active_cell_iterator
- cell = this->begin_active();
- cell != this->end();
- ++cell)
- if (cell->refine_flag_set() || cell->coarsen_flag_set())
- {
- mesh_changed = true;
- break;
- }
-
- // actually do the refinement
- // but prevent the refinement
- // hook below from taking
- // over
- const bool saved_refinement_in_progress = refinement_in_progress;
- refinement_in_progress = true;
-
- try
- {
- this->execute_coarsening_and_refinement();
- }
- catch (const typename Triangulation<dim,spacedim>::DistortedCellList &)
- {
- // the underlying
- // triangulation should not
- // be checking for
- // distorted cells
- AssertThrow (false, ExcInternalError());
- }
-
- refinement_in_progress = saved_refinement_in_progress;
- }
+ {
+ for (typename Triangulation<dim,spacedim>::cell_iterator
+ cell = this->begin(0);
+ cell != this->end(0);
+ ++cell)
+ {
+ // if this processor
+ // stores no part of the
+ // forest that comes out
+ // of this coarse grid
+ // cell, then we need to
+ // delete all children of
+ // this cell (the coarse
+ // grid cell remains)
+ if (tree_exists_locally<dim,spacedim>(parallel_forest,
+ coarse_cell_to_p4est_tree_permutation[cell->index()])
+ == false)
+ {
+ delete_all_children<dim,spacedim> (cell);
+ cell->set_subdomain_id (types::artificial_subdomain_id);
+ }
+
+ else
+ {
+
+ // this processor
+ // stores at least a
+ // part of the tree
+ // that comes out of
+ // this cell.
+
+
+ typename dealii::internal::p4est::types<dim>::quadrant p4est_coarse_cell;
+ typename dealii::internal::p4est::types<dim>::tree *tree =
+ init_tree(cell->index());
+
+ dealii::internal::p4est::init_coarse_quadrant<dim>(p4est_coarse_cell);
+
+ match_tree_recursively<dim,spacedim> (*tree, cell,
+ p4est_coarse_cell,
+ *parallel_forest,
+ my_subdomain);
+ }
+ }
+
+ // check mesh for ghostcells,
+ // refine as neccessary.
+ // iterate over every ghostquadrant,
+ // find corresponding deal coarsecell
+ // and recurse.
+ typename dealii::internal::p4est::types<dim>::quadrant * quadr;
+ unsigned int ghost_owner=0;
+
+ for (unsigned int g_idx=0;g_idx<ghostlayer->ghosts.elem_count;++g_idx)
+ {
+ while (g_idx >= (unsigned int)ghostlayer->proc_offsets[ghost_owner+1])
+ ++ghost_owner;
+
+ quadr = static_cast<typename dealii::internal::p4est::types<dim>::quadrant *>
+ ( sc_array_index(&ghostlayer->ghosts, g_idx) );
+
+ unsigned int coarse_cell_index =
+ p4est_tree_to_coarse_cell_permutation[quadr->p.piggy3.which_tree];
+
+ const typename Triangulation<dim,spacedim>::cell_iterator
+ cell (this, 0U, coarse_cell_index);
+
+ typename dealii::internal::p4est::types<dim>::quadrant p4est_coarse_cell;
+ dealii::internal::p4est::init_coarse_quadrant<dim> (p4est_coarse_cell);
+
+ match_quadrant_recursively<dim,spacedim> (p4est_coarse_cell, cell, *quadr,
+ *parallel_forest, ghost_owner);
+ }
+
+ // fix all the flags to make
+ // sure we have a consistent
+ // mesh
+ this->prepare_coarsening_and_refinement ();
+
+ // see if any flags are still set
+ mesh_changed = false;
+ for (typename Triangulation<dim,spacedim>::active_cell_iterator
+ cell = this->begin_active();
+ cell != this->end();
+ ++cell)
+ if (cell->refine_flag_set() || cell->coarsen_flag_set())
+ {
+ mesh_changed = true;
+ break;
+ }
+
+ // actually do the refinement
+ // but prevent the refinement
+ // hook below from taking
+ // over
+ const bool saved_refinement_in_progress = refinement_in_progress;
+ refinement_in_progress = true;
+
+ try
+ {
+ this->execute_coarsening_and_refinement();
+ }
+ catch (const typename Triangulation<dim,spacedim>::DistortedCellList &)
+ {
+ // the underlying
+ // triangulation should not
+ // be checking for
+ // distorted cells
+ AssertThrow (false, ExcInternalError());
+ }
+
+ refinement_in_progress = saved_refinement_in_progress;
+ }
while (mesh_changed);
#ifdef DEBUG
- // check if correct number of ghosts is created
+ // check if correct number of ghosts is created
unsigned int num_ghosts = 0;
for (typename Triangulation<dim,spacedim>::active_cell_iterator
- cell = this->begin_active();
- cell != this->end();
- ++cell)
- {
- if (cell->subdomain_id() != my_subdomain
- &&
- cell->subdomain_id() != types::artificial_subdomain_id)
- ++num_ghosts;
- }
+ cell = this->begin_active();
+ cell != this->end();
+ ++cell)
+ {
+ if (cell->subdomain_id() != my_subdomain
+ &&
+ cell->subdomain_id() != types::artificial_subdomain_id)
+ ++num_ghosts;
+ }
Assert( num_ghosts == ghostlayer->ghosts.elem_count, ExcInternalError());
#endif
- // check that our local copy has
- // exactly as many cells as the
- // p4est original (at least if we
- // are on only one processor);
- // for parallel computations, we
- // want to check that we have at
- // least as many as p4est stores
- // locally (in the future we
- // should check that we have
- // exactly as many non-artificial
- // cells as
- // parallel_forest->local_num_quadrants)
+ // check that our local copy has
+ // exactly as many cells as the
+ // p4est original (at least if we
+ // are on only one processor);
+ // for parallel computations, we
+ // want to check that we have at
+ // least as many as p4est stores
+ // locally (in the future we
+ // should check that we have
+ // exactly as many non-artificial
+ // cells as
+ // parallel_forest->local_num_quadrants)
{
- const unsigned int total_local_cells = this->n_active_cells();
-
- if (Utilities::MPI::n_mpi_processes (mpi_communicator) == 1)
- Assert (static_cast<unsigned int>(parallel_forest->local_num_quadrants) ==
- total_local_cells,
- ExcInternalError())
- else
- Assert (static_cast<unsigned int>(parallel_forest->local_num_quadrants) <=
- total_local_cells,
- ExcInternalError());
-
- // count the number of owned, active
- // cells and compare with p4est.
- unsigned int n_owned = 0;
- for (typename Triangulation<dim,spacedim>::active_cell_iterator
- cell = this->begin_active();
- cell != this->end(); ++cell)
- {
- if (cell->subdomain_id() == my_subdomain)
- ++n_owned;
- }
-
- Assert(static_cast<unsigned int>(parallel_forest->local_num_quadrants) ==
- n_owned, ExcInternalError());
+ const unsigned int total_local_cells = this->n_active_cells();
+
+ if (Utilities::MPI::n_mpi_processes (mpi_communicator) == 1)
+ Assert (static_cast<unsigned int>(parallel_forest->local_num_quadrants) ==
+ total_local_cells,
+ ExcInternalError())
+ else
+ Assert (static_cast<unsigned int>(parallel_forest->local_num_quadrants) <=
+ total_local_cells,
+ ExcInternalError());
+
+ // count the number of owned, active
+ // cells and compare with p4est.
+ unsigned int n_owned = 0;
+ for (typename Triangulation<dim,spacedim>::active_cell_iterator
+ cell = this->begin_active();
+ cell != this->end(); ++cell)
+ {
+ if (cell->subdomain_id() == my_subdomain)
+ ++n_owned;
+ }
+
+ Assert(static_cast<unsigned int>(parallel_forest->local_num_quadrants) ==
+ n_owned, ExcInternalError());
}
void
Triangulation<dim, spacedim>::execute_coarsening_and_refinement ()
{
- // first make sure that recursive
- // calls are handled correctly
+ // first make sure that recursive
+ // calls are handled correctly
if (refinement_in_progress == true)
- {
- dealii::Triangulation<dim,spacedim>::execute_coarsening_and_refinement ();
- return;
- }
-
- // now do the work we're
- // supposed to do when we are
- // in charge
+ {
+ dealii::Triangulation<dim,spacedim>::execute_coarsening_and_refinement ();
+ return;
+ }
+
+ // now do the work we're
+ // supposed to do when we are
+ // in charge
refinement_in_progress = true;
this->prepare_coarsening_and_refinement ();
- // make sure all flags are
- // cleared on cells we don't
- // own, since nothing good can
- // come of that if they are
- // still around
+ // make sure all flags are
+ // cleared on cells we don't
+ // own, since nothing good can
+ // come of that if they are
+ // still around
for (typename Triangulation<dim,spacedim>::active_cell_iterator
- cell = this->begin_active();
- cell != this->end(); ++cell)
- if (cell->is_ghost() || cell->is_artificial())
- {
- cell->clear_refine_flag ();
- cell->clear_coarsen_flag ();
- }
- else
- // if this is a cell we do
- // own, make sure they are
- // not refined
- // anisotropically since we
- // don't support this
- if (cell->refine_flag_set())
- Assert (cell->refine_flag_set() ==
- RefinementPossibilities<dim>::isotropic_refinement,
- ExcMessage ("This class does not support anisotropic refinement"));
-
-
-
- // count how many cells will be refined
- // and coarsened, and allocate that much
- // memory
+ cell = this->begin_active();
+ cell != this->end(); ++cell)
+ if (cell->is_ghost() || cell->is_artificial())
+ {
+ cell->clear_refine_flag ();
+ cell->clear_coarsen_flag ();
+ }
+ else
+ // if this is a cell we do
+ // own, make sure they are
+ // not refined
+ // anisotropically since we
+ // don't support this
+ if (cell->refine_flag_set())
+ Assert (cell->refine_flag_set() ==
+ RefinementPossibilities<dim>::isotropic_refinement,
+ ExcMessage ("This class does not support anisotropic refinement"));
+
+
+
+ // count how many cells will be refined
+ // and coarsened, and allocate that much
+ // memory
RefineAndCoarsenList<dim,spacedim>
- refine_and_coarsen_list (*this,
- p4est_tree_to_coarse_cell_permutation,
- my_subdomain,
- *parallel_forest);
-
- // copy refine and coarsen flags into
- // p4est and execute the refinement and
- // coarsening. this uses the
- // refine_and_coarsen_list just built,
- // which is communicated to the callback
- // functions through the
- // user_pointer
+ refine_and_coarsen_list (*this,
+ p4est_tree_to_coarse_cell_permutation,
+ my_subdomain,
+ *parallel_forest);
+
+ // copy refine and coarsen flags into
+ // p4est and execute the refinement and
+ // coarsening. this uses the
+ // refine_and_coarsen_list just built,
+ // which is communicated to the callback
+ // functions through the
+ // user_pointer
Assert (parallel_forest->user_pointer == this,
- ExcInternalError());
+ ExcInternalError());
parallel_forest->user_pointer = &refine_and_coarsen_list;
dealii::internal::p4est::functions<dim>::
- refine (parallel_forest, /* refine_recursive */ false,
- &RefineAndCoarsenList<dim,spacedim>::refine_callback,
- /*init_callback=*/NULL);
+ refine (parallel_forest, /* refine_recursive */ false,
+ &RefineAndCoarsenList<dim,spacedim>::refine_callback,
+ /*init_callback=*/NULL);
dealii::internal::p4est::functions<dim>::
- coarsen (parallel_forest, /* coarsen_recursive */ false,
- &RefineAndCoarsenList<dim,spacedim>::coarsen_callback,
- /*init_callback=*/NULL);
+ coarsen (parallel_forest, /* coarsen_recursive */ false,
+ &RefineAndCoarsenList<dim,spacedim>::coarsen_callback,
+ /*init_callback=*/NULL);
- // make sure all cells in the lists have
- // been consumed
+ // make sure all cells in the lists have
+ // been consumed
Assert (refine_and_coarsen_list.pointers_are_at_end(),
- ExcInternalError());
+ ExcInternalError());
- // reset the pointer
+ // reset the pointer
parallel_forest->user_pointer = this;
- // enforce 2:1 hanging node condition
+ // enforce 2:1 hanging node condition
dealii::internal::p4est::functions<dim>::
- balance (parallel_forest,
- /* face and corner balance */
- (dim == 2
- ?
- typename dealii::internal::p4est::types<dim>::
- balance_type(P4EST_BALANCE_FULL)
- :
- typename dealii::internal::p4est::types<dim>::
- balance_type(P8EST_BALANCE_FULL)),
- /*init_callback=*/NULL);
-
-
- // before repartitioning the mesh let
- // others attach mesh related info
- // (such as SolutionTransfer data) to
- // the p4est
+ balance (parallel_forest,
+ /* face and corner balance */
+ (dim == 2
+ ?
+ typename dealii::internal::p4est::types<dim>::
+ balance_type(P4EST_BALANCE_FULL)
+ :
+ typename dealii::internal::p4est::types<dim>::
+ balance_type(P8EST_BALANCE_FULL)),
+ /*init_callback=*/NULL);
+
+
+ // before repartitioning the mesh let
+ // others attach mesh related info
+ // (such as SolutionTransfer data) to
+ // the p4est
attach_mesh_data();
- // partition the new mesh between
- // all processors
+ // partition the new mesh between
+ // all processors
dealii::internal::p4est::functions<dim>::
- partition (parallel_forest,
+ partition (parallel_forest,
/* prepare coarsening */ 1,
- /* weight_callback */ NULL);
-
- // finally copy back from local
- // part of tree to deal.II
- // triangulation. before doing
- // so, make sure there are no
- // refine or coarsen flags
- // pending
+ /* weight_callback */ NULL);
+
+ // finally copy back from local
+ // part of tree to deal.II
+ // triangulation. before doing
+ // so, make sure there are no
+ // refine or coarsen flags
+ // pending
for (typename Triangulation<dim,spacedim>::active_cell_iterator
- cell = this->begin_active();
- cell != this->end(); ++cell)
- {
- cell->clear_refine_flag();
- cell->clear_coarsen_flag();
- }
+ cell = this->begin_active();
+ cell != this->end(); ++cell)
+ {
+ cell->clear_refine_flag();
+ cell->clear_coarsen_flag();
+ }
try
- {
- copy_local_forest_to_triangulation ();
- }
+ {
+ copy_local_forest_to_triangulation ();
+ }
catch (const typename Triangulation<dim>::DistortedCellList &)
- {
- // the underlying
- // triangulation should not
- // be checking for
- // distorted cells
- AssertThrow (false, ExcInternalError());
- }
+ {
+ // the underlying
+ // triangulation should not
+ // be checking for
+ // distorted cells
+ AssertThrow (false, ExcInternalError());
+ }
refinement_in_progress = false;
Triangulation<dim,spacedim>::update_number_cache ()
{
Assert (number_cache.n_locally_owned_active_cells.size()
- ==
- Utilities::MPI::n_mpi_processes (mpi_communicator),
- ExcInternalError());
+ ==
+ Utilities::MPI::n_mpi_processes (mpi_communicator),
+ ExcInternalError());
std::fill (number_cache.n_locally_owned_active_cells.begin(),
- number_cache.n_locally_owned_active_cells.end(),
- 0);
+ number_cache.n_locally_owned_active_cells.end(),
+ 0);
if (this->n_levels() > 0)
- for (typename Triangulation<dim,spacedim>::active_cell_iterator
- cell = this->begin_active();
- cell != this->end(); ++cell)
- if (cell->subdomain_id() == my_subdomain)
- ++number_cache.n_locally_owned_active_cells[my_subdomain];
+ for (typename Triangulation<dim,spacedim>::active_cell_iterator
+ cell = this->begin_active();
+ cell != this->end(); ++cell)
+ if (cell->subdomain_id() == my_subdomain)
+ ++number_cache.n_locally_owned_active_cells[my_subdomain];
unsigned int send_value
- = number_cache.n_locally_owned_active_cells[my_subdomain];
+ = number_cache.n_locally_owned_active_cells[my_subdomain];
MPI_Allgather (&send_value,
- 1,
- MPI_UNSIGNED,
- &number_cache.n_locally_owned_active_cells[0],
- 1,
- MPI_UNSIGNED,
- mpi_communicator);
+ 1,
+ MPI_UNSIGNED,
+ &number_cache.n_locally_owned_active_cells[0],
+ 1,
+ MPI_UNSIGNED,
+ mpi_communicator);
number_cache.n_global_active_cells
- = std::accumulate (number_cache.n_locally_owned_active_cells.begin(),
- number_cache.n_locally_owned_active_cells.end(),
- 0);
+ = std::accumulate (number_cache.n_locally_owned_active_cells.begin(),
+ number_cache.n_locally_owned_active_cells.end(),
+ 0);
}
unsigned int
Triangulation<dim,spacedim>::
register_data_attach (const std::size_t size,
- const std_cxx1x::function<void(const cell_iterator&,
- const CellStatus,
- void*)> & pack_callback)
+ const std_cxx1x::function<void(const cell_iterator&,
+ const CellStatus,
+ void*)> & pack_callback)
{
Assert(size>0, ExcMessage("register_data_attach(), size==0"));
Assert(attached_data_pack_callbacks.size()==n_attached_datas,
- ExcMessage("register_data_attach(), not all data has been unpacked last time?"));
+ ExcMessage("register_data_attach(), not all data has been unpacked last time?"));
unsigned int offset = attached_data_size+sizeof(CellStatus);
++n_attached_datas;
void
Triangulation<dim,spacedim>::
notify_ready_to_unpack (const unsigned int offset,
- const std_cxx1x::function<void (const cell_iterator&,
- const CellStatus,
- const void*)> & unpack_callback)
+ const std_cxx1x::function<void (const cell_iterator&,
+ const CellStatus,
+ const void*)> & unpack_callback)
{
Assert (offset < attached_data_size, ExcMessage ("invalid offset in notify_ready_to_unpack()"));
Assert (n_attached_datas > 0, ExcMessage ("notify_ready_to_unpack() called too often"));
- // Recurse over p4est and hand the caller the data back
+ // Recurse over p4est and hand the caller the data back
for (typename Triangulation<dim, spacedim>::cell_iterator
- cell = this->begin (0);
+ cell = this->begin (0);
cell != this->end (0);
++cell)
{
- //skip coarse cells, that are not ours
+ //skip coarse cells, that are not ours
if (tree_exists_locally<dim, spacedim> (parallel_forest,
coarse_cell_to_p4est_tree_permutation[cell->index() ])
== false)
dealii::internal::p4est::init_coarse_quadrant<dim> (p4est_coarse_cell);
- // parent_cell is not correct here,
- // but is only used in a refined
- // cell
+ // parent_cell is not correct here,
+ // but is only used in a refined
+ // cell
post_mesh_data_recursively<dim, spacedim> (*tree,
- cell,
- cell,
- p4est_coarse_cell,
- offset,
- unpack_callback);
+ cell,
+ cell,
+ p4est_coarse_cell,
+ offset,
+ unpack_callback);
}
--n_attached_datas;
attached_data_pack_callbacks.pop_front();
}
- // important: only remove data if we are not in the deserialization
- // process. There, each SolutionTransfer registers and unpacks
- // before the next one does this, so n_attached_datas is only 1 here.
- // This would destroy the saved data before the second SolutionTransfer
- // can get it. This created a bug that is documented in
- // tests/mpi/p4est_save_03 with more than one SolutionTransfer.
+ // important: only remove data if we are not in the deserialization
+ // process. There, each SolutionTransfer registers and unpacks
+ // before the next one does this, so n_attached_datas is only 1 here.
+ // This would destroy the saved data before the second SolutionTransfer
+ // can get it. This created a bug that is documented in
+ // tests/mpi/p4est_save_03 with more than one SolutionTransfer.
if (!n_attached_datas && n_attached_deserialize == 0)
{
- // everybody got his data, time for cleanup!
+ // everybody got his data, time for cleanup!
attached_data_size = 0;
attached_data_pack_callbacks.clear();
- // and release the data
+ // and release the data
void * userptr = parallel_forest->user_pointer;
dealii::internal::p4est::functions<dim>::reset_data (parallel_forest, 0, NULL, NULL);
parallel_forest->user_pointer = userptr;
Triangulation<dim,spacedim>::memory_consumption () const
{
std::size_t mem=
- this->dealii::Triangulation<dim,spacedim>::memory_consumption()
- + MemoryConsumption::memory_consumption(mpi_communicator)
- + MemoryConsumption::memory_consumption(my_subdomain)
- + MemoryConsumption::memory_consumption(triangulation_has_content)
- + MemoryConsumption::memory_consumption(number_cache.n_locally_owned_active_cells)
- + MemoryConsumption::memory_consumption(number_cache.n_global_active_cells)
- + MemoryConsumption::memory_consumption(connectivity)
- + MemoryConsumption::memory_consumption(parallel_forest)
- + MemoryConsumption::memory_consumption(refinement_in_progress)
- + MemoryConsumption::memory_consumption(attached_data_size)
- + MemoryConsumption::memory_consumption(n_attached_datas)
-// + MemoryConsumption::memory_consumption(attached_data_pack_callbacks) //TODO[TH]: how?
- + MemoryConsumption::memory_consumption(coarse_cell_to_p4est_tree_permutation)
- + MemoryConsumption::memory_consumption(p4est_tree_to_coarse_cell_permutation)
- + memory_consumption_p4est();
+ this->dealii::Triangulation<dim,spacedim>::memory_consumption()
+ + MemoryConsumption::memory_consumption(mpi_communicator)
+ + MemoryConsumption::memory_consumption(my_subdomain)
+ + MemoryConsumption::memory_consumption(triangulation_has_content)
+ + MemoryConsumption::memory_consumption(number_cache.n_locally_owned_active_cells)
+ + MemoryConsumption::memory_consumption(number_cache.n_global_active_cells)
+ + MemoryConsumption::memory_consumption(connectivity)
+ + MemoryConsumption::memory_consumption(parallel_forest)
+ + MemoryConsumption::memory_consumption(refinement_in_progress)
+ + MemoryConsumption::memory_consumption(attached_data_size)
+ + MemoryConsumption::memory_consumption(n_attached_datas)
+// + MemoryConsumption::memory_consumption(attached_data_pack_callbacks) //TODO[TH]: how?
+ + MemoryConsumption::memory_consumption(coarse_cell_to_p4est_tree_permutation)
+ + MemoryConsumption::memory_consumption(p4est_tree_to_coarse_cell_permutation)
+ + memory_consumption_p4est();
return mem;
}
Triangulation<dim,spacedim>::memory_consumption_p4est () const
{
return dealii::internal::p4est::functions<dim>::forest_memory_used(parallel_forest)
- + dealii::internal::p4est::functions<dim>::connectivity_memory_used(connectivity);
+ + dealii::internal::p4est::functions<dim>::connectivity_memory_used(connectivity);
}
Triangulation<dim,spacedim>::
attach_mesh_data()
{
- // determine size of memory in bytes to
- // attach to each cell. This needs to
- // be constant because of p4est.
+ // determine size of memory in bytes to
+ // attach to each cell. This needs to
+ // be constant because of p4est.
if (attached_data_size==0)
- {
- Assert(n_attached_datas==0, ExcInternalError());
+ {
+ Assert(n_attached_datas==0, ExcInternalError());
- //nothing to do
- return;
- }
+ //nothing to do
+ return;
+ }
- // realloc user_data in p4est
+ // realloc user_data in p4est
void * userptr = parallel_forest->user_pointer;
dealii::internal::p4est::functions<dim>::reset_data (parallel_forest,
- attached_data_size+sizeof(CellStatus),
- NULL, NULL);
+ attached_data_size+sizeof(CellStatus),
+ NULL, NULL);
parallel_forest->user_pointer = userptr;
- // Recurse over p4est and Triangulation
- // to find refined/coarsened/kept
- // cells. Then query and attach the data.
+ // Recurse over p4est and Triangulation
+ // to find refined/coarsened/kept
+ // cells. Then query and attach the data.
for (typename Triangulation<dim,spacedim>::cell_iterator
- cell = this->begin(0);
- cell != this->end(0);
- ++cell)
- {
- //skip coarse cells, that are not ours
- if (tree_exists_locally<dim,spacedim>(parallel_forest,
- coarse_cell_to_p4est_tree_permutation[cell->index()])
- == false)
- continue;
-
- typename dealii::internal::p4est::types<dim>::quadrant p4est_coarse_cell;
- typename dealii::internal::p4est::types<dim>::tree *tree =
- init_tree(cell->index());
-
- dealii::internal::p4est::init_coarse_quadrant<dim>(p4est_coarse_cell);
-
- attach_mesh_data_recursively<dim,spacedim>(*tree,
- cell,
- p4est_coarse_cell,
- attached_data_pack_callbacks);
- }
+ cell = this->begin(0);
+ cell != this->end(0);
+ ++cell)
+ {
+ //skip coarse cells, that are not ours
+ if (tree_exists_locally<dim,spacedim>(parallel_forest,
+ coarse_cell_to_p4est_tree_permutation[cell->index()])
+ == false)
+ continue;
+
+ typename dealii::internal::p4est::types<dim>::quadrant p4est_coarse_cell;
+ typename dealii::internal::p4est::types<dim>::tree *tree =
+ init_tree(cell->index());
+
+ dealii::internal::p4est::init_coarse_quadrant<dim>(p4est_coarse_cell);
+
+ attach_mesh_data_recursively<dim,spacedim>(*tree,
+ cell,
+ p4est_coarse_cell,
+ attached_data_pack_callbacks);
+ }
}
- // TODO: again problems with specialization in
- // only one template argument
+ // TODO: again problems with specialization in
+ // only one template argument
template <>
Triangulation<1,1>::Triangulation (MPI_Comm)
{
// $Id$
// Version: $Name$
//
-// Copyright (C) 2009, 2010 by the deal.II authors
+// Copyright (C) 2009, 2010, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
local_renumbering.resize(fe.n_dofs_per_cell());
FETools::compute_block_renumbering(fe,
- local_renumbering,
- sizes, false);
+ local_renumbering,
+ sizes, false);
bi_local.reinit(sizes);
}
// $Id$
// Version: $Name$
//
-// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 by the deal.II authors
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
template <class DH>
typename internal::DoFHandler::Iterators<DH>::cell_iterator
DoFCellAccessor<DH>::neighbor_child_on_subface (const unsigned int face,
- const unsigned int subface) const
+ const unsigned int subface) const
{
const TriaIterator<CellAccessor<dim,spacedim> > q
= CellAccessor<dim,spacedim>::neighbor_child_on_subface (face, subface);
return
typename internal::DoFHandler::Iterators<DH>::cell_iterator (this->tria,
- q->level (),
- q->index (),
- this->dof_handler);
+ q->level (),
+ q->index (),
+ this->dof_handler);
}
void
DoFCellAccessor<DH>::
get_interpolated_dof_values (const InputVector &values,
- Vector<number> &interpolated_values) const
+ Vector<number> &interpolated_values) const
{
const FiniteElement<dim,spacedim> &fe = this->get_fe();
const unsigned int dofs_per_cell = fe.dofs_per_cell;
Assert (this->dof_handler != 0,
- typename BaseClass::ExcInvalidObject());
+ typename BaseClass::ExcInvalidObject());
Assert (&fe != 0,
- typename BaseClass::ExcInvalidObject());
+ typename BaseClass::ExcInvalidObject());
Assert (interpolated_values.size() == dofs_per_cell,
- typename BaseClass::ExcVectorDoesNotMatch());
+ typename BaseClass::ExcVectorDoesNotMatch());
Assert (values.size() == this->dof_handler->n_dofs(),
- typename BaseClass::ExcVectorDoesNotMatch());
+ typename BaseClass::ExcVectorDoesNotMatch());
if (!this->has_children())
- // if this cell has no children: simply
- // return the exact values on this cell
+ // if this cell has no children: simply
+ // return the exact values on this cell
this->get_dof_values (values, interpolated_values);
else
- // otherwise clobber them from the children
+ // otherwise clobber them from the children
{
Vector<number> tmp1(dofs_per_cell);
Vector<number> tmp2(dofs_per_cell);
restriction_is_additive[i] = fe.restriction_is_additive(i);
for (unsigned int child=0; child<this->n_children(); ++child)
- {
- // get the values from the present
- // child, if necessary by
- // interpolation itself
- this->child(child)->get_interpolated_dof_values (values,
- tmp1);
- // interpolate these to the mother
- // cell
- fe.get_restriction_matrix(child, this->refinement_case()).vmult (tmp2, tmp1);
+ {
+ // get the values from the present
+ // child, if necessary by
+ // interpolation itself
+ this->child(child)->get_interpolated_dof_values (values,
+ tmp1);
+ // interpolate these to the mother
+ // cell
+ fe.get_restriction_matrix(child, this->refinement_case()).vmult (tmp2, tmp1);
// and add up or set them
// in the output vector
- for (unsigned int i=0; i<dofs_per_cell; ++i)
+ for (unsigned int i=0; i<dofs_per_cell; ++i)
if (restriction_is_additive[i])
interpolated_values(i) += tmp2(i);
else
if (tmp2(i) != number())
interpolated_values(i) = tmp2(i);
- }
+ }
}
}
void
DoFCellAccessor<DH>::
set_dof_values_by_interpolation (const Vector<number> &local_values,
- OutputVector &values) const
+ OutputVector &values) const
{
const unsigned int dofs_per_cell = this->get_fe().dofs_per_cell;
Assert (this->dof_handler != 0,
- typename BaseClass::ExcInvalidObject());
+ typename BaseClass::ExcInvalidObject());
Assert (&this->get_fe() != 0,
- typename BaseClass::ExcInvalidObject());
+ typename BaseClass::ExcInvalidObject());
Assert (local_values.size() == dofs_per_cell,
- typename BaseClass::ExcVectorDoesNotMatch());
+ typename BaseClass::ExcVectorDoesNotMatch());
Assert (values.size() == this->dof_handler->n_dofs(),
- typename BaseClass::ExcVectorDoesNotMatch());
+ typename BaseClass::ExcVectorDoesNotMatch());
if (!this->has_children())
// if this cell has no children: simply
- // set the values on this cell
+ // set the values on this cell
this->set_dof_values (local_values, values);
else
- // otherwise distribute them to the children
+ // otherwise distribute them to the children
{
Vector<number> tmp(dofs_per_cell);
for (unsigned int child=0; child<this->n_children(); ++child)
- {
- // prolong the given data
- // to the present cell
- this->get_fe().get_prolongation_matrix(child, this->refinement_case())
+ {
+ // prolong the given data
+ // to the present cell
+ this->get_fe().get_prolongation_matrix(child, this->refinement_case())
.vmult (tmp, local_values);
- this->child(child)->set_dof_values_by_interpolation (tmp, values);
- }
+ this->child(child)->set_dof_values_by_interpolation (tmp, values);
+ }
}
}
// $Id$
// Version: $Name$
//
-// Copyright (C) 2006, 2010, 2011 by the deal.II authors
+// Copyright (C) 2006, 2010, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
DoFFaces<3>::memory_consumption () const
{
return (MemoryConsumption::memory_consumption (quads) +
- MemoryConsumption::memory_consumption (lines) );
+ MemoryConsumption::memory_consumption (lines) );
}
}
}
// $Id$
// Version: $Name$
//
-// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 by the deal.II authors
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
{
namespace DoFHandler
{
- // access class
- // dealii::DoFHandler instead of
- // namespace internal::DoFHandler
+ // access class
+ // dealii::DoFHandler instead of
+ // namespace internal::DoFHandler
using dealii::DoFHandler;
*/
struct Implementation
{
- /**
- * Implement the function of same name in
- * the mother class.
- */
- template <int spacedim>
- static
- unsigned int
- max_couplings_between_dofs (const DoFHandler<1,spacedim> &dof_handler)
- {
- return std::min(3*dof_handler.selected_fe->dofs_per_vertex +
- 2*dof_handler.selected_fe->dofs_per_line,
- dof_handler.n_dofs());
- }
-
-
-
- template <int spacedim>
- static
- unsigned int
- max_couplings_between_dofs (const DoFHandler<2,spacedim> &dof_handler)
- {
-
- // get these numbers by drawing pictures
- // and counting...
- // example:
- // | | |
- // --x-----x--x--X--
- // | | | |
- // | x--x--x
- // | | | |
- // --x--x--*--x--x--
- // | | | |
- // x--x--x |
- // | | | |
- // --X--x--x-----x--
- // | | |
- // x = vertices connected with center vertex *;
- // = total of 19
- // (the X vertices are connected with * if
- // the vertices adjacent to X are hanging
- // nodes)
- // count lines -> 28 (don't forget to count
- // mother and children separately!)
- unsigned int max_couplings;
- switch (dof_handler.tria->max_adjacent_cells())
- {
- case 4:
- max_couplings=19*dof_handler.selected_fe->dofs_per_vertex +
- 28*dof_handler.selected_fe->dofs_per_line +
- 8*dof_handler.selected_fe->dofs_per_quad;
- break;
- case 5:
- max_couplings=21*dof_handler.selected_fe->dofs_per_vertex +
- 31*dof_handler.selected_fe->dofs_per_line +
- 9*dof_handler.selected_fe->dofs_per_quad;
- break;
- case 6:
- max_couplings=28*dof_handler.selected_fe->dofs_per_vertex +
- 42*dof_handler.selected_fe->dofs_per_line +
- 12*dof_handler.selected_fe->dofs_per_quad;
- break;
- case 7:
- max_couplings=30*dof_handler.selected_fe->dofs_per_vertex +
- 45*dof_handler.selected_fe->dofs_per_line +
- 13*dof_handler.selected_fe->dofs_per_quad;
- break;
- case 8:
- max_couplings=37*dof_handler.selected_fe->dofs_per_vertex +
- 56*dof_handler.selected_fe->dofs_per_line +
- 16*dof_handler.selected_fe->dofs_per_quad;
- break;
-
- // the following
- // numbers are not
- // based on actual
- // counting but by
- // extrapolating the
- // number sequences
- // from the previous
- // ones (for example,
- // for dofs_per_vertex,
- // the sequence above
- // is 19, 21, 28, 30,
- // 37, and is continued
- // as follows):
- case 9:
- max_couplings=39*dof_handler.selected_fe->dofs_per_vertex +
- 59*dof_handler.selected_fe->dofs_per_line +
- 17*dof_handler.selected_fe->dofs_per_quad;
- break;
- case 10:
- max_couplings=46*dof_handler.selected_fe->dofs_per_vertex +
- 70*dof_handler.selected_fe->dofs_per_line +
- 20*dof_handler.selected_fe->dofs_per_quad;
- break;
- case 11:
- max_couplings=48*dof_handler.selected_fe->dofs_per_vertex +
- 73*dof_handler.selected_fe->dofs_per_line +
- 21*dof_handler.selected_fe->dofs_per_quad;
- break;
- case 12:
- max_couplings=55*dof_handler.selected_fe->dofs_per_vertex +
- 84*dof_handler.selected_fe->dofs_per_line +
- 24*dof_handler.selected_fe->dofs_per_quad;
- break;
- case 13:
- max_couplings=57*dof_handler.selected_fe->dofs_per_vertex +
- 87*dof_handler.selected_fe->dofs_per_line +
- 25*dof_handler.selected_fe->dofs_per_quad;
- break;
- case 14:
- max_couplings=63*dof_handler.selected_fe->dofs_per_vertex +
- 98*dof_handler.selected_fe->dofs_per_line +
- 28*dof_handler.selected_fe->dofs_per_quad;
- break;
- case 15:
- max_couplings=65*dof_handler.selected_fe->dofs_per_vertex +
- 103*dof_handler.selected_fe->dofs_per_line +
- 29*dof_handler.selected_fe->dofs_per_quad;
- break;
- case 16:
- max_couplings=72*dof_handler.selected_fe->dofs_per_vertex +
- 114*dof_handler.selected_fe->dofs_per_line +
- 32*dof_handler.selected_fe->dofs_per_quad;
- break;
-
- default:
- Assert (false, ExcNotImplemented());
- max_couplings=0;
- }
- return std::min(max_couplings,dof_handler.n_dofs());
- }
-
-
- template <int spacedim>
- static
- unsigned int
- max_couplings_between_dofs (const DoFHandler<3,spacedim> &dof_handler)
- {
+ /**
+ * Implement the function of same name in
+ * the mother class.
+ */
+ template <int spacedim>
+ static
+ unsigned int
+ max_couplings_between_dofs (const DoFHandler<1,spacedim> &dof_handler)
+ {
+ return std::min(3*dof_handler.selected_fe->dofs_per_vertex +
+ 2*dof_handler.selected_fe->dofs_per_line,
+ dof_handler.n_dofs());
+ }
+
+
+
+ template <int spacedim>
+ static
+ unsigned int
+ max_couplings_between_dofs (const DoFHandler<2,spacedim> &dof_handler)
+ {
+
+ // get these numbers by drawing pictures
+ // and counting...
+ // example:
+ // | | |
+ // --x-----x--x--X--
+ // | | | |
+ // | x--x--x
+ // | | | |
+ // --x--x--*--x--x--
+ // | | | |
+ // x--x--x |
+ // | | | |
+ // --X--x--x-----x--
+ // | | |
+ // x = vertices connected with center vertex *;
+ // = total of 19
+ // (the X vertices are connected with * if
+ // the vertices adjacent to X are hanging
+ // nodes)
+ // count lines -> 28 (don't forget to count
+ // mother and children separately!)
+ unsigned int max_couplings;
+ switch (dof_handler.tria->max_adjacent_cells())
+ {
+ case 4:
+ max_couplings=19*dof_handler.selected_fe->dofs_per_vertex +
+ 28*dof_handler.selected_fe->dofs_per_line +
+ 8*dof_handler.selected_fe->dofs_per_quad;
+ break;
+ case 5:
+ max_couplings=21*dof_handler.selected_fe->dofs_per_vertex +
+ 31*dof_handler.selected_fe->dofs_per_line +
+ 9*dof_handler.selected_fe->dofs_per_quad;
+ break;
+ case 6:
+ max_couplings=28*dof_handler.selected_fe->dofs_per_vertex +
+ 42*dof_handler.selected_fe->dofs_per_line +
+ 12*dof_handler.selected_fe->dofs_per_quad;
+ break;
+ case 7:
+ max_couplings=30*dof_handler.selected_fe->dofs_per_vertex +
+ 45*dof_handler.selected_fe->dofs_per_line +
+ 13*dof_handler.selected_fe->dofs_per_quad;
+ break;
+ case 8:
+ max_couplings=37*dof_handler.selected_fe->dofs_per_vertex +
+ 56*dof_handler.selected_fe->dofs_per_line +
+ 16*dof_handler.selected_fe->dofs_per_quad;
+ break;
+
+ // the following
+ // numbers are not
+ // based on actual
+ // counting but by
+ // extrapolating the
+ // number sequences
+ // from the previous
+ // ones (for example,
+ // for dofs_per_vertex,
+ // the sequence above
+ // is 19, 21, 28, 30,
+ // 37, and is continued
+ // as follows):
+ case 9:
+ max_couplings=39*dof_handler.selected_fe->dofs_per_vertex +
+ 59*dof_handler.selected_fe->dofs_per_line +
+ 17*dof_handler.selected_fe->dofs_per_quad;
+ break;
+ case 10:
+ max_couplings=46*dof_handler.selected_fe->dofs_per_vertex +
+ 70*dof_handler.selected_fe->dofs_per_line +
+ 20*dof_handler.selected_fe->dofs_per_quad;
+ break;
+ case 11:
+ max_couplings=48*dof_handler.selected_fe->dofs_per_vertex +
+ 73*dof_handler.selected_fe->dofs_per_line +
+ 21*dof_handler.selected_fe->dofs_per_quad;
+ break;
+ case 12:
+ max_couplings=55*dof_handler.selected_fe->dofs_per_vertex +
+ 84*dof_handler.selected_fe->dofs_per_line +
+ 24*dof_handler.selected_fe->dofs_per_quad;
+ break;
+ case 13:
+ max_couplings=57*dof_handler.selected_fe->dofs_per_vertex +
+ 87*dof_handler.selected_fe->dofs_per_line +
+ 25*dof_handler.selected_fe->dofs_per_quad;
+ break;
+ case 14:
+ max_couplings=63*dof_handler.selected_fe->dofs_per_vertex +
+ 98*dof_handler.selected_fe->dofs_per_line +
+ 28*dof_handler.selected_fe->dofs_per_quad;
+ break;
+ case 15:
+ max_couplings=65*dof_handler.selected_fe->dofs_per_vertex +
+ 103*dof_handler.selected_fe->dofs_per_line +
+ 29*dof_handler.selected_fe->dofs_per_quad;
+ break;
+ case 16:
+ max_couplings=72*dof_handler.selected_fe->dofs_per_vertex +
+ 114*dof_handler.selected_fe->dofs_per_line +
+ 32*dof_handler.selected_fe->dofs_per_quad;
+ break;
+
+ default:
+ Assert (false, ExcNotImplemented());
+ max_couplings=0;
+ }
+ return std::min(max_couplings,dof_handler.n_dofs());
+ }
+
+
+ template <int spacedim>
+ static
+ unsigned int
+ max_couplings_between_dofs (const DoFHandler<3,spacedim> &dof_handler)
+ {
//TODO:[?] Invent significantly better estimates than the ones in this function
- // doing the same thing here is a
- // rather complicated thing, compared
- // to the 2d case, since it is hard
- // to draw pictures with several
- // refined hexahedra :-) so I
- // presently only give a coarse
- // estimate for the case that at most
- // 8 hexes meet at each vertex
- //
- // can anyone give better estimate
- // here?
- const unsigned int max_adjacent_cells
- = dof_handler.tria->max_adjacent_cells();
-
- unsigned int max_couplings;
- if (max_adjacent_cells <= 8)
- max_couplings=7*7*7*dof_handler.selected_fe->dofs_per_vertex +
- 7*6*7*3*dof_handler.selected_fe->dofs_per_line +
- 9*4*7*3*dof_handler.selected_fe->dofs_per_quad +
- 27*dof_handler.selected_fe->dofs_per_hex;
- else
- {
- Assert (false, ExcNotImplemented());
- max_couplings=0;
- }
-
- return std::min(max_couplings,dof_handler.n_dofs());
- }
-
-
- /**
- * Reserve enough space in the
- * <tt>levels[]</tt> objects to store the
- * numbers of the degrees of freedom
- * needed for the given element. The
- * given element is that one which
- * was selected when calling
- * @p distribute_dofs the last time.
- */
- template <int spacedim>
- static
- void reserve_space (DoFHandler<1,spacedim> &dof_handler)
- {
- dof_handler.vertex_dofs
- .resize(dof_handler.tria->n_vertices() *
- dof_handler.selected_fe->dofs_per_vertex,
- DoFHandler<1,spacedim>::invalid_dof_index);
-
- for (unsigned int i=0; i<dof_handler.tria->n_levels(); ++i)
- {
- dof_handler.levels
- .push_back (new internal::DoFHandler::DoFLevel<1>);
-
- dof_handler.levels.back()->lines.dofs
- .resize (dof_handler.tria->n_raw_lines(i) *
- dof_handler.selected_fe->dofs_per_line,
- DoFHandler<1,spacedim>::invalid_dof_index);
-
- dof_handler.levels.back()->cell_dof_indices_cache
- .resize (dof_handler.tria->n_raw_lines(i) *
- dof_handler.selected_fe->dofs_per_cell,
- DoFHandler<1,spacedim>::invalid_dof_index);
- }
- }
-
-
- template <int spacedim>
- static
- void reserve_space (DoFHandler<2,spacedim> &dof_handler)
- {
- dof_handler.vertex_dofs
- .resize(dof_handler.tria->n_vertices() *
- dof_handler.selected_fe->dofs_per_vertex,
- DoFHandler<2,spacedim>::invalid_dof_index);
-
- for (unsigned int i=0; i<dof_handler.tria->n_levels(); ++i)
- {
- dof_handler.levels.push_back (new internal::DoFHandler::DoFLevel<2>);
-
- dof_handler.levels.back()->quads.dofs
- .resize (dof_handler.tria->n_raw_quads(i) *
- dof_handler.selected_fe->dofs_per_quad,
- DoFHandler<2,spacedim>::invalid_dof_index);
-
- dof_handler.levels.back()->cell_dof_indices_cache
- .resize (dof_handler.tria->n_raw_quads(i) *
- dof_handler.selected_fe->dofs_per_cell,
- DoFHandler<2,spacedim>::invalid_dof_index);
- }
-
- dof_handler.faces = new internal::DoFHandler::DoFFaces<2>;
- dof_handler.faces->lines.dofs
- .resize (dof_handler.tria->n_raw_lines() *
- dof_handler.selected_fe->dofs_per_line,
- DoFHandler<2,spacedim>::invalid_dof_index);
- }
-
-
- template <int spacedim>
- static
- void reserve_space (DoFHandler<3,spacedim> &dof_handler)
- {
- dof_handler.vertex_dofs
- .resize(dof_handler.tria->n_vertices() *
- dof_handler.selected_fe->dofs_per_vertex,
- DoFHandler<3,spacedim>::invalid_dof_index);
-
- for (unsigned int i=0; i<dof_handler.tria->n_levels(); ++i)
- {
- dof_handler.levels.push_back (new internal::DoFHandler::DoFLevel<3>);
-
- dof_handler.levels.back()->hexes.dofs
- .resize (dof_handler.tria->n_raw_hexs(i) *
- dof_handler.selected_fe->dofs_per_hex,
- DoFHandler<3,spacedim>::invalid_dof_index);
-
- dof_handler.levels.back()->cell_dof_indices_cache
- .resize (dof_handler.tria->n_raw_hexs(i) *
- dof_handler.selected_fe->dofs_per_cell,
- DoFHandler<3,spacedim>::invalid_dof_index);
- }
- dof_handler.faces = new internal::DoFHandler::DoFFaces<3>;
-
- dof_handler.faces->lines.dofs
- .resize (dof_handler.tria->n_raw_lines() *
- dof_handler.selected_fe->dofs_per_line,
- DoFHandler<3,spacedim>::invalid_dof_index);
- dof_handler.faces->quads.dofs
- .resize (dof_handler.tria->n_raw_quads() *
- dof_handler.selected_fe->dofs_per_quad,
- DoFHandler<3,spacedim>::invalid_dof_index);
- }
+ // doing the same thing here is a
+ // rather complicated thing, compared
+ // to the 2d case, since it is hard
+ // to draw pictures with several
+ // refined hexahedra :-) so I
+ // presently only give a coarse
+ // estimate for the case that at most
+ // 8 hexes meet at each vertex
+ //
+ // can anyone give better estimate
+ // here?
+ const unsigned int max_adjacent_cells
+ = dof_handler.tria->max_adjacent_cells();
+
+ unsigned int max_couplings;
+ if (max_adjacent_cells <= 8)
+ max_couplings=7*7*7*dof_handler.selected_fe->dofs_per_vertex +
+ 7*6*7*3*dof_handler.selected_fe->dofs_per_line +
+ 9*4*7*3*dof_handler.selected_fe->dofs_per_quad +
+ 27*dof_handler.selected_fe->dofs_per_hex;
+ else
+ {
+ Assert (false, ExcNotImplemented());
+ max_couplings=0;
+ }
+
+ return std::min(max_couplings,dof_handler.n_dofs());
+ }
+
+
+ /**
+ * Reserve enough space in the
+ * <tt>levels[]</tt> objects to store the
+ * numbers of the degrees of freedom
+ * needed for the given element. The
+ * given element is that one which
+ * was selected when calling
+ * @p distribute_dofs the last time.
+ */
+ template <int spacedim>
+ static
+ void reserve_space (DoFHandler<1,spacedim> &dof_handler)
+ {
+ dof_handler.vertex_dofs
+ .resize(dof_handler.tria->n_vertices() *
+ dof_handler.selected_fe->dofs_per_vertex,
+ DoFHandler<1,spacedim>::invalid_dof_index);
+
+ for (unsigned int i=0; i<dof_handler.tria->n_levels(); ++i)
+ {
+ dof_handler.levels
+ .push_back (new internal::DoFHandler::DoFLevel<1>);
+
+ dof_handler.levels.back()->lines.dofs
+ .resize (dof_handler.tria->n_raw_lines(i) *
+ dof_handler.selected_fe->dofs_per_line,
+ DoFHandler<1,spacedim>::invalid_dof_index);
+
+ dof_handler.levels.back()->cell_dof_indices_cache
+ .resize (dof_handler.tria->n_raw_lines(i) *
+ dof_handler.selected_fe->dofs_per_cell,
+ DoFHandler<1,spacedim>::invalid_dof_index);
+ }
+ }
+
+
+ template <int spacedim>
+ static
+ void reserve_space (DoFHandler<2,spacedim> &dof_handler)
+ {
+ dof_handler.vertex_dofs
+ .resize(dof_handler.tria->n_vertices() *
+ dof_handler.selected_fe->dofs_per_vertex,
+ DoFHandler<2,spacedim>::invalid_dof_index);
+
+ for (unsigned int i=0; i<dof_handler.tria->n_levels(); ++i)
+ {
+ dof_handler.levels.push_back (new internal::DoFHandler::DoFLevel<2>);
+
+ dof_handler.levels.back()->quads.dofs
+ .resize (dof_handler.tria->n_raw_quads(i) *
+ dof_handler.selected_fe->dofs_per_quad,
+ DoFHandler<2,spacedim>::invalid_dof_index);
+
+ dof_handler.levels.back()->cell_dof_indices_cache
+ .resize (dof_handler.tria->n_raw_quads(i) *
+ dof_handler.selected_fe->dofs_per_cell,
+ DoFHandler<2,spacedim>::invalid_dof_index);
+ }
+
+ dof_handler.faces = new internal::DoFHandler::DoFFaces<2>;
+ dof_handler.faces->lines.dofs
+ .resize (dof_handler.tria->n_raw_lines() *
+ dof_handler.selected_fe->dofs_per_line,
+ DoFHandler<2,spacedim>::invalid_dof_index);
+ }
+
+
+ template <int spacedim>
+ static
+ void reserve_space (DoFHandler<3,spacedim> &dof_handler)
+ {
+ dof_handler.vertex_dofs
+ .resize(dof_handler.tria->n_vertices() *
+ dof_handler.selected_fe->dofs_per_vertex,
+ DoFHandler<3,spacedim>::invalid_dof_index);
+
+ for (unsigned int i=0; i<dof_handler.tria->n_levels(); ++i)
+ {
+ dof_handler.levels.push_back (new internal::DoFHandler::DoFLevel<3>);
+
+ dof_handler.levels.back()->hexes.dofs
+ .resize (dof_handler.tria->n_raw_hexs(i) *
+ dof_handler.selected_fe->dofs_per_hex,
+ DoFHandler<3,spacedim>::invalid_dof_index);
+
+ dof_handler.levels.back()->cell_dof_indices_cache
+ .resize (dof_handler.tria->n_raw_hexs(i) *
+ dof_handler.selected_fe->dofs_per_cell,
+ DoFHandler<3,spacedim>::invalid_dof_index);
+ }
+ dof_handler.faces = new internal::DoFHandler::DoFFaces<3>;
+
+ dof_handler.faces->lines.dofs
+ .resize (dof_handler.tria->n_raw_lines() *
+ dof_handler.selected_fe->dofs_per_line,
+ DoFHandler<3,spacedim>::invalid_dof_index);
+ dof_handler.faces->quads.dofs
+ .resize (dof_handler.tria->n_raw_quads() *
+ dof_handler.selected_fe->dofs_per_quad,
+ DoFHandler<3,spacedim>::invalid_dof_index);
+ }
};
}
}
template<int dim, int spacedim>
DoFHandler<dim,spacedim>::DoFHandler (const Triangulation<dim,spacedim> &tria)
- :
- tria(&tria, typeid(*this).name()),
- selected_fe(0, typeid(*this).name()),
- faces(NULL)
-{
- // decide whether we need a
- // sequential or a parallel
- // distributed policy
+ :
+ tria(&tria, typeid(*this).name()),
+ selected_fe(0, typeid(*this).name()),
+ faces(NULL)
+{
+ // decide whether we need a
+ // sequential or a parallel
+ // distributed policy
if (dynamic_cast<const parallel::distributed::Triangulation< dim, spacedim >*>
(&tria)
== 0)
template<int dim, int spacedim>
DoFHandler<dim,spacedim>::DoFHandler ()
- :
- tria(0, typeid(*this).name()),
- selected_fe(0, typeid(*this).name()),
- faces(NULL)
+ :
+ tria(0, typeid(*this).name()),
+ selected_fe(0, typeid(*this).name()),
+ faces(NULL)
{}
template <int dim, int spacedim>
DoFHandler<dim,spacedim>::~DoFHandler ()
{
- // release allocated memory
+ // release allocated memory
clear ();
}
faces = 0;
number_cache.n_global_dofs = 0;
- // decide whether we need a
- // sequential or a parallel
- // distributed policy
+ // decide whether we need a
+ // sequential or a parallel
+ // distributed policy
if (dynamic_cast<const parallel::distributed::Triangulation< dim, spacedim >*>
(&t)
== 0)
switch (dim)
{
case 1:
- return begin_raw_line (level);
+ return begin_raw_line (level);
case 2:
- return begin_raw_quad (level);
+ return begin_raw_quad (level);
case 3:
- return begin_raw_hex (level);
+ return begin_raw_hex (level);
default:
- Assert (false, ExcNotImplemented());
- return raw_cell_iterator();
+ Assert (false, ExcNotImplemented());
+ return raw_cell_iterator();
}
}
switch (dim)
{
case 1:
- return begin_line (level);
+ return begin_line (level);
case 2:
- return begin_quad (level);
+ return begin_quad (level);
case 3:
- return begin_hex (level);
+ return begin_hex (level);
default:
- Assert (false, ExcImpossibleInDim(dim));
- return cell_iterator();
+ Assert (false, ExcImpossibleInDim(dim));
+ return cell_iterator();
}
}
switch (dim)
{
case 1:
- return begin_active_line (level);
+ return begin_active_line (level);
case 2:
- return begin_active_quad (level);
+ return begin_active_quad (level);
case 3:
- return begin_active_hex (level);
+ return begin_active_hex (level);
default:
- Assert (false, ExcNotImplemented());
- return active_cell_iterator();
+ Assert (false, ExcNotImplemented());
+ return active_cell_iterator();
}
}
switch (dim)
{
case 1:
- return last_raw_line ();
+ return last_raw_line ();
case 2:
- return last_raw_quad ();
+ return last_raw_quad ();
case 3:
- return last_raw_hex ();
+ return last_raw_hex ();
default:
- Assert (false, ExcNotImplemented());
- return raw_cell_iterator();
+ Assert (false, ExcNotImplemented());
+ return raw_cell_iterator();
}
}
switch (dim)
{
case 1:
- return last_raw_line (level);
+ return last_raw_line (level);
case 2:
- return last_raw_quad (level);
+ return last_raw_quad (level);
case 3:
- return last_raw_hex (level);
+ return last_raw_hex (level);
default:
- Assert (false, ExcNotImplemented());
- return raw_cell_iterator();
+ Assert (false, ExcNotImplemented());
+ return raw_cell_iterator();
}
}
switch (dim)
{
case 1:
- return last_line ();
+ return last_line ();
case 2:
- return last_quad ();
+ return last_quad ();
case 3:
- return last_hex ();
+ return last_hex ();
default:
- Assert (false, ExcNotImplemented());
- return cell_iterator();
+ Assert (false, ExcNotImplemented());
+ return cell_iterator();
}
}
switch (dim)
{
case 1:
- return last_line (level);
+ return last_line (level);
case 2:
- return last_quad (level);
+ return last_quad (level);
case 3:
- return last_hex (level);
+ return last_hex (level);
default:
- Assert (false, ExcNotImplemented());
- return cell_iterator();
+ Assert (false, ExcNotImplemented());
+ return cell_iterator();
}
}
switch (dim)
{
case 1:
- return last_active_line ();
+ return last_active_line ();
case 2:
- return last_active_quad ();
+ return last_active_quad ();
case 3:
- return last_active_hex ();
+ return last_active_hex ();
default:
- Assert (false, ExcNotImplemented());
- return active_cell_iterator();
+ Assert (false, ExcNotImplemented());
+ return active_cell_iterator();
}
}
switch (dim)
{
case 1:
- return last_active_line (level);
+ return last_active_line (level);
case 2:
- return last_active_quad (level);
+ return last_active_quad (level);
case 3:
- return last_active_hex (level);
+ return last_active_hex (level);
default:
- Assert (false, ExcNotImplemented());
- return active_cell_iterator();
+ Assert (false, ExcNotImplemented());
+ return active_cell_iterator();
}
}
switch (dim)
{
case 1:
- return end_line();
+ return end_line();
case 2:
- return end_quad();
+ return end_quad();
case 3:
- return end_hex();
+ return end_hex();
default:
- Assert (false, ExcImpossibleInDim(dim));
- return raw_cell_iterator();
+ Assert (false, ExcImpossibleInDim(dim));
+ return raw_cell_iterator();
}
}
{
Assert(tria != 0, ExcNotInitialized());
return (level == tria->n_levels()-1 ?
- end() :
- begin_raw (level+1));
+ end() :
+ begin_raw (level+1));
}
{
Assert(tria != 0, ExcNotInitialized());
return (level == tria->n_levels()-1 ?
- cell_iterator(end()) :
- begin (level+1));
+ cell_iterator(end()) :
+ begin (level+1));
}
{
Assert(tria != 0, ExcNotInitialized());
return (level == tria->n_levels()-1 ?
- active_cell_iterator(end()) :
- begin_active (level+1));
+ active_cell_iterator(end()) :
+ begin_active (level+1));
}
switch (dim)
{
case 1:
- Assert (false, ExcImpossibleInDim(1));
- return raw_face_iterator();
+ Assert (false, ExcImpossibleInDim(1));
+ return raw_face_iterator();
case 2:
- return begin_raw_line ();
+ return begin_raw_line ();
case 3:
- return begin_raw_quad ();
+ return begin_raw_quad ();
default:
- Assert (false, ExcNotImplemented());
- return raw_face_iterator ();
+ Assert (false, ExcNotImplemented());
+ return raw_face_iterator ();
}
}
switch (dim)
{
case 1:
- Assert (false, ExcImpossibleInDim(1));
- return raw_face_iterator();
+ Assert (false, ExcImpossibleInDim(1));
+ return raw_face_iterator();
case 2:
- return begin_line ();
+ return begin_line ();
case 3:
- return begin_quad ();
+ return begin_quad ();
default:
- Assert (false, ExcNotImplemented());
- return face_iterator ();
+ Assert (false, ExcNotImplemented());
+ return face_iterator ();
}
}
switch (dim)
{
case 1:
- Assert (false, ExcImpossibleInDim(1));
- return raw_face_iterator();
+ Assert (false, ExcImpossibleInDim(1));
+ return raw_face_iterator();
case 2:
- return begin_active_line ();
+ return begin_active_line ();
case 3:
- return begin_active_quad ();
+ return begin_active_quad ();
default:
- Assert (false, ExcNotImplemented());
- return active_face_iterator ();
+ Assert (false, ExcNotImplemented());
+ return active_face_iterator ();
}
}
switch (dim)
{
case 1:
- Assert (false, ExcImpossibleInDim(1));
- return raw_face_iterator();
+ Assert (false, ExcImpossibleInDim(1));
+ return raw_face_iterator();
case 2:
- return end_line ();
+ return end_line ();
case 3:
- return end_quad ();
+ return end_quad ();
default:
- Assert (false, ExcNotImplemented());
- return raw_face_iterator ();
+ Assert (false, ExcNotImplemented());
+ return raw_face_iterator ();
}
}
switch (dim)
{
case 1:
- Assert (false, ExcImpossibleInDim(1));
- return raw_face_iterator();
+ Assert (false, ExcImpossibleInDim(1));
+ return raw_face_iterator();
case 2:
- return last_raw_line ();
+ return last_raw_line ();
case 3:
- return last_raw_quad ();
+ return last_raw_quad ();
default:
- Assert (false, ExcNotImplemented());
- return raw_face_iterator ();
+ Assert (false, ExcNotImplemented());
+ return raw_face_iterator ();
}
}
switch (dim)
{
case 1:
- Assert (false, ExcImpossibleInDim(1));
- return raw_face_iterator();
+ Assert (false, ExcImpossibleInDim(1));
+ return raw_face_iterator();
case 2:
- return last_line ();
+ return last_line ();
case 3:
- return last_quad ();
+ return last_quad ();
default:
- Assert (false, ExcNotImplemented());
- return raw_face_iterator ();
+ Assert (false, ExcNotImplemented());
+ return raw_face_iterator ();
}
}
switch (dim)
{
case 1:
- Assert (false, ExcImpossibleInDim(1));
- return raw_face_iterator();
+ Assert (false, ExcImpossibleInDim(1));
+ return raw_face_iterator();
case 2:
- return last_active_line ();
+ return last_active_line ();
case 3:
- return last_active_quad ();
+ return last_active_quad ();
default:
- Assert (false, ExcNotImplemented());
- return raw_face_iterator ();
+ Assert (false, ExcNotImplemented());
+ return raw_face_iterator ();
}
}
switch (dim)
{
case 1:
- Assert (level<tria->n_levels(), ExcInvalidLevel(level));
+ Assert (level<tria->n_levels(), ExcInvalidLevel(level));
- if (tria->n_raw_lines(level) == 0)
- return end_line ();
+ if (tria->n_raw_lines(level) == 0)
+ return end_line ();
- return raw_line_iterator (tria,
- level,
- 0,
- this);
+ return raw_line_iterator (tria,
+ level,
+ 0,
+ this);
default:
- Assert (level == 0, ExcFacesHaveNoLevel());
- return raw_line_iterator (tria,
- 0,
- 0,
- this);
+ Assert (level == 0, ExcFacesHaveNoLevel());
+ return raw_line_iterator (tria,
+ 0,
+ 0,
+ this);
}
}
typename DoFHandler<dim, spacedim>::line_iterator
DoFHandler<dim, spacedim>::begin_line (const unsigned int level) const
{
- // level is checked in begin_raw
+ // level is checked in begin_raw
raw_line_iterator ri = begin_raw_line (level);
if (ri.state() != IteratorState::valid)
return ri;
typename DoFHandler<dim, spacedim>::active_line_iterator
DoFHandler<dim, spacedim>::begin_active_line (const unsigned int level) const
{
- // level is checked in begin_raw
+ // level is checked in begin_raw
line_iterator i = begin_line (level);
if (i.state() != IteratorState::valid)
return i;
DoFHandler<dim, spacedim>::end_line () const
{
return raw_line_iterator (tria,
- -1,
- -1,
- this);
+ -1,
+ -1,
+ this);
}
switch (dim)
{
case 1:
- Assert (level<tria->n_levels(), ExcInvalidLevel(level));
- Assert (tria->n_raw_lines(level) != 0,
- ExcEmptyLevel (level));
+ Assert (level<tria->n_levels(), ExcInvalidLevel(level));
+ Assert (tria->n_raw_lines(level) != 0,
+ ExcEmptyLevel (level));
- return raw_line_iterator (tria,
- level,
- tria->n_raw_lines(level)-1,
- this);
+ return raw_line_iterator (tria,
+ level,
+ tria->n_raw_lines(level)-1,
+ this);
default:
- Assert (level == 0, ExcFacesHaveNoLevel());
- return raw_line_iterator (tria,
- 0,
- tria->n_raw_lines()-1,
- this);
+ Assert (level == 0, ExcFacesHaveNoLevel());
+ return raw_line_iterator (tria,
+ 0,
+ tria->n_raw_lines()-1,
+ this);
}
}
typename DoFHandler<dim, spacedim>::line_iterator
DoFHandler<dim, spacedim>::last_line (const unsigned int level) const
{
- // level is checked in last_raw
+ // level is checked in last_raw
raw_line_iterator ri = last_raw_line(level);
if (ri->used()==true)
return ri;
typename DoFHandler<dim, spacedim>::active_line_iterator
DoFHandler<dim, spacedim>::last_active_line (const unsigned int level) const
{
- // level is checked in last_raw
+ // level is checked in last_raw
line_iterator i = last_line(level);
if (i->has_children()==false)
return i;
Assert (dim == 1 || level == 0, ExcFacesHaveNoLevel());
if (dim == 1)
return (level == tria->n_levels()-1 ?
- end_line() :
- begin_raw_line (level+1));
+ end_line() :
+ begin_raw_line (level+1));
else
return end_line();
}
Assert (dim == 1 || level == 0, ExcFacesHaveNoLevel());
if (dim == 1)
return (level == tria->n_levels()-1 ?
- line_iterator(end_line()) :
- begin_line (level+1));
+ line_iterator(end_line()) :
+ begin_line (level+1));
else
return line_iterator(end_line());
}
Assert (dim == 1 || level == 0, ExcFacesHaveNoLevel());
if (dim == 1)
return (level == tria->n_levels()-1 ?
- active_line_iterator(end_line()) :
- begin_active_line (level+1));
+ active_line_iterator(end_line()) :
+ begin_active_line (level+1));
else
return active_line_iterator(end_line());
}
switch (dim)
{
case 1:
- Assert (false, ExcImpossibleInDim(1));
- return raw_hex_iterator();
+ Assert (false, ExcImpossibleInDim(1));
+ return raw_hex_iterator();
case 2:
{
- Assert (level<tria->n_levels(), ExcInvalidLevel(level));
+ Assert (level<tria->n_levels(), ExcInvalidLevel(level));
- if (tria->n_raw_quads(level) == 0)
- return end_quad();
+ if (tria->n_raw_quads(level) == 0)
+ return end_quad();
- return raw_quad_iterator (tria,
- level,
- 0,
- this);
+ return raw_quad_iterator (tria,
+ level,
+ 0,
+ this);
}
case 3:
{
- Assert (level == 0, ExcFacesHaveNoLevel());
+ Assert (level == 0, ExcFacesHaveNoLevel());
- return raw_quad_iterator (tria,
- 0,
- 0,
- this);
+ return raw_quad_iterator (tria,
+ 0,
+ 0,
+ this);
}
default:
- Assert (false, ExcNotImplemented());
- return raw_hex_iterator();
+ Assert (false, ExcNotImplemented());
+ return raw_hex_iterator();
}
}
typename DoFHandler<dim,spacedim>::quad_iterator
DoFHandler<dim,spacedim>::begin_quad (const unsigned int level) const
{
- // level is checked in begin_raw
+ // level is checked in begin_raw
raw_quad_iterator ri = begin_raw_quad (level);
if (ri.state() != IteratorState::valid)
return ri;
typename DoFHandler<dim,spacedim>::active_quad_iterator
DoFHandler<dim,spacedim>::begin_active_quad (const unsigned int level) const
{
- // level is checked in begin_raw
+ // level is checked in begin_raw
quad_iterator i = begin_quad (level);
if (i.state() != IteratorState::valid)
return i;
Assert (dim == 2 || level == 0, ExcFacesHaveNoLevel());
if (dim == 2)
return (level == tria->n_levels()-1 ?
- end_quad() :
- begin_raw_quad (level+1));
+ end_quad() :
+ begin_raw_quad (level+1));
else
return end_quad();
}
Assert (dim == 2 || level == 0, ExcFacesHaveNoLevel());
if (dim == 2)
return (level == tria->n_levels()-1 ?
- quad_iterator(end_quad()) :
- begin_quad (level+1));
+ quad_iterator(end_quad()) :
+ begin_quad (level+1));
else
return quad_iterator(end_quad());
}
Assert(dim == 2 || level == 0, ExcFacesHaveNoLevel());
if (dim == 2)
return (level == tria->n_levels()-1 ?
- active_quad_iterator(end_quad()) :
- begin_active_quad (level+1));
+ active_quad_iterator(end_quad()) :
+ begin_active_quad (level+1));
else
return active_quad_iterator(end_quad());
}
DoFHandler<dim,spacedim>::end_quad () const
{
return raw_quad_iterator (tria,
- -1,
- -1,
- this);
+ -1,
+ -1,
+ this);
}
switch (dim)
{
case 1:
- Assert (false, ExcImpossibleInDim(1));
- return raw_quad_iterator();
+ Assert (false, ExcImpossibleInDim(1));
+ return raw_quad_iterator();
case 2:
- Assert (level<tria->n_levels(),
- ExcInvalidLevel(level));
- Assert (tria->n_raw_quads(level) != 0,
- ExcEmptyLevel (level));
- return raw_quad_iterator (tria,
- level,
- tria->n_raw_quads(level)-1,
- this);
+ Assert (level<tria->n_levels(),
+ ExcInvalidLevel(level));
+ Assert (tria->n_raw_quads(level) != 0,
+ ExcEmptyLevel (level));
+ return raw_quad_iterator (tria,
+ level,
+ tria->n_raw_quads(level)-1,
+ this);
case 3:
- Assert (level == 0, ExcFacesHaveNoLevel());
- return raw_quad_iterator (tria,
- 0,
- tria->n_raw_quads()-1,
- this);
+ Assert (level == 0, ExcFacesHaveNoLevel());
+ return raw_quad_iterator (tria,
+ 0,
+ tria->n_raw_quads()-1,
+ this);
default:
- Assert (false, ExcNotImplemented());
- return raw_quad_iterator();
+ Assert (false, ExcNotImplemented());
+ return raw_quad_iterator();
}
}
typename DoFHandler<dim,spacedim>::quad_iterator
DoFHandler<dim,spacedim>::last_quad (const unsigned int level) const
{
- // level is checked in last_raw
+ // level is checked in last_raw
raw_quad_iterator ri = last_raw_quad(level);
if (ri->used()==true)
return ri;
typename DoFHandler<dim,spacedim>::active_quad_iterator
DoFHandler<dim,spacedim>::last_active_quad (const unsigned int level) const
{
- // level is checked in last_raw
+ // level is checked in last_raw
quad_iterator i = last_quad(level);
if (i->has_children()==false)
return i;
{
case 1:
case 2:
- Assert (false, ExcImpossibleInDim(1));
- return raw_hex_iterator();
+ Assert (false, ExcImpossibleInDim(1));
+ return raw_hex_iterator();
case 3:
{
- Assert (level<tria->n_levels(), ExcInvalidLevel(level));
+ Assert (level<tria->n_levels(), ExcInvalidLevel(level));
- if (tria->n_raw_hexs(level) == 0)
- return end_hex();
+ if (tria->n_raw_hexs(level) == 0)
+ return end_hex();
- return raw_hex_iterator (tria,
- level,
- 0,
- this);
+ return raw_hex_iterator (tria,
+ level,
+ 0,
+ this);
}
default:
- Assert (false, ExcNotImplemented());
- return raw_hex_iterator();
+ Assert (false, ExcNotImplemented());
+ return raw_hex_iterator();
}
}
typename DoFHandler<dim,spacedim>::hex_iterator
DoFHandler<dim,spacedim>::begin_hex (const unsigned int level) const
{
- // level is checked in begin_raw
+ // level is checked in begin_raw
raw_hex_iterator ri = begin_raw_hex (level);
if (ri.state() != IteratorState::valid)
return ri;
typename DoFHandler<dim, spacedim>::active_hex_iterator
DoFHandler<dim, spacedim>::begin_active_hex (const unsigned int level) const
{
- // level is checked in begin_raw
+ // level is checked in begin_raw
hex_iterator i = begin_hex (level);
if (i.state() != IteratorState::valid)
return i;
DoFHandler<dim, spacedim>::end_raw_hex (const unsigned int level) const
{
return (level == tria->n_levels()-1 ?
- end_hex() :
- begin_raw_hex (level+1));
+ end_hex() :
+ begin_raw_hex (level+1));
}
DoFHandler<dim, spacedim>::end_hex (const unsigned int level) const
{
return (level == tria->n_levels()-1 ?
- hex_iterator(end_hex()) :
- begin_hex (level+1));
+ hex_iterator(end_hex()) :
+ begin_hex (level+1));
}
DoFHandler<dim, spacedim>::end_active_hex (const unsigned int level) const
{
return (level == tria->n_levels()-1 ?
- active_hex_iterator(end_hex()) :
- begin_active_hex (level+1));
+ active_hex_iterator(end_hex()) :
+ begin_active_hex (level+1));
}
DoFHandler<dim, spacedim>::end_hex () const
{
return raw_hex_iterator (tria,
- -1,
- -1,
- this);
+ -1,
+ -1,
+ this);
}
{
case 1:
case 2:
- Assert (false, ExcImpossibleInDim(dim));
- return raw_hex_iterator();
+ Assert (false, ExcImpossibleInDim(dim));
+ return raw_hex_iterator();
case 3:
- Assert (level<tria->n_levels(),
- ExcInvalidLevel(level));
- Assert (tria->n_raw_hexs(level) != 0,
- ExcEmptyLevel (level));
-
- return raw_hex_iterator (tria,
- level,
- tria->n_raw_hexs(level)-1,
- this);
+ Assert (level<tria->n_levels(),
+ ExcInvalidLevel(level));
+ Assert (tria->n_raw_hexs(level) != 0,
+ ExcEmptyLevel (level));
+
+ return raw_hex_iterator (tria,
+ level,
+ tria->n_raw_hexs(level)-1,
+ this);
default:
- Assert (false, ExcNotImplemented());
- return raw_hex_iterator();
+ Assert (false, ExcNotImplemented());
+ return raw_hex_iterator();
}
}
typename DoFHandler<dim, spacedim>::hex_iterator
DoFHandler<dim, spacedim>::last_hex (const unsigned int level) const
{
- // level is checked in last_raw
+ // level is checked in last_raw
raw_hex_iterator ri = last_raw_hex(level);
if (ri->used()==true)
return ri;
typename DoFHandler<dim, spacedim>::active_hex_iterator
DoFHandler<dim, spacedim>::last_active_hex (const unsigned int level) const
{
- // level is checked in last_raw
+ // level is checked in last_raw
hex_iterator i = last_hex(level);
if (i->has_children()==false)
return i;
template <>
unsigned int DoFHandler<1>::n_boundary_dofs (const FunctionMap &boundary_indicators) const
{
- // check that only boundary
- // indicators 0 and 1 are allowed
- // in 1d
+ // check that only boundary
+ // indicators 0 and 1 are allowed
+ // in 1d
for (FunctionMap::const_iterator i=boundary_indicators.begin();
i!=boundary_indicators.end(); ++i)
Assert ((i->first == 0) || (i->first == 1),
- ExcInvalidBoundaryIndicator());
+ ExcInvalidBoundaryIndicator());
return boundary_indicators.size()*get_fe().dofs_per_vertex;
}
template <>
unsigned int DoFHandler<1>::n_boundary_dofs (const std::set<types::boundary_id_t> &boundary_indicators) const
{
- // check that only boundary
- // indicators 0 and 1 are allowed
- // in 1d
+ // check that only boundary
+ // indicators 0 and 1 are allowed
+ // in 1d
for (std::set<types::boundary_id_t>::const_iterator i=boundary_indicators.begin();
i!=boundary_indicators.end(); ++i)
Assert ((*i == 0) || (*i == 1),
- ExcInvalidBoundaryIndicator());
+ ExcInvalidBoundaryIndicator());
return boundary_indicators.size()*get_fe().dofs_per_vertex;
}
template <>
unsigned int DoFHandler<1,2>::n_boundary_dofs (const FunctionMap &boundary_indicators) const
{
- // check that only boundary
- // indicators 0 and 1 are allowed
- // in 1d
+ // check that only boundary
+ // indicators 0 and 1 are allowed
+ // in 1d
for (FunctionMap::const_iterator i=boundary_indicators.begin();
i!=boundary_indicators.end(); ++i)
Assert ((i->first == 0) || (i->first == 1),
- ExcInvalidBoundaryIndicator());
+ ExcInvalidBoundaryIndicator());
return boundary_indicators.size()*get_fe().dofs_per_vertex;
}
template <>
unsigned int DoFHandler<1,2>::n_boundary_dofs (const std::set<types::boundary_id_t> &boundary_indicators) const
{
- // check that only boundary
- // indicators 0 and 1 are allowed
- // in 1d
+ // check that only boundary
+ // indicators 0 and 1 are allowed
+ // in 1d
for (std::set<types::boundary_id_t>::const_iterator i=boundary_indicators.begin();
i!=boundary_indicators.end(); ++i)
Assert ((*i == 0) || (*i == 1),
- ExcInvalidBoundaryIndicator());
+ ExcInvalidBoundaryIndicator());
return boundary_indicators.size()*get_fe().dofs_per_vertex;
}
const unsigned int dofs_per_face = get_fe().dofs_per_face;
std::vector<unsigned int> dofs_on_face(dofs_per_face);
- // loop over all faces to check
- // whether they are at a
- // boundary. note that we need not
- // take special care of single
- // lines (using
- // @p{cell->has_boundary_lines}),
- // since we do not support
- // boundaries of dimension dim-2,
- // and so every boundary line is
- // also part of a boundary face.
+ // loop over all faces to check
+ // whether they are at a
+ // boundary. note that we need not
+ // take special care of single
+ // lines (using
+ // @p{cell->has_boundary_lines}),
+ // since we do not support
+ // boundaries of dimension dim-2,
+ // and so every boundary line is
+ // also part of a boundary face.
active_face_iterator face = begin_active_face (),
- endf = end_face();
+ endf = end_face();
for (; face!=endf; ++face)
if (face->at_boundary())
{
- face->get_dof_indices (dofs_on_face);
- for (unsigned int i=0; i<dofs_per_face; ++i)
- boundary_dofs.insert(dofs_on_face[i]);
+ face->get_dof_indices (dofs_on_face);
+ for (unsigned int i=0; i<dofs_per_face; ++i)
+ boundary_dofs.insert(dofs_on_face[i]);
}
return boundary_dofs.size();
}
DoFHandler<dim,spacedim>::n_boundary_dofs (const FunctionMap &boundary_indicators) const
{
Assert (boundary_indicators.find(types::internal_face_boundary_id) == boundary_indicators.end(),
- ExcInvalidBoundaryIndicator());
+ ExcInvalidBoundaryIndicator());
std::set<int> boundary_dofs;
const unsigned int dofs_per_face = get_fe().dofs_per_face;
std::vector<unsigned int> dofs_on_face(dofs_per_face);
active_face_iterator face = begin_active_face (),
- endf = end_face();
+ endf = end_face();
for (; face!=endf; ++face)
if (boundary_indicators.find(face->boundary_indicator()) !=
- boundary_indicators.end())
+ boundary_indicators.end())
{
- face->get_dof_indices (dofs_on_face);
- for (unsigned int i=0; i<dofs_per_face; ++i)
- boundary_dofs.insert(dofs_on_face[i]);
+ face->get_dof_indices (dofs_on_face);
+ for (unsigned int i=0; i<dofs_per_face; ++i)
+ boundary_dofs.insert(dofs_on_face[i]);
}
return boundary_dofs.size();
}
DoFHandler<dim,spacedim>::n_boundary_dofs (const std::set<types::boundary_id_t> &boundary_indicators) const
{
Assert (boundary_indicators.find (types::internal_face_boundary_id) == boundary_indicators.end(),
- ExcInvalidBoundaryIndicator());
+ ExcInvalidBoundaryIndicator());
std::set<int> boundary_dofs;
const unsigned int dofs_per_face = get_fe().dofs_per_face;
std::vector<unsigned int> dofs_on_face(dofs_per_face);
active_face_iterator face = begin_active_face (),
- endf = end_face();
+ endf = end_face();
for (; face!=endf; ++face)
if (std::find (boundary_indicators.begin(),
- boundary_indicators.end(),
- face->boundary_indicator()) !=
- boundary_indicators.end())
+ boundary_indicators.end(),
+ face->boundary_indicator()) !=
+ boundary_indicators.end())
{
- face->get_dof_indices (dofs_on_face);
- for (unsigned int i=0; i<dofs_per_face; ++i)
- boundary_dofs.insert(dofs_on_face[i]);
+ face->get_dof_indices (dofs_on_face);
+ for (unsigned int i=0; i<dofs_per_face; ++i)
+ boundary_dofs.insert(dofs_on_face[i]);
}
return boundary_dofs.size();
}
DoFHandler<dim,spacedim>::memory_consumption () const
{
std::size_t mem = (MemoryConsumption::memory_consumption (tria) +
- MemoryConsumption::memory_consumption (selected_fe) +
- MemoryConsumption::memory_consumption (block_info_object) +
- MemoryConsumption::memory_consumption (levels) +
- MemoryConsumption::memory_consumption (*faces) +
- MemoryConsumption::memory_consumption (faces) +
- sizeof (number_cache) +
- MemoryConsumption::memory_consumption (vertex_dofs));
+ MemoryConsumption::memory_consumption (selected_fe) +
+ MemoryConsumption::memory_consumption (block_info_object) +
+ MemoryConsumption::memory_consumption (levels) +
+ MemoryConsumption::memory_consumption (*faces) +
+ MemoryConsumption::memory_consumption (faces) +
+ sizeof (number_cache) +
+ MemoryConsumption::memory_consumption (vertex_dofs));
for (unsigned int i=0; i<levels.size(); ++i)
mem += MemoryConsumption::memory_consumption (*levels[i]);
template<int dim, int spacedim>
void DoFHandler<dim,spacedim>::
distribute_dofs (const FiniteElement<dim,spacedim> &ff,
- const unsigned int offset)
+ const unsigned int offset)
{
selected_fe = &ff;
clear_space ();
internal::DoFHandler::Implementation::reserve_space (*this);
- // hand things off to the policy
+ // hand things off to the policy
number_cache = policy->distribute_dofs (offset,
- *this);
+ *this);
- // initialize the block info object
- // only if this is a sequential
- // triangulation. it doesn't work
- // correctly yet if it is parallel
+ // initialize the block info object
+ // only if this is a sequential
+ // triangulation. it doesn't work
+ // correctly yet if it is parallel
if (dynamic_cast<const parallel::distributed::Triangulation<dim,spacedim>*>(&*tria) == 0)
block_info_object.initialize(*this);
}
template<int dim, int spacedim>
void DoFHandler<dim,spacedim>::clear ()
{
- // release lock to old fe
+ // release lock to old fe
selected_fe = 0;
- // release memory
+ // release memory
clear_space ();
}
renumber_dofs (const std::vector<unsigned int> &new_numbers)
{
Assert (new_numbers.size() == n_locally_owned_dofs(),
- ExcRenumberingIncomplete());
+ ExcRenumberingIncomplete());
#ifdef DEBUG
- // assert that the new indices are
- // consecutively numbered if we are
- // working on a single
- // processor. this doesn't need to
- // hold in the case of a parallel
- // mesh since we map the interval
- // [0...n_dofs()) into itself but
- // only globally, not on each
- // processor
+ // assert that the new indices are
+ // consecutively numbered if we are
+ // working on a single
+ // processor. this doesn't need to
+ // hold in the case of a parallel
+ // mesh since we map the interval
+ // [0...n_dofs()) into itself but
+ // only globally, not on each
+ // processor
if (n_locally_owned_dofs() == n_dofs())
{
std::vector<unsigned int> tmp(new_numbers);
std::vector<unsigned int>::const_iterator p = tmp.begin();
unsigned int i = 0;
for (; p!=tmp.end(); ++p, ++i)
- Assert (*p == i, ExcNewNumbersNotConsecutive(i));
+ Assert (*p == i, ExcNewNumbersNotConsecutive(i));
}
else
for (unsigned int i=0; i<new_numbers.size(); ++i)
Assert (new_numbers[i] < n_dofs(),
- ExcMessage ("New DoF index is not less than the total number of dofs."));
+ ExcMessage ("New DoF index is not less than the total number of dofs."));
#endif
number_cache = policy->renumber_dofs (new_numbers, *this);
switch (dim)
{
case 1:
- return get_fe().dofs_per_vertex;
+ return get_fe().dofs_per_vertex;
case 2:
- return (3*get_fe().dofs_per_vertex +
- 2*get_fe().dofs_per_line);
+ return (3*get_fe().dofs_per_vertex +
+ 2*get_fe().dofs_per_line);
case 3:
- // we need to take refinement of
- // one boundary face into
- // consideration here; in fact,
- // this function returns what
- // #max_coupling_between_dofs<2>
- // returns
- //
- // we assume here, that only four
- // faces meet at the boundary;
- // this assumption is not
- // justified and needs to be
- // fixed some time. fortunately,
- // ommitting it for now does no
- // harm since the matrix will cry
- // foul if its requirements are
- // not satisfied
- return (19*get_fe().dofs_per_vertex +
- 28*get_fe().dofs_per_line +
- 8*get_fe().dofs_per_quad);
+ // we need to take refinement of
+ // one boundary face into
+ // consideration here; in fact,
+ // this function returns what
+ // #max_coupling_between_dofs<2>
+ // returns
+ //
+ // we assume here, that only four
+ // faces meet at the boundary;
+ // this assumption is not
+ // justified and needs to be
+ // fixed some time. fortunately,
+ // ommitting it for now does no
+ // harm since the matrix will cry
+ // foul if its requirements are
+ // not satisfied
+ return (19*get_fe().dofs_per_vertex +
+ 28*get_fe().dofs_per_line +
+ 8*get_fe().dofs_per_quad);
default:
- Assert (false, ExcNotImplemented());
- return numbers::invalid_unsigned_int;
+ Assert (false, ExcNotImplemented());
+ return numbers::invalid_unsigned_int;
}
}
// $Id$
// Version: $Name$
//
-// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 by the deal.II authors
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
{
namespace Policy
{
- // use class dealii::DoFHandler instead
- // of namespace internal::DoFHandler in
- // the following
+ // use class dealii::DoFHandler instead
+ // of namespace internal::DoFHandler in
+ // the following
using dealii::DoFHandler;
struct Implementation
/* -------------- distribute_dofs functionality ------------- */
- /**
- * Distribute dofs on the given cell,
- * with new dofs starting with index
- * @p next_free_dof. Return the next
- * unused index number.
- *
- * This function is excluded from the
- * @p distribute_dofs function since
- * it can not be implemented dimension
- * independent.
- */
- template <int spacedim>
- static
- unsigned int
- distribute_dofs_on_cell (const DoFHandler<1,spacedim> &dof_handler,
- const typename DoFHandler<1,spacedim>::active_cell_iterator &cell,
- unsigned int next_free_dof)
- {
-
- // distribute dofs of vertices
- if (dof_handler.get_fe().dofs_per_vertex > 0)
- for (unsigned int v=0; v<GeometryInfo<1>::vertices_per_cell; ++v)
- {
- if (cell->vertex_dof_index (v,0) ==
- DoFHandler<1,spacedim>::invalid_dof_index)
- for (unsigned int d=0;
- d<dof_handler.get_fe().dofs_per_vertex; ++d)
- {
- Assert ((cell->vertex_dof_index (v,d) ==
- DoFHandler<1,spacedim>::invalid_dof_index),
- ExcInternalError());
- cell->set_vertex_dof_index (v, d, next_free_dof++);
- }
- else
- for (unsigned int d=0;
- d<dof_handler.get_fe().dofs_per_vertex; ++d)
- Assert ((cell->vertex_dof_index (v,d) !=
- DoFHandler<1,spacedim>::invalid_dof_index),
- ExcInternalError());
- }
-
- // dofs of line
- for (unsigned int d=0;
- d<dof_handler.get_fe().dofs_per_line; ++d)
- cell->set_dof_index (d, next_free_dof++);
-
- // note that this cell has been
- // processed
- cell->set_user_flag ();
-
- return next_free_dof;
- }
-
-
-
- template <int spacedim>
- static
- unsigned int
- distribute_dofs_on_cell (const DoFHandler<2,spacedim> &dof_handler,
- const typename DoFHandler<2,spacedim>::active_cell_iterator &cell,
- unsigned int next_free_dof)
- {
- if (dof_handler.get_fe().dofs_per_vertex > 0)
- // number dofs on vertices
- for (unsigned int vertex=0; vertex<GeometryInfo<2>::vertices_per_cell; ++vertex)
- // check whether dofs for this
- // vertex have been distributed
- // (only check the first dof)
- if (cell->vertex_dof_index(vertex, 0) == DoFHandler<2,spacedim>::invalid_dof_index)
- for (unsigned int d=0; d<dof_handler.get_fe().dofs_per_vertex; ++d)
- cell->set_vertex_dof_index (vertex, d, next_free_dof++);
-
- // for the four sides
- if (dof_handler.get_fe().dofs_per_line > 0)
- for (unsigned int side=0; side<GeometryInfo<2>::faces_per_cell; ++side)
- {
- const typename DoFHandler<2,spacedim>::line_iterator
- line = cell->line(side);
-
- // distribute dofs if necessary:
- // check whether line dof is already
- // numbered (check only first dof)
- if (line->dof_index(0) == DoFHandler<2,spacedim>::invalid_dof_index)
- // if not: distribute dofs
- for (unsigned int d=0; d<dof_handler.get_fe().dofs_per_line; ++d)
- line->set_dof_index (d, next_free_dof++);
- }
-
-
- // dofs of quad
- if (dof_handler.get_fe().dofs_per_quad > 0)
- for (unsigned int d=0; d<dof_handler.get_fe().dofs_per_quad; ++d)
- cell->set_dof_index (d, next_free_dof++);
-
-
- // note that this cell has been processed
- cell->set_user_flag ();
-
- return next_free_dof;
- }
-
-
- template <int spacedim>
- static
- unsigned int
- distribute_dofs_on_cell (const DoFHandler<3,spacedim> &dof_handler,
- const typename DoFHandler<3,spacedim>::active_cell_iterator &cell,
- unsigned int next_free_dof)
- {
- if (dof_handler.get_fe().dofs_per_vertex > 0)
- // number dofs on vertices
- for (unsigned int vertex=0; vertex<GeometryInfo<3>::vertices_per_cell; ++vertex)
- // check whether dofs for this
- // vertex have been distributed
- // (only check the first dof)
- if (cell->vertex_dof_index(vertex, 0) == DoFHandler<3,spacedim>::invalid_dof_index)
- for (unsigned int d=0; d<dof_handler.get_fe().dofs_per_vertex; ++d)
- cell->set_vertex_dof_index (vertex, d, next_free_dof++);
-
- // for the lines
- if (dof_handler.get_fe().dofs_per_line > 0)
- for (unsigned int l=0; l<GeometryInfo<3>::lines_per_cell; ++l)
- {
- const typename DoFHandler<3,spacedim>::line_iterator
- line = cell->line(l);
-
- // distribute dofs if necessary:
- // check whether line dof is already
- // numbered (check only first dof)
- if (line->dof_index(0) == DoFHandler<3,spacedim>::invalid_dof_index)
- // if not: distribute dofs
- for (unsigned int d=0; d<dof_handler.get_fe().dofs_per_line; ++d)
- line->set_dof_index (d, next_free_dof++);
- }
-
- // for the quads
- if (dof_handler.get_fe().dofs_per_quad > 0)
- for (unsigned int q=0; q<GeometryInfo<3>::quads_per_cell; ++q)
- {
- const typename DoFHandler<3,spacedim>::quad_iterator
- quad = cell->quad(q);
-
- // distribute dofs if necessary:
- // check whether quad dof is already
- // numbered (check only first dof)
- if (quad->dof_index(0) == DoFHandler<3,spacedim>::invalid_dof_index)
- // if not: distribute dofs
- for (unsigned int d=0; d<dof_handler.get_fe().dofs_per_quad; ++d)
- quad->set_dof_index (d, next_free_dof++);
- }
-
-
- // dofs of hex
- if (dof_handler.get_fe().dofs_per_hex > 0)
- for (unsigned int d=0; d<dof_handler.get_fe().dofs_per_hex; ++d)
- cell->set_dof_index (d, next_free_dof++);
-
-
- // note that this cell has been
- // processed
- cell->set_user_flag ();
-
- return next_free_dof;
- }
-
-
- /**
- * Distribute degrees of
- * freedom on all cells, or
- * on cells with the
- * correct subdomain_id if
- * the corresponding
- * argument is not equal to
- * types::invalid_subdomain_id. Return
- * the total number of dofs
- * returned.
- */
- template <int dim, int spacedim>
- static
- unsigned int
- distribute_dofs (const unsigned int offset,
- const types::subdomain_id_t subdomain_id,
- DoFHandler<dim,spacedim> &dof_handler)
- {
- const dealii::Triangulation<dim,spacedim> & tria
- = dof_handler.get_tria();
- Assert (tria.n_levels() > 0, ExcMessage("Empty triangulation"));
-
- // Clear user flags because we will
- // need them. But first we save
- // them and make sure that we
- // restore them later such that at
- // the end of this function the
- // Triangulation will be in the
- // same state as it was at the
- // beginning of this function.
- std::vector<bool> user_flags;
- tria.save_user_flags(user_flags);
- const_cast<dealii::Triangulation<dim,spacedim> &>(tria).clear_user_flags ();
-
- unsigned int next_free_dof = offset;
- typename DoFHandler<dim,spacedim>::active_cell_iterator
- cell = dof_handler.begin_active(),
- endc = dof_handler.end();
-
- for (; cell != endc; ++cell)
- if ((subdomain_id == types::invalid_subdomain_id)
- ||
- (cell->subdomain_id() == subdomain_id))
- next_free_dof
- = Implementation::distribute_dofs_on_cell (dof_handler, cell, next_free_dof);
-
- // update the cache used
- // for cell dof indices
- for (typename DoFHandler<dim,spacedim>::cell_iterator
- cell = dof_handler.begin(); cell != dof_handler.end(); ++cell)
- if (cell->subdomain_id() != types::artificial_subdomain_id)
- cell->update_cell_dof_indices_cache ();
-
- // finally restore the user flags
- const_cast<dealii::Triangulation<dim,spacedim> &>(tria).load_user_flags(user_flags);
-
- return next_free_dof;
- }
+ /**
+ * Distribute dofs on the given cell,
+ * with new dofs starting with index
+ * @p next_free_dof. Return the next
+ * unused index number.
+ *
+ * This function is excluded from the
+ * @p distribute_dofs function since
+ * it can not be implemented dimension
+ * independent.
+ */
+ template <int spacedim>
+ static
+ unsigned int
+ distribute_dofs_on_cell (const DoFHandler<1,spacedim> &dof_handler,
+ const typename DoFHandler<1,spacedim>::active_cell_iterator &cell,
+ unsigned int next_free_dof)
+ {
+
+ // distribute dofs of vertices
+ if (dof_handler.get_fe().dofs_per_vertex > 0)
+ for (unsigned int v=0; v<GeometryInfo<1>::vertices_per_cell; ++v)
+ {
+ if (cell->vertex_dof_index (v,0) ==
+ DoFHandler<1,spacedim>::invalid_dof_index)
+ for (unsigned int d=0;
+ d<dof_handler.get_fe().dofs_per_vertex; ++d)
+ {
+ Assert ((cell->vertex_dof_index (v,d) ==
+ DoFHandler<1,spacedim>::invalid_dof_index),
+ ExcInternalError());
+ cell->set_vertex_dof_index (v, d, next_free_dof++);
+ }
+ else
+ for (unsigned int d=0;
+ d<dof_handler.get_fe().dofs_per_vertex; ++d)
+ Assert ((cell->vertex_dof_index (v,d) !=
+ DoFHandler<1,spacedim>::invalid_dof_index),
+ ExcInternalError());
+ }
+
+ // dofs of line
+ for (unsigned int d=0;
+ d<dof_handler.get_fe().dofs_per_line; ++d)
+ cell->set_dof_index (d, next_free_dof++);
+
+ // note that this cell has been
+ // processed
+ cell->set_user_flag ();
+
+ return next_free_dof;
+ }
+
+
+
+ template <int spacedim>
+ static
+ unsigned int
+ distribute_dofs_on_cell (const DoFHandler<2,spacedim> &dof_handler,
+ const typename DoFHandler<2,spacedim>::active_cell_iterator &cell,
+ unsigned int next_free_dof)
+ {
+ if (dof_handler.get_fe().dofs_per_vertex > 0)
+ // number dofs on vertices
+ for (unsigned int vertex=0; vertex<GeometryInfo<2>::vertices_per_cell; ++vertex)
+ // check whether dofs for this
+ // vertex have been distributed
+ // (only check the first dof)
+ if (cell->vertex_dof_index(vertex, 0) == DoFHandler<2,spacedim>::invalid_dof_index)
+ for (unsigned int d=0; d<dof_handler.get_fe().dofs_per_vertex; ++d)
+ cell->set_vertex_dof_index (vertex, d, next_free_dof++);
+
+ // for the four sides
+ if (dof_handler.get_fe().dofs_per_line > 0)
+ for (unsigned int side=0; side<GeometryInfo<2>::faces_per_cell; ++side)
+ {
+ const typename DoFHandler<2,spacedim>::line_iterator
+ line = cell->line(side);
+
+ // distribute dofs if necessary:
+ // check whether line dof is already
+ // numbered (check only first dof)
+ if (line->dof_index(0) == DoFHandler<2,spacedim>::invalid_dof_index)
+ // if not: distribute dofs
+ for (unsigned int d=0; d<dof_handler.get_fe().dofs_per_line; ++d)
+ line->set_dof_index (d, next_free_dof++);
+ }
+
+
+ // dofs of quad
+ if (dof_handler.get_fe().dofs_per_quad > 0)
+ for (unsigned int d=0; d<dof_handler.get_fe().dofs_per_quad; ++d)
+ cell->set_dof_index (d, next_free_dof++);
+
+
+ // note that this cell has been processed
+ cell->set_user_flag ();
+
+ return next_free_dof;
+ }
+
+
+ template <int spacedim>
+ static
+ unsigned int
+ distribute_dofs_on_cell (const DoFHandler<3,spacedim> &dof_handler,
+ const typename DoFHandler<3,spacedim>::active_cell_iterator &cell,
+ unsigned int next_free_dof)
+ {
+ if (dof_handler.get_fe().dofs_per_vertex > 0)
+ // number dofs on vertices
+ for (unsigned int vertex=0; vertex<GeometryInfo<3>::vertices_per_cell; ++vertex)
+ // check whether dofs for this
+ // vertex have been distributed
+ // (only check the first dof)
+ if (cell->vertex_dof_index(vertex, 0) == DoFHandler<3,spacedim>::invalid_dof_index)
+ for (unsigned int d=0; d<dof_handler.get_fe().dofs_per_vertex; ++d)
+ cell->set_vertex_dof_index (vertex, d, next_free_dof++);
+
+ // for the lines
+ if (dof_handler.get_fe().dofs_per_line > 0)
+ for (unsigned int l=0; l<GeometryInfo<3>::lines_per_cell; ++l)
+ {
+ const typename DoFHandler<3,spacedim>::line_iterator
+ line = cell->line(l);
+
+ // distribute dofs if necessary:
+ // check whether line dof is already
+ // numbered (check only first dof)
+ if (line->dof_index(0) == DoFHandler<3,spacedim>::invalid_dof_index)
+ // if not: distribute dofs
+ for (unsigned int d=0; d<dof_handler.get_fe().dofs_per_line; ++d)
+ line->set_dof_index (d, next_free_dof++);
+ }
+
+ // for the quads
+ if (dof_handler.get_fe().dofs_per_quad > 0)
+ for (unsigned int q=0; q<GeometryInfo<3>::quads_per_cell; ++q)
+ {
+ const typename DoFHandler<3,spacedim>::quad_iterator
+ quad = cell->quad(q);
+
+ // distribute dofs if necessary:
+ // check whether quad dof is already
+ // numbered (check only first dof)
+ if (quad->dof_index(0) == DoFHandler<3,spacedim>::invalid_dof_index)
+ // if not: distribute dofs
+ for (unsigned int d=0; d<dof_handler.get_fe().dofs_per_quad; ++d)
+ quad->set_dof_index (d, next_free_dof++);
+ }
+
+
+ // dofs of hex
+ if (dof_handler.get_fe().dofs_per_hex > 0)
+ for (unsigned int d=0; d<dof_handler.get_fe().dofs_per_hex; ++d)
+ cell->set_dof_index (d, next_free_dof++);
+
+
+ // note that this cell has been
+ // processed
+ cell->set_user_flag ();
+
+ return next_free_dof;
+ }
+
+
+ /**
+ * Distribute degrees of
+ * freedom on all cells, or
+ * on cells with the
+ * correct subdomain_id if
+ * the corresponding
+ * argument is not equal to
+ * types::invalid_subdomain_id. Return
+ * the total number of dofs
+ * returned.
+ */
+ template <int dim, int spacedim>
+ static
+ unsigned int
+ distribute_dofs (const unsigned int offset,
+ const types::subdomain_id_t subdomain_id,
+ DoFHandler<dim,spacedim> &dof_handler)
+ {
+ const dealii::Triangulation<dim,spacedim> & tria
+ = dof_handler.get_tria();
+ Assert (tria.n_levels() > 0, ExcMessage("Empty triangulation"));
+
+ // Clear user flags because we will
+ // need them. But first we save
+ // them and make sure that we
+ // restore them later such that at
+ // the end of this function the
+ // Triangulation will be in the
+ // same state as it was at the
+ // beginning of this function.
+ std::vector<bool> user_flags;
+ tria.save_user_flags(user_flags);
+ const_cast<dealii::Triangulation<dim,spacedim> &>(tria).clear_user_flags ();
+
+ unsigned int next_free_dof = offset;
+ typename DoFHandler<dim,spacedim>::active_cell_iterator
+ cell = dof_handler.begin_active(),
+ endc = dof_handler.end();
+
+ for (; cell != endc; ++cell)
+ if ((subdomain_id == types::invalid_subdomain_id)
+ ||
+ (cell->subdomain_id() == subdomain_id))
+ next_free_dof
+ = Implementation::distribute_dofs_on_cell (dof_handler, cell, next_free_dof);
+
+ // update the cache used
+ // for cell dof indices
+ for (typename DoFHandler<dim,spacedim>::cell_iterator
+ cell = dof_handler.begin(); cell != dof_handler.end(); ++cell)
+ if (cell->subdomain_id() != types::artificial_subdomain_id)
+ cell->update_cell_dof_indices_cache ();
+
+ // finally restore the user flags
+ const_cast<dealii::Triangulation<dim,spacedim> &>(tria).load_user_flags(user_flags);
+
+ return next_free_dof;
+ }
/* --------------------- renumber_dofs functionality ---------------- */
- /**
- * Implementation of the
- * general template of same
- * name.
- *
- * If the second argument
- * has any elements set,
- * elements of the then the
- * vector of new numbers do
- * not relate to the old
- * DoF number but instead
- * to the index of the old
- * DoF number within the
- * set of locally owned
- * DoFs.
- */
- template <int spacedim>
- static
- void
- renumber_dofs (const std::vector<unsigned int> &new_numbers,
- const IndexSet &,
- DoFHandler<1,spacedim> &dof_handler,
- const bool check_validity)
- {
- // note that we can not use cell
- // iterators in this function since
- // then we would renumber the dofs on
- // the interface of two cells more
- // than once. Anyway, this way it's
- // not only more correct but also
- // faster; note, however, that dof
- // numbers may be invalid_dof_index,
- // namely when the appropriate
- // vertex/line/etc is unused
- for (std::vector<unsigned int>::iterator
- i=dof_handler.vertex_dofs.begin();
- i!=dof_handler.vertex_dofs.end(); ++i)
- if (*i != DoFHandler<1,spacedim>::invalid_dof_index)
- *i = new_numbers[*i];
- else if (check_validity)
- // if index is
- // invalid_dof_index:
- // check if this one
- // really is unused
- Assert (dof_handler.get_tria()
- .vertex_used((i-dof_handler.vertex_dofs.begin()) /
- dof_handler.selected_fe->dofs_per_vertex)
- == false,
- ExcInternalError ());
-
- for (unsigned int level=0; level<dof_handler.levels.size(); ++level)
- for (std::vector<unsigned int>::iterator
- i=dof_handler.levels[level]->lines.dofs.begin();
- i!=dof_handler.levels[level]->lines.dofs.end(); ++i)
- if (*i != DoFHandler<1,spacedim>::invalid_dof_index)
- *i = new_numbers[*i];
-
- // update the cache
- // used for cell dof
- // indices
- for (typename DoFHandler<1,spacedim>::cell_iterator
- cell = dof_handler.begin();
- cell != dof_handler.end(); ++cell)
- cell->update_cell_dof_indices_cache ();
- }
-
-
-
- template <int spacedim>
- static
- void
- renumber_dofs (const std::vector<unsigned int> &new_numbers,
- const IndexSet &indices,
- DoFHandler<2,spacedim> &dof_handler,
- const bool check_validity)
- {
- // note that we can not use cell
- // iterators in this function since
- // then we would renumber the dofs on
- // the interface of two cells more
- // than once. Anyway, this way it's
- // not only more correct but also
- // faster; note, however, that dof
- // numbers may be invalid_dof_index,
- // namely when the appropriate
- // vertex/line/etc is unused
- for (std::vector<unsigned int>::iterator
- i=dof_handler.vertex_dofs.begin();
- i!=dof_handler.vertex_dofs.end(); ++i)
- if (*i != DoFHandler<2,spacedim>::invalid_dof_index)
- *i = (indices.n_elements() == 0)?
- (new_numbers[*i]) :
- (new_numbers[indices.index_within_set(*i)]);
- else if (check_validity)
- // if index is invalid_dof_index:
- // check if this one really is
- // unused
- Assert (dof_handler.get_tria()
- .vertex_used((i-dof_handler.vertex_dofs.begin()) /
- dof_handler.selected_fe->dofs_per_vertex)
- == false,
- ExcInternalError ());
-
- for (std::vector<unsigned int>::iterator
- i=dof_handler.faces->lines.dofs.begin();
- i!=dof_handler.faces->lines.dofs.end(); ++i)
- if (*i != DoFHandler<2,spacedim>::invalid_dof_index)
- *i = ((indices.n_elements() == 0) ?
- new_numbers[*i] :
- new_numbers[indices.index_within_set(*i)]);
-
- for (unsigned int level=0; level<dof_handler.levels.size(); ++level)
- {
- for (std::vector<unsigned int>::iterator
- i=dof_handler.levels[level]->quads.dofs.begin();
- i!=dof_handler.levels[level]->quads.dofs.end(); ++i)
- if (*i != DoFHandler<2,spacedim>::invalid_dof_index)
- *i = ((indices.n_elements() == 0) ?
- new_numbers[*i] :
- new_numbers[indices.index_within_set(*i)]);
- }
-
- // update the cache
- // used for cell dof
- // indices
- for (typename DoFHandler<2,spacedim>::cell_iterator
- cell = dof_handler.begin();
- cell != dof_handler.end(); ++cell)
- cell->update_cell_dof_indices_cache ();
- }
-
-
- template <int spacedim>
- static
- void
- renumber_dofs (const std::vector<unsigned int> &new_numbers,
- const IndexSet &indices,
- DoFHandler<3,spacedim> &dof_handler,
- const bool check_validity)
- {
- // note that we can not use cell
- // iterators in this function since
- // then we would renumber the dofs on
- // the interface of two cells more
- // than once. Anyway, this way it's
- // not only more correct but also
- // faster; note, however, that dof
- // numbers may be invalid_dof_index,
- // namely when the appropriate
- // vertex/line/etc is unused
- for (std::vector<unsigned int>::iterator
- i=dof_handler.vertex_dofs.begin();
- i!=dof_handler.vertex_dofs.end(); ++i)
- if (*i != DoFHandler<3,spacedim>::invalid_dof_index)
- *i = ((indices.n_elements() == 0) ?
- new_numbers[*i] :
- new_numbers[indices.index_within_set(*i)]);
- else if (check_validity)
- // if index is invalid_dof_index:
- // check if this one really is
- // unused
- Assert (dof_handler.get_tria()
- .vertex_used((i-dof_handler.vertex_dofs.begin()) /
- dof_handler.selected_fe->dofs_per_vertex)
- == false,
- ExcInternalError ());
-
- for (std::vector<unsigned int>::iterator
- i=dof_handler.faces->lines.dofs.begin();
- i!=dof_handler.faces->lines.dofs.end(); ++i)
- if (*i != DoFHandler<3,spacedim>::invalid_dof_index)
- *i = ((indices.n_elements() == 0) ?
- new_numbers[*i] :
- new_numbers[indices.index_within_set(*i)]);
- for (std::vector<unsigned int>::iterator
- i=dof_handler.faces->quads.dofs.begin();
- i!=dof_handler.faces->quads.dofs.end(); ++i)
- if (*i != DoFHandler<3,spacedim>::invalid_dof_index)
- *i = ((indices.n_elements() == 0) ?
- new_numbers[*i] :
- new_numbers[indices.index_within_set(*i)]);
-
- for (unsigned int level=0; level<dof_handler.levels.size(); ++level)
- {
- for (std::vector<unsigned int>::iterator
- i=dof_handler.levels[level]->hexes.dofs.begin();
- i!=dof_handler.levels[level]->hexes.dofs.end(); ++i)
- if (*i != DoFHandler<3,spacedim>::invalid_dof_index)
- *i = ((indices.n_elements() == 0) ?
- new_numbers[*i] :
- new_numbers[indices.index_within_set(*i)]);
- }
-
- // update the cache
- // used for cell dof
- // indices
- for (typename DoFHandler<3,spacedim>::cell_iterator
- cell = dof_handler.begin();
- cell != dof_handler.end(); ++cell)
- cell->update_cell_dof_indices_cache ();
- }
+ /**
+ * Implementation of the
+ * general template of same
+ * name.
+ *
+ * If the second argument
+ * has any elements set,
+ * elements of the then the
+ * vector of new numbers do
+ * not relate to the old
+ * DoF number but instead
+ * to the index of the old
+ * DoF number within the
+ * set of locally owned
+ * DoFs.
+ */
+ template <int spacedim>
+ static
+ void
+ renumber_dofs (const std::vector<unsigned int> &new_numbers,
+ const IndexSet &,
+ DoFHandler<1,spacedim> &dof_handler,
+ const bool check_validity)
+ {
+ // note that we can not use cell
+ // iterators in this function since
+ // then we would renumber the dofs on
+ // the interface of two cells more
+ // than once. Anyway, this way it's
+ // not only more correct but also
+ // faster; note, however, that dof
+ // numbers may be invalid_dof_index,
+ // namely when the appropriate
+ // vertex/line/etc is unused
+ for (std::vector<unsigned int>::iterator
+ i=dof_handler.vertex_dofs.begin();
+ i!=dof_handler.vertex_dofs.end(); ++i)
+ if (*i != DoFHandler<1,spacedim>::invalid_dof_index)
+ *i = new_numbers[*i];
+ else if (check_validity)
+ // if index is
+ // invalid_dof_index:
+ // check if this one
+ // really is unused
+ Assert (dof_handler.get_tria()
+ .vertex_used((i-dof_handler.vertex_dofs.begin()) /
+ dof_handler.selected_fe->dofs_per_vertex)
+ == false,
+ ExcInternalError ());
+
+ for (unsigned int level=0; level<dof_handler.levels.size(); ++level)
+ for (std::vector<unsigned int>::iterator
+ i=dof_handler.levels[level]->lines.dofs.begin();
+ i!=dof_handler.levels[level]->lines.dofs.end(); ++i)
+ if (*i != DoFHandler<1,spacedim>::invalid_dof_index)
+ *i = new_numbers[*i];
+
+ // update the cache
+ // used for cell dof
+ // indices
+ for (typename DoFHandler<1,spacedim>::cell_iterator
+ cell = dof_handler.begin();
+ cell != dof_handler.end(); ++cell)
+ cell->update_cell_dof_indices_cache ();
+ }
+
+
+
+ template <int spacedim>
+ static
+ void
+ renumber_dofs (const std::vector<unsigned int> &new_numbers,
+ const IndexSet &indices,
+ DoFHandler<2,spacedim> &dof_handler,
+ const bool check_validity)
+ {
+ // note that we can not use cell
+ // iterators in this function since
+ // then we would renumber the dofs on
+ // the interface of two cells more
+ // than once. Anyway, this way it's
+ // not only more correct but also
+ // faster; note, however, that dof
+ // numbers may be invalid_dof_index,
+ // namely when the appropriate
+ // vertex/line/etc is unused
+ for (std::vector<unsigned int>::iterator
+ i=dof_handler.vertex_dofs.begin();
+ i!=dof_handler.vertex_dofs.end(); ++i)
+ if (*i != DoFHandler<2,spacedim>::invalid_dof_index)
+ *i = (indices.n_elements() == 0)?
+ (new_numbers[*i]) :
+ (new_numbers[indices.index_within_set(*i)]);
+ else if (check_validity)
+ // if index is invalid_dof_index:
+ // check if this one really is
+ // unused
+ Assert (dof_handler.get_tria()
+ .vertex_used((i-dof_handler.vertex_dofs.begin()) /
+ dof_handler.selected_fe->dofs_per_vertex)
+ == false,
+ ExcInternalError ());
+
+ for (std::vector<unsigned int>::iterator
+ i=dof_handler.faces->lines.dofs.begin();
+ i!=dof_handler.faces->lines.dofs.end(); ++i)
+ if (*i != DoFHandler<2,spacedim>::invalid_dof_index)
+ *i = ((indices.n_elements() == 0) ?
+ new_numbers[*i] :
+ new_numbers[indices.index_within_set(*i)]);
+
+ for (unsigned int level=0; level<dof_handler.levels.size(); ++level)
+ {
+ for (std::vector<unsigned int>::iterator
+ i=dof_handler.levels[level]->quads.dofs.begin();
+ i!=dof_handler.levels[level]->quads.dofs.end(); ++i)
+ if (*i != DoFHandler<2,spacedim>::invalid_dof_index)
+ *i = ((indices.n_elements() == 0) ?
+ new_numbers[*i] :
+ new_numbers[indices.index_within_set(*i)]);
+ }
+
+ // update the cache
+ // used for cell dof
+ // indices
+ for (typename DoFHandler<2,spacedim>::cell_iterator
+ cell = dof_handler.begin();
+ cell != dof_handler.end(); ++cell)
+ cell->update_cell_dof_indices_cache ();
+ }
+
+
+ template <int spacedim>
+ static
+ void
+ renumber_dofs (const std::vector<unsigned int> &new_numbers,
+ const IndexSet &indices,
+ DoFHandler<3,spacedim> &dof_handler,
+ const bool check_validity)
+ {
+ // note that we can not use cell
+ // iterators in this function since
+ // then we would renumber the dofs on
+ // the interface of two cells more
+ // than once. Anyway, this way it's
+ // not only more correct but also
+ // faster; note, however, that dof
+ // numbers may be invalid_dof_index,
+ // namely when the appropriate
+ // vertex/line/etc is unused
+ for (std::vector<unsigned int>::iterator
+ i=dof_handler.vertex_dofs.begin();
+ i!=dof_handler.vertex_dofs.end(); ++i)
+ if (*i != DoFHandler<3,spacedim>::invalid_dof_index)
+ *i = ((indices.n_elements() == 0) ?
+ new_numbers[*i] :
+ new_numbers[indices.index_within_set(*i)]);
+ else if (check_validity)
+ // if index is invalid_dof_index:
+ // check if this one really is
+ // unused
+ Assert (dof_handler.get_tria()
+ .vertex_used((i-dof_handler.vertex_dofs.begin()) /
+ dof_handler.selected_fe->dofs_per_vertex)
+ == false,
+ ExcInternalError ());
+
+ for (std::vector<unsigned int>::iterator
+ i=dof_handler.faces->lines.dofs.begin();
+ i!=dof_handler.faces->lines.dofs.end(); ++i)
+ if (*i != DoFHandler<3,spacedim>::invalid_dof_index)
+ *i = ((indices.n_elements() == 0) ?
+ new_numbers[*i] :
+ new_numbers[indices.index_within_set(*i)]);
+ for (std::vector<unsigned int>::iterator
+ i=dof_handler.faces->quads.dofs.begin();
+ i!=dof_handler.faces->quads.dofs.end(); ++i)
+ if (*i != DoFHandler<3,spacedim>::invalid_dof_index)
+ *i = ((indices.n_elements() == 0) ?
+ new_numbers[*i] :
+ new_numbers[indices.index_within_set(*i)]);
+
+ for (unsigned int level=0; level<dof_handler.levels.size(); ++level)
+ {
+ for (std::vector<unsigned int>::iterator
+ i=dof_handler.levels[level]->hexes.dofs.begin();
+ i!=dof_handler.levels[level]->hexes.dofs.end(); ++i)
+ if (*i != DoFHandler<3,spacedim>::invalid_dof_index)
+ *i = ((indices.n_elements() == 0) ?
+ new_numbers[*i] :
+ new_numbers[indices.index_within_set(*i)]);
+ }
+
+ // update the cache
+ // used for cell dof
+ // indices
+ for (typename DoFHandler<3,spacedim>::cell_iterator
+ cell = dof_handler.begin();
+ cell != dof_handler.end(); ++cell)
+ cell->update_cell_dof_indices_cache ();
+ }
};
NumberCache
Sequential<dim,spacedim>::
distribute_dofs (const unsigned int offset,
- DoFHandler<dim,spacedim> &dof_handler) const
+ DoFHandler<dim,spacedim> &dof_handler) const
{
- const unsigned int n_dofs =
- Implementation::distribute_dofs (offset,
- types::invalid_subdomain_id,
- dof_handler);
-
- // now set the elements of the
- // number cache appropriately
- NumberCache number_cache;
- number_cache.n_global_dofs = n_dofs;
- number_cache.n_locally_owned_dofs = number_cache.n_global_dofs;
-
- number_cache.locally_owned_dofs
- = IndexSet (number_cache.n_global_dofs);
- number_cache.locally_owned_dofs.add_range (0,
- number_cache.n_global_dofs);
- number_cache.locally_owned_dofs.compress();
-
- number_cache.n_locally_owned_dofs_per_processor
- = std::vector<unsigned int> (1,
- number_cache.n_global_dofs);
-
- number_cache.locally_owned_dofs_per_processor
- = std::vector<IndexSet> (1,
- number_cache.locally_owned_dofs);
- return number_cache;
+ const unsigned int n_dofs =
+ Implementation::distribute_dofs (offset,
+ types::invalid_subdomain_id,
+ dof_handler);
+
+ // now set the elements of the
+ // number cache appropriately
+ NumberCache number_cache;
+ number_cache.n_global_dofs = n_dofs;
+ number_cache.n_locally_owned_dofs = number_cache.n_global_dofs;
+
+ number_cache.locally_owned_dofs
+ = IndexSet (number_cache.n_global_dofs);
+ number_cache.locally_owned_dofs.add_range (0,
+ number_cache.n_global_dofs);
+ number_cache.locally_owned_dofs.compress();
+
+ number_cache.n_locally_owned_dofs_per_processor
+ = std::vector<unsigned int> (1,
+ number_cache.n_global_dofs);
+
+ number_cache.locally_owned_dofs_per_processor
+ = std::vector<IndexSet> (1,
+ number_cache.locally_owned_dofs);
+ return number_cache;
}
NumberCache
Sequential<dim,spacedim>::
renumber_dofs (const std::vector<unsigned int> &new_numbers,
- dealii::DoFHandler<dim,spacedim> &dof_handler) const
+ dealii::DoFHandler<dim,spacedim> &dof_handler) const
{
- Implementation::renumber_dofs (new_numbers, IndexSet(0),
- dof_handler, true);
-
- // in the sequential case,
- // the number cache should
- // not have changed but we
- // have to set the elements
- // of the structure
- // appropriately anyway
- NumberCache number_cache;
- number_cache.n_global_dofs = dof_handler.n_dofs();
- number_cache.n_locally_owned_dofs = number_cache.n_global_dofs;
-
- number_cache.locally_owned_dofs
- = IndexSet (number_cache.n_global_dofs);
- number_cache.locally_owned_dofs.add_range (0,
- number_cache.n_global_dofs);
- number_cache.locally_owned_dofs.compress();
-
- number_cache.n_locally_owned_dofs_per_processor
- = std::vector<unsigned int> (1,
- number_cache.n_global_dofs);
-
- number_cache.locally_owned_dofs_per_processor
- = std::vector<IndexSet> (1,
- number_cache.locally_owned_dofs);
- return number_cache;
+ Implementation::renumber_dofs (new_numbers, IndexSet(0),
+ dof_handler, true);
+
+ // in the sequential case,
+ // the number cache should
+ // not have changed but we
+ // have to set the elements
+ // of the structure
+ // appropriately anyway
+ NumberCache number_cache;
+ number_cache.n_global_dofs = dof_handler.n_dofs();
+ number_cache.n_locally_owned_dofs = number_cache.n_global_dofs;
+
+ number_cache.locally_owned_dofs
+ = IndexSet (number_cache.n_global_dofs);
+ number_cache.locally_owned_dofs.add_range (0,
+ number_cache.n_global_dofs);
+ number_cache.locally_owned_dofs.compress();
+
+ number_cache.n_locally_owned_dofs_per_processor
+ = std::vector<unsigned int> (1,
+ number_cache.n_global_dofs);
+
+ number_cache.locally_owned_dofs_per_processor
+ = std::vector<IndexSet> (1,
+ number_cache.locally_owned_dofs);
+ return number_cache;
}
namespace
{
- template <int dim>
- struct types
- {
-
- /**
- * A list of tree+quadrant and
- * their dof indices. dofs is of
- * the form num_dofindices of
- * quadrant 0, followed by
- * num_dofindices indices,
- * num_dofindices of quadrant 1,
- * ...
- */
- struct cellinfo
- {
- std::vector<unsigned int> tree_index;
- std::vector<typename dealii::internal::p4est::types<dim>::quadrant> quadrants;
- std::vector<unsigned int> dofs;
-
- unsigned int bytes_for_buffer () const
- {
- return (sizeof(unsigned int) +
- tree_index.size() * sizeof(unsigned int) +
- quadrants.size() * sizeof(typename dealii::internal::p4est
- ::types<dim>::quadrant) +
- dofs.size() * sizeof(unsigned int));
- }
-
- void pack_data (std::vector<char> &buffer) const
- {
- buffer.resize(bytes_for_buffer());
-
- char * ptr = &buffer[0];
-
- const unsigned int num_cells = tree_index.size();
- std::memcpy(ptr, &num_cells, sizeof(unsigned int));
- ptr += sizeof(unsigned int);
-
- std::memcpy(ptr,
- &tree_index[0],
- num_cells*sizeof(unsigned int));
- ptr += num_cells*sizeof(unsigned int);
-
- std::memcpy(ptr,
- &quadrants[0],
- num_cells * sizeof(typename dealii::internal::p4est::
- types<dim>::quadrant));
- ptr += num_cells*sizeof(typename dealii::internal::p4est::types<dim>::
- quadrant);
-
- std::memcpy(ptr,
- &dofs[0],
- dofs.size() * sizeof(unsigned int));
- ptr += dofs.size() * sizeof(unsigned int);
-
- Assert (ptr == &buffer[0]+buffer.size(),
- ExcInternalError());
-
- }
- };
- };
-
-
-
- template <int dim, int spacedim>
- void
- fill_dofindices_recursively (const typename parallel::distributed::Triangulation<dim,spacedim> & tria,
- const unsigned int tree_index,
- const typename DoFHandler<dim,spacedim>::cell_iterator &dealii_cell,
- const typename dealii::internal::p4est::types<dim>::quadrant &p4est_cell,
- const std::map<unsigned int, std::set<dealii::types::subdomain_id_t> > &vertices_with_ghost_neighbors,
- std::map<dealii::types::subdomain_id_t, typename types<dim>::cellinfo> &needs_to_get_cell)
- {
- // see if we have to
- // recurse...
- if (dealii_cell->has_children())
- {
- typename dealii::internal::p4est::types<dim>::quadrant
- p4est_child[GeometryInfo<dim>::max_children_per_cell];
- internal::p4est::init_quadrant_children<dim>(p4est_cell, p4est_child);
-
-
- for (unsigned int c=0;c<GeometryInfo<dim>::max_children_per_cell; ++c)
- fill_dofindices_recursively<dim,spacedim>(tria,
- tree_index,
- dealii_cell->child(c),
- p4est_child[c],
- vertices_with_ghost_neighbors,
- needs_to_get_cell);
- return;
- }
-
- // we're at a leaf cell. see if
- // the cell is flagged as
- // interesting. note that we
- // have only flagged our own
- // cells before
- if (dealii_cell->user_flag_set() && !dealii_cell->is_ghost())
- {
- Assert (!dealii_cell->is_artificial(), ExcInternalError());
-
- // check each vertex if
- // it is interesting and
- // push dofindices if yes
- std::set<dealii::types::subdomain_id_t> send_to;
- for (unsigned int v=0; v<GeometryInfo<dim>::vertices_per_cell; ++v)
- {
- const std::map<unsigned int, std::set<dealii::types::subdomain_id_t> >::const_iterator
- neighbor_subdomains_of_vertex
- = vertices_with_ghost_neighbors.find (dealii_cell->vertex_index(v));
-
- if (neighbor_subdomains_of_vertex ==
- vertices_with_ghost_neighbors.end())
- continue;
-
- Assert(neighbor_subdomains_of_vertex->second.size()!=0,
- ExcInternalError());
-
- send_to.insert(neighbor_subdomains_of_vertex->second.begin(),
- neighbor_subdomains_of_vertex->second.end());
- }
-
- if (send_to.size() > 0)
- {
- // this cell's dof_indices
- // need to be sent to
- // someone
- std::vector<unsigned int>
- local_dof_indices (dealii_cell->get_fe().dofs_per_cell);
- dealii_cell->get_dof_indices (local_dof_indices);
-
- for (std::set<dealii::types::subdomain_id_t>::iterator it=send_to.begin();
- it!=send_to.end();++it)
- {
- const dealii::types::subdomain_id_t subdomain = *it;
-
- // get an iterator
- // to what needs to
- // be sent to that
- // subdomain (if
- // already exists),
- // or create such
- // an object
- typename std::map<dealii::types::subdomain_id_t, typename types<dim>::cellinfo>::iterator
- p
- = needs_to_get_cell.insert (std::make_pair(subdomain,
- typename types<dim>::cellinfo()))
- .first;
-
- p->second.tree_index.push_back(tree_index);
- p->second.quadrants.push_back(p4est_cell);
-
- p->second.dofs.push_back(dealii_cell->get_fe().dofs_per_cell);
- p->second.dofs.insert(p->second.dofs.end(),
- local_dof_indices.begin(),
- local_dof_indices.end());
-
- }
- }
- }
- }
-
-
- template <int dim, int spacedim>
- void
- set_dofindices_recursively (
- const parallel::distributed::Triangulation<dim,spacedim> &tria,
- const typename dealii::internal::p4est::types<dim>::quadrant &p4est_cell,
- const typename DoFHandler<dim,spacedim>::cell_iterator &dealii_cell,
- const typename dealii::internal::p4est::types<dim>::quadrant &quadrant,
- unsigned int * dofs)
- {
- if (internal::p4est::quadrant_is_equal<dim>(p4est_cell, quadrant))
- {
- Assert(!dealii_cell->has_children(), ExcInternalError());
- Assert(dealii_cell->is_ghost(), ExcInternalError());
-
- // update dof indices of cell
- std::vector<unsigned int>
- dof_indices (dealii_cell->get_fe().dofs_per_cell);
- dealii_cell->update_cell_dof_indices_cache();
- dealii_cell->get_dof_indices(dof_indices);
-
- bool complete = true;
- for (unsigned int i=0;i<dof_indices.size();++i)
- if (dofs[i] != DoFHandler<dim,spacedim>::invalid_dof_index)
- {
- Assert((dof_indices[i] ==
- (DoFHandler<dim,spacedim>::invalid_dof_index))
- ||
- (dof_indices[i]==dofs[i]),
- ExcInternalError());
- dof_indices[i]=dofs[i];
- }
- else
- complete=false;
-
- if (!complete)
- const_cast
- <typename DoFHandler<dim,spacedim>::cell_iterator &>
- (dealii_cell)->set_user_flag();
- else
- const_cast
- <typename DoFHandler<dim,spacedim>::cell_iterator &>
- (dealii_cell)->clear_user_flag();
-
- const_cast
- <typename DoFHandler<dim,spacedim>::cell_iterator &>
- (dealii_cell)->set_dof_indices(dof_indices);
-
- return;
- }
-
- if (! dealii_cell->has_children())
- return;
-
- if (! internal::p4est::quadrant_is_ancestor<dim> (p4est_cell, quadrant))
- return;
-
- typename dealii::internal::p4est::types<dim>::quadrant
- p4est_child[GeometryInfo<dim>::max_children_per_cell];
- internal::p4est::init_quadrant_children<dim>(p4est_cell, p4est_child);
-
- for (unsigned int c=0; c<GeometryInfo<dim>::max_children_per_cell; ++c)
- set_dofindices_recursively<dim,spacedim> (tria, p4est_child[c],
- dealii_cell->child(c),
- quadrant, dofs);
- }
-
- /**
- * Return a vector in which,
- * for every vertex index, we
- * mark whether a locally owned
- * cell is adjacent.
- */
- template <int dim, int spacedim>
- std::vector<bool>
- mark_locally_active_vertices (const parallel::distributed::Triangulation<dim,spacedim> &triangulation)
- {
- std::vector<bool> locally_active_vertices (triangulation.n_vertices(),
- false);
-
- for (typename dealii::Triangulation<dim,spacedim>::active_cell_iterator
- cell = triangulation.begin_active();
- cell != triangulation.end(); ++cell)
- if (cell->subdomain_id() == triangulation.locally_owned_subdomain())
- for (unsigned int v=0; v<GeometryInfo<dim>::vertices_per_cell; ++v)
- locally_active_vertices[cell->vertex_index(v)] = true;
-
- return locally_active_vertices;
- }
-
-
-
- template <int spacedim>
- void
- communicate_dof_indices_on_marked_cells
- (const DoFHandler<1,spacedim> &,
- const std::map<unsigned int, std::set<dealii::types::subdomain_id_t> > &,
- const std::vector<unsigned int> &,
- const std::vector<unsigned int> &)
- {
- Assert (false, ExcNotImplemented());
- }
-
-
-
- template <int dim, int spacedim>
- void
- communicate_dof_indices_on_marked_cells
- (const DoFHandler<dim,spacedim> &dof_handler,
- const std::map<unsigned int, std::set<dealii::types::subdomain_id_t> > &vertices_with_ghost_neighbors,
- const std::vector<unsigned int> &coarse_cell_to_p4est_tree_permutation,
- const std::vector<unsigned int> &p4est_tree_to_coarse_cell_permutation)
- {
+ template <int dim>
+ struct types
+ {
+
+ /**
+ * A list of tree+quadrant and
+ * their dof indices. dofs is of
+ * the form num_dofindices of
+ * quadrant 0, followed by
+ * num_dofindices indices,
+ * num_dofindices of quadrant 1,
+ * ...
+ */
+ struct cellinfo
+ {
+ std::vector<unsigned int> tree_index;
+ std::vector<typename dealii::internal::p4est::types<dim>::quadrant> quadrants;
+ std::vector<unsigned int> dofs;
+
+ unsigned int bytes_for_buffer () const
+ {
+ return (sizeof(unsigned int) +
+ tree_index.size() * sizeof(unsigned int) +
+ quadrants.size() * sizeof(typename dealii::internal::p4est
+ ::types<dim>::quadrant) +
+ dofs.size() * sizeof(unsigned int));
+ }
+
+ void pack_data (std::vector<char> &buffer) const
+ {
+ buffer.resize(bytes_for_buffer());
+
+ char * ptr = &buffer[0];
+
+ const unsigned int num_cells = tree_index.size();
+ std::memcpy(ptr, &num_cells, sizeof(unsigned int));
+ ptr += sizeof(unsigned int);
+
+ std::memcpy(ptr,
+ &tree_index[0],
+ num_cells*sizeof(unsigned int));
+ ptr += num_cells*sizeof(unsigned int);
+
+ std::memcpy(ptr,
+ &quadrants[0],
+ num_cells * sizeof(typename dealii::internal::p4est::
+ types<dim>::quadrant));
+ ptr += num_cells*sizeof(typename dealii::internal::p4est::types<dim>::
+ quadrant);
+
+ std::memcpy(ptr,
+ &dofs[0],
+ dofs.size() * sizeof(unsigned int));
+ ptr += dofs.size() * sizeof(unsigned int);
+
+ Assert (ptr == &buffer[0]+buffer.size(),
+ ExcInternalError());
+
+ }
+ };
+ };
+
+
+
+ template <int dim, int spacedim>
+ void
+ fill_dofindices_recursively (const typename parallel::distributed::Triangulation<dim,spacedim> & tria,
+ const unsigned int tree_index,
+ const typename DoFHandler<dim,spacedim>::cell_iterator &dealii_cell,
+ const typename dealii::internal::p4est::types<dim>::quadrant &p4est_cell,
+ const std::map<unsigned int, std::set<dealii::types::subdomain_id_t> > &vertices_with_ghost_neighbors,
+ std::map<dealii::types::subdomain_id_t, typename types<dim>::cellinfo> &needs_to_get_cell)
+ {
+ // see if we have to
+ // recurse...
+ if (dealii_cell->has_children())
+ {
+ typename dealii::internal::p4est::types<dim>::quadrant
+ p4est_child[GeometryInfo<dim>::max_children_per_cell];
+ internal::p4est::init_quadrant_children<dim>(p4est_cell, p4est_child);
+
+
+ for (unsigned int c=0;c<GeometryInfo<dim>::max_children_per_cell; ++c)
+ fill_dofindices_recursively<dim,spacedim>(tria,
+ tree_index,
+ dealii_cell->child(c),
+ p4est_child[c],
+ vertices_with_ghost_neighbors,
+ needs_to_get_cell);
+ return;
+ }
+
+ // we're at a leaf cell. see if
+ // the cell is flagged as
+ // interesting. note that we
+ // have only flagged our own
+ // cells before
+ if (dealii_cell->user_flag_set() && !dealii_cell->is_ghost())
+ {
+ Assert (!dealii_cell->is_artificial(), ExcInternalError());
+
+ // check each vertex if
+ // it is interesting and
+ // push dofindices if yes
+ std::set<dealii::types::subdomain_id_t> send_to;
+ for (unsigned int v=0; v<GeometryInfo<dim>::vertices_per_cell; ++v)
+ {
+ const std::map<unsigned int, std::set<dealii::types::subdomain_id_t> >::const_iterator
+ neighbor_subdomains_of_vertex
+ = vertices_with_ghost_neighbors.find (dealii_cell->vertex_index(v));
+
+ if (neighbor_subdomains_of_vertex ==
+ vertices_with_ghost_neighbors.end())
+ continue;
+
+ Assert(neighbor_subdomains_of_vertex->second.size()!=0,
+ ExcInternalError());
+
+ send_to.insert(neighbor_subdomains_of_vertex->second.begin(),
+ neighbor_subdomains_of_vertex->second.end());
+ }
+
+ if (send_to.size() > 0)
+ {
+ // this cell's dof_indices
+ // need to be sent to
+ // someone
+ std::vector<unsigned int>
+ local_dof_indices (dealii_cell->get_fe().dofs_per_cell);
+ dealii_cell->get_dof_indices (local_dof_indices);
+
+ for (std::set<dealii::types::subdomain_id_t>::iterator it=send_to.begin();
+ it!=send_to.end();++it)
+ {
+ const dealii::types::subdomain_id_t subdomain = *it;
+
+ // get an iterator
+ // to what needs to
+ // be sent to that
+ // subdomain (if
+ // already exists),
+ // or create such
+ // an object
+ typename std::map<dealii::types::subdomain_id_t, typename types<dim>::cellinfo>::iterator
+ p
+ = needs_to_get_cell.insert (std::make_pair(subdomain,
+ typename types<dim>::cellinfo()))
+ .first;
+
+ p->second.tree_index.push_back(tree_index);
+ p->second.quadrants.push_back(p4est_cell);
+
+ p->second.dofs.push_back(dealii_cell->get_fe().dofs_per_cell);
+ p->second.dofs.insert(p->second.dofs.end(),
+ local_dof_indices.begin(),
+ local_dof_indices.end());
+
+ }
+ }
+ }
+ }
+
+
+ template <int dim, int spacedim>
+ void
+ set_dofindices_recursively (
+ const parallel::distributed::Triangulation<dim,spacedim> &tria,
+ const typename dealii::internal::p4est::types<dim>::quadrant &p4est_cell,
+ const typename DoFHandler<dim,spacedim>::cell_iterator &dealii_cell,
+ const typename dealii::internal::p4est::types<dim>::quadrant &quadrant,
+ unsigned int * dofs)
+ {
+ if (internal::p4est::quadrant_is_equal<dim>(p4est_cell, quadrant))
+ {
+ Assert(!dealii_cell->has_children(), ExcInternalError());
+ Assert(dealii_cell->is_ghost(), ExcInternalError());
+
+ // update dof indices of cell
+ std::vector<unsigned int>
+ dof_indices (dealii_cell->get_fe().dofs_per_cell);
+ dealii_cell->update_cell_dof_indices_cache();
+ dealii_cell->get_dof_indices(dof_indices);
+
+ bool complete = true;
+ for (unsigned int i=0;i<dof_indices.size();++i)
+ if (dofs[i] != DoFHandler<dim,spacedim>::invalid_dof_index)
+ {
+ Assert((dof_indices[i] ==
+ (DoFHandler<dim,spacedim>::invalid_dof_index))
+ ||
+ (dof_indices[i]==dofs[i]),
+ ExcInternalError());
+ dof_indices[i]=dofs[i];
+ }
+ else
+ complete=false;
+
+ if (!complete)
+ const_cast
+ <typename DoFHandler<dim,spacedim>::cell_iterator &>
+ (dealii_cell)->set_user_flag();
+ else
+ const_cast
+ <typename DoFHandler<dim,spacedim>::cell_iterator &>
+ (dealii_cell)->clear_user_flag();
+
+ const_cast
+ <typename DoFHandler<dim,spacedim>::cell_iterator &>
+ (dealii_cell)->set_dof_indices(dof_indices);
+
+ return;
+ }
+
+ if (! dealii_cell->has_children())
+ return;
+
+ if (! internal::p4est::quadrant_is_ancestor<dim> (p4est_cell, quadrant))
+ return;
+
+ typename dealii::internal::p4est::types<dim>::quadrant
+ p4est_child[GeometryInfo<dim>::max_children_per_cell];
+ internal::p4est::init_quadrant_children<dim>(p4est_cell, p4est_child);
+
+ for (unsigned int c=0; c<GeometryInfo<dim>::max_children_per_cell; ++c)
+ set_dofindices_recursively<dim,spacedim> (tria, p4est_child[c],
+ dealii_cell->child(c),
+ quadrant, dofs);
+ }
+
+ /**
+ * Return a vector in which,
+ * for every vertex index, we
+ * mark whether a locally owned
+ * cell is adjacent.
+ */
+ template <int dim, int spacedim>
+ std::vector<bool>
+ mark_locally_active_vertices (const parallel::distributed::Triangulation<dim,spacedim> &triangulation)
+ {
+ std::vector<bool> locally_active_vertices (triangulation.n_vertices(),
+ false);
+
+ for (typename dealii::Triangulation<dim,spacedim>::active_cell_iterator
+ cell = triangulation.begin_active();
+ cell != triangulation.end(); ++cell)
+ if (cell->subdomain_id() == triangulation.locally_owned_subdomain())
+ for (unsigned int v=0; v<GeometryInfo<dim>::vertices_per_cell; ++v)
+ locally_active_vertices[cell->vertex_index(v)] = true;
+
+ return locally_active_vertices;
+ }
+
+
+
+ template <int spacedim>
+ void
+ communicate_dof_indices_on_marked_cells
+ (const DoFHandler<1,spacedim> &,
+ const std::map<unsigned int, std::set<dealii::types::subdomain_id_t> > &,
+ const std::vector<unsigned int> &,
+ const std::vector<unsigned int> &)
+ {
+ Assert (false, ExcNotImplemented());
+ }
+
+
+
+ template <int dim, int spacedim>
+ void
+ communicate_dof_indices_on_marked_cells
+ (const DoFHandler<dim,spacedim> &dof_handler,
+ const std::map<unsigned int, std::set<dealii::types::subdomain_id_t> > &vertices_with_ghost_neighbors,
+ const std::vector<unsigned int> &coarse_cell_to_p4est_tree_permutation,
+ const std::vector<unsigned int> &p4est_tree_to_coarse_cell_permutation)
+ {
#ifndef DEAL_II_USE_P4EST
- (void)vertices_with_ghost_neighbors;
- Assert (false, ExcNotImplemented());
+ (void)vertices_with_ghost_neighbors;
+ Assert (false, ExcNotImplemented());
#else
- const parallel::distributed::Triangulation< dim, spacedim > * tr
- = (dynamic_cast<const parallel::distributed::Triangulation<dim,spacedim>*>
- (&dof_handler.get_tria()));
- Assert (tr != 0, ExcInternalError());
-
- // now collect cells and their
- // dof_indices for the
- // interested neighbors
- typedef
- std::map<dealii::types::subdomain_id_t, typename types<dim>::cellinfo>
- cellmap_t;
- cellmap_t needs_to_get_cells;
-
- for (typename DoFHandler<dim,spacedim>::cell_iterator
- cell = dof_handler.begin(0);
- cell != dof_handler.end(0);
- ++cell)
- {
- typename dealii::internal::p4est::types<dim>::quadrant p4est_coarse_cell;
- internal::p4est::init_coarse_quadrant<dim>(p4est_coarse_cell);
-
- fill_dofindices_recursively<dim,spacedim>
- (*tr,
- coarse_cell_to_p4est_tree_permutation[cell->index()],
- cell,
- p4est_coarse_cell,
- vertices_with_ghost_neighbors,
- needs_to_get_cells);
- }
-
-
-
- //sending
- std::vector<std::vector<char> > sendbuffers (needs_to_get_cells.size());
- std::vector<std::vector<char> >::iterator buffer = sendbuffers.begin();
- std::vector<MPI_Request> requests (needs_to_get_cells.size());
-
- unsigned int idx=0;
-
- for (typename cellmap_t::iterator it=needs_to_get_cells.begin();
- it!=needs_to_get_cells.end();
- ++it, ++buffer, ++idx)
- {
- const unsigned int num_cells = it->second.tree_index.size();
-
- Assert(num_cells==it->second.quadrants.size(), ExcInternalError());
- Assert(num_cells>0, ExcInternalError());
-
- // pack all the data into
- // the buffer for this
- // recipient and send
- // it. keep data around
- // till we can make sure
- // that the packet has been
- // received
- it->second.pack_data (*buffer);
- MPI_Isend(&(*buffer)[0], buffer->size(),
- MPI_BYTE, it->first,
- 123, tr->get_communicator(), &requests[idx]);
- }
-
-
- // mark all own cells, that miss some
- // dof_data and collect the neighbors
- // that are going to send stuff to us
- std::set<dealii::types::subdomain_id_t> senders;
- {
- std::vector<unsigned int> local_dof_indices;
- typename DoFHandler<dim,spacedim>::active_cell_iterator
- cell, endc = dof_handler.end();
-
- for (cell = dof_handler.begin_active(); cell != endc; ++cell)
- if (!cell->is_artificial())
- {
- if (cell->is_ghost())
- {
- if (cell->user_flag_set())
- senders.insert(cell->subdomain_id());
- }
- else
- {
- local_dof_indices.resize (cell->get_fe().dofs_per_cell);
- cell->get_dof_indices (local_dof_indices);
- if (local_dof_indices.end() !=
- std::find (local_dof_indices.begin(),
- local_dof_indices.end(),
- DoFHandler<dim,spacedim>::invalid_dof_index))
- cell->set_user_flag();
- else
- cell->clear_user_flag();
- }
-
- }
- }
-
-
- //* 5. receive ghostcelldata
- std::vector<char> receive;
- typename types<dim>::cellinfo cellinfo;
- for (unsigned int i=0;i<senders.size();++i)
- {
- MPI_Status status;
- int len;
- MPI_Probe(MPI_ANY_SOURCE, 123, tr->get_communicator(), &status);
- MPI_Get_count(&status, MPI_BYTE, &len);
- receive.resize(len);
-
- char * ptr = &receive[0];
- MPI_Recv(ptr, len, MPI_BYTE, status.MPI_SOURCE, status.MPI_TAG,
- tr->get_communicator(), &status);
-
- unsigned int cells;
- memcpy(&cells, ptr, sizeof(unsigned int));
- ptr+=sizeof(unsigned int);
-
- //reinterpret too evil?
- unsigned int * treeindex=reinterpret_cast<unsigned int*>(ptr);
- ptr+=cells*sizeof(unsigned int);
- typename dealii::internal::p4est::types<dim>::quadrant * quadrant
- =reinterpret_cast<typename dealii::internal::p4est::types<dim>::quadrant *>(ptr);
- ptr+=cells*sizeof(typename dealii::internal::p4est::types<dim>::quadrant);
- unsigned int * dofs=reinterpret_cast<unsigned int*>(ptr);
-
- for (unsigned int c=0;c<cells;++c, dofs+=1+dofs[0])
- {
- typename DoFHandler<dim,spacedim>::cell_iterator
- cell (&dof_handler.get_tria(),
- 0,
- p4est_tree_to_coarse_cell_permutation[treeindex[c]],
- &dof_handler);
-
- typename dealii::internal::p4est::types<dim>::quadrant p4est_coarse_cell;
- internal::p4est::init_coarse_quadrant<dim>(p4est_coarse_cell);
-
- Assert(cell->get_fe().dofs_per_cell==dofs[0], ExcInternalError());
-
- set_dofindices_recursively<dim,spacedim> (*tr,
- p4est_coarse_cell,
- cell,
- quadrant[c],
- (dofs+1));
- }
- }
-
- // complete all sends, so that we can
- // safely destroy the buffers.
- if (requests.size() > 0)
- MPI_Waitall(requests.size(), &requests[0], MPI_STATUSES_IGNORE);
+ const parallel::distributed::Triangulation< dim, spacedim > * tr
+ = (dynamic_cast<const parallel::distributed::Triangulation<dim,spacedim>*>
+ (&dof_handler.get_tria()));
+ Assert (tr != 0, ExcInternalError());
+
+ // now collect cells and their
+ // dof_indices for the
+ // interested neighbors
+ typedef
+ std::map<dealii::types::subdomain_id_t, typename types<dim>::cellinfo>
+ cellmap_t;
+ cellmap_t needs_to_get_cells;
+
+ for (typename DoFHandler<dim,spacedim>::cell_iterator
+ cell = dof_handler.begin(0);
+ cell != dof_handler.end(0);
+ ++cell)
+ {
+ typename dealii::internal::p4est::types<dim>::quadrant p4est_coarse_cell;
+ internal::p4est::init_coarse_quadrant<dim>(p4est_coarse_cell);
+
+ fill_dofindices_recursively<dim,spacedim>
+ (*tr,
+ coarse_cell_to_p4est_tree_permutation[cell->index()],
+ cell,
+ p4est_coarse_cell,
+ vertices_with_ghost_neighbors,
+ needs_to_get_cells);
+ }
+
+
+
+ //sending
+ std::vector<std::vector<char> > sendbuffers (needs_to_get_cells.size());
+ std::vector<std::vector<char> >::iterator buffer = sendbuffers.begin();
+ std::vector<MPI_Request> requests (needs_to_get_cells.size());
+
+ unsigned int idx=0;
+
+ for (typename cellmap_t::iterator it=needs_to_get_cells.begin();
+ it!=needs_to_get_cells.end();
+ ++it, ++buffer, ++idx)
+ {
+ const unsigned int num_cells = it->second.tree_index.size();
+
+ Assert(num_cells==it->second.quadrants.size(), ExcInternalError());
+ Assert(num_cells>0, ExcInternalError());
+
+ // pack all the data into
+ // the buffer for this
+ // recipient and send
+ // it. keep data around
+ // till we can make sure
+ // that the packet has been
+ // received
+ it->second.pack_data (*buffer);
+ MPI_Isend(&(*buffer)[0], buffer->size(),
+ MPI_BYTE, it->first,
+ 123, tr->get_communicator(), &requests[idx]);
+ }
+
+
+ // mark all own cells, that miss some
+ // dof_data and collect the neighbors
+ // that are going to send stuff to us
+ std::set<dealii::types::subdomain_id_t> senders;
+ {
+ std::vector<unsigned int> local_dof_indices;
+ typename DoFHandler<dim,spacedim>::active_cell_iterator
+ cell, endc = dof_handler.end();
+
+ for (cell = dof_handler.begin_active(); cell != endc; ++cell)
+ if (!cell->is_artificial())
+ {
+ if (cell->is_ghost())
+ {
+ if (cell->user_flag_set())
+ senders.insert(cell->subdomain_id());
+ }
+ else
+ {
+ local_dof_indices.resize (cell->get_fe().dofs_per_cell);
+ cell->get_dof_indices (local_dof_indices);
+ if (local_dof_indices.end() !=
+ std::find (local_dof_indices.begin(),
+ local_dof_indices.end(),
+ DoFHandler<dim,spacedim>::invalid_dof_index))
+ cell->set_user_flag();
+ else
+ cell->clear_user_flag();
+ }
+
+ }
+ }
+
+
+ //* 5. receive ghostcelldata
+ std::vector<char> receive;
+ typename types<dim>::cellinfo cellinfo;
+ for (unsigned int i=0;i<senders.size();++i)
+ {
+ MPI_Status status;
+ int len;
+ MPI_Probe(MPI_ANY_SOURCE, 123, tr->get_communicator(), &status);
+ MPI_Get_count(&status, MPI_BYTE, &len);
+ receive.resize(len);
+
+ char * ptr = &receive[0];
+ MPI_Recv(ptr, len, MPI_BYTE, status.MPI_SOURCE, status.MPI_TAG,
+ tr->get_communicator(), &status);
+
+ unsigned int cells;
+ memcpy(&cells, ptr, sizeof(unsigned int));
+ ptr+=sizeof(unsigned int);
+
+ //reinterpret too evil?
+ unsigned int * treeindex=reinterpret_cast<unsigned int*>(ptr);
+ ptr+=cells*sizeof(unsigned int);
+ typename dealii::internal::p4est::types<dim>::quadrant * quadrant
+ =reinterpret_cast<typename dealii::internal::p4est::types<dim>::quadrant *>(ptr);
+ ptr+=cells*sizeof(typename dealii::internal::p4est::types<dim>::quadrant);
+ unsigned int * dofs=reinterpret_cast<unsigned int*>(ptr);
+
+ for (unsigned int c=0;c<cells;++c, dofs+=1+dofs[0])
+ {
+ typename DoFHandler<dim,spacedim>::cell_iterator
+ cell (&dof_handler.get_tria(),
+ 0,
+ p4est_tree_to_coarse_cell_permutation[treeindex[c]],
+ &dof_handler);
+
+ typename dealii::internal::p4est::types<dim>::quadrant p4est_coarse_cell;
+ internal::p4est::init_coarse_quadrant<dim>(p4est_coarse_cell);
+
+ Assert(cell->get_fe().dofs_per_cell==dofs[0], ExcInternalError());
+
+ set_dofindices_recursively<dim,spacedim> (*tr,
+ p4est_coarse_cell,
+ cell,
+ quadrant[c],
+ (dofs+1));
+ }
+ }
+
+ // complete all sends, so that we can
+ // safely destroy the buffers.
+ if (requests.size() > 0)
+ MPI_Waitall(requests.size(), &requests[0], MPI_STATUSES_IGNORE);
#ifdef DEBUG
- {
- //check all msgs got sent and received
- unsigned int sum_send=0;
- unsigned int sum_recv=0;
- unsigned int sent=needs_to_get_cells.size();
- unsigned int recv=senders.size();
-
- MPI_Reduce(&sent, &sum_send, 1, MPI_UNSIGNED, MPI_SUM, 0, tr->get_communicator());
- MPI_Reduce(&recv, &sum_recv, 1, MPI_UNSIGNED, MPI_SUM, 0, tr->get_communicator());
- Assert(sum_send==sum_recv, ExcInternalError());
- }
+ {
+ //check all msgs got sent and received
+ unsigned int sum_send=0;
+ unsigned int sum_recv=0;
+ unsigned int sent=needs_to_get_cells.size();
+ unsigned int recv=senders.size();
+
+ MPI_Reduce(&sent, &sum_send, 1, MPI_UNSIGNED, MPI_SUM, 0, tr->get_communicator());
+ MPI_Reduce(&recv, &sum_recv, 1, MPI_UNSIGNED, MPI_SUM, 0, tr->get_communicator());
+ Assert(sum_send==sum_recv, ExcInternalError());
+ }
#endif
- //update dofindices
- {
- typename DoFHandler<dim,spacedim>::active_cell_iterator
- cell, endc = dof_handler.end();
-
- for (cell = dof_handler.begin_active(); cell != endc; ++cell)
- if (!cell->is_artificial())
- cell->update_cell_dof_indices_cache();
- }
-
- // important, so that sends between two
- // calls to this function are not mixed
- // up.
- //
- // this is necessary because above we
- // just see if there are messages and
- // then receive them, without
- // discriminating where they come from
- // and whether they were sent in phase
- // 1 or 2. the need for a global
- // communication step like this barrier
- // could be avoided by receiving
- // messages specifically from those
- // processors from which we expect
- // messages, and by using different
- // tags for phase 1 and 2
- MPI_Barrier(tr->get_communicator());
+ //update dofindices
+ {
+ typename DoFHandler<dim,spacedim>::active_cell_iterator
+ cell, endc = dof_handler.end();
+
+ for (cell = dof_handler.begin_active(); cell != endc; ++cell)
+ if (!cell->is_artificial())
+ cell->update_cell_dof_indices_cache();
+ }
+
+ // important, so that sends between two
+ // calls to this function are not mixed
+ // up.
+ //
+ // this is necessary because above we
+ // just see if there are messages and
+ // then receive them, without
+ // discriminating where they come from
+ // and whether they were sent in phase
+ // 1 or 2. the need for a global
+ // communication step like this barrier
+ // could be avoided by receiving
+ // messages specifically from those
+ // processors from which we expect
+ // messages, and by using different
+ // tags for phase 1 and 2
+ MPI_Barrier(tr->get_communicator());
#endif
- }
+ }
}
#endif // DEAL_II_USE_P4EST
NumberCache
ParallelDistributed<dim, spacedim>::
distribute_dofs (const unsigned int offset,
- DoFHandler<dim,spacedim> &dof_handler) const
+ DoFHandler<dim,spacedim> &dof_handler) const
{
- Assert(offset==0, ExcNotImplemented());
- NumberCache number_cache;
+ Assert(offset==0, ExcNotImplemented());
+ NumberCache number_cache;
#ifndef DEAL_II_USE_P4EST
- (void)dof_handler;
- Assert (false, ExcNotImplemented());
+ (void)dof_handler;
+ Assert (false, ExcNotImplemented());
#else
- parallel::distributed::Triangulation< dim, spacedim > * tr
- = (dynamic_cast<parallel::distributed::Triangulation<dim,spacedim>*>
- (const_cast<dealii::Triangulation< dim, spacedim >*>
- (&dof_handler.get_tria())));
- Assert (tr != 0, ExcInternalError());
-
- const unsigned int
- n_cpus = Utilities::MPI::n_mpi_processes (tr->get_communicator());
-
- //* 1. distribute on own
- //* subdomain
- const unsigned int n_initial_local_dofs =
- Implementation::distribute_dofs (0, tr->locally_owned_subdomain(),
- dof_handler);
-
- //* 2. iterate over ghostcells and
- //kill dofs that are not owned
- //by us
- std::vector<unsigned int> renumbering(n_initial_local_dofs);
- for (unsigned int i=0; i<renumbering.size(); ++i)
- renumbering[i] = i;
-
- {
- std::vector<unsigned int> local_dof_indices;
-
- typename DoFHandler<dim,spacedim>::active_cell_iterator
- cell = dof_handler.begin_active(),
- endc = dof_handler.end();
-
- for (; cell != endc; ++cell)
- if (cell->is_ghost() &&
- (cell->subdomain_id() < tr->locally_owned_subdomain()))
- {
- // we found a
- // neighboring ghost
- // cell whose subdomain
- // is "stronger" than
- // our own subdomain
-
- // delete all dofs that
- // live there and that
- // we have previously
- // assigned a number to
- // (i.e. the ones on
- // the interface)
- local_dof_indices.resize (cell->get_fe().dofs_per_cell);
- cell->get_dof_indices (local_dof_indices);
- for (unsigned int i=0; i<cell->get_fe().dofs_per_cell; ++i)
- if (local_dof_indices[i] != DoFHandler<dim,spacedim>::invalid_dof_index)
- renumbering[local_dof_indices[i]]
- = DoFHandler<dim,spacedim>::invalid_dof_index;
- }
- }
-
-
- // make indices consecutive
- number_cache.n_locally_owned_dofs = 0;
- for (std::vector<unsigned int>::iterator it=renumbering.begin();
- it!=renumbering.end(); ++it)
- if (*it != DoFHandler<dim,spacedim>::invalid_dof_index)
- *it = number_cache.n_locally_owned_dofs++;
-
- //* 3. communicate local dofcount and
- //shift ids to make them unique
- number_cache.n_locally_owned_dofs_per_processor.resize(n_cpus);
-
- MPI_Allgather ( &number_cache.n_locally_owned_dofs,
- 1, MPI_UNSIGNED,
- &number_cache.n_locally_owned_dofs_per_processor[0],
- 1, MPI_UNSIGNED,
- tr->get_communicator());
-
- const unsigned int
- shift = std::accumulate (number_cache
- .n_locally_owned_dofs_per_processor.begin(),
- number_cache
- .n_locally_owned_dofs_per_processor.begin()
- + tr->locally_owned_subdomain(),
- 0);
- for (std::vector<unsigned int>::iterator it=renumbering.begin();
- it!=renumbering.end(); ++it)
- if (*it != DoFHandler<dim,spacedim>::invalid_dof_index)
- (*it) += shift;
-
- // now re-enumerate all dofs to
- // this shifted and condensed
- // numbering form. we renumber
- // some dofs as invalid, so
- // choose the nocheck-version.
- Implementation::renumber_dofs (renumbering, IndexSet(0),
- dof_handler, false);
-
- // now a little bit of
- // housekeeping
- number_cache.n_global_dofs
- = std::accumulate (number_cache
- .n_locally_owned_dofs_per_processor.begin(),
- number_cache
- .n_locally_owned_dofs_per_processor.end(),
- 0);
-
- number_cache.locally_owned_dofs = IndexSet(number_cache.n_global_dofs);
- number_cache.locally_owned_dofs
- .add_range(shift,
- shift+number_cache.n_locally_owned_dofs);
- number_cache.locally_owned_dofs.compress();
-
- // fill global_dof_indexsets
- number_cache.locally_owned_dofs_per_processor.resize(n_cpus);
- {
- unsigned int lshift = 0;
- for (unsigned int i=0;i<n_cpus;++i)
- {
- number_cache.locally_owned_dofs_per_processor[i]
- = IndexSet(number_cache.n_global_dofs);
- number_cache.locally_owned_dofs_per_processor[i]
- .add_range(lshift,
- lshift +
- number_cache.n_locally_owned_dofs_per_processor[i]);
- lshift += number_cache.n_locally_owned_dofs_per_processor[i];
- }
- }
- Assert(number_cache.locally_owned_dofs_per_processor
- [tr->locally_owned_subdomain()].n_elements()
- ==
- number_cache.n_locally_owned_dofs,
- ExcInternalError());
- Assert(!number_cache.locally_owned_dofs_per_processor
- [tr->locally_owned_subdomain()].n_elements()
- ||
- number_cache.locally_owned_dofs_per_processor
- [tr->locally_owned_subdomain()].nth_index_in_set(0)
- == shift,
- ExcInternalError());
-
- //* 4. send dofids of cells that are
- //ghostcells on other machines
-
- std::vector<bool> user_flags;
- tr->save_user_flags(user_flags);
- tr->clear_user_flags ();
-
- //mark all own cells for transfer
- typename DoFHandler<dim,spacedim>::active_cell_iterator
- cell, endc = dof_handler.end();
- for (cell = dof_handler.begin_active(); cell != endc; ++cell)
- if (!cell->is_artificial())
- cell->set_user_flag();
-
- //mark the vertices we are interested
- //in, i.e. belonging to own and marked cells
- const std::vector<bool> locally_active_vertices
- = mark_locally_active_vertices (*tr);
-
- // add each ghostcells'
- // subdomain to the vertex and
- // keep track of interesting
- // neighbors
- std::map<unsigned int, std::set<dealii::types::subdomain_id_t> >
- vertices_with_ghost_neighbors;
- for (typename DoFHandler<dim,spacedim>::active_cell_iterator
- cell = dof_handler.begin_active();
- cell != dof_handler.end(); ++cell)
- if (cell->is_ghost ())
- for (unsigned int v=0; v<GeometryInfo<dim>::vertices_per_cell; ++v)
- if (locally_active_vertices[cell->vertex_index(v)])
- vertices_with_ghost_neighbors[cell->vertex_index(v)]
- .insert (cell->subdomain_id());
-
-
- /* Send and receive cells. After this,
- only the local cells are marked,
- that received new data. This has to
- be communicated in a second
- communication step. */
- communicate_dof_indices_on_marked_cells (dof_handler,
- vertices_with_ghost_neighbors,
- tr->coarse_cell_to_p4est_tree_permutation,
- tr->p4est_tree_to_coarse_cell_permutation);
-
- communicate_dof_indices_on_marked_cells (dof_handler,
- vertices_with_ghost_neighbors,
- tr->coarse_cell_to_p4est_tree_permutation,
- tr->p4est_tree_to_coarse_cell_permutation);
-
- tr->load_user_flags(user_flags);
+ parallel::distributed::Triangulation< dim, spacedim > * tr
+ = (dynamic_cast<parallel::distributed::Triangulation<dim,spacedim>*>
+ (const_cast<dealii::Triangulation< dim, spacedim >*>
+ (&dof_handler.get_tria())));
+ Assert (tr != 0, ExcInternalError());
+
+ const unsigned int
+ n_cpus = Utilities::MPI::n_mpi_processes (tr->get_communicator());
+
+ //* 1. distribute on own
+ //* subdomain
+ const unsigned int n_initial_local_dofs =
+ Implementation::distribute_dofs (0, tr->locally_owned_subdomain(),
+ dof_handler);
+
+ //* 2. iterate over ghostcells and
+ //kill dofs that are not owned
+ //by us
+ std::vector<unsigned int> renumbering(n_initial_local_dofs);
+ for (unsigned int i=0; i<renumbering.size(); ++i)
+ renumbering[i] = i;
+
+ {
+ std::vector<unsigned int> local_dof_indices;
+
+ typename DoFHandler<dim,spacedim>::active_cell_iterator
+ cell = dof_handler.begin_active(),
+ endc = dof_handler.end();
+
+ for (; cell != endc; ++cell)
+ if (cell->is_ghost() &&
+ (cell->subdomain_id() < tr->locally_owned_subdomain()))
+ {
+ // we found a
+ // neighboring ghost
+ // cell whose subdomain
+ // is "stronger" than
+ // our own subdomain
+
+ // delete all dofs that
+ // live there and that
+ // we have previously
+ // assigned a number to
+ // (i.e. the ones on
+ // the interface)
+ local_dof_indices.resize (cell->get_fe().dofs_per_cell);
+ cell->get_dof_indices (local_dof_indices);
+ for (unsigned int i=0; i<cell->get_fe().dofs_per_cell; ++i)
+ if (local_dof_indices[i] != DoFHandler<dim,spacedim>::invalid_dof_index)
+ renumbering[local_dof_indices[i]]
+ = DoFHandler<dim,spacedim>::invalid_dof_index;
+ }
+ }
+
+
+ // make indices consecutive
+ number_cache.n_locally_owned_dofs = 0;
+ for (std::vector<unsigned int>::iterator it=renumbering.begin();
+ it!=renumbering.end(); ++it)
+ if (*it != DoFHandler<dim,spacedim>::invalid_dof_index)
+ *it = number_cache.n_locally_owned_dofs++;
+
+ //* 3. communicate local dofcount and
+ //shift ids to make them unique
+ number_cache.n_locally_owned_dofs_per_processor.resize(n_cpus);
+
+ MPI_Allgather ( &number_cache.n_locally_owned_dofs,
+ 1, MPI_UNSIGNED,
+ &number_cache.n_locally_owned_dofs_per_processor[0],
+ 1, MPI_UNSIGNED,
+ tr->get_communicator());
+
+ const unsigned int
+ shift = std::accumulate (number_cache
+ .n_locally_owned_dofs_per_processor.begin(),
+ number_cache
+ .n_locally_owned_dofs_per_processor.begin()
+ + tr->locally_owned_subdomain(),
+ 0);
+ for (std::vector<unsigned int>::iterator it=renumbering.begin();
+ it!=renumbering.end(); ++it)
+ if (*it != DoFHandler<dim,spacedim>::invalid_dof_index)
+ (*it) += shift;
+
+ // now re-enumerate all dofs to
+ // this shifted and condensed
+ // numbering form. we renumber
+ // some dofs as invalid, so
+ // choose the nocheck-version.
+ Implementation::renumber_dofs (renumbering, IndexSet(0),
+ dof_handler, false);
+
+ // now a little bit of
+ // housekeeping
+ number_cache.n_global_dofs
+ = std::accumulate (number_cache
+ .n_locally_owned_dofs_per_processor.begin(),
+ number_cache
+ .n_locally_owned_dofs_per_processor.end(),
+ 0);
+
+ number_cache.locally_owned_dofs = IndexSet(number_cache.n_global_dofs);
+ number_cache.locally_owned_dofs
+ .add_range(shift,
+ shift+number_cache.n_locally_owned_dofs);
+ number_cache.locally_owned_dofs.compress();
+
+ // fill global_dof_indexsets
+ number_cache.locally_owned_dofs_per_processor.resize(n_cpus);
+ {
+ unsigned int lshift = 0;
+ for (unsigned int i=0;i<n_cpus;++i)
+ {
+ number_cache.locally_owned_dofs_per_processor[i]
+ = IndexSet(number_cache.n_global_dofs);
+ number_cache.locally_owned_dofs_per_processor[i]
+ .add_range(lshift,
+ lshift +
+ number_cache.n_locally_owned_dofs_per_processor[i]);
+ lshift += number_cache.n_locally_owned_dofs_per_processor[i];
+ }
+ }
+ Assert(number_cache.locally_owned_dofs_per_processor
+ [tr->locally_owned_subdomain()].n_elements()
+ ==
+ number_cache.n_locally_owned_dofs,
+ ExcInternalError());
+ Assert(!number_cache.locally_owned_dofs_per_processor
+ [tr->locally_owned_subdomain()].n_elements()
+ ||
+ number_cache.locally_owned_dofs_per_processor
+ [tr->locally_owned_subdomain()].nth_index_in_set(0)
+ == shift,
+ ExcInternalError());
+
+ //* 4. send dofids of cells that are
+ //ghostcells on other machines
+
+ std::vector<bool> user_flags;
+ tr->save_user_flags(user_flags);
+ tr->clear_user_flags ();
+
+ //mark all own cells for transfer
+ typename DoFHandler<dim,spacedim>::active_cell_iterator
+ cell, endc = dof_handler.end();
+ for (cell = dof_handler.begin_active(); cell != endc; ++cell)
+ if (!cell->is_artificial())
+ cell->set_user_flag();
+
+ //mark the vertices we are interested
+ //in, i.e. belonging to own and marked cells
+ const std::vector<bool> locally_active_vertices
+ = mark_locally_active_vertices (*tr);
+
+ // add each ghostcells'
+ // subdomain to the vertex and
+ // keep track of interesting
+ // neighbors
+ std::map<unsigned int, std::set<dealii::types::subdomain_id_t> >
+ vertices_with_ghost_neighbors;
+ for (typename DoFHandler<dim,spacedim>::active_cell_iterator
+ cell = dof_handler.begin_active();
+ cell != dof_handler.end(); ++cell)
+ if (cell->is_ghost ())
+ for (unsigned int v=0; v<GeometryInfo<dim>::vertices_per_cell; ++v)
+ if (locally_active_vertices[cell->vertex_index(v)])
+ vertices_with_ghost_neighbors[cell->vertex_index(v)]
+ .insert (cell->subdomain_id());
+
+
+ /* Send and receive cells. After this,
+ only the local cells are marked,
+ that received new data. This has to
+ be communicated in a second
+ communication step. */
+ communicate_dof_indices_on_marked_cells (dof_handler,
+ vertices_with_ghost_neighbors,
+ tr->coarse_cell_to_p4est_tree_permutation,
+ tr->p4est_tree_to_coarse_cell_permutation);
+
+ communicate_dof_indices_on_marked_cells (dof_handler,
+ vertices_with_ghost_neighbors,
+ tr->coarse_cell_to_p4est_tree_permutation,
+ tr->p4est_tree_to_coarse_cell_permutation);
+
+ tr->load_user_flags(user_flags);
#ifdef DEBUG
- //check that we are really done
- {
- std::vector<unsigned int> local_dof_indices;
- typename DoFHandler<dim,spacedim>::active_cell_iterator
- cell, endc = dof_handler.end();
-
- for (cell = dof_handler.begin_active(); cell != endc; ++cell)
- if (!cell->is_artificial())
- {
- local_dof_indices.resize (cell->get_fe().dofs_per_cell);
- cell->get_dof_indices (local_dof_indices);
- if (local_dof_indices.end() !=
- std::find (local_dof_indices.begin(),
- local_dof_indices.end(),
- DoFHandler<dim,spacedim>::invalid_dof_index))
- {
- if (cell->is_ghost())
- {
- Assert(false, ExcMessage ("Not a ghost cell"));
- }
- else
- {
- Assert(false, ExcMessage ("Not one of our own cells"));
- }
- }
- }
- }
+ //check that we are really done
+ {
+ std::vector<unsigned int> local_dof_indices;
+ typename DoFHandler<dim,spacedim>::active_cell_iterator
+ cell, endc = dof_handler.end();
+
+ for (cell = dof_handler.begin_active(); cell != endc; ++cell)
+ if (!cell->is_artificial())
+ {
+ local_dof_indices.resize (cell->get_fe().dofs_per_cell);
+ cell->get_dof_indices (local_dof_indices);
+ if (local_dof_indices.end() !=
+ std::find (local_dof_indices.begin(),
+ local_dof_indices.end(),
+ DoFHandler<dim,spacedim>::invalid_dof_index))
+ {
+ if (cell->is_ghost())
+ {
+ Assert(false, ExcMessage ("Not a ghost cell"));
+ }
+ else
+ {
+ Assert(false, ExcMessage ("Not one of our own cells"));
+ }
+ }
+ }
+ }
#endif // DEBUG
#endif // DEAL_II_USE_P4EST
- return number_cache;
+ return number_cache;
}
NumberCache
ParallelDistributed<dim, spacedim>::
renumber_dofs (const std::vector<unsigned int> &new_numbers,
- dealii::DoFHandler<dim,spacedim> &dof_handler) const
+ dealii::DoFHandler<dim,spacedim> &dof_handler) const
{
- Assert (new_numbers.size() == dof_handler.locally_owned_dofs().n_elements(),
- ExcInternalError());
+ Assert (new_numbers.size() == dof_handler.locally_owned_dofs().n_elements(),
+ ExcInternalError());
- NumberCache number_cache;
+ NumberCache number_cache;
#ifndef DEAL_II_USE_P4EST
- Assert (false, ExcNotImplemented());
+ Assert (false, ExcNotImplemented());
#else
- //calculate new IndexSet. First try
- //to find out if the new indices are
- //contiguous blocks. This avoids
- //inserting each index individually
- //into the IndexSet, which is slow.
- //If we own no DoFs, we still need to
- //go through this function, but we
- //can skip this calculation.
-
- number_cache.locally_owned_dofs = IndexSet (dof_handler.n_dofs());
- if (dof_handler.locally_owned_dofs().n_elements()>0)
- {
- std::vector<unsigned int>::const_iterator it = new_numbers.begin();
- const unsigned int n_blocks = dof_handler.get_fe().n_blocks();
- std::vector<std::pair<unsigned int,unsigned int> > block_indices(n_blocks);
- block_indices[0].first = *it++;
- block_indices[0].second = 1;
- unsigned int current_block = 0, n_filled_blocks = 1;
- for ( ; it != new_numbers.end(); ++it)
- {
- bool done = false;
-
- // search from the current block onwards
- // whether the next index is shifted by one
- // from the previous one.
- for (unsigned int i=0; i<n_filled_blocks; ++i)
- if (*it == block_indices[current_block].first
- +block_indices[current_block].second)
- {
- block_indices[current_block].second++;
- done = true;
- break;
- }
- else
- {
- if (current_block == n_filled_blocks-1)
- current_block = 0;
- else
- ++current_block;
- }
-
- // could not find any contiguous range: need
- // to add a new block if possible. Abort
- // otherwise, which will add all elements
- // individually to the IndexSet.
- if (done == false)
- {
- if (n_filled_blocks < n_blocks)
- {
- block_indices[n_filled_blocks].first = *it;
- block_indices[n_filled_blocks].second = 1;
- current_block = n_filled_blocks;
- ++n_filled_blocks;
- }
- else
- break;
- }
- }
-
- // check whether all indices could be assigned
- // to blocks. If yes, we can add the block
- // ranges to the IndexSet, otherwise we need
- // to go through the indices once again and
- // add each element individually (slow!)
- unsigned int sum = 0;
- for (unsigned int i=0; i<n_filled_blocks; ++i)
- sum += block_indices[i].second;
- if (sum == new_numbers.size())
- for (unsigned int i=0; i<n_filled_blocks; ++i)
- number_cache.locally_owned_dofs.add_range (block_indices[i].first,
- block_indices[i].first+
- block_indices[i].second);
- else
- for (it=new_numbers.begin() ; it != new_numbers.end(); ++it)
- number_cache.locally_owned_dofs.add_index (*it);
- }
-
-
- number_cache.locally_owned_dofs.compress();
- Assert (number_cache.locally_owned_dofs.n_elements() == new_numbers.size(),
- ExcInternalError());
- // also check with the number
- // of locally owned degrees
- // of freedom that the
- // DoFHandler object still
- // stores
- Assert (number_cache.locally_owned_dofs.n_elements() ==
- dof_handler.n_locally_owned_dofs(),
- ExcInternalError());
-
- // then also set this number
- // in our own copy
- number_cache.n_locally_owned_dofs = dof_handler.n_locally_owned_dofs();
-
- // mark not locally active DoFs as
- // invalid
- {
- std::vector<unsigned int> local_dof_indices;
-
- typename DoFHandler<dim,spacedim>::active_cell_iterator
- cell = dof_handler.begin_active(),
- endc = dof_handler.end();
-
- for (; cell != endc; ++cell)
- if (!cell->is_artificial())
- {
- local_dof_indices.resize (cell->get_fe().dofs_per_cell);
- cell->get_dof_indices (local_dof_indices);
- for (unsigned int i=0; i<cell->get_fe().dofs_per_cell; ++i)
- {
- if (local_dof_indices[i] == DoFHandler<dim,spacedim>::invalid_dof_index)
- continue;
-
- if (!dof_handler.locally_owned_dofs().is_element(local_dof_indices[i]))
- {
- //this DoF is not owned
- //by us, so set it to
- //invalid.
- local_dof_indices[i]
- = DoFHandler<dim,spacedim>::invalid_dof_index;
- }
- }
-
- cell->set_dof_indices (local_dof_indices);
- }
- }
-
-
- // renumber. Skip when there is
- // nothing to do because we own no
- // DoF.
- if (dof_handler.locally_owned_dofs().n_elements() > 0)
- Implementation::renumber_dofs (new_numbers,
- dof_handler.locally_owned_dofs(),
- dof_handler,
- false);
-
- // communication
- {
- parallel::distributed::Triangulation< dim, spacedim > * tr
- = (dynamic_cast<parallel::distributed::Triangulation<dim,spacedim>*>
- (const_cast<dealii::Triangulation< dim, spacedim >*>
- (&dof_handler.get_tria())));
- Assert (tr != 0, ExcInternalError());
-
- std::vector<bool> user_flags;
- tr->save_user_flags(user_flags);
- tr->clear_user_flags ();
-
- //mark all own cells for transfer
- typename DoFHandler<dim,spacedim>::active_cell_iterator
- cell, endc = dof_handler.end();
- for (cell = dof_handler.begin_active(); cell != endc; ++cell)
- if (!cell->is_artificial())
- cell->set_user_flag();
- //mark the vertices we are interested
- //in, i.e. belonging to own and marked cells
- const std::vector<bool> locally_active_vertices
- = mark_locally_active_vertices (*tr);
-
- // add each ghostcells'
- // subdomain to the vertex and
- // keep track of interesting
- // neighbors
- std::map<unsigned int, std::set<dealii::types::subdomain_id_t> >
- vertices_with_ghost_neighbors;
- for (typename DoFHandler<dim,spacedim>::active_cell_iterator
- cell = dof_handler.begin_active();
- cell != dof_handler.end(); ++cell)
- if (cell->is_ghost ())
- for (unsigned int v=0; v<GeometryInfo<dim>::vertices_per_cell; ++v)
- if (locally_active_vertices[cell->vertex_index(v)])
- vertices_with_ghost_neighbors[cell->vertex_index(v)]
- .insert (cell->subdomain_id());
-
- // Send and receive cells. After this, only
- // the local cells are marked, that received
- // new data. This has to be communicated in a
- // second communication step.
- communicate_dof_indices_on_marked_cells (dof_handler,
- vertices_with_ghost_neighbors,
- tr->coarse_cell_to_p4est_tree_permutation,
- tr->p4est_tree_to_coarse_cell_permutation);
-
- communicate_dof_indices_on_marked_cells (dof_handler,
- vertices_with_ghost_neighbors,
- tr->coarse_cell_to_p4est_tree_permutation,
- tr->p4est_tree_to_coarse_cell_permutation);
-
-
- // * Create global_dof_indexsets by
- // transfering our own owned_dofs to
- // every other machine.
- const unsigned int n_cpus = Utilities::System::
- get_n_mpi_processes (tr->get_communicator());
-
- // Serialize our IndexSet and
- // determine size.
- std::ostringstream oss;
- number_cache.locally_owned_dofs.block_write(oss);
- std::string oss_str=oss.str();
- std::vector<char> my_data(oss_str.begin(), oss_str.end());
- unsigned int my_size = oss_str.size();
-
- // determine maximum size of IndexSet
- const unsigned int max_size
- = Utilities::MPI::max (my_size, tr->get_communicator());
-
- // as we are reading past the end, we
- // need to increase the size of the
- // local buffer. This is filled with
- // zeros.
- my_data.resize(max_size);
-
- std::vector<char> buffer(max_size*n_cpus);
- MPI_Allgather(&my_data[0], max_size, MPI_BYTE,
- &buffer[0], max_size, MPI_BYTE,
- tr->get_communicator());
-
- number_cache.locally_owned_dofs_per_processor.resize (n_cpus);
- number_cache.n_locally_owned_dofs_per_processor.resize (n_cpus);
- for (unsigned int i=0;i<n_cpus;++i)
- {
- std::stringstream strstr;
- strstr.write(&buffer[i*max_size],max_size);
- // This does not read the whole
- // buffer, when the size is
- // smaller than
- // max_size. Therefor we need to
- // create a new stringstream in
- // each iteration (resetting
- // would be fine too).
- number_cache.locally_owned_dofs_per_processor[i]
- .block_read(strstr);
- number_cache.n_locally_owned_dofs_per_processor[i]
- = number_cache.locally_owned_dofs_per_processor[i].n_elements();
- }
-
- number_cache.n_global_dofs
- = std::accumulate (number_cache
- .n_locally_owned_dofs_per_processor.begin(),
- number_cache
- .n_locally_owned_dofs_per_processor.end(),
- 0);
-
- tr->load_user_flags(user_flags);
- }
+ //calculate new IndexSet. First try
+ //to find out if the new indices are
+ //contiguous blocks. This avoids
+ //inserting each index individually
+ //into the IndexSet, which is slow.
+ //If we own no DoFs, we still need to
+ //go through this function, but we
+ //can skip this calculation.
+
+ number_cache.locally_owned_dofs = IndexSet (dof_handler.n_dofs());
+ if (dof_handler.locally_owned_dofs().n_elements()>0)
+ {
+ std::vector<unsigned int>::const_iterator it = new_numbers.begin();
+ const unsigned int n_blocks = dof_handler.get_fe().n_blocks();
+ std::vector<std::pair<unsigned int,unsigned int> > block_indices(n_blocks);
+ block_indices[0].first = *it++;
+ block_indices[0].second = 1;
+ unsigned int current_block = 0, n_filled_blocks = 1;
+ for ( ; it != new_numbers.end(); ++it)
+ {
+ bool done = false;
+
+ // search from the current block onwards
+ // whether the next index is shifted by one
+ // from the previous one.
+ for (unsigned int i=0; i<n_filled_blocks; ++i)
+ if (*it == block_indices[current_block].first
+ +block_indices[current_block].second)
+ {
+ block_indices[current_block].second++;
+ done = true;
+ break;
+ }
+ else
+ {
+ if (current_block == n_filled_blocks-1)
+ current_block = 0;
+ else
+ ++current_block;
+ }
+
+ // could not find any contiguous range: need
+ // to add a new block if possible. Abort
+ // otherwise, which will add all elements
+ // individually to the IndexSet.
+ if (done == false)
+ {
+ if (n_filled_blocks < n_blocks)
+ {
+ block_indices[n_filled_blocks].first = *it;
+ block_indices[n_filled_blocks].second = 1;
+ current_block = n_filled_blocks;
+ ++n_filled_blocks;
+ }
+ else
+ break;
+ }
+ }
+
+ // check whether all indices could be assigned
+ // to blocks. If yes, we can add the block
+ // ranges to the IndexSet, otherwise we need
+ // to go through the indices once again and
+ // add each element individually (slow!)
+ unsigned int sum = 0;
+ for (unsigned int i=0; i<n_filled_blocks; ++i)
+ sum += block_indices[i].second;
+ if (sum == new_numbers.size())
+ for (unsigned int i=0; i<n_filled_blocks; ++i)
+ number_cache.locally_owned_dofs.add_range (block_indices[i].first,
+ block_indices[i].first+
+ block_indices[i].second);
+ else
+ for (it=new_numbers.begin() ; it != new_numbers.end(); ++it)
+ number_cache.locally_owned_dofs.add_index (*it);
+ }
+
+
+ number_cache.locally_owned_dofs.compress();
+ Assert (number_cache.locally_owned_dofs.n_elements() == new_numbers.size(),
+ ExcInternalError());
+ // also check with the number
+ // of locally owned degrees
+ // of freedom that the
+ // DoFHandler object still
+ // stores
+ Assert (number_cache.locally_owned_dofs.n_elements() ==
+ dof_handler.n_locally_owned_dofs(),
+ ExcInternalError());
+
+ // then also set this number
+ // in our own copy
+ number_cache.n_locally_owned_dofs = dof_handler.n_locally_owned_dofs();
+
+ // mark not locally active DoFs as
+ // invalid
+ {
+ std::vector<unsigned int> local_dof_indices;
+
+ typename DoFHandler<dim,spacedim>::active_cell_iterator
+ cell = dof_handler.begin_active(),
+ endc = dof_handler.end();
+
+ for (; cell != endc; ++cell)
+ if (!cell->is_artificial())
+ {
+ local_dof_indices.resize (cell->get_fe().dofs_per_cell);
+ cell->get_dof_indices (local_dof_indices);
+ for (unsigned int i=0; i<cell->get_fe().dofs_per_cell; ++i)
+ {
+ if (local_dof_indices[i] == DoFHandler<dim,spacedim>::invalid_dof_index)
+ continue;
+
+ if (!dof_handler.locally_owned_dofs().is_element(local_dof_indices[i]))
+ {
+ //this DoF is not owned
+ //by us, so set it to
+ //invalid.
+ local_dof_indices[i]
+ = DoFHandler<dim,spacedim>::invalid_dof_index;
+ }
+ }
+
+ cell->set_dof_indices (local_dof_indices);
+ }
+ }
+
+
+ // renumber. Skip when there is
+ // nothing to do because we own no
+ // DoF.
+ if (dof_handler.locally_owned_dofs().n_elements() > 0)
+ Implementation::renumber_dofs (new_numbers,
+ dof_handler.locally_owned_dofs(),
+ dof_handler,
+ false);
+
+ // communication
+ {
+ parallel::distributed::Triangulation< dim, spacedim > * tr
+ = (dynamic_cast<parallel::distributed::Triangulation<dim,spacedim>*>
+ (const_cast<dealii::Triangulation< dim, spacedim >*>
+ (&dof_handler.get_tria())));
+ Assert (tr != 0, ExcInternalError());
+
+ std::vector<bool> user_flags;
+ tr->save_user_flags(user_flags);
+ tr->clear_user_flags ();
+
+ //mark all own cells for transfer
+ typename DoFHandler<dim,spacedim>::active_cell_iterator
+ cell, endc = dof_handler.end();
+ for (cell = dof_handler.begin_active(); cell != endc; ++cell)
+ if (!cell->is_artificial())
+ cell->set_user_flag();
+ //mark the vertices we are interested
+ //in, i.e. belonging to own and marked cells
+ const std::vector<bool> locally_active_vertices
+ = mark_locally_active_vertices (*tr);
+
+ // add each ghostcells'
+ // subdomain to the vertex and
+ // keep track of interesting
+ // neighbors
+ std::map<unsigned int, std::set<dealii::types::subdomain_id_t> >
+ vertices_with_ghost_neighbors;
+ for (typename DoFHandler<dim,spacedim>::active_cell_iterator
+ cell = dof_handler.begin_active();
+ cell != dof_handler.end(); ++cell)
+ if (cell->is_ghost ())
+ for (unsigned int v=0; v<GeometryInfo<dim>::vertices_per_cell; ++v)
+ if (locally_active_vertices[cell->vertex_index(v)])
+ vertices_with_ghost_neighbors[cell->vertex_index(v)]
+ .insert (cell->subdomain_id());
+
+ // Send and receive cells. After this, only
+ // the local cells are marked, that received
+ // new data. This has to be communicated in a
+ // second communication step.
+ communicate_dof_indices_on_marked_cells (dof_handler,
+ vertices_with_ghost_neighbors,
+ tr->coarse_cell_to_p4est_tree_permutation,
+ tr->p4est_tree_to_coarse_cell_permutation);
+
+ communicate_dof_indices_on_marked_cells (dof_handler,
+ vertices_with_ghost_neighbors,
+ tr->coarse_cell_to_p4est_tree_permutation,
+ tr->p4est_tree_to_coarse_cell_permutation);
+
+
+ // * Create global_dof_indexsets by
+ // transfering our own owned_dofs to
+ // every other machine.
+ const unsigned int n_cpus = Utilities::System::
+ get_n_mpi_processes (tr->get_communicator());
+
+ // Serialize our IndexSet and
+ // determine size.
+ std::ostringstream oss;
+ number_cache.locally_owned_dofs.block_write(oss);
+ std::string oss_str=oss.str();
+ std::vector<char> my_data(oss_str.begin(), oss_str.end());
+ unsigned int my_size = oss_str.size();
+
+ // determine maximum size of IndexSet
+ const unsigned int max_size
+ = Utilities::MPI::max (my_size, tr->get_communicator());
+
+ // as we are reading past the end, we
+ // need to increase the size of the
+ // local buffer. This is filled with
+ // zeros.
+ my_data.resize(max_size);
+
+ std::vector<char> buffer(max_size*n_cpus);
+ MPI_Allgather(&my_data[0], max_size, MPI_BYTE,
+ &buffer[0], max_size, MPI_BYTE,
+ tr->get_communicator());
+
+ number_cache.locally_owned_dofs_per_processor.resize (n_cpus);
+ number_cache.n_locally_owned_dofs_per_processor.resize (n_cpus);
+ for (unsigned int i=0;i<n_cpus;++i)
+ {
+ std::stringstream strstr;
+ strstr.write(&buffer[i*max_size],max_size);
+ // This does not read the whole
+ // buffer, when the size is
+ // smaller than
+ // max_size. Therefor we need to
+ // create a new stringstream in
+ // each iteration (resetting
+ // would be fine too).
+ number_cache.locally_owned_dofs_per_processor[i]
+ .block_read(strstr);
+ number_cache.n_locally_owned_dofs_per_processor[i]
+ = number_cache.locally_owned_dofs_per_processor[i].n_elements();
+ }
+
+ number_cache.n_global_dofs
+ = std::accumulate (number_cache
+ .n_locally_owned_dofs_per_processor.begin(),
+ number_cache
+ .n_locally_owned_dofs_per_processor.end(),
+ 0);
+
+ tr->load_user_flags(user_flags);
+ }
#endif
- return number_cache;
+ return number_cache;
}
}
}
// $Id$
// Version: $Name$
//
-// Copyright (C) 2000, 2001, 2002, 2003, 2005, 2006, 2011 by the deal.II authors
+// Copyright (C) 2000, 2001, 2002, 2003, 2005, 2006, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
{
namespace DoFHandler
{
-
+
std::size_t
DoFLevel<0>::memory_consumption () const
{
}
-
+
std::size_t
DoFLevel<1>::memory_consumption () const
{
MemoryConsumption::memory_consumption (lines));
}
-
-
+
+
std::size_t
DoFLevel<2>::memory_consumption () const
{
MemoryConsumption::memory_consumption (quads));
}
-
+
std::size_t
DoFLevel<3>::memory_consumption () const
return (DoFLevel<0>::memory_consumption () +
MemoryConsumption::memory_consumption (hexes));
}
-
+
}
-
+
}
DEAL_II_NAMESPACE_CLOSE
// $Id$
// Version: $Name$
//
-// Copyright (C) 2006, 2010, 2011 by the deal.II authors
+// Copyright (C) 2006, 2010, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
void
DoFObjects<dim>::
set_dof_index (const dealii::DoFHandler<dh_dim, spacedim> &dof_handler,
- const unsigned int obj_index,
- const unsigned int fe_index,
- const unsigned int local_index,
- const unsigned int global_index)
+ const unsigned int obj_index,
+ const unsigned int fe_index,
+ const unsigned int local_index,
+ const unsigned int global_index)
{
Assert ((fe_index == dealii::DoFHandler<dh_dim, spacedim>::default_fe_index),
- ExcMessage ("Only the default FE index is allowed for non-hp DoFHandler objects"));
+ ExcMessage ("Only the default FE index is allowed for non-hp DoFHandler objects"));
Assert (local_index<dof_handler.get_fe().template n_dofs_per_object<dim>(),
- ExcIndexRange (local_index, 0, dof_handler.get_fe().template n_dofs_per_object<dim>()));
+ ExcIndexRange (local_index, 0, dof_handler.get_fe().template n_dofs_per_object<dim>()));
Assert (obj_index * dof_handler.get_fe().template n_dofs_per_object<dim>()+local_index
- <
- dofs.size(),
- ExcInternalError());
+ <
+ dofs.size(),
+ ExcInternalError());
dofs[obj_index * dof_handler.get_fe()
.template n_dofs_per_object<dim>() + local_index] = global_index;
// $Id$
// Version: $name$
//
-// Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 by the deal.II authors
+// Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
class WrapDoFIterator : private T
{
public:
- typedef typename T::AccessorType AccessorType;
-
- WrapDoFIterator (const T& t) : T(t) {}
-
- void get_dof_indices (std::vector<unsigned int>& v) const
- {
- (*this)->get_dof_indices(v);
- }
-
- template <class T2>
- bool operator != (const T2& i) const
- {
- return (! (T::operator==(i)));
- }
- // Allow access to these private operators of T
- using T::operator->;
- using T::operator++;
- using T::operator==;
+ typedef typename T::AccessorType AccessorType;
+
+ WrapDoFIterator (const T& t) : T(t) {}
+
+ void get_dof_indices (std::vector<unsigned int>& v) const
+ {
+ (*this)->get_dof_indices(v);
+ }
+
+ template <class T2>
+ bool operator != (const T2& i) const
+ {
+ return (! (T::operator==(i)));
+ }
+ // Allow access to these private operators of T
+ using T::operator->;
+ using T::operator++;
+ using T::operator==;
};
class WrapMGDoFIterator : private T
{
public:
- typedef typename T::AccessorType AccessorType;
-
- WrapMGDoFIterator (const T& t) : T(t) {}
-
- void get_dof_indices (std::vector<unsigned int>& v) const
- {
- (*this)->get_mg_dof_indices(v);
- }
-
- bool operator != (const WrapMGDoFIterator<T>& i) const
- {
- return (! (T::operator==(i)));
- }
- // Allow access to these
- // private operators of T
- using T::operator->;
- using T::operator++;
- using T::operator==;
+ typedef typename T::AccessorType AccessorType;
+
+ WrapMGDoFIterator (const T& t) : T(t) {}
+
+ void get_dof_indices (std::vector<unsigned int>& v) const
+ {
+ (*this)->get_mg_dof_indices(v);
+ }
+
+ bool operator != (const WrapMGDoFIterator<T>& i) const
+ {
+ return (! (T::operator==(i)));
+ }
+ // Allow access to these
+ // private operators of T
+ using T::operator->;
+ using T::operator++;
+ using T::operator==;
};
}
using namespace std;
typedef adjacency_list<vecS, vecS, undirectedS,
- property<vertex_color_t, default_color_type,
- property<vertex_degree_t,int> > > Graph;
+ property<vertex_color_t, default_color_type,
+ property<vertex_degree_t,int> > > Graph;
typedef graph_traits<Graph>::vertex_descriptor Vertex;
typedef graph_traits<Graph>::vertices_size_type size_type;
{
template <class DH>
void create_graph (const DH &dof_handler,
- const bool use_constraints,
- types::Graph &graph,
- types::property_map<types::Graph,types::vertex_degree_t>::type &graph_degree)
+ const bool use_constraints,
+ types::Graph &graph,
+ types::property_map<types::Graph,types::vertex_degree_t>::type &graph_degree)
{
- {
- // create intermediate sparsity pattern
- // (faster than directly submitting
- // indices)
- ConstraintMatrix constraints;
- if (use_constraints)
- DoFTools::make_hanging_node_constraints (dof_handler, constraints);
- constraints.close ();
- CompressedSimpleSparsityPattern csp (dof_handler.n_dofs(),
- dof_handler.n_dofs());
- DoFTools::make_sparsity_pattern (dof_handler, csp, constraints);
-
- // submit the entries to the boost graph
- for (unsigned int row=0;row<csp.n_rows(); ++row)
- for (unsigned int col=0; col < csp.row_length(row); ++col)
- add_edge (row, csp.column_number (row, col), graph);
- }
-
- types::graph_traits<types::Graph>::vertex_iterator ui, ui_end;
-
- graph_degree = get(::boost::vertex_degree, graph);
- for (::boost::tie(ui, ui_end) = vertices(graph); ui != ui_end; ++ui)
- graph_degree[*ui] = degree(*ui, graph);
+ {
+ // create intermediate sparsity pattern
+ // (faster than directly submitting
+ // indices)
+ ConstraintMatrix constraints;
+ if (use_constraints)
+ DoFTools::make_hanging_node_constraints (dof_handler, constraints);
+ constraints.close ();
+ CompressedSimpleSparsityPattern csp (dof_handler.n_dofs(),
+ dof_handler.n_dofs());
+ DoFTools::make_sparsity_pattern (dof_handler, csp, constraints);
+
+ // submit the entries to the boost graph
+ for (unsigned int row=0;row<csp.n_rows(); ++row)
+ for (unsigned int col=0; col < csp.row_length(row); ++col)
+ add_edge (row, csp.column_number (row, col), graph);
+ }
+
+ types::graph_traits<types::Graph>::vertex_iterator ui, ui_end;
+
+ graph_degree = get(::boost::vertex_degree, graph);
+ for (::boost::tie(ui, ui_end) = vertices(graph); ui != ui_end; ++ui)
+ graph_degree[*ui] = degree(*ui, graph);
}
}
#endif
template <class DH>
void
Cuthill_McKee (DH& dof_handler,
- const bool reversed_numbering,
- const bool use_constraints)
+ const bool reversed_numbering,
+ const bool use_constraints)
{
std::vector<unsigned int> renumbering(dof_handler.n_dofs(),
- DH::invalid_dof_index);
+ DH::invalid_dof_index);
compute_Cuthill_McKee(renumbering, dof_handler, reversed_numbering,
- use_constraints);
+ use_constraints);
- // actually perform renumbering;
- // this is dimension specific and
- // thus needs an own function
+ // actually perform renumbering;
+ // this is dimension specific and
+ // thus needs an own function
dof_handler.renumber_dofs (renumbering);
}
template <class DH>
void
compute_Cuthill_McKee (std::vector<unsigned int>& new_dof_indices,
- const DH &dof_handler,
- const bool reversed_numbering,
- const bool use_constraints)
+ const DH &dof_handler,
+ const bool reversed_numbering,
+ const bool use_constraints)
{
#ifdef DEAL_II_BOOST_GRAPH_COMPILER_BUG
(void)new_dof_indices;
(void)reversed_numbering;
(void)use_constraints;
Assert (false,
- ExcMessage ("Due to a bug in your compiler, this function triggers an internal "
- "compiler error and has been disabled. If you need to use the "
- "function, you need to upgrade to a newer version of the compiler."));
+ ExcMessage ("Due to a bug in your compiler, this function triggers an internal "
+ "compiler error and has been disabled. If you need to use the "
+ "function, you need to upgrade to a newer version of the compiler."));
#else
types::Graph
- graph(dof_handler.n_dofs());
+ graph(dof_handler.n_dofs());
types::property_map<types::Graph,types::vertex_degree_t>::type
- graph_degree;
+ graph_degree;
internal::create_graph (dof_handler, use_constraints, graph, graph_degree);
types::property_map<types::Graph, types::vertex_index_t>::type
- index_map = get(::boost::vertex_index, graph);
+ index_map = get(::boost::vertex_index, graph);
std::vector<types::Vertex> inv_perm(num_vertices(graph));
if (reversed_numbering == false)
- ::boost::cuthill_mckee_ordering(graph, inv_perm.rbegin(),
- get(::boost::vertex_color, graph),
- make_degree_map(graph));
+ ::boost::cuthill_mckee_ordering(graph, inv_perm.rbegin(),
+ get(::boost::vertex_color, graph),
+ make_degree_map(graph));
else
- ::boost::cuthill_mckee_ordering(graph, inv_perm.begin(),
- get(::boost::vertex_color, graph),
- make_degree_map(graph));
+ ::boost::cuthill_mckee_ordering(graph, inv_perm.begin(),
+ get(::boost::vertex_color, graph),
+ make_degree_map(graph));
for (types::size_type c = 0; c != inv_perm.size(); ++c)
- new_dof_indices[index_map[inv_perm[c]]] = c;
+ new_dof_indices[index_map[inv_perm[c]]] = c;
Assert (std::find (new_dof_indices.begin(), new_dof_indices.end(),
- DH::invalid_dof_index) == new_dof_indices.end(),
- ExcInternalError());
+ DH::invalid_dof_index) == new_dof_indices.end(),
+ ExcInternalError());
#endif
}
template <class DH>
void
king_ordering (DH& dof_handler,
- const bool reversed_numbering,
- const bool use_constraints)
+ const bool reversed_numbering,
+ const bool use_constraints)
{
std::vector<unsigned int> renumbering(dof_handler.n_dofs(),
- DH::invalid_dof_index);
+ DH::invalid_dof_index);
compute_king_ordering(renumbering, dof_handler, reversed_numbering,
- use_constraints);
+ use_constraints);
- // actually perform renumbering;
- // this is dimension specific and
- // thus needs an own function
+ // actually perform renumbering;
+ // this is dimension specific and
+ // thus needs an own function
dof_handler.renumber_dofs (renumbering);
}
template <class DH>
void
compute_king_ordering (std::vector<unsigned int>& new_dof_indices,
- const DH &dof_handler,
- const bool reversed_numbering,
- const bool use_constraints)
+ const DH &dof_handler,
+ const bool reversed_numbering,
+ const bool use_constraints)
{
#ifdef DEAL_II_BOOST_GRAPH_COMPILER_BUG
(void)new_dof_indices;
(void)reversed_numbering;
(void)use_constraints;
Assert (false,
- ExcMessage ("Due to a bug in your compiler, this function triggers an internal "
- "compiler error and has been disabled. If you need to use the "
- "function, you need to upgrade to a newer version of the compiler."));
+ ExcMessage ("Due to a bug in your compiler, this function triggers an internal "
+ "compiler error and has been disabled. If you need to use the "
+ "function, you need to upgrade to a newer version of the compiler."));
#else
types::Graph
- graph(dof_handler.n_dofs());
+ graph(dof_handler.n_dofs());
types::property_map<types::Graph,types::vertex_degree_t>::type
- graph_degree;
+ graph_degree;
internal::create_graph (dof_handler, use_constraints, graph, graph_degree);
types::property_map<types::Graph, types::vertex_index_t>::type
- index_map = get(::boost::vertex_index, graph);
+ index_map = get(::boost::vertex_index, graph);
std::vector<types::Vertex> inv_perm(num_vertices(graph));
if (reversed_numbering == false)
- ::boost::king_ordering(graph, inv_perm.rbegin());
+ ::boost::king_ordering(graph, inv_perm.rbegin());
else
- ::boost::king_ordering(graph, inv_perm.begin());
+ ::boost::king_ordering(graph, inv_perm.begin());
for (types::size_type c = 0; c != inv_perm.size(); ++c)
- new_dof_indices[index_map[inv_perm[c]]] = c;
+ new_dof_indices[index_map[inv_perm[c]]] = c;
Assert (std::find (new_dof_indices.begin(), new_dof_indices.end(),
- DH::invalid_dof_index) == new_dof_indices.end(),
- ExcInternalError());
+ DH::invalid_dof_index) == new_dof_indices.end(),
+ ExcInternalError());
#endif
}
template <class DH>
void
minimum_degree (DH& dof_handler,
- const bool reversed_numbering,
- const bool use_constraints)
+ const bool reversed_numbering,
+ const bool use_constraints)
{
std::vector<unsigned int> renumbering(dof_handler.n_dofs(),
- DH::invalid_dof_index);
+ DH::invalid_dof_index);
compute_minimum_degree(renumbering, dof_handler, reversed_numbering,
- use_constraints);
+ use_constraints);
- // actually perform renumbering;
- // this is dimension specific and
- // thus needs an own function
+ // actually perform renumbering;
+ // this is dimension specific and
+ // thus needs an own function
dof_handler.renumber_dofs (renumbering);
}
template <class DH>
void
compute_minimum_degree (std::vector<unsigned int>& new_dof_indices,
- const DH &dof_handler,
- const bool reversed_numbering,
- const bool use_constraints)
+ const DH &dof_handler,
+ const bool reversed_numbering,
+ const bool use_constraints)
{
Assert (use_constraints == false, ExcNotImplemented());
- // the following code is pretty
- // much a verbatim copy of the
- // sample code for the
- // minimum_degree_ordering manual
- // page from the BOOST Graph
- // Library
+ // the following code is pretty
+ // much a verbatim copy of the
+ // sample code for the
+ // minimum_degree_ordering manual
+ // page from the BOOST Graph
+ // Library
using namespace ::boost;
int delta = 0;
typedef double Type;
- // must be BGL directed graph now
+ // must be BGL directed graph now
typedef adjacency_list<vecS, vecS, directedS> Graph;
typedef graph_traits<Graph>::vertex_descriptor Vertex;
std::vector<unsigned int> dofs_on_this_cell;
typename DH::active_cell_iterator cell = dof_handler.begin_active(),
- endc = dof_handler.end();
+ endc = dof_handler.end();
for (; cell!=endc; ++cell)
- {
+ {
- const unsigned int dofs_per_cell = cell->get_fe().dofs_per_cell;
+ const unsigned int dofs_per_cell = cell->get_fe().dofs_per_cell;
- dofs_on_this_cell.resize (dofs_per_cell);
+ dofs_on_this_cell.resize (dofs_per_cell);
- cell->get_dof_indices (dofs_on_this_cell);
- for (unsigned int i=0; i<dofs_per_cell; ++i)
- for (unsigned int j=0; j<dofs_per_cell; ++j)
- if (dofs_on_this_cell[i] > dofs_on_this_cell[j])
- {
- add_edge (dofs_on_this_cell[i], dofs_on_this_cell[j], G);
- add_edge (dofs_on_this_cell[j], dofs_on_this_cell[i], G);
- }
- }
+ cell->get_dof_indices (dofs_on_this_cell);
+ for (unsigned int i=0; i<dofs_per_cell; ++i)
+ for (unsigned int j=0; j<dofs_per_cell; ++j)
+ if (dofs_on_this_cell[i] > dofs_on_this_cell[j])
+ {
+ add_edge (dofs_on_this_cell[i], dofs_on_this_cell[j], G);
+ add_edge (dofs_on_this_cell[j], dofs_on_this_cell[i], G);
+ }
+ }
typedef std::vector<int> Vector;
Vector supernode_sizes(n, 1);
- // init has to be 1
+ // init has to be 1
::boost::property_map<Graph, vertex_index_t>::type
- id = get(vertex_index, G);
+ id = get(vertex_index, G);
Vector degree(n, 0);
minimum_degree_ordering
- (G,
- make_iterator_property_map(°ree[0], id, degree[0]),
- &inverse_perm[0],
- &perm[0],
- make_iterator_property_map(&supernode_sizes[0], id, supernode_sizes[0]),
- delta, id);
+ (G,
+ make_iterator_property_map(°ree[0], id, degree[0]),
+ &inverse_perm[0],
+ &perm[0],
+ make_iterator_property_map(&supernode_sizes[0], id, supernode_sizes[0]),
+ delta, id);
for (int i=0; i<n; ++i)
- {
- Assert (std::find (perm.begin(), perm.end(), i)
- != perm.end(),
- ExcInternalError());
- Assert (std::find (inverse_perm.begin(), inverse_perm.end(), i)
- != inverse_perm.end(),
- ExcInternalError());
- Assert (inverse_perm[perm[i]] == i, ExcInternalError());
- }
+ {
+ Assert (std::find (perm.begin(), perm.end(), i)
+ != perm.end(),
+ ExcInternalError());
+ Assert (std::find (inverse_perm.begin(), inverse_perm.end(), i)
+ != inverse_perm.end(),
+ ExcInternalError());
+ Assert (inverse_perm[perm[i]] == i, ExcInternalError());
+ }
if (reversed_numbering == true)
- std::copy (perm.begin(), perm.end(),
- new_dof_indices.begin());
+ std::copy (perm.begin(), perm.end(),
+ new_dof_indices.begin());
else
- std::copy (inverse_perm.begin(), inverse_perm.end(),
- new_dof_indices.begin());
+ std::copy (inverse_perm.begin(), inverse_perm.end(),
+ new_dof_indices.begin());
}
} // namespace boost
template <class DH>
void
Cuthill_McKee (DH& dof_handler,
- const bool reversed_numbering,
- const bool use_constraints,
- const std::vector<unsigned int> &starting_indices)
+ const bool reversed_numbering,
+ const bool use_constraints,
+ const std::vector<unsigned int> &starting_indices)
{
std::vector<unsigned int> renumbering(dof_handler.n_dofs(),
- DH::invalid_dof_index);
+ DH::invalid_dof_index);
compute_Cuthill_McKee(renumbering, dof_handler, reversed_numbering,
- use_constraints, starting_indices);
+ use_constraints, starting_indices);
- // actually perform renumbering;
- // this is dimension specific and
- // thus needs an own function
+ // actually perform renumbering;
+ // this is dimension specific and
+ // thus needs an own function
dof_handler.renumber_dofs (renumbering);
}
template <class DH>
void
compute_Cuthill_McKee (std::vector<unsigned int>& new_indices,
- const DH& dof_handler,
- const bool reversed_numbering,
- const bool use_constraints,
- const std::vector<unsigned int>& starting_indices)
+ const DH& dof_handler,
+ const bool reversed_numbering,
+ const bool use_constraints,
+ const std::vector<unsigned int>& starting_indices)
{
- // make the connection graph. in
- // more than 2d use an intermediate
- // compressed sparsity pattern
- // since the we don't have very
- // good estimates for
- // max_couplings_between_dofs() in
- // 3d and this then leads to
- // excessive memory consumption
- //
- // note that if constraints are not
- // requested, then the
- // 'constraints' object will be
- // empty, and calling condense with
- // it is a no-op
+ // make the connection graph. in
+ // more than 2d use an intermediate
+ // compressed sparsity pattern
+ // since the we don't have very
+ // good estimates for
+ // max_couplings_between_dofs() in
+ // 3d and this then leads to
+ // excessive memory consumption
+ //
+ // note that if constraints are not
+ // requested, then the
+ // 'constraints' object will be
+ // empty, and calling condense with
+ // it is a no-op
ConstraintMatrix constraints;
if (use_constraints)
DoFTools::make_hanging_node_constraints (dof_handler, constraints);
SparsityPattern sparsity;
if (DH::dimension < 2)
{
- sparsity.reinit (dof_handler.n_dofs(),
- dof_handler.n_dofs(),
- dof_handler.max_couplings_between_dofs());
- DoFTools::make_sparsity_pattern (dof_handler, sparsity, constraints);
- sparsity.compress();
+ sparsity.reinit (dof_handler.n_dofs(),
+ dof_handler.n_dofs(),
+ dof_handler.max_couplings_between_dofs());
+ DoFTools::make_sparsity_pattern (dof_handler, sparsity, constraints);
+ sparsity.compress();
}
else
{
- CompressedSimpleSparsityPattern csp (dof_handler.n_dofs(),
- dof_handler.n_dofs());
- DoFTools::make_sparsity_pattern (dof_handler, csp, constraints);
- sparsity.copy_from (csp);
+ CompressedSimpleSparsityPattern csp (dof_handler.n_dofs(),
+ dof_handler.n_dofs());
+ DoFTools::make_sparsity_pattern (dof_handler, csp, constraints);
+ sparsity.copy_from (csp);
}
- // constraints are not needed anymore
+ // constraints are not needed anymore
constraints.clear ();
Assert(new_indices.size() == sparsity.n_rows(),
- ExcDimensionMismatch(new_indices.size(),
- sparsity.n_rows()));
+ ExcDimensionMismatch(new_indices.size(),
+ sparsity.n_rows()));
SparsityTools::reorder_Cuthill_McKee (sparsity, new_indices,
- starting_indices);
+ starting_indices);
if (reversed_numbering)
new_indices = Utilities::reverse_permutation (new_indices);
template <int dim>
void Cuthill_McKee (MGDoFHandler<dim> &dof_handler,
- const unsigned int level,
- const bool reversed_numbering,
- const std::vector<unsigned int> &starting_indices)
+ const unsigned int level,
+ const bool reversed_numbering,
+ const std::vector<unsigned int> &starting_indices)
{
//TODO: we should be doing the same here as in the other compute_CMK function to preserve some memory
- // make the connection graph
+ // make the connection graph
SparsityPattern sparsity (dof_handler.n_dofs(level),
- dof_handler.max_couplings_between_dofs());
+ dof_handler.max_couplings_between_dofs());
MGTools::make_sparsity_pattern (dof_handler, sparsity, level);
std::vector<unsigned int> new_indices(sparsity.n_rows());
SparsityTools::reorder_Cuthill_McKee (sparsity, new_indices,
- starting_indices);
+ starting_indices);
if (reversed_numbering)
new_indices = Utilities::reverse_permutation (new_indices);
- // actually perform renumbering;
- // this is dimension specific and
- // thus needs an own function
+ // actually perform renumbering;
+ // this is dimension specific and
+ // thus needs an own function
dof_handler.renumber_dofs (level, new_indices);
}
template <int dim, int spacedim>
void
component_wise (DoFHandler<dim,spacedim> &dof_handler,
- const std::vector<unsigned int> &component_order_arg)
+ const std::vector<unsigned int> &component_order_arg)
{
std::vector<unsigned int> renumbering (dof_handler.n_locally_owned_dofs(),
- DoFHandler<dim>::invalid_dof_index);
+ DoFHandler<dim>::invalid_dof_index);
typedef
internal::WrapDoFIterator<typename DoFHandler<dim,spacedim>
if (result == 0)
return;
- // verify that the last numbered
- // degree of freedom is either
- // equal to the number of degrees
- // of freedom in total (the
- // sequential case) or in the
- // distributed case at least
- // makes sense
+ // verify that the last numbered
+ // degree of freedom is either
+ // equal to the number of degrees
+ // of freedom in total (the
+ // sequential case) or in the
+ // distributed case at least
+ // makes sense
Assert ((result == dof_handler.n_locally_owned_dofs())
- ||
- ((dof_handler.n_locally_owned_dofs() < dof_handler.n_dofs())
- &&
- (result <= dof_handler.n_dofs())),
- ExcRenumberingIncomplete());
+ ||
+ ((dof_handler.n_locally_owned_dofs() < dof_handler.n_dofs())
+ &&
+ (result <= dof_handler.n_dofs())),
+ ExcRenumberingIncomplete());
dof_handler.renumber_dofs (renumbering);
}
template <int dim>
void
component_wise (hp::DoFHandler<dim> &dof_handler,
- const std::vector<unsigned int> &component_order_arg)
+ const std::vector<unsigned int> &component_order_arg)
{
std::vector<unsigned int> renumbering (dof_handler.n_dofs(),
- hp::DoFHandler<dim>::invalid_dof_index);
+ hp::DoFHandler<dim>::invalid_dof_index);
typedef
internal::WrapDoFIterator<typename hp::DoFHandler<dim>::active_cell_iterator> ITERATOR;
const unsigned int result =
compute_component_wise<dim, dim, ITERATOR,
typename hp::DoFHandler<dim>::cell_iterator>(renumbering,
- start, end,
- component_order_arg);
+ start, end,
+ component_order_arg);
if (result == 0) return;
Assert (result == dof_handler.n_dofs(),
- ExcRenumberingIncomplete());
+ ExcRenumberingIncomplete());
dof_handler.renumber_dofs (renumbering);
}
template <int dim>
void
component_wise (MGDoFHandler<dim> &dof_handler,
- const unsigned int level,
- const std::vector<unsigned int> &component_order_arg)
+ const unsigned int level,
+ const std::vector<unsigned int> &component_order_arg)
{
std::vector<unsigned int> renumbering (dof_handler.n_dofs(level),
- DoFHandler<dim>::invalid_dof_index);
+ DoFHandler<dim>::invalid_dof_index);
typedef
internal::WrapMGDoFIterator<typename MGDoFHandler<dim>::cell_iterator> ITERATOR;
const unsigned int result =
compute_component_wise<dim, dim, ITERATOR, ITERATOR>(
- renumbering, start, end, component_order_arg);
+ renumbering, start, end, component_order_arg);
if (result == 0) return;
Assert (result == dof_handler.n_dofs(level),
- ExcRenumberingIncomplete());
+ ExcRenumberingIncomplete());
if (renumbering.size()!=0)
dof_handler.renumber_dofs (level, renumbering);
template <int dim>
void
component_wise (MGDoFHandler<dim> &dof_handler,
- const std::vector<unsigned int> &component_order_arg)
+ const std::vector<unsigned int> &component_order_arg)
{
- // renumber the non-MG part of
- // the DoFHandler in parallel to
- // the MG part. Because
- // MGDoFHandler::renumber_dofs
- // uses the user flags we can't
- // run renumbering on individual
- // levels in parallel to the
- // other levels
+ // renumber the non-MG part of
+ // the DoFHandler in parallel to
+ // the MG part. Because
+ // MGDoFHandler::renumber_dofs
+ // uses the user flags we can't
+ // run renumbering on individual
+ // levels in parallel to the
+ // other levels
void (*non_mg_part) (DoFHandler<dim> &, const std::vector<unsigned int> &)
= &component_wise<dim>;
Threads::Task<>
template <int dim, int spacedim, class ITERATOR, class ENDITERATOR>
unsigned int
compute_component_wise (std::vector<unsigned int>& new_indices,
- const ITERATOR & start,
- const ENDITERATOR& end,
- const std::vector<unsigned int> &component_order_arg)
+ const ITERATOR & start,
+ const ENDITERATOR& end,
+ const std::vector<unsigned int> &component_order_arg)
{
const hp::FECollection<dim,spacedim>
fe_collection (start->get_dof_handler().get_fe ());
- // do nothing if the FE has only
- // one component
+ // do nothing if the FE has only
+ // one component
if (fe_collection.n_components() == 1)
{
- new_indices.resize(0);
- return 0;
+ new_indices.resize(0);
+ return 0;
}
- // Copy last argument into a
- // writable vector.
+ // Copy last argument into a
+ // writable vector.
std::vector<unsigned int> component_order (component_order_arg);
- // If the last argument was an
- // empty vector, set up things to
- // store components in the order
- // found in the system.
+ // If the last argument was an
+ // empty vector, set up things to
+ // store components in the order
+ // found in the system.
if (component_order.size() == 0)
for (unsigned int i=0; i<fe_collection.n_components(); ++i)
- component_order.push_back (i);
+ component_order.push_back (i);
Assert (component_order.size() == fe_collection.n_components(),
- ExcDimensionMismatch(component_order.size(), fe_collection.n_components()));
+ ExcDimensionMismatch(component_order.size(), fe_collection.n_components()));
for (unsigned int i=0; i<component_order.size(); ++i)
Assert(component_order[i] < fe_collection.n_components(),
- ExcIndexRange(component_order[i], 0, fe_collection.n_components()));
+ ExcIndexRange(component_order[i], 0, fe_collection.n_components()));
- // vector to hold the dof indices on
- // the cell we visit at a time
+ // vector to hold the dof indices on
+ // the cell we visit at a time
std::vector<unsigned int> local_dof_indices;
- // prebuilt list to which component
- // a given dof on a cell
- // should go. note that we get into
- // trouble here if the shape
- // function is not primitive, since
- // then there is no single vector
- // component to which it
- // belongs. in this case, assign it
- // to the first vector component to
- // which it belongs
+ // prebuilt list to which component
+ // a given dof on a cell
+ // should go. note that we get into
+ // trouble here if the shape
+ // function is not primitive, since
+ // then there is no single vector
+ // component to which it
+ // belongs. in this case, assign it
+ // to the first vector component to
+ // which it belongs
std::vector<std::vector<unsigned int> > component_list (fe_collection.size());
for (unsigned int f=0; f<fe_collection.size(); ++f)
{
- const FiniteElement<dim,spacedim> & fe = fe_collection[f];
- const unsigned int dofs_per_cell = fe.dofs_per_cell;
- component_list[f].resize(dofs_per_cell);
- for (unsigned int i=0; i<dofs_per_cell; ++i)
- if (fe.is_primitive(i))
- component_list[f][i]
- = component_order[fe.system_to_component_index(i).first];
- else
- {
- const unsigned int comp = (std::find(fe.get_nonzero_components(i).begin(),
- fe.get_nonzero_components(i).end(),
- true) -
- fe.get_nonzero_components(i).begin());
-
- // then associate this degree
- // of freedom with this
- // component
- component_list[f][i] = component_order[comp];
- }
+ const FiniteElement<dim,spacedim> & fe = fe_collection[f];
+ const unsigned int dofs_per_cell = fe.dofs_per_cell;
+ component_list[f].resize(dofs_per_cell);
+ for (unsigned int i=0; i<dofs_per_cell; ++i)
+ if (fe.is_primitive(i))
+ component_list[f][i]
+ = component_order[fe.system_to_component_index(i).first];
+ else
+ {
+ const unsigned int comp = (std::find(fe.get_nonzero_components(i).begin(),
+ fe.get_nonzero_components(i).end(),
+ true) -
+ fe.get_nonzero_components(i).begin());
+
+ // then associate this degree
+ // of freedom with this
+ // component
+ component_list[f][i] = component_order[comp];
+ }
}
- // set up a map where for each
- // component the respective degrees
- // of freedom are collected.
- //
- // note that this map is sorted by
- // component but that within each
- // component it is NOT sorted by
- // dof index. note also that some
- // dof indices are entered
- // multiply, so we will have to
- // take care of that
+ // set up a map where for each
+ // component the respective degrees
+ // of freedom are collected.
+ //
+ // note that this map is sorted by
+ // component but that within each
+ // component it is NOT sorted by
+ // dof index. note also that some
+ // dof indices are entered
+ // multiply, so we will have to
+ // take care of that
std::vector<std::vector<unsigned int> >
component_to_dof_map (fe_collection.n_components());
for (ITERATOR cell=start; cell!=end; ++cell)
if (cell->is_locally_owned())
- {
- // on each cell: get dof indices
- // and insert them into the global
- // list using their component
- const unsigned int fe_index = cell->active_fe_index();
- const unsigned int dofs_per_cell =fe_collection[fe_index].dofs_per_cell;
- local_dof_indices.resize (dofs_per_cell);
- cell.get_dof_indices (local_dof_indices);
- for (unsigned int i=0; i<dofs_per_cell; ++i)
- if (start->get_dof_handler().locally_owned_dofs().is_element(local_dof_indices[i]))
- component_to_dof_map[component_list[fe_index][i]].
- push_back (local_dof_indices[i]);
- }
-
- // now we've got all indices sorted
- // into buckets labelled with their
- // target component number. we've
- // only got to traverse this list
- // and assign the new indices
- //
- // however, we first want to sort
- // the indices entered into the
- // buckets to preserve the order
- // within each component and during
- // this also remove duplicate
- // entries
- //
- // note that we no longer have to
- // care about non-primitive shape
- // functions since the buckets
- // corresponding to the second and
- // following vector components of a
- // non-primitive FE will simply be
- // empty, everything being shoved
- // into the first one. The same
- // holds if several components were
- // joined into a single target.
+ {
+ // on each cell: get dof indices
+ // and insert them into the global
+ // list using their component
+ const unsigned int fe_index = cell->active_fe_index();
+ const unsigned int dofs_per_cell =fe_collection[fe_index].dofs_per_cell;
+ local_dof_indices.resize (dofs_per_cell);
+ cell.get_dof_indices (local_dof_indices);
+ for (unsigned int i=0; i<dofs_per_cell; ++i)
+ if (start->get_dof_handler().locally_owned_dofs().is_element(local_dof_indices[i]))
+ component_to_dof_map[component_list[fe_index][i]].
+ push_back (local_dof_indices[i]);
+ }
+
+ // now we've got all indices sorted
+ // into buckets labelled with their
+ // target component number. we've
+ // only got to traverse this list
+ // and assign the new indices
+ //
+ // however, we first want to sort
+ // the indices entered into the
+ // buckets to preserve the order
+ // within each component and during
+ // this also remove duplicate
+ // entries
+ //
+ // note that we no longer have to
+ // care about non-primitive shape
+ // functions since the buckets
+ // corresponding to the second and
+ // following vector components of a
+ // non-primitive FE will simply be
+ // empty, everything being shoved
+ // into the first one. The same
+ // holds if several components were
+ // joined into a single target.
for (unsigned int component=0; component<fe_collection.n_components();
- ++component)
+ ++component)
{
- std::sort (component_to_dof_map[component].begin(),
- component_to_dof_map[component].end());
- component_to_dof_map[component]
- .erase (std::unique (component_to_dof_map[component].begin(),
- component_to_dof_map[component].end()),
- component_to_dof_map[component].end());
+ std::sort (component_to_dof_map[component].begin(),
+ component_to_dof_map[component].end());
+ component_to_dof_map[component]
+ .erase (std::unique (component_to_dof_map[component].begin(),
+ component_to_dof_map[component].end()),
+ component_to_dof_map[component].end());
}
- // calculate the number of locally owned
- // DoFs per bucket
+ // calculate the number of locally owned
+ // DoFs per bucket
const unsigned int n_buckets = fe_collection.n_components();
std::vector<unsigned int> shifts(n_buckets);
if (const parallel::distributed::Triangulation<dim,spacedim> * tria
- = (dynamic_cast<const parallel::distributed::Triangulation<dim,spacedim>*>
- (&start->get_dof_handler().get_tria())))
+ = (dynamic_cast<const parallel::distributed::Triangulation<dim,spacedim>*>
+ (&start->get_dof_handler().get_tria())))
{
#ifdef DEAL_II_USE_P4EST
- std::vector<unsigned int> local_dof_count(n_buckets);
-
- for (unsigned int c=0; c<n_buckets; ++c)
- local_dof_count[c] = component_to_dof_map[c].size();
-
-
- // gather information from all CPUs
- std::vector<unsigned int>
- all_dof_counts(fe_collection.n_components() *
- Utilities::MPI::n_mpi_processes (tria->get_communicator()));
-
- MPI_Allgather ( &local_dof_count[0], n_buckets, MPI_UNSIGNED, &all_dof_counts[0],
- n_buckets, MPI_UNSIGNED, tria->get_communicator());
-
- for (unsigned int i=0; i<n_buckets; ++i)
- Assert (all_dof_counts[n_buckets*tria->locally_owned_subdomain()+i]
- ==
- local_dof_count[i],
- ExcInternalError());
-
- //calculate shifts
- unsigned int cumulated = 0;
- for (unsigned int c=0; c<n_buckets; ++c)
- {
- shifts[c]=cumulated;
- for (types::subdomain_id_t i=0; i<tria->locally_owned_subdomain(); ++i)
- shifts[c] += all_dof_counts[c+n_buckets*i];
- for (unsigned int i=0; i<Utilities::MPI::n_mpi_processes (tria->get_communicator()); ++i)
- cumulated += all_dof_counts[c+n_buckets*i];
- }
+ std::vector<unsigned int> local_dof_count(n_buckets);
+
+ for (unsigned int c=0; c<n_buckets; ++c)
+ local_dof_count[c] = component_to_dof_map[c].size();
+
+
+ // gather information from all CPUs
+ std::vector<unsigned int>
+ all_dof_counts(fe_collection.n_components() *
+ Utilities::MPI::n_mpi_processes (tria->get_communicator()));
+
+ MPI_Allgather ( &local_dof_count[0], n_buckets, MPI_UNSIGNED, &all_dof_counts[0],
+ n_buckets, MPI_UNSIGNED, tria->get_communicator());
+
+ for (unsigned int i=0; i<n_buckets; ++i)
+ Assert (all_dof_counts[n_buckets*tria->locally_owned_subdomain()+i]
+ ==
+ local_dof_count[i],
+ ExcInternalError());
+
+ //calculate shifts
+ unsigned int cumulated = 0;
+ for (unsigned int c=0; c<n_buckets; ++c)
+ {
+ shifts[c]=cumulated;
+ for (types::subdomain_id_t i=0; i<tria->locally_owned_subdomain(); ++i)
+ shifts[c] += all_dof_counts[c+n_buckets*i];
+ for (unsigned int i=0; i<Utilities::MPI::n_mpi_processes (tria->get_communicator()); ++i)
+ cumulated += all_dof_counts[c+n_buckets*i];
+ }
#else
- (void)tria;
- Assert (false, ExcInternalError());
+ (void)tria;
+ Assert (false, ExcInternalError());
#endif
}
else
{
- shifts[0] = 0;
- for (unsigned int c=1; c<fe_collection.n_components(); ++c)
- shifts[c] = shifts[c-1] + component_to_dof_map[c-1].size();
+ shifts[0] = 0;
+ for (unsigned int c=1; c<fe_collection.n_components(); ++c)
+ shifts[c] = shifts[c-1] + component_to_dof_map[c-1].size();
}
- // now concatenate all the
- // components in the order the user
- // desired to see
+ // now concatenate all the
+ // components in the order the user
+ // desired to see
unsigned int next_free_index = 0;
for (unsigned int component=0; component<fe_collection.n_components(); ++component)
{
- const typename std::vector<unsigned int>::const_iterator
- begin_of_component = component_to_dof_map[component].begin(),
- end_of_component = component_to_dof_map[component].end();
-
- next_free_index = shifts[component];
-
- for (typename std::vector<unsigned int>::const_iterator
- dof_index = begin_of_component;
- dof_index != end_of_component; ++dof_index)
- {
- Assert (start->get_dof_handler().locally_owned_dofs()
- .index_within_set(*dof_index)
- <
- new_indices.size(),
- ExcInternalError());
- new_indices[start->get_dof_handler().locally_owned_dofs()
- .index_within_set(*dof_index)]
- = next_free_index++;
- }
+ const typename std::vector<unsigned int>::const_iterator
+ begin_of_component = component_to_dof_map[component].begin(),
+ end_of_component = component_to_dof_map[component].end();
+
+ next_free_index = shifts[component];
+
+ for (typename std::vector<unsigned int>::const_iterator
+ dof_index = begin_of_component;
+ dof_index != end_of_component; ++dof_index)
+ {
+ Assert (start->get_dof_handler().locally_owned_dofs()
+ .index_within_set(*dof_index)
+ <
+ new_indices.size(),
+ ExcInternalError());
+ new_indices[start->get_dof_handler().locally_owned_dofs()
+ .index_within_set(*dof_index)]
+ = next_free_index++;
+ }
}
return next_free_index;
namespace
{
- // helper function for hierarchical()
+ // helper function for hierarchical()
template <int dim, class iterator>
unsigned int
compute_hierarchical_recursive (
{
if (cell->has_children())
{
- //recursion
+ //recursion
for (unsigned int c = 0;c < GeometryInfo<dim>::max_children_per_cell; ++c)
next_free = compute_hierarchical_recursive<dim> (
next_free,
hierarchical (DoFHandler<dim> &dof_handler)
{
std::vector<unsigned int> renumbering (dof_handler.n_locally_owned_dofs(),
- DoFHandler<dim>::invalid_dof_index);
+ DoFHandler<dim>::invalid_dof_index);
- typename DoFHandler<dim>::cell_iterator cell;
+ typename DoFHandler<dim>::cell_iterator cell;
- unsigned int next_free = 0;
- const IndexSet locally_owned = dof_handler.locally_owned_dofs();
+ unsigned int next_free = 0;
+ const IndexSet locally_owned = dof_handler.locally_owned_dofs();
const parallel::distributed::Triangulation<dim> * tria
- = dynamic_cast<const parallel::distributed::Triangulation<dim>*>
- (&dof_handler.get_tria());
+ = dynamic_cast<const parallel::distributed::Triangulation<dim>*>
+ (&dof_handler.get_tria());
- if (tria)
+ if (tria)
{
#ifdef DEAL_II_USE_P4EST
//this is a distributed Triangulation. We need to traverse the coarse
locally_owned);
}
- // verify that the last numbered
- // degree of freedom is either
- // equal to the number of degrees
- // of freedom in total (the
- // sequential case) or in the
- // distributed case at least
- // makes sense
+ // verify that the last numbered
+ // degree of freedom is either
+ // equal to the number of degrees
+ // of freedom in total (the
+ // sequential case) or in the
+ // distributed case at least
+ // makes sense
Assert ((next_free == dof_handler.n_locally_owned_dofs())
- ||
- ((dof_handler.n_locally_owned_dofs() < dof_handler.n_dofs())
- &&
- (next_free <= dof_handler.n_dofs())),
- ExcRenumberingIncomplete());
-
- // make sure that all local DoFs got new numbers assigned
- Assert (std::find (renumbering.begin(), renumbering.end(),
- numbers::invalid_unsigned_int)
- == renumbering.end(),
- ExcInternalError());
-
- dof_handler.renumber_dofs(renumbering);
+ ||
+ ((dof_handler.n_locally_owned_dofs() < dof_handler.n_dofs())
+ &&
+ (next_free <= dof_handler.n_dofs())),
+ ExcRenumberingIncomplete());
+
+ // make sure that all local DoFs got new numbers assigned
+ Assert (std::find (renumbering.begin(), renumbering.end(),
+ numbers::invalid_unsigned_int)
+ == renumbering.end(),
+ ExcInternalError());
+
+ dof_handler.renumber_dofs(renumbering);
}
template <class DH>
void
sort_selected_dofs_back (DH& dof_handler,
- const std::vector<bool>& selected_dofs)
+ const std::vector<bool>& selected_dofs)
{
std::vector<unsigned int> renumbering(dof_handler.n_dofs(),
- DH::invalid_dof_index);
+ DH::invalid_dof_index);
compute_sort_selected_dofs_back(renumbering, dof_handler, selected_dofs);
dof_handler.renumber_dofs(renumbering);
template <class DH>
void
compute_sort_selected_dofs_back (std::vector<unsigned int>& new_indices,
- const DH& dof_handler,
- const std::vector<bool>& selected_dofs)
+ const DH& dof_handler,
+ const std::vector<bool>& selected_dofs)
{
const unsigned int n_dofs = dof_handler.n_dofs();
Assert (selected_dofs.size() == n_dofs,
- ExcDimensionMismatch (selected_dofs.size(), n_dofs));
+ ExcDimensionMismatch (selected_dofs.size(), n_dofs));
- // re-sort the dofs according to
- // their selection state
+ // re-sort the dofs according to
+ // their selection state
Assert (new_indices.size() == n_dofs,
- ExcDimensionMismatch(new_indices.size(), n_dofs));
+ ExcDimensionMismatch(new_indices.size(), n_dofs));
const unsigned int n_selected_dofs = std::count (selected_dofs.begin(),
- selected_dofs.end(),
- false);
+ selected_dofs.end(),
+ false);
unsigned int next_unselected = 0;
unsigned int next_selected = n_selected_dofs;
for (unsigned int i=0; i<n_dofs; ++i)
if (selected_dofs[i] == false)
- {
- new_indices[i] = next_unselected;
- ++next_unselected;
- }
+ {
+ new_indices[i] = next_unselected;
+ ++next_unselected;
+ }
else
- {
- new_indices[i] = next_selected;
- ++next_selected;
- };
+ {
+ new_indices[i] = next_selected;
+ ++next_selected;
+ };
Assert (next_unselected == n_selected_dofs, ExcInternalError());
Assert (next_selected == n_dofs, ExcInternalError());
}
template <class DH>
void
cell_wise_dg (DH& dof,
- const std::vector<typename DH::cell_iterator>& cells)
+ const std::vector<typename DH::cell_iterator>& cells)
{
std::vector<unsigned int> renumbering(dof.n_dofs());
std::vector<unsigned int> reverse(dof.n_dofs());
const typename std::vector<typename DH::cell_iterator>& cells)
{
Assert(cells.size() == dof.get_tria().n_active_cells(),
- ExcDimensionMismatch(cells.size(),
- dof.get_tria().n_active_cells()));
+ ExcDimensionMismatch(cells.size(),
+ dof.get_tria().n_active_cells()));
unsigned int n_global_dofs = dof.n_dofs();
- // Actually, we compute the
- // inverse of the reordering
- // vector, called reverse here.
- // Later, its inverse is computed
- // into new_indices, which is the
- // return argument.
+ // Actually, we compute the
+ // inverse of the reordering
+ // vector, called reverse here.
+ // Later, its inverse is computed
+ // into new_indices, which is the
+ // return argument.
Assert(new_indices.size() == n_global_dofs,
- ExcDimensionMismatch(new_indices.size(), n_global_dofs));
+ ExcDimensionMismatch(new_indices.size(), n_global_dofs));
Assert(reverse.size() == n_global_dofs,
- ExcDimensionMismatch(reverse.size(), n_global_dofs));
+ ExcDimensionMismatch(reverse.size(), n_global_dofs));
std::vector<unsigned int> cell_dofs;
for(cell = cells.begin(); cell != cells.end(); ++cell)
{
- Assert((*cell)->get_fe().n_dofs_per_face()==0, ExcNotDGFEM());
- // Determine the number of dofs
- // on this cell and reinit the
- // vector storing these
- // numbers.
- unsigned int n_cell_dofs = (*cell)->get_fe().n_dofs_per_cell();
- cell_dofs.resize(n_cell_dofs);
-
- (*cell)->get_dof_indices(cell_dofs);
-
- // Sort here to make sure that
- // degrees of freedom inside a
- // single cell are in the same
- // order after renumbering.
- std::sort(cell_dofs.begin(), cell_dofs.end());
-
- for (unsigned int i=0;i<n_cell_dofs;++i)
- {
- reverse[global_index++] = cell_dofs[i];
- }
+ Assert((*cell)->get_fe().n_dofs_per_face()==0, ExcNotDGFEM());
+ // Determine the number of dofs
+ // on this cell and reinit the
+ // vector storing these
+ // numbers.
+ unsigned int n_cell_dofs = (*cell)->get_fe().n_dofs_per_cell();
+ cell_dofs.resize(n_cell_dofs);
+
+ (*cell)->get_dof_indices(cell_dofs);
+
+ // Sort here to make sure that
+ // degrees of freedom inside a
+ // single cell are in the same
+ // order after renumbering.
+ std::sort(cell_dofs.begin(), cell_dofs.end());
+
+ for (unsigned int i=0;i<n_cell_dofs;++i)
+ {
+ reverse[global_index++] = cell_dofs[i];
+ }
}
Assert(global_index == n_global_dofs, ExcRenumberingIncomplete());
const typename std::vector<typename DH::cell_iterator>& cells)
{
Assert(cells.size() == dof.get_tria().n_active_cells(),
- ExcDimensionMismatch(cells.size(),
- dof.get_tria().n_active_cells()));
+ ExcDimensionMismatch(cells.size(),
+ dof.get_tria().n_active_cells()));
unsigned int n_global_dofs = dof.n_dofs();
- // Actually, we compute the
- // inverse of the reordering
- // vector, called reverse here.
- // Later, irs inverse is computed
- // into new_indices, which is the
- // return argument.
+ // Actually, we compute the
+ // inverse of the reordering
+ // vector, called reverse here.
+ // Later, irs inverse is computed
+ // into new_indices, which is the
+ // return argument.
Assert(new_indices.size() == n_global_dofs,
- ExcDimensionMismatch(new_indices.size(), n_global_dofs));
+ ExcDimensionMismatch(new_indices.size(), n_global_dofs));
Assert(reverse.size() == n_global_dofs,
- ExcDimensionMismatch(reverse.size(), n_global_dofs));
+ ExcDimensionMismatch(reverse.size(), n_global_dofs));
- // For continuous elements, we must
- // make sure, that each dof is
- // reordered only once.
+ // For continuous elements, we must
+ // make sure, that each dof is
+ // reordered only once.
std::vector<bool> already_sorted(n_global_dofs, false);
std::vector<unsigned int> cell_dofs;
for(cell = cells.begin(); cell != cells.end(); ++cell)
{
- // Determine the number of dofs
- // on this cell and reinit the
- // vector storing these
- // numbers.
- unsigned int n_cell_dofs = (*cell)->get_fe().n_dofs_per_cell();
- cell_dofs.resize(n_cell_dofs);
-
- (*cell)->get_dof_indices(cell_dofs);
-
- // Sort here to make sure that
- // degrees of freedom inside a
- // single cell are in the same
- // order after renumbering.
- std::sort(cell_dofs.begin(), cell_dofs.end());
-
- for (unsigned int i=0;i<n_cell_dofs;++i)
- {
- if (!already_sorted[cell_dofs[i]])
- {
- already_sorted[cell_dofs[i]] = true;
- reverse[global_index++] = cell_dofs[i];
- }
- }
+ // Determine the number of dofs
+ // on this cell and reinit the
+ // vector storing these
+ // numbers.
+ unsigned int n_cell_dofs = (*cell)->get_fe().n_dofs_per_cell();
+ cell_dofs.resize(n_cell_dofs);
+
+ (*cell)->get_dof_indices(cell_dofs);
+
+ // Sort here to make sure that
+ // degrees of freedom inside a
+ // single cell are in the same
+ // order after renumbering.
+ std::sort(cell_dofs.begin(), cell_dofs.end());
+
+ for (unsigned int i=0;i<n_cell_dofs;++i)
+ {
+ if (!already_sorted[cell_dofs[i]])
+ {
+ already_sorted[cell_dofs[i]] = true;
+ reverse[global_index++] = cell_dofs[i];
+ }
+ }
}
Assert(global_index == n_global_dofs, ExcRenumberingIncomplete());
const typename std::vector<typename MGDoFHandler<dim>::cell_iterator>& cells)
{
Assert(cells.size() == dof.get_tria().n_cells(level),
- ExcDimensionMismatch(cells.size(),
- dof.get_tria().n_cells(level)));
+ ExcDimensionMismatch(cells.size(),
+ dof.get_tria().n_cells(level)));
switch (dim)
{
- case 3:
- Assert(dof.get_fe().n_dofs_per_quad()==0,
- ExcNotDGFEM());
- case 2:
- Assert(dof.get_fe().n_dofs_per_line()==0,
- ExcNotDGFEM());
- default:
- Assert(dof.get_fe().n_dofs_per_vertex()==0,
- ExcNotDGFEM());
+ case 3:
+ Assert(dof.get_fe().n_dofs_per_quad()==0,
+ ExcNotDGFEM());
+ case 2:
+ Assert(dof.get_fe().n_dofs_per_line()==0,
+ ExcNotDGFEM());
+ default:
+ Assert(dof.get_fe().n_dofs_per_vertex()==0,
+ ExcNotDGFEM());
}
Assert (new_order.size() == dof.n_dofs(level),
- ExcDimensionMismatch(new_order.size(), dof.n_dofs(level)));
+ ExcDimensionMismatch(new_order.size(), dof.n_dofs(level)));
Assert (reverse.size() == dof.n_dofs(level),
- ExcDimensionMismatch(reverse.size(), dof.n_dofs(level)));
+ ExcDimensionMismatch(reverse.size(), dof.n_dofs(level)));
unsigned int n_global_dofs = dof.n_dofs(level);
unsigned int n_cell_dofs = dof.get_fe().n_dofs_per_cell();
for(cell = cells.begin(); cell != cells.end(); ++cell)
{
- Assert ((*cell)->level() == (int) level, ExcInternalError());
+ Assert ((*cell)->level() == (int) level, ExcInternalError());
- (*cell)->get_mg_dof_indices(cell_dofs);
- std::sort(cell_dofs.begin(), cell_dofs.end());
+ (*cell)->get_mg_dof_indices(cell_dofs);
+ std::sort(cell_dofs.begin(), cell_dofs.end());
- for (unsigned int i=0;i<n_cell_dofs;++i)
- {
- reverse[global_index++] = cell_dofs[i];
- }
+ for (unsigned int i=0;i<n_cell_dofs;++i)
+ {
+ reverse[global_index++] = cell_dofs[i];
+ }
}
Assert(global_index == n_global_dofs, ExcRenumberingIncomplete());
const typename std::vector<typename MGDoFHandler<dim>::cell_iterator>& cells)
{
Assert(cells.size() == dof.get_tria().n_cells(level),
- ExcDimensionMismatch(cells.size(),
- dof.get_tria().n_cells(level)));
+ ExcDimensionMismatch(cells.size(),
+ dof.get_tria().n_cells(level)));
Assert (new_order.size() == dof.n_dofs(level),
- ExcDimensionMismatch(new_order.size(), dof.n_dofs(level)));
+ ExcDimensionMismatch(new_order.size(), dof.n_dofs(level)));
Assert (reverse.size() == dof.n_dofs(level),
- ExcDimensionMismatch(reverse.size(), dof.n_dofs(level)));
+ ExcDimensionMismatch(reverse.size(), dof.n_dofs(level)));
unsigned int n_global_dofs = dof.n_dofs(level);
unsigned int n_cell_dofs = dof.get_fe().n_dofs_per_cell();
for(cell = cells.begin(); cell != cells.end(); ++cell)
{
- Assert ((*cell)->level() == (int) level, ExcInternalError());
-
- (*cell)->get_mg_dof_indices(cell_dofs);
- std::sort(cell_dofs.begin(), cell_dofs.end());
-
- for (unsigned int i=0;i<n_cell_dofs;++i)
- {
- if (!already_sorted[cell_dofs[i]])
- {
- already_sorted[cell_dofs[i]] = true;
- reverse[global_index++] = cell_dofs[i];
- }
- }
+ Assert ((*cell)->level() == (int) level, ExcInternalError());
+
+ (*cell)->get_mg_dof_indices(cell_dofs);
+ std::sort(cell_dofs.begin(), cell_dofs.end());
+
+ for (unsigned int i=0;i<n_cell_dofs;++i)
+ {
+ if (!already_sorted[cell_dofs[i]])
+ {
+ already_sorted[cell_dofs[i]] = true;
+ reverse[global_index++] = cell_dofs[i];
+ }
+ }
}
Assert(global_index == n_global_dofs, ExcRenumberingIncomplete());
template <class DH, int dim>
void
downstream (DH& dof, const Point<dim>& direction,
- const bool dof_wise_renumbering)
+ const bool dof_wise_renumbering)
{
std::vector<unsigned int> renumbering(dof.n_dofs());
std::vector<unsigned int> reverse(dof.n_dofs());
compute_downstream(renumbering, reverse, dof, direction,
- dof_wise_renumbering);
+ dof_wise_renumbering);
dof.renumber_dofs(renumbering);
}
{
if (dof_wise_renumbering == false)
{
- std::vector<typename DH::cell_iterator>
- ordered_cells(dof.get_tria().n_active_cells());
- const CompareDownstream<typename DH::cell_iterator, dim> comparator(direction);
+ std::vector<typename DH::cell_iterator>
+ ordered_cells(dof.get_tria().n_active_cells());
+ const CompareDownstream<typename DH::cell_iterator, dim> comparator(direction);
- typename DH::active_cell_iterator begin = dof.begin_active();
- typename DH::active_cell_iterator end = dof.end();
+ typename DH::active_cell_iterator begin = dof.begin_active();
+ typename DH::active_cell_iterator end = dof.end();
- copy (begin, end, ordered_cells.begin());
- std::sort (ordered_cells.begin(), ordered_cells.end(), comparator);
+ copy (begin, end, ordered_cells.begin());
+ std::sort (ordered_cells.begin(), ordered_cells.end(), comparator);
- compute_cell_wise(new_indices, reverse, dof, ordered_cells);
+ compute_cell_wise(new_indices, reverse, dof, ordered_cells);
}
else
{
- // similar code as for
- // DoFTools::map_dofs_to_support_points, but
- // need to do this for general DH classes and
- // want to be able to sort the result
- // (otherwise, could use something like
- // DoFTools::map_support_points_to_dofs)
- const unsigned int n_dofs = dof.n_dofs();
- std::vector<std::pair<Point<dim>,unsigned int> > support_point_list
- (n_dofs);
-
- const hp::FECollection<dim> fe_collection (dof.get_fe ());
- Assert (fe_collection[0].has_support_points(),
- typename FiniteElement<dim>::ExcFEHasNoSupportPoints());
- hp::QCollection<dim> quadrature_collection;
- for (unsigned int comp=0; comp<fe_collection.size(); ++comp)
- {
- Assert (fe_collection[comp].has_support_points(),
- typename FiniteElement<dim>::ExcFEHasNoSupportPoints());
- quadrature_collection.push_back
- (Quadrature<DH::dimension> (fe_collection[comp].
- get_unit_support_points()));
- }
- hp::FEValues<DH::dimension,DH::space_dimension>
- hp_fe_values (fe_collection, quadrature_collection,
- update_quadrature_points);
-
- std::vector<bool> already_touched (n_dofs, false);
-
- std::vector<unsigned int> local_dof_indices;
- typename DH::active_cell_iterator begin = dof.begin_active();
- typename DH::active_cell_iterator end = dof.end();
- for ( ; begin != end; ++begin)
- {
- const unsigned int dofs_per_cell = begin->get_fe().dofs_per_cell;
- local_dof_indices.resize (dofs_per_cell);
- hp_fe_values.reinit (begin);
- const FEValues<dim> &fe_values =
- hp_fe_values.get_present_fe_values ();
- begin->get_dof_indices(local_dof_indices);
- const std::vector<Point<DH::space_dimension> > & points
- = fe_values.get_quadrature_points ();
- for (unsigned int i=0; i<dofs_per_cell; ++i)
- if (!already_touched[local_dof_indices[i]])
- {
- support_point_list[local_dof_indices[i]].first = points[i];
- support_point_list[local_dof_indices[i]].second =
- local_dof_indices[i];
- already_touched[local_dof_indices[i]] = true;
- }
- }
-
- ComparePointwiseDownstream<dim> comparator (direction);
- std::sort (support_point_list.begin(), support_point_list.end(),
- comparator);
- for (unsigned int i=0; i<n_dofs; ++i)
- new_indices[support_point_list[i].second] = i;
+ // similar code as for
+ // DoFTools::map_dofs_to_support_points, but
+ // need to do this for general DH classes and
+ // want to be able to sort the result
+ // (otherwise, could use something like
+ // DoFTools::map_support_points_to_dofs)
+ const unsigned int n_dofs = dof.n_dofs();
+ std::vector<std::pair<Point<dim>,unsigned int> > support_point_list
+ (n_dofs);
+
+ const hp::FECollection<dim> fe_collection (dof.get_fe ());
+ Assert (fe_collection[0].has_support_points(),
+ typename FiniteElement<dim>::ExcFEHasNoSupportPoints());
+ hp::QCollection<dim> quadrature_collection;
+ for (unsigned int comp=0; comp<fe_collection.size(); ++comp)
+ {
+ Assert (fe_collection[comp].has_support_points(),
+ typename FiniteElement<dim>::ExcFEHasNoSupportPoints());
+ quadrature_collection.push_back
+ (Quadrature<DH::dimension> (fe_collection[comp].
+ get_unit_support_points()));
+ }
+ hp::FEValues<DH::dimension,DH::space_dimension>
+ hp_fe_values (fe_collection, quadrature_collection,
+ update_quadrature_points);
+
+ std::vector<bool> already_touched (n_dofs, false);
+
+ std::vector<unsigned int> local_dof_indices;
+ typename DH::active_cell_iterator begin = dof.begin_active();
+ typename DH::active_cell_iterator end = dof.end();
+ for ( ; begin != end; ++begin)
+ {
+ const unsigned int dofs_per_cell = begin->get_fe().dofs_per_cell;
+ local_dof_indices.resize (dofs_per_cell);
+ hp_fe_values.reinit (begin);
+ const FEValues<dim> &fe_values =
+ hp_fe_values.get_present_fe_values ();
+ begin->get_dof_indices(local_dof_indices);
+ const std::vector<Point<DH::space_dimension> > & points
+ = fe_values.get_quadrature_points ();
+ for (unsigned int i=0; i<dofs_per_cell; ++i)
+ if (!already_touched[local_dof_indices[i]])
+ {
+ support_point_list[local_dof_indices[i]].first = points[i];
+ support_point_list[local_dof_indices[i]].second =
+ local_dof_indices[i];
+ already_touched[local_dof_indices[i]] = true;
+ }
+ }
+
+ ComparePointwiseDownstream<dim> comparator (direction);
+ std::sort (support_point_list.begin(), support_point_list.end(),
+ comparator);
+ for (unsigned int i=0; i<n_dofs; ++i)
+ new_indices[support_point_list[i].second] = i;
}
}
template <int dim>
void downstream_dg (MGDoFHandler<dim>& dof,
- const unsigned int level,
- const Point<dim>& direction)
+ const unsigned int level,
+ const Point<dim>& direction)
{
std::vector<unsigned int> renumbering(dof.n_dofs(level));
std::vector<unsigned int> reverse(dof.n_dofs(level));
template <int dim>
void downstream (MGDoFHandler<dim>& dof,
- const unsigned int level,
- const Point<dim>& direction,
- const bool dof_wise_renumbering)
+ const unsigned int level,
+ const Point<dim>& direction,
+ const bool dof_wise_renumbering)
{
std::vector<unsigned int> renumbering(dof.n_dofs(level));
std::vector<unsigned int> reverse(dof.n_dofs(level));
compute_downstream(renumbering, reverse, dof, level, direction,
- dof_wise_renumbering);
+ dof_wise_renumbering);
dof.renumber_dofs(level, renumbering);
}
{
if (dof_wise_renumbering == false)
{
- std::vector<typename MGDoFHandler<dim>::cell_iterator>
- ordered_cells(dof.get_tria().n_cells(level));
- const CompareDownstream<typename MGDoFHandler<dim>::cell_iterator, dim> comparator(direction);
+ std::vector<typename MGDoFHandler<dim>::cell_iterator>
+ ordered_cells(dof.get_tria().n_cells(level));
+ const CompareDownstream<typename MGDoFHandler<dim>::cell_iterator, dim> comparator(direction);
- typename MGDoFHandler<dim>::cell_iterator begin = dof.begin(level);
- typename MGDoFHandler<dim>::cell_iterator end = dof.end(level);
+ typename MGDoFHandler<dim>::cell_iterator begin = dof.begin(level);
+ typename MGDoFHandler<dim>::cell_iterator end = dof.end(level);
- std::copy (begin, end, ordered_cells.begin());
- std::sort (ordered_cells.begin(), ordered_cells.end(), comparator);
+ std::copy (begin, end, ordered_cells.begin());
+ std::sort (ordered_cells.begin(), ordered_cells.end(), comparator);
- compute_cell_wise(new_indices, reverse, dof, level, ordered_cells);
+ compute_cell_wise(new_indices, reverse, dof, level, ordered_cells);
}
else
{
- Assert (dof.get_fe().has_support_points(),
- typename FiniteElement<dim>::ExcFEHasNoSupportPoints());
- const unsigned int n_dofs = dof.n_dofs(level);
- std::vector<std::pair<Point<dim>,unsigned int> > support_point_list
- (n_dofs);
-
- Quadrature<dim> q_dummy(dof.get_fe().get_unit_support_points());
- FEValues<dim,dim> fe_values (dof.get_fe(), q_dummy,
- update_quadrature_points);
-
- std::vector<bool> already_touched (dof.n_dofs(), false);
-
- const unsigned int dofs_per_cell = dof.get_fe().dofs_per_cell;
- std::vector<unsigned int> local_dof_indices (dofs_per_cell);
- typename MGDoFHandler<dim>::cell_iterator begin = dof.begin(level);
- typename MGDoFHandler<dim>::cell_iterator end = dof.end(level);
- for ( ; begin != end; ++begin)
- {
- begin->get_mg_dof_indices(local_dof_indices);
- fe_values.reinit (begin);
- const std::vector<Point<dim> > & points
- = fe_values.get_quadrature_points ();
- for (unsigned int i=0; i<dofs_per_cell; ++i)
- if (!already_touched[local_dof_indices[i]])
- {
- support_point_list[local_dof_indices[i]].first = points[i];
- support_point_list[local_dof_indices[i]].second =
- local_dof_indices[i];
- already_touched[local_dof_indices[i]] = true;
- }
- }
-
- ComparePointwiseDownstream<dim> comparator (direction);
- std::sort (support_point_list.begin(), support_point_list.end(),
- comparator);
- for (unsigned int i=0; i<n_dofs; ++i)
- new_indices[support_point_list[i].second] = i;
+ Assert (dof.get_fe().has_support_points(),
+ typename FiniteElement<dim>::ExcFEHasNoSupportPoints());
+ const unsigned int n_dofs = dof.n_dofs(level);
+ std::vector<std::pair<Point<dim>,unsigned int> > support_point_list
+ (n_dofs);
+
+ Quadrature<dim> q_dummy(dof.get_fe().get_unit_support_points());
+ FEValues<dim,dim> fe_values (dof.get_fe(), q_dummy,
+ update_quadrature_points);
+
+ std::vector<bool> already_touched (dof.n_dofs(), false);
+
+ const unsigned int dofs_per_cell = dof.get_fe().dofs_per_cell;
+ std::vector<unsigned int> local_dof_indices (dofs_per_cell);
+ typename MGDoFHandler<dim>::cell_iterator begin = dof.begin(level);
+ typename MGDoFHandler<dim>::cell_iterator end = dof.end(level);
+ for ( ; begin != end; ++begin)
+ {
+ begin->get_mg_dof_indices(local_dof_indices);
+ fe_values.reinit (begin);
+ const std::vector<Point<dim> > & points
+ = fe_values.get_quadrature_points ();
+ for (unsigned int i=0; i<dofs_per_cell; ++i)
+ if (!already_touched[local_dof_indices[i]])
+ {
+ support_point_list[local_dof_indices[i]].first = points[i];
+ support_point_list[local_dof_indices[i]].second =
+ local_dof_indices[i];
+ already_touched[local_dof_indices[i]] = true;
+ }
+ }
+
+ ComparePointwiseDownstream<dim> comparator (direction);
+ std::sort (support_point_list.begin(), support_point_list.end(),
+ comparator);
+ for (unsigned int i=0; i<n_dofs; ++i)
+ new_indices[support_point_list[i].second] = i;
}
}
template <int dim>
struct ClockCells
{
- /**
- * Center of rotation.
- */
- const Point<dim>& center;
- /**
- * Revert sorting order.
- */
- bool counter;
-
- /**
- * Constructor.
- */
- ClockCells (const Point<dim>& center, bool counter) :
- center(center),
- counter(counter)
- {}
- /**
- * Comparison operator
- */
- template <class DHCellIterator>
- bool operator () (const DHCellIterator& c1,
- const DHCellIterator& c2) const
- {
-
- const Point<dim> v1 = c1->center() - center;
- const Point<dim> v2 = c2->center() - center;
- const double s1 = std::atan2(v1(0), v1(1));
- const double s2 = std::atan2(v2(0), v2(1));
- return ( counter ? (s1>s2) : (s2>s1));
- }
+ /**
+ * Center of rotation.
+ */
+ const Point<dim>& center;
+ /**
+ * Revert sorting order.
+ */
+ bool counter;
+
+ /**
+ * Constructor.
+ */
+ ClockCells (const Point<dim>& center, bool counter) :
+ center(center),
+ counter(counter)
+ {}
+ /**
+ * Comparison operator
+ */
+ template <class DHCellIterator>
+ bool operator () (const DHCellIterator& c1,
+ const DHCellIterator& c2) const
+ {
+
+ const Point<dim> v1 = c1->center() - center;
+ const Point<dim> v2 = c2->center() - center;
+ const double s1 = std::atan2(v1(0), v1(1));
+ const double s2 = std::atan2(v2(0), v2(1));
+ return ( counter ? (s1>s2) : (s2>s1));
+ }
};
}
template <int dim>
void clockwise_dg (MGDoFHandler<dim>& dof,
- const unsigned int level,
- const Point<dim>& center,
- const bool counter)
+ const unsigned int level,
+ const Point<dim>& center,
+ const bool counter)
{
std::vector<typename MGDoFHandler<dim>::cell_iterator>
ordered_cells(dof.get_tria().n_cells(level));
random (DH& dof_handler)
{
std::vector<unsigned int> renumbering(dof_handler.n_dofs(),
- DH::invalid_dof_index);
+ DH::invalid_dof_index);
compute_random(renumbering, dof_handler);
dof_handler.renumber_dofs(renumbering);
{
const unsigned int n_dofs = dof_handler.n_dofs();
Assert(new_indices.size() == n_dofs,
- ExcDimensionMismatch(new_indices.size(), n_dofs));
+ ExcDimensionMismatch(new_indices.size(), n_dofs));
for (unsigned i=0; i<n_dofs; ++i)
new_indices[i] = i;
subdomain_wise (DH &dof_handler)
{
std::vector<unsigned int> renumbering(dof_handler.n_dofs(),
- DH::invalid_dof_index);
+ DH::invalid_dof_index);
compute_subdomain_wise(renumbering, dof_handler);
dof_handler.renumber_dofs(renumbering);
template <class DH>
void
compute_subdomain_wise (std::vector<unsigned int> &new_dof_indices,
- const DH &dof_handler)
+ const DH &dof_handler)
{
const unsigned int n_dofs = dof_handler.n_dofs();
Assert (new_dof_indices.size() == n_dofs,
- ExcDimensionMismatch (new_dof_indices.size(), n_dofs));
+ ExcDimensionMismatch (new_dof_indices.size(), n_dofs));
- // first get the association of each dof
- // with a subdomain and determine the total
- // number of subdomain ids used
+ // first get the association of each dof
+ // with a subdomain and determine the total
+ // number of subdomain ids used
std::vector<types::subdomain_id_t> subdomain_association (n_dofs);
DoFTools::get_subdomain_association (dof_handler,
- subdomain_association);
+ subdomain_association);
const unsigned int n_subdomains
= *std::max_element (subdomain_association.begin(),
- subdomain_association.end()) + 1;
-
- // then renumber the subdomains by first
- // looking at those belonging to subdomain
- // 0, then those of subdomain 1, etc. note
- // that the algorithm is stable, i.e. if
- // two dofs i,j have i<j and belong to the
- // same subdomain, then they will be in
- // this order also after reordering
+ subdomain_association.end()) + 1;
+
+ // then renumber the subdomains by first
+ // looking at those belonging to subdomain
+ // 0, then those of subdomain 1, etc. note
+ // that the algorithm is stable, i.e. if
+ // two dofs i,j have i<j and belong to the
+ // same subdomain, then they will be in
+ // this order also after reordering
std::fill (new_dof_indices.begin(), new_dof_indices.end(),
- numbers::invalid_unsigned_int);
+ numbers::invalid_unsigned_int);
unsigned int next_free_index = 0;
for (unsigned int subdomain=0; subdomain<n_subdomains; ++subdomain)
for (unsigned int i=0; i<n_dofs; ++i)
- if (subdomain_association[i] == subdomain)
- {
- Assert (new_dof_indices[i] == numbers::invalid_unsigned_int,
- ExcInternalError());
- new_dof_indices[i] = next_free_index;
- ++next_free_index;
- }
-
- // we should have numbered all dofs
+ if (subdomain_association[i] == subdomain)
+ {
+ Assert (new_dof_indices[i] == numbers::invalid_unsigned_int,
+ ExcInternalError());
+ new_dof_indices[i] = next_free_index;
+ ++next_free_index;
+ }
+
+ // we should have numbered all dofs
Assert (next_free_index == n_dofs, ExcInternalError());
Assert (std::find (new_dof_indices.begin(), new_dof_indices.end(),
- numbers::invalid_unsigned_int)
- == new_dof_indices.end(),
- ExcInternalError());
+ numbers::invalid_unsigned_int)
+ == new_dof_indices.end(),
+ ExcInternalError());
}
} // namespace DoFRenumbering
// $Id$
// Version: $Name$
//
-// Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 by the deal.II authors
+// Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
template <class DH, class SparsityPattern>
void
make_sparsity_pattern (const DH &dof,
- SparsityPattern &sparsity,
- const ConstraintMatrix &constraints,
- const bool keep_constrained_dofs,
- const types::subdomain_id_t subdomain_id)
+ SparsityPattern &sparsity,
+ const ConstraintMatrix &constraints,
+ const bool keep_constrained_dofs,
+ const types::subdomain_id_t subdomain_id)
{
const unsigned int n_dofs = dof.n_dofs();
Assert (sparsity.n_rows() == n_dofs,
- ExcDimensionMismatch (sparsity.n_rows(), n_dofs));
+ ExcDimensionMismatch (sparsity.n_rows(), n_dofs));
Assert (sparsity.n_cols() == n_dofs,
- ExcDimensionMismatch (sparsity.n_cols(), n_dofs));
+ ExcDimensionMismatch (sparsity.n_cols(), n_dofs));
- // If we have a distributed::Triangulation only
- // allow locally_owned subdomain. Not setting a
- // subdomain is also okay, because we skip ghost
- // cells in the loop below.
+ // If we have a distributed::Triangulation only
+ // allow locally_owned subdomain. Not setting a
+ // subdomain is also okay, because we skip ghost
+ // cells in the loop below.
Assert (
(dof.get_tria().locally_owned_subdomain() == types::invalid_subdomain_id)
||
||
(subdomain_id == dof.get_tria().locally_owned_subdomain()),
ExcMessage ("For parallel::distributed::Triangulation objects and "
- "associated DoF handler objects, asking for any subdomain other "
- "than the locally owned one does not make sense."));
+ "associated DoF handler objects, asking for any subdomain other "
+ "than the locally owned one does not make sense."));
std::vector<unsigned int> dofs_on_this_cell;
dofs_on_this_cell.reserve (max_dofs_per_cell(dof));
typename DH::active_cell_iterator cell = dof.begin_active(),
- endc = dof.end();
+ endc = dof.end();
- // In case we work with a distributed
- // sparsity pattern of Trilinos type, we
- // only have to do the work if the
- // current cell is owned by the calling
- // processor. Otherwise, just continue.
+ // In case we work with a distributed
+ // sparsity pattern of Trilinos type, we
+ // only have to do the work if the
+ // current cell is owned by the calling
+ // processor. Otherwise, just continue.
for (; cell!=endc; ++cell)
if (((subdomain_id == types::invalid_subdomain_id)
- ||
- (subdomain_id == cell->subdomain_id()))
- &&
- cell->is_locally_owned())
- {
- const unsigned int dofs_per_cell = cell->get_fe().dofs_per_cell;
- dofs_on_this_cell.resize (dofs_per_cell);
- cell->get_dof_indices (dofs_on_this_cell);
-
- // make sparsity pattern for this
- // cell. if no constraints pattern was
- // given, then the following call acts
- // as if simply no constraints existed
- constraints.add_entries_local_to_global (dofs_on_this_cell,
- sparsity,
- keep_constrained_dofs);
- }
+ ||
+ (subdomain_id == cell->subdomain_id()))
+ &&
+ cell->is_locally_owned())
+ {
+ const unsigned int dofs_per_cell = cell->get_fe().dofs_per_cell;
+ dofs_on_this_cell.resize (dofs_per_cell);
+ cell->get_dof_indices (dofs_on_this_cell);
+
+ // make sparsity pattern for this
+ // cell. if no constraints pattern was
+ // given, then the following call acts
+ // as if simply no constraints existed
+ constraints.add_entries_local_to_global (dofs_on_this_cell,
+ sparsity,
+ keep_constrained_dofs);
+ }
}
template <class DH, class SparsityPattern>
void
make_sparsity_pattern (const DH &dof,
- const Table<2,Coupling> &couplings,
- SparsityPattern &sparsity,
- const ConstraintMatrix &constraints,
- const bool keep_constrained_dofs,
- const types::subdomain_id_t subdomain_id)
+ const Table<2,Coupling> &couplings,
+ SparsityPattern &sparsity,
+ const ConstraintMatrix &constraints,
+ const bool keep_constrained_dofs,
+ const types::subdomain_id_t subdomain_id)
{
const unsigned int n_dofs = dof.n_dofs();
Assert (sparsity.n_rows() == n_dofs,
- ExcDimensionMismatch (sparsity.n_rows(), n_dofs));
+ ExcDimensionMismatch (sparsity.n_rows(), n_dofs));
Assert (sparsity.n_cols() == n_dofs,
- ExcDimensionMismatch (sparsity.n_cols(), n_dofs));
+ ExcDimensionMismatch (sparsity.n_cols(), n_dofs));
Assert (couplings.n_rows() == dof.get_fe().n_components(),
- ExcDimensionMismatch(couplings.n_rows(), dof.get_fe().n_components()));
+ ExcDimensionMismatch(couplings.n_rows(), dof.get_fe().n_components()));
Assert (couplings.n_cols() == dof.get_fe().n_components(),
- ExcDimensionMismatch(couplings.n_cols(), dof.get_fe().n_components()));
+ ExcDimensionMismatch(couplings.n_cols(), dof.get_fe().n_components()));
- // If we have a distributed::Triangulation only
- // allow locally_owned subdomain. Not setting a
- // subdomain is also okay, because we skip ghost
- // cells in the loop below.
+ // If we have a distributed::Triangulation only
+ // allow locally_owned subdomain. Not setting a
+ // subdomain is also okay, because we skip ghost
+ // cells in the loop below.
Assert (
(dof.get_tria().locally_owned_subdomain() == types::invalid_subdomain_id)
||
||
(subdomain_id == dof.get_tria().locally_owned_subdomain()),
ExcMessage ("For parallel::distributed::Triangulation objects and "
- "associated DoF handler objects, asking for any subdomain other "
- "than the locally owned one does not make sense."));
+ "associated DoF handler objects, asking for any subdomain other "
+ "than the locally owned one does not make sense."));
const hp::FECollection<DH::dimension,DH::space_dimension> fe_collection (dof.get_fe());
- // first, for each finite element, build a
- // mask for each dof, not like the one
- // given which represents components. make
- // sure we do the right thing also with
- // respect to non-primitive shape
- // functions, which takes some additional
- // thought
+ // first, for each finite element, build a
+ // mask for each dof, not like the one
+ // given which represents components. make
+ // sure we do the right thing also with
+ // respect to non-primitive shape
+ // functions, which takes some additional
+ // thought
std::vector<Table<2,bool> > dof_mask(fe_collection.size());
- // check whether the table of couplings
- // contains only true arguments, i.e., we
- // do not exclude any index. that is the
- // easy case, since we don't have to set
- // up the tables
+ // check whether the table of couplings
+ // contains only true arguments, i.e., we
+ // do not exclude any index. that is the
+ // easy case, since we don't have to set
+ // up the tables
bool need_dof_mask = false;
for (unsigned int i=0; i<couplings.n_rows(); ++i)
for (unsigned int j=0; j<couplings.n_cols(); ++j)
- if (couplings(i,j) == none)
- need_dof_mask = true;
+ if (couplings(i,j) == none)
+ need_dof_mask = true;
if (need_dof_mask == true)
for (unsigned int f=0; f<fe_collection.size(); ++f)
- {
- const unsigned int dofs_per_cell = fe_collection[f].dofs_per_cell;
-
- dof_mask[f].reinit (dofs_per_cell, dofs_per_cell);
-
- for (unsigned int i=0; i<dofs_per_cell; ++i)
- for (unsigned int j=0; j<dofs_per_cell; ++j)
- if (fe_collection[f].is_primitive(i) &&
- fe_collection[f].is_primitive(j))
- dof_mask[f](i,j)
- = (couplings(fe_collection[f].system_to_component_index(i).first,
- fe_collection[f].system_to_component_index(j).first) != none);
- else
- {
- const unsigned int first_nonzero_comp_i
- = (std::find (fe_collection[f].get_nonzero_components(i).begin(),
- fe_collection[f].get_nonzero_components(i).end(),
- true)
- -
- fe_collection[f].get_nonzero_components(i).begin());
- const unsigned int first_nonzero_comp_j
- = (std::find (fe_collection[f].get_nonzero_components(j).begin(),
- fe_collection[f].get_nonzero_components(j).end(),
- true)
- -
- fe_collection[f].get_nonzero_components(j).begin());
- Assert (first_nonzero_comp_i < fe_collection[f].n_components(),
- ExcInternalError());
- Assert (first_nonzero_comp_j < fe_collection[f].n_components(),
- ExcInternalError());
-
- dof_mask[f](i,j)
- = (couplings(first_nonzero_comp_i,first_nonzero_comp_j) != none);
- }
- }
+ {
+ const unsigned int dofs_per_cell = fe_collection[f].dofs_per_cell;
+
+ dof_mask[f].reinit (dofs_per_cell, dofs_per_cell);
+
+ for (unsigned int i=0; i<dofs_per_cell; ++i)
+ for (unsigned int j=0; j<dofs_per_cell; ++j)
+ if (fe_collection[f].is_primitive(i) &&
+ fe_collection[f].is_primitive(j))
+ dof_mask[f](i,j)
+ = (couplings(fe_collection[f].system_to_component_index(i).first,
+ fe_collection[f].system_to_component_index(j).first) != none);
+ else
+ {
+ const unsigned int first_nonzero_comp_i
+ = (std::find (fe_collection[f].get_nonzero_components(i).begin(),
+ fe_collection[f].get_nonzero_components(i).end(),
+ true)
+ -
+ fe_collection[f].get_nonzero_components(i).begin());
+ const unsigned int first_nonzero_comp_j
+ = (std::find (fe_collection[f].get_nonzero_components(j).begin(),
+ fe_collection[f].get_nonzero_components(j).end(),
+ true)
+ -
+ fe_collection[f].get_nonzero_components(j).begin());
+ Assert (first_nonzero_comp_i < fe_collection[f].n_components(),
+ ExcInternalError());
+ Assert (first_nonzero_comp_j < fe_collection[f].n_components(),
+ ExcInternalError());
+
+ dof_mask[f](i,j)
+ = (couplings(first_nonzero_comp_i,first_nonzero_comp_j) != none);
+ }
+ }
std::vector<unsigned int> dofs_on_this_cell(fe_collection.max_dofs_per_cell());
typename DH::active_cell_iterator cell = dof.begin_active(),
- endc = dof.end();
+ endc = dof.end();
- // In case we work with a distributed
- // sparsity pattern of Trilinos type, we
- // only have to do the work if the
- // current cell is owned by the calling
- // processor. Otherwise, just continue.
+ // In case we work with a distributed
+ // sparsity pattern of Trilinos type, we
+ // only have to do the work if the
+ // current cell is owned by the calling
+ // processor. Otherwise, just continue.
for (; cell!=endc; ++cell)
if (((subdomain_id == types::invalid_subdomain_id)
- ||
- (subdomain_id == cell->subdomain_id()))
- &&
- cell->is_locally_owned())
- {
- const unsigned int fe_index = cell->active_fe_index();
- const unsigned int dofs_per_cell =fe_collection[fe_index].dofs_per_cell;
-
- dofs_on_this_cell.resize (dofs_per_cell);
- cell->get_dof_indices (dofs_on_this_cell);
-
-
- // make sparsity pattern for this
- // cell. if no constraints pattern was
- // given, then the following call acts
- // as if simply no constraints existed
- constraints.add_entries_local_to_global (dofs_on_this_cell,
- sparsity,
- keep_constrained_dofs,
- dof_mask[fe_index]);
- }
+ ||
+ (subdomain_id == cell->subdomain_id()))
+ &&
+ cell->is_locally_owned())
+ {
+ const unsigned int fe_index = cell->active_fe_index();
+ const unsigned int dofs_per_cell =fe_collection[fe_index].dofs_per_cell;
+
+ dofs_on_this_cell.resize (dofs_per_cell);
+ cell->get_dof_indices (dofs_on_this_cell);
+
+
+ // make sparsity pattern for this
+ // cell. if no constraints pattern was
+ // given, then the following call acts
+ // as if simply no constraints existed
+ constraints.add_entries_local_to_global (dofs_on_this_cell,
+ sparsity,
+ keep_constrained_dofs,
+ dof_mask[fe_index]);
+ }
}
const unsigned int n_dofs_col = dof_col.n_dofs();
Assert (sparsity.n_rows() == n_dofs_row,
- ExcDimensionMismatch (sparsity.n_rows(), n_dofs_row));
+ ExcDimensionMismatch (sparsity.n_rows(), n_dofs_row));
Assert (sparsity.n_cols() == n_dofs_col,
- ExcDimensionMismatch (sparsity.n_cols(), n_dofs_col));
+ ExcDimensionMismatch (sparsity.n_cols(), n_dofs_col));
const std::list<std::pair<typename DH::cell_iterator,
for (; cell_iter!=cell_list.end(); ++cell_iter)
{
- const typename DH::cell_iterator cell_row = cell_iter->first;
- const typename DH::cell_iterator cell_col = cell_iter->second;
-
- if (!cell_row->has_children() && !cell_col->has_children())
- {
- const unsigned int dofs_per_cell_row =
- cell_row->get_fe().dofs_per_cell;
- const unsigned int dofs_per_cell_col =
- cell_col->get_fe().dofs_per_cell;
- std::vector<unsigned int>
- local_dof_indices_row(dofs_per_cell_row);
- std::vector<unsigned int>
- local_dof_indices_col(dofs_per_cell_col);
- cell_row->get_dof_indices (local_dof_indices_row);
- cell_col->get_dof_indices (local_dof_indices_col);
- for (unsigned int i=0; i<dofs_per_cell_row; ++i)
- sparsity.add_entries (local_dof_indices_row[i],
- local_dof_indices_col.begin(),
- local_dof_indices_col.end());
- }
- else if (cell_row->has_children())
- {
- const std::vector<typename DH::active_cell_iterator >
- child_cells = GridTools::get_active_child_cells<DH> (cell_row);
- for (unsigned int i=0; i<child_cells.size(); i++)
- {
- const typename DH::active_cell_iterator
- cell_row_child = child_cells[i];
- const unsigned int dofs_per_cell_row =
- cell_row_child->get_fe().dofs_per_cell;
- const unsigned int dofs_per_cell_col =
- cell_col->get_fe().dofs_per_cell;
- std::vector<unsigned int>
- local_dof_indices_row(dofs_per_cell_row);
- std::vector<unsigned int>
- local_dof_indices_col(dofs_per_cell_col);
- cell_row_child->get_dof_indices (local_dof_indices_row);
- cell_col->get_dof_indices (local_dof_indices_col);
- for (unsigned int i=0; i<dofs_per_cell_row; ++i)
- sparsity.add_entries (local_dof_indices_row[i],
- local_dof_indices_col.begin(),
- local_dof_indices_col.end());
- }
- }
- else
- {
- std::vector<typename DH::active_cell_iterator>
- child_cells = GridTools::get_active_child_cells<DH> (cell_col);
- for (unsigned int i=0; i<child_cells.size(); i++)
- {
- const typename DH::active_cell_iterator
- cell_col_child = child_cells[i];
- const unsigned int dofs_per_cell_row =
- cell_row->get_fe().dofs_per_cell;
- const unsigned int dofs_per_cell_col =
- cell_col_child->get_fe().dofs_per_cell;
- std::vector<unsigned int>
- local_dof_indices_row(dofs_per_cell_row);
- std::vector<unsigned int>
- local_dof_indices_col(dofs_per_cell_col);
- cell_row->get_dof_indices (local_dof_indices_row);
- cell_col_child->get_dof_indices (local_dof_indices_col);
- for (unsigned int i=0; i<dofs_per_cell_row; ++i)
- sparsity.add_entries (local_dof_indices_row[i],
- local_dof_indices_col.begin(),
- local_dof_indices_col.end());
- }
- }
+ const typename DH::cell_iterator cell_row = cell_iter->first;
+ const typename DH::cell_iterator cell_col = cell_iter->second;
+
+ if (!cell_row->has_children() && !cell_col->has_children())
+ {
+ const unsigned int dofs_per_cell_row =
+ cell_row->get_fe().dofs_per_cell;
+ const unsigned int dofs_per_cell_col =
+ cell_col->get_fe().dofs_per_cell;
+ std::vector<unsigned int>
+ local_dof_indices_row(dofs_per_cell_row);
+ std::vector<unsigned int>
+ local_dof_indices_col(dofs_per_cell_col);
+ cell_row->get_dof_indices (local_dof_indices_row);
+ cell_col->get_dof_indices (local_dof_indices_col);
+ for (unsigned int i=0; i<dofs_per_cell_row; ++i)
+ sparsity.add_entries (local_dof_indices_row[i],
+ local_dof_indices_col.begin(),
+ local_dof_indices_col.end());
+ }
+ else if (cell_row->has_children())
+ {
+ const std::vector<typename DH::active_cell_iterator >
+ child_cells = GridTools::get_active_child_cells<DH> (cell_row);
+ for (unsigned int i=0; i<child_cells.size(); i++)
+ {
+ const typename DH::active_cell_iterator
+ cell_row_child = child_cells[i];
+ const unsigned int dofs_per_cell_row =
+ cell_row_child->get_fe().dofs_per_cell;
+ const unsigned int dofs_per_cell_col =
+ cell_col->get_fe().dofs_per_cell;
+ std::vector<unsigned int>
+ local_dof_indices_row(dofs_per_cell_row);
+ std::vector<unsigned int>
+ local_dof_indices_col(dofs_per_cell_col);
+ cell_row_child->get_dof_indices (local_dof_indices_row);
+ cell_col->get_dof_indices (local_dof_indices_col);
+ for (unsigned int i=0; i<dofs_per_cell_row; ++i)
+ sparsity.add_entries (local_dof_indices_row[i],
+ local_dof_indices_col.begin(),
+ local_dof_indices_col.end());
+ }
+ }
+ else
+ {
+ std::vector<typename DH::active_cell_iterator>
+ child_cells = GridTools::get_active_child_cells<DH> (cell_col);
+ for (unsigned int i=0; i<child_cells.size(); i++)
+ {
+ const typename DH::active_cell_iterator
+ cell_col_child = child_cells[i];
+ const unsigned int dofs_per_cell_row =
+ cell_row->get_fe().dofs_per_cell;
+ const unsigned int dofs_per_cell_col =
+ cell_col_child->get_fe().dofs_per_cell;
+ std::vector<unsigned int>
+ local_dof_indices_row(dofs_per_cell_row);
+ std::vector<unsigned int>
+ local_dof_indices_col(dofs_per_cell_col);
+ cell_row->get_dof_indices (local_dof_indices_row);
+ cell_col_child->get_dof_indices (local_dof_indices_col);
+ for (unsigned int i=0; i<dofs_per_cell_row; ++i)
+ sparsity.add_entries (local_dof_indices_row[i],
+ local_dof_indices_col.begin(),
+ local_dof_indices_col.end());
+ }
+ }
}
}
{
if (DH::dimension == 1)
{
- // there are only 2 boundary
- // indicators in 1d, so it is no
- // performance problem to call the
- // other function
- typename DH::FunctionMap boundary_indicators;
- boundary_indicators[0] = 0;
- boundary_indicators[1] = 0;
- make_boundary_sparsity_pattern<DH, SparsityPattern> (dof,
- boundary_indicators,
- dof_to_boundary_mapping,
- sparsity);
- return;
+ // there are only 2 boundary
+ // indicators in 1d, so it is no
+ // performance problem to call the
+ // other function
+ typename DH::FunctionMap boundary_indicators;
+ boundary_indicators[0] = 0;
+ boundary_indicators[1] = 0;
+ make_boundary_sparsity_pattern<DH, SparsityPattern> (dof,
+ boundary_indicators,
+ dof_to_boundary_mapping,
+ sparsity);
+ return;
}
const unsigned int n_dofs = dof.n_dofs();
#ifdef DEBUG
if (sparsity.n_rows() != 0)
{
- unsigned int max_element = 0;
- for (std::vector<unsigned int>::const_iterator i=dof_to_boundary_mapping.begin();
- i!=dof_to_boundary_mapping.end(); ++i)
- if ((*i != DH::invalid_dof_index) &&
- (*i > max_element))
- max_element = *i;
- AssertDimension (max_element, sparsity.n_rows()-1);
+ unsigned int max_element = 0;
+ for (std::vector<unsigned int>::const_iterator i=dof_to_boundary_mapping.begin();
+ i!=dof_to_boundary_mapping.end(); ++i)
+ if ((*i != DH::invalid_dof_index) &&
+ (*i > max_element))
+ max_element = *i;
+ AssertDimension (max_element, sparsity.n_rows()-1);
};
#endif
std::vector<unsigned int> dofs_on_this_face;
dofs_on_this_face.reserve (max_dofs_per_face(dof));
- // loop over all faces to check
- // whether they are at a
- // boundary. note that we need not
- // take special care of single
- // lines (using
- // @p{cell->has_boundary_lines}),
- // since we do not support
- // boundaries of dimension dim-2,
- // and so every boundary line is
- // also part of a boundary face.
+ // loop over all faces to check
+ // whether they are at a
+ // boundary. note that we need not
+ // take special care of single
+ // lines (using
+ // @p{cell->has_boundary_lines}),
+ // since we do not support
+ // boundaries of dimension dim-2,
+ // and so every boundary line is
+ // also part of a boundary face.
typename DH::active_cell_iterator cell = dof.begin_active(),
- endc = dof.end();
+ endc = dof.end();
for (; cell!=endc; ++cell)
for (unsigned int f=0; f<GeometryInfo<DH::dimension>::faces_per_cell; ++f)
- if (cell->at_boundary(f))
- {
- const unsigned int dofs_per_face = cell->get_fe().dofs_per_face;
- dofs_on_this_face.resize (dofs_per_face);
- cell->face(f)->get_dof_indices (dofs_on_this_face,
- cell->active_fe_index());
-
- // make sparsity pattern for this cell
- for (unsigned int i=0; i<dofs_per_face; ++i)
- for (unsigned int j=0; j<dofs_per_face; ++j)
- sparsity.add (dof_to_boundary_mapping[dofs_on_this_face[i]],
- dof_to_boundary_mapping[dofs_on_this_face[j]]);
- }
+ if (cell->at_boundary(f))
+ {
+ const unsigned int dofs_per_face = cell->get_fe().dofs_per_face;
+ dofs_on_this_face.resize (dofs_per_face);
+ cell->face(f)->get_dof_indices (dofs_on_this_face,
+ cell->active_fe_index());
+
+ // make sparsity pattern for this cell
+ for (unsigned int i=0; i<dofs_per_face; ++i)
+ for (unsigned int j=0; j<dofs_per_face; ++j)
+ sparsity.add (dof_to_boundary_mapping[dofs_on_this_face[i]],
+ dof_to_boundary_mapping[dofs_on_this_face[j]]);
+ }
}
{
if (DH::dimension == 1)
{
- // first check left, then right
- // boundary point
- for (unsigned int direction=0; direction<2; ++direction)
- {
- // if this boundary is not
- // requested, then go on with next one
- if (boundary_indicators.find(direction) ==
- boundary_indicators.end())
- continue;
-
- // find active cell at that
- // boundary: first go to
- // left/right, then to children
- typename DH::cell_iterator cell = dof.begin(0);
- while (!cell->at_boundary(direction))
- cell = cell->neighbor(direction);
- while (!cell->active())
- cell = cell->child(direction);
-
- const unsigned int dofs_per_vertex = cell->get_fe().dofs_per_vertex;
- std::vector<unsigned int> boundary_dof_boundary_indices (dofs_per_vertex);
-
- // next get boundary mapped dof
- // indices of boundary dofs
- for (unsigned int i=0; i<dofs_per_vertex; ++i)
- boundary_dof_boundary_indices[i]
- = dof_to_boundary_mapping[cell->vertex_dof_index(direction,i)];
-
- for (unsigned int i=0; i<dofs_per_vertex; ++i)
- sparsity.add_entries (boundary_dof_boundary_indices[i],
- boundary_dof_boundary_indices.begin(),
- boundary_dof_boundary_indices.end());
- };
- return;
+ // first check left, then right
+ // boundary point
+ for (unsigned int direction=0; direction<2; ++direction)
+ {
+ // if this boundary is not
+ // requested, then go on with next one
+ if (boundary_indicators.find(direction) ==
+ boundary_indicators.end())
+ continue;
+
+ // find active cell at that
+ // boundary: first go to
+ // left/right, then to children
+ typename DH::cell_iterator cell = dof.begin(0);
+ while (!cell->at_boundary(direction))
+ cell = cell->neighbor(direction);
+ while (!cell->active())
+ cell = cell->child(direction);
+
+ const unsigned int dofs_per_vertex = cell->get_fe().dofs_per_vertex;
+ std::vector<unsigned int> boundary_dof_boundary_indices (dofs_per_vertex);
+
+ // next get boundary mapped dof
+ // indices of boundary dofs
+ for (unsigned int i=0; i<dofs_per_vertex; ++i)
+ boundary_dof_boundary_indices[i]
+ = dof_to_boundary_mapping[cell->vertex_dof_index(direction,i)];
+
+ for (unsigned int i=0; i<dofs_per_vertex; ++i)
+ sparsity.add_entries (boundary_dof_boundary_indices[i],
+ boundary_dof_boundary_indices.begin(),
+ boundary_dof_boundary_indices.end());
+ };
+ return;
}
const unsigned int n_dofs = dof.n_dofs();
AssertDimension (dof_to_boundary_mapping.size(), n_dofs);
Assert (boundary_indicators.find(types::internal_face_boundary_id) == boundary_indicators.end(),
- typename DH::ExcInvalidBoundaryIndicator());
+ typename DH::ExcInvalidBoundaryIndicator());
Assert (sparsity.n_rows() == dof.n_boundary_dofs (boundary_indicators),
- ExcDimensionMismatch (sparsity.n_rows(), dof.n_boundary_dofs (boundary_indicators)));
+ ExcDimensionMismatch (sparsity.n_rows(), dof.n_boundary_dofs (boundary_indicators)));
Assert (sparsity.n_cols() == dof.n_boundary_dofs (boundary_indicators),
- ExcDimensionMismatch (sparsity.n_cols(), dof.n_boundary_dofs (boundary_indicators)));
+ ExcDimensionMismatch (sparsity.n_cols(), dof.n_boundary_dofs (boundary_indicators)));
#ifdef DEBUG
if (sparsity.n_rows() != 0)
{
- unsigned int max_element = 0;
- for (std::vector<unsigned int>::const_iterator i=dof_to_boundary_mapping.begin();
- i!=dof_to_boundary_mapping.end(); ++i)
- if ((*i != DH::invalid_dof_index) &&
- (*i > max_element))
- max_element = *i;
- AssertDimension (max_element, sparsity.n_rows()-1);
+ unsigned int max_element = 0;
+ for (std::vector<unsigned int>::const_iterator i=dof_to_boundary_mapping.begin();
+ i!=dof_to_boundary_mapping.end(); ++i)
+ if ((*i != DH::invalid_dof_index) &&
+ (*i > max_element))
+ max_element = *i;
+ AssertDimension (max_element, sparsity.n_rows()-1);
};
#endif
std::vector<unsigned int> dofs_on_this_face;
dofs_on_this_face.reserve (max_dofs_per_face(dof));
typename DH::active_cell_iterator cell = dof.begin_active(),
- endc = dof.end();
+ endc = dof.end();
for (; cell!=endc; ++cell)
for (unsigned int f=0; f<GeometryInfo<DH::dimension>::faces_per_cell; ++f)
- if (boundary_indicators.find(cell->face(f)->boundary_indicator()) !=
- boundary_indicators.end())
- {
- const unsigned int dofs_per_face = cell->get_fe().dofs_per_face;
- dofs_on_this_face.resize (dofs_per_face);
- cell->face(f)->get_dof_indices (dofs_on_this_face,
- cell->active_fe_index());
-
- // make sparsity pattern for this cell
- for (unsigned int i=0; i<dofs_per_face; ++i)
- for (unsigned int j=0; j<dofs_per_face; ++j)
- sparsity.add (dof_to_boundary_mapping[dofs_on_this_face[i]],
- dof_to_boundary_mapping[dofs_on_this_face[j]]);
- }
+ if (boundary_indicators.find(cell->face(f)->boundary_indicator()) !=
+ boundary_indicators.end())
+ {
+ const unsigned int dofs_per_face = cell->get_fe().dofs_per_face;
+ dofs_on_this_face.resize (dofs_per_face);
+ cell->face(f)->get_dof_indices (dofs_on_this_face,
+ cell->active_fe_index());
+
+ // make sparsity pattern for this cell
+ for (unsigned int i=0; i<dofs_per_face; ++i)
+ for (unsigned int j=0; j<dofs_per_face; ++j)
+ sparsity.add (dof_to_boundary_mapping[dofs_on_this_face[i]],
+ dof_to_boundary_mapping[dofs_on_this_face[j]]);
+ }
}
template <class DH, class SparsityPattern>
void
make_flux_sparsity_pattern (const DH &dof,
- SparsityPattern &sparsity,
- const ConstraintMatrix &constraints,
- const bool keep_constrained_dofs,
+ SparsityPattern &sparsity,
+ const ConstraintMatrix &constraints,
+ const bool keep_constrained_dofs,
const types::subdomain_id_t subdomain_id)
{
const unsigned int n_dofs = dof.n_dofs();
||
(subdomain_id == dof.get_tria().locally_owned_subdomain()),
ExcMessage ("For parallel::distributed::Triangulation objects and "
- "associated DoF handler objects, asking for any subdomain other "
- "than the locally owned one does not make sense."));
+ "associated DoF handler objects, asking for any subdomain other "
+ "than the locally owned one does not make sense."));
std::vector<unsigned int> dofs_on_this_cell;
std::vector<unsigned int> dofs_on_other_cell;
dofs_on_this_cell.reserve (max_dofs_per_cell(dof));
dofs_on_other_cell.reserve (max_dofs_per_cell(dof));
typename DH::active_cell_iterator cell = dof.begin_active(),
- endc = dof.end();
-
- // TODO: in an old implementation, we used
- // user flags before to tag faces that were
- // already touched. this way, we could reduce
- // the work a little bit. now, we instead add
- // only data from one side. this should be OK,
- // but we need to actually verify it.
-
- // In case we work with a distributed
- // sparsity pattern of Trilinos type, we
- // only have to do the work if the
- // current cell is owned by the calling
- // processor. Otherwise, just continue.
+ endc = dof.end();
+
+ // TODO: in an old implementation, we used
+ // user flags before to tag faces that were
+ // already touched. this way, we could reduce
+ // the work a little bit. now, we instead add
+ // only data from one side. this should be OK,
+ // but we need to actually verify it.
+
+ // In case we work with a distributed
+ // sparsity pattern of Trilinos type, we
+ // only have to do the work if the
+ // current cell is owned by the calling
+ // processor. Otherwise, just continue.
for (; cell!=endc; ++cell)
if (((subdomain_id == types::invalid_subdomain_id)
- ||
- (subdomain_id == cell->subdomain_id()))
+ ||
+ (subdomain_id == cell->subdomain_id()))
&&
cell->is_locally_owned())
- {
- const unsigned int n_dofs_on_this_cell = cell->get_fe().dofs_per_cell;
- dofs_on_this_cell.resize (n_dofs_on_this_cell);
- cell->get_dof_indices (dofs_on_this_cell);
-
- // make sparsity pattern for this
- // cell. if no constraints pattern was
- // given, then the following call acts
- // as if simply no constraints existed
- constraints.add_entries_local_to_global (dofs_on_this_cell,
- sparsity,
- keep_constrained_dofs);
-
- for (unsigned int face = 0;
- face < GeometryInfo<DH::dimension>::faces_per_cell;
- ++face)
- {
- typename DH::face_iterator cell_face = cell->face(face);
- if (! cell->at_boundary(face) )
- {
- typename DH::cell_iterator neighbor = cell->neighbor(face);
-
- if (cell_face->has_children())
- {
- for (unsigned int sub_nr = 0;
- sub_nr != cell_face->number_of_children();
- ++sub_nr)
- {
- const typename DH::cell_iterator
- sub_neighbor
- = cell->neighbor_child_on_subface (face, sub_nr);
-
- const unsigned int n_dofs_on_neighbor
- = sub_neighbor->get_fe().dofs_per_cell;
- dofs_on_other_cell.resize (n_dofs_on_neighbor);
- sub_neighbor->get_dof_indices (dofs_on_other_cell);
-
- constraints.add_entries_local_to_global
- (dofs_on_this_cell, dofs_on_other_cell,
- sparsity, keep_constrained_dofs);
- constraints.add_entries_local_to_global
- (dofs_on_other_cell, dofs_on_this_cell,
- sparsity, keep_constrained_dofs);
- }
- }
- else
- {
- // Refinement edges are taken care of
- // by coarser cells
-
- // TODO: in the distributed case, we miss out
- // the constraints when the neighbor cell is
- // coarser, but only the current cell is owned
- // locally!
- if (cell->neighbor_is_coarser(face))
- continue;
-
- const unsigned int n_dofs_on_neighbor
- = neighbor->get_fe().dofs_per_cell;
- dofs_on_other_cell.resize (n_dofs_on_neighbor);
-
- neighbor->get_dof_indices (dofs_on_other_cell);
-
- constraints.add_entries_local_to_global
- (dofs_on_this_cell, dofs_on_other_cell,
- sparsity, keep_constrained_dofs);
-
- // only need to add these in case the neighbor
- // cell is not locally owned - otherwise, we
- // touch each face twice and hence put the
- // indices the other way around
- if (cell->neighbor(face)->subdomain_id() !=
- cell->subdomain_id())
- constraints.add_entries_local_to_global
- (dofs_on_other_cell, dofs_on_this_cell,
- sparsity, keep_constrained_dofs);
- }
- }
- }
- }
+ {
+ const unsigned int n_dofs_on_this_cell = cell->get_fe().dofs_per_cell;
+ dofs_on_this_cell.resize (n_dofs_on_this_cell);
+ cell->get_dof_indices (dofs_on_this_cell);
+
+ // make sparsity pattern for this
+ // cell. if no constraints pattern was
+ // given, then the following call acts
+ // as if simply no constraints existed
+ constraints.add_entries_local_to_global (dofs_on_this_cell,
+ sparsity,
+ keep_constrained_dofs);
+
+ for (unsigned int face = 0;
+ face < GeometryInfo<DH::dimension>::faces_per_cell;
+ ++face)
+ {
+ typename DH::face_iterator cell_face = cell->face(face);
+ if (! cell->at_boundary(face) )
+ {
+ typename DH::cell_iterator neighbor = cell->neighbor(face);
+
+ if (cell_face->has_children())
+ {
+ for (unsigned int sub_nr = 0;
+ sub_nr != cell_face->number_of_children();
+ ++sub_nr)
+ {
+ const typename DH::cell_iterator
+ sub_neighbor
+ = cell->neighbor_child_on_subface (face, sub_nr);
+
+ const unsigned int n_dofs_on_neighbor
+ = sub_neighbor->get_fe().dofs_per_cell;
+ dofs_on_other_cell.resize (n_dofs_on_neighbor);
+ sub_neighbor->get_dof_indices (dofs_on_other_cell);
+
+ constraints.add_entries_local_to_global
+ (dofs_on_this_cell, dofs_on_other_cell,
+ sparsity, keep_constrained_dofs);
+ constraints.add_entries_local_to_global
+ (dofs_on_other_cell, dofs_on_this_cell,
+ sparsity, keep_constrained_dofs);
+ }
+ }
+ else
+ {
+ // Refinement edges are taken care of
+ // by coarser cells
+
+ // TODO: in the distributed case, we miss out
+ // the constraints when the neighbor cell is
+ // coarser, but only the current cell is owned
+ // locally!
+ if (cell->neighbor_is_coarser(face))
+ continue;
+
+ const unsigned int n_dofs_on_neighbor
+ = neighbor->get_fe().dofs_per_cell;
+ dofs_on_other_cell.resize (n_dofs_on_neighbor);
+
+ neighbor->get_dof_indices (dofs_on_other_cell);
+
+ constraints.add_entries_local_to_global
+ (dofs_on_this_cell, dofs_on_other_cell,
+ sparsity, keep_constrained_dofs);
+
+ // only need to add these in case the neighbor
+ // cell is not locally owned - otherwise, we
+ // touch each face twice and hence put the
+ // indices the other way around
+ if (cell->neighbor(face)->subdomain_id() !=
+ cell->subdomain_id())
+ constraints.add_entries_local_to_global
+ (dofs_on_other_cell, dofs_on_this_cell,
+ sparsity, keep_constrained_dofs);
+ }
+ }
+ }
+ }
}
const Table<2,Coupling> &component_couplings)
{
Assert(component_couplings.n_rows() == fe.n_components(),
- ExcDimensionMismatch(component_couplings.n_rows(),
- fe.n_components()));
+ ExcDimensionMismatch(component_couplings.n_rows(),
+ fe.n_components()));
Assert(component_couplings.n_cols() == fe.n_components(),
- ExcDimensionMismatch(component_couplings.n_cols(),
- fe.n_components()));
+ ExcDimensionMismatch(component_couplings.n_cols(),
+ fe.n_components()));
const unsigned int n_dofs = fe.dofs_per_cell;
for (unsigned int i=0; i<n_dofs; ++i)
{
- const unsigned int ii
- = (fe.is_primitive(i) ?
- fe.system_to_component_index(i).first
- :
- (std::find (fe.get_nonzero_components(i).begin(),
- fe.get_nonzero_components(i).end(),
- true)
- -
- fe.get_nonzero_components(i).begin())
- );
- Assert (ii < fe.n_components(), ExcInternalError());
-
- for (unsigned int j=0; j<n_dofs; ++j)
- {
- const unsigned int jj
- = (fe.is_primitive(j) ?
- fe.system_to_component_index(j).first
- :
- (std::find (fe.get_nonzero_components(j).begin(),
- fe.get_nonzero_components(j).end(),
- true)
- -
- fe.get_nonzero_components(j).begin())
- );
- Assert (jj < fe.n_components(), ExcInternalError());
-
- dof_couplings(i,j) = component_couplings(ii,jj);
- }
+ const unsigned int ii
+ = (fe.is_primitive(i) ?
+ fe.system_to_component_index(i).first
+ :
+ (std::find (fe.get_nonzero_components(i).begin(),
+ fe.get_nonzero_components(i).end(),
+ true)
+ -
+ fe.get_nonzero_components(i).begin())
+ );
+ Assert (ii < fe.n_components(), ExcInternalError());
+
+ for (unsigned int j=0; j<n_dofs; ++j)
+ {
+ const unsigned int jj
+ = (fe.is_primitive(j) ?
+ fe.system_to_component_index(j).first
+ :
+ (std::find (fe.get_nonzero_components(j).begin(),
+ fe.get_nonzero_components(j).end(),
+ true)
+ -
+ fe.get_nonzero_components(j).begin())
+ );
+ Assert (jj < fe.n_components(), ExcInternalError());
+
+ dof_couplings(i,j) = component_couplings(ii,jj);
+ }
}
return dof_couplings;
}
std::vector<Table<2,Coupling> > return_value (fe.size());
for (unsigned int i=0; i<fe.size(); ++i)
return_value[i]
- = dof_couplings_from_component_couplings(fe[i], component_couplings);
+ = dof_couplings_from_component_couplings(fe[i], component_couplings);
return return_value;
}
namespace
{
- // implementation of the same function in
- // namespace DoFTools for non-hp
- // DoFHandlers
+ // implementation of the same function in
+ // namespace DoFTools for non-hp
+ // DoFHandlers
template <class DH, class SparsityPattern>
void
make_flux_sparsity_pattern (const DH &dof,
- SparsityPattern &sparsity,
- const Table<2,Coupling> &int_mask,
- const Table<2,Coupling> &flux_mask)
+ SparsityPattern &sparsity,
+ const Table<2,Coupling> &int_mask,
+ const Table<2,Coupling> &flux_mask)
{
- const FiniteElement<DH::dimension,DH::space_dimension> &fe = dof.get_fe();
+ const FiniteElement<DH::dimension,DH::space_dimension> &fe = dof.get_fe();
- std::vector<unsigned int> dofs_on_this_cell(fe.dofs_per_cell);
- std::vector<unsigned int> dofs_on_other_cell(fe.dofs_per_cell);
+ std::vector<unsigned int> dofs_on_this_cell(fe.dofs_per_cell);
+ std::vector<unsigned int> dofs_on_other_cell(fe.dofs_per_cell);
- const Table<2,Coupling>
- int_dof_mask = dof_couplings_from_component_couplings(fe, int_mask),
- flux_dof_mask = dof_couplings_from_component_couplings(fe, flux_mask);
+ const Table<2,Coupling>
+ int_dof_mask = dof_couplings_from_component_couplings(fe, int_mask),
+ flux_dof_mask = dof_couplings_from_component_couplings(fe, flux_mask);
- Table<2,bool> support_on_face(fe.dofs_per_cell,
- GeometryInfo<DH::dimension>::faces_per_cell);
- for (unsigned int i=0; i<fe.dofs_per_cell; ++i)
- for (unsigned int f=0; f<GeometryInfo<DH::dimension>::faces_per_cell;++f)
- support_on_face(i,f) = fe.has_support_on_face(i,f);
+ Table<2,bool> support_on_face(fe.dofs_per_cell,
+ GeometryInfo<DH::dimension>::faces_per_cell);
+ for (unsigned int i=0; i<fe.dofs_per_cell; ++i)
+ for (unsigned int f=0; f<GeometryInfo<DH::dimension>::faces_per_cell;++f)
+ support_on_face(i,f) = fe.has_support_on_face(i,f);
- typename DH::active_cell_iterator cell = dof.begin_active(),
- endc = dof.end();
- for (; cell!=endc; ++cell)
+ typename DH::active_cell_iterator cell = dof.begin_active(),
+ endc = dof.end();
+ for (; cell!=endc; ++cell)
if (cell->is_locally_owned())
- {
- cell->get_dof_indices (dofs_on_this_cell);
- // make sparsity pattern for this cell
- for (unsigned int i=0; i<fe.dofs_per_cell; ++i)
- for (unsigned int j=0; j<fe.dofs_per_cell; ++j)
- if (int_dof_mask(i,j) != none)
- sparsity.add (dofs_on_this_cell[i],
- dofs_on_this_cell[j]);
-
- // Loop over all interior neighbors
- for (unsigned int face = 0;
- face < GeometryInfo<DH::dimension>::faces_per_cell;
- ++face)
- {
- const typename DH::face_iterator
- cell_face = cell->face(face);
- if (cell_face->user_flag_set ())
- continue;
-
- if (cell->at_boundary (face) )
- {
- for (unsigned int i=0; i<fe.dofs_per_cell; ++i)
- {
- const bool i_non_zero_i = support_on_face (i, face);
- for (unsigned int j=0; j<fe.dofs_per_cell; ++j)
- {
- const bool j_non_zero_i = support_on_face (j, face);
-
- if ((flux_dof_mask(i,j) == always)
- ||
- (flux_dof_mask(i,j) == nonzero
- &&
- i_non_zero_i
- &&
- j_non_zero_i))
- sparsity.add (dofs_on_this_cell[i],
- dofs_on_this_cell[j]);
- }
- }
- }
- else
- {
- typename DH::cell_iterator
- neighbor = cell->neighbor(face);
- // Refinement edges are taken care of
- // by coarser cells
- if (cell->neighbor_is_coarser(face))
- continue;
-
- typename DH::face_iterator cell_face = cell->face(face);
- const unsigned int
- neighbor_face = cell->neighbor_of_neighbor(face);
-
- if (cell_face->has_children())
- {
- for (unsigned int sub_nr = 0;
- sub_nr != cell_face->n_children();
- ++sub_nr)
- {
- const typename DH::cell_iterator
- sub_neighbor
- = cell->neighbor_child_on_subface (face, sub_nr);
-
- sub_neighbor->get_dof_indices (dofs_on_other_cell);
- for (unsigned int i=0; i<fe.dofs_per_cell; ++i)
- {
- const bool i_non_zero_i = support_on_face (i, face);
- const bool i_non_zero_e = support_on_face (i, neighbor_face);
- for (unsigned int j=0; j<fe.dofs_per_cell; ++j)
- {
- const bool j_non_zero_i = support_on_face (j, face);
- const bool j_non_zero_e = support_on_face (j, neighbor_face);
-
- if (flux_dof_mask(i,j) == always)
- {
- sparsity.add (dofs_on_this_cell[i],
- dofs_on_other_cell[j]);
- sparsity.add (dofs_on_other_cell[i],
- dofs_on_this_cell[j]);
- sparsity.add (dofs_on_this_cell[i],
- dofs_on_this_cell[j]);
- sparsity.add (dofs_on_other_cell[i],
- dofs_on_other_cell[j]);
- }
- else if (flux_dof_mask(i,j) == nonzero)
- {
- if (i_non_zero_i && j_non_zero_e)
- sparsity.add (dofs_on_this_cell[i],
- dofs_on_other_cell[j]);
- if (i_non_zero_e && j_non_zero_i)
- sparsity.add (dofs_on_other_cell[i],
- dofs_on_this_cell[j]);
- if (i_non_zero_i && j_non_zero_i)
- sparsity.add (dofs_on_this_cell[i],
- dofs_on_this_cell[j]);
- if (i_non_zero_e && j_non_zero_e)
- sparsity.add (dofs_on_other_cell[i],
- dofs_on_other_cell[j]);
- }
-
- if (flux_dof_mask(j,i) == always)
- {
- sparsity.add (dofs_on_this_cell[j],
- dofs_on_other_cell[i]);
- sparsity.add (dofs_on_other_cell[j],
- dofs_on_this_cell[i]);
- sparsity.add (dofs_on_this_cell[j],
- dofs_on_this_cell[i]);
- sparsity.add (dofs_on_other_cell[j],
- dofs_on_other_cell[i]);
- }
- else if (flux_dof_mask(j,i) == nonzero)
- {
- if (j_non_zero_i && i_non_zero_e)
- sparsity.add (dofs_on_this_cell[j],
- dofs_on_other_cell[i]);
- if (j_non_zero_e && i_non_zero_i)
- sparsity.add (dofs_on_other_cell[j],
- dofs_on_this_cell[i]);
- if (j_non_zero_i && i_non_zero_i)
- sparsity.add (dofs_on_this_cell[j],
- dofs_on_this_cell[i]);
- if (j_non_zero_e && i_non_zero_e)
- sparsity.add (dofs_on_other_cell[j],
- dofs_on_other_cell[i]);
- }
- }
- }
- sub_neighbor->face(neighbor_face)->set_user_flag ();
- }
- }
- else
- {
- neighbor->get_dof_indices (dofs_on_other_cell);
- for (unsigned int i=0; i<fe.dofs_per_cell; ++i)
- {
- const bool i_non_zero_i = support_on_face (i, face);
- const bool i_non_zero_e = support_on_face (i, neighbor_face);
- for (unsigned int j=0; j<fe.dofs_per_cell; ++j)
- {
- const bool j_non_zero_i = support_on_face (j, face);
- const bool j_non_zero_e = support_on_face (j, neighbor_face);
- if (flux_dof_mask(i,j) == always)
- {
- sparsity.add (dofs_on_this_cell[i],
- dofs_on_other_cell[j]);
- sparsity.add (dofs_on_other_cell[i],
- dofs_on_this_cell[j]);
- sparsity.add (dofs_on_this_cell[i],
- dofs_on_this_cell[j]);
- sparsity.add (dofs_on_other_cell[i],
- dofs_on_other_cell[j]);
- }
- if (flux_dof_mask(i,j) == nonzero)
- {
- if (i_non_zero_i && j_non_zero_e)
- sparsity.add (dofs_on_this_cell[i],
- dofs_on_other_cell[j]);
- if (i_non_zero_e && j_non_zero_i)
- sparsity.add (dofs_on_other_cell[i],
- dofs_on_this_cell[j]);
- if (i_non_zero_i && j_non_zero_i)
- sparsity.add (dofs_on_this_cell[i],
- dofs_on_this_cell[j]);
- if (i_non_zero_e && j_non_zero_e)
- sparsity.add (dofs_on_other_cell[i],
- dofs_on_other_cell[j]);
- }
-
- if (flux_dof_mask(j,i) == always)
- {
- sparsity.add (dofs_on_this_cell[j],
- dofs_on_other_cell[i]);
- sparsity.add (dofs_on_other_cell[j],
- dofs_on_this_cell[i]);
- sparsity.add (dofs_on_this_cell[j],
- dofs_on_this_cell[i]);
- sparsity.add (dofs_on_other_cell[j],
- dofs_on_other_cell[i]);
- }
- if (flux_dof_mask(j,i) == nonzero)
- {
- if (j_non_zero_i && i_non_zero_e)
- sparsity.add (dofs_on_this_cell[j],
- dofs_on_other_cell[i]);
- if (j_non_zero_e && i_non_zero_i)
- sparsity.add (dofs_on_other_cell[j],
- dofs_on_this_cell[i]);
- if (j_non_zero_i && i_non_zero_i)
- sparsity.add (dofs_on_this_cell[j],
- dofs_on_this_cell[i]);
- if (j_non_zero_e && i_non_zero_e)
- sparsity.add (dofs_on_other_cell[j],
- dofs_on_other_cell[i]);
- }
- }
- }
- neighbor->face(neighbor_face)->set_user_flag ();
- }
- }
- }
+ {
+ cell->get_dof_indices (dofs_on_this_cell);
+ // make sparsity pattern for this cell
+ for (unsigned int i=0; i<fe.dofs_per_cell; ++i)
+ for (unsigned int j=0; j<fe.dofs_per_cell; ++j)
+ if (int_dof_mask(i,j) != none)
+ sparsity.add (dofs_on_this_cell[i],
+ dofs_on_this_cell[j]);
+
+ // Loop over all interior neighbors
+ for (unsigned int face = 0;
+ face < GeometryInfo<DH::dimension>::faces_per_cell;
+ ++face)
+ {
+ const typename DH::face_iterator
+ cell_face = cell->face(face);
+ if (cell_face->user_flag_set ())
+ continue;
+
+ if (cell->at_boundary (face) )
+ {
+ for (unsigned int i=0; i<fe.dofs_per_cell; ++i)
+ {
+ const bool i_non_zero_i = support_on_face (i, face);
+ for (unsigned int j=0; j<fe.dofs_per_cell; ++j)
+ {
+ const bool j_non_zero_i = support_on_face (j, face);
+
+ if ((flux_dof_mask(i,j) == always)
+ ||
+ (flux_dof_mask(i,j) == nonzero
+ &&
+ i_non_zero_i
+ &&
+ j_non_zero_i))
+ sparsity.add (dofs_on_this_cell[i],
+ dofs_on_this_cell[j]);
+ }
+ }
+ }
+ else
+ {
+ typename DH::cell_iterator
+ neighbor = cell->neighbor(face);
+ // Refinement edges are taken care of
+ // by coarser cells
+ if (cell->neighbor_is_coarser(face))
+ continue;
+
+ typename DH::face_iterator cell_face = cell->face(face);
+ const unsigned int
+ neighbor_face = cell->neighbor_of_neighbor(face);
+
+ if (cell_face->has_children())
+ {
+ for (unsigned int sub_nr = 0;
+ sub_nr != cell_face->n_children();
+ ++sub_nr)
+ {
+ const typename DH::cell_iterator
+ sub_neighbor
+ = cell->neighbor_child_on_subface (face, sub_nr);
+
+ sub_neighbor->get_dof_indices (dofs_on_other_cell);
+ for (unsigned int i=0; i<fe.dofs_per_cell; ++i)
+ {
+ const bool i_non_zero_i = support_on_face (i, face);
+ const bool i_non_zero_e = support_on_face (i, neighbor_face);
+ for (unsigned int j=0; j<fe.dofs_per_cell; ++j)
+ {
+ const bool j_non_zero_i = support_on_face (j, face);
+ const bool j_non_zero_e = support_on_face (j, neighbor_face);
+
+ if (flux_dof_mask(i,j) == always)
+ {
+ sparsity.add (dofs_on_this_cell[i],
+ dofs_on_other_cell[j]);
+ sparsity.add (dofs_on_other_cell[i],
+ dofs_on_this_cell[j]);
+ sparsity.add (dofs_on_this_cell[i],
+ dofs_on_this_cell[j]);
+ sparsity.add (dofs_on_other_cell[i],
+ dofs_on_other_cell[j]);
+ }
+ else if (flux_dof_mask(i,j) == nonzero)
+ {
+ if (i_non_zero_i && j_non_zero_e)
+ sparsity.add (dofs_on_this_cell[i],
+ dofs_on_other_cell[j]);
+ if (i_non_zero_e && j_non_zero_i)
+ sparsity.add (dofs_on_other_cell[i],
+ dofs_on_this_cell[j]);
+ if (i_non_zero_i && j_non_zero_i)
+ sparsity.add (dofs_on_this_cell[i],
+ dofs_on_this_cell[j]);
+ if (i_non_zero_e && j_non_zero_e)
+ sparsity.add (dofs_on_other_cell[i],
+ dofs_on_other_cell[j]);
+ }
+
+ if (flux_dof_mask(j,i) == always)
+ {
+ sparsity.add (dofs_on_this_cell[j],
+ dofs_on_other_cell[i]);
+ sparsity.add (dofs_on_other_cell[j],
+ dofs_on_this_cell[i]);
+ sparsity.add (dofs_on_this_cell[j],
+ dofs_on_this_cell[i]);
+ sparsity.add (dofs_on_other_cell[j],
+ dofs_on_other_cell[i]);
+ }
+ else if (flux_dof_mask(j,i) == nonzero)
+ {
+ if (j_non_zero_i && i_non_zero_e)
+ sparsity.add (dofs_on_this_cell[j],
+ dofs_on_other_cell[i]);
+ if (j_non_zero_e && i_non_zero_i)
+ sparsity.add (dofs_on_other_cell[j],
+ dofs_on_this_cell[i]);
+ if (j_non_zero_i && i_non_zero_i)
+ sparsity.add (dofs_on_this_cell[j],
+ dofs_on_this_cell[i]);
+ if (j_non_zero_e && i_non_zero_e)
+ sparsity.add (dofs_on_other_cell[j],
+ dofs_on_other_cell[i]);
+ }
+ }
+ }
+ sub_neighbor->face(neighbor_face)->set_user_flag ();
+ }
+ }
+ else
+ {
+ neighbor->get_dof_indices (dofs_on_other_cell);
+ for (unsigned int i=0; i<fe.dofs_per_cell; ++i)
+ {
+ const bool i_non_zero_i = support_on_face (i, face);
+ const bool i_non_zero_e = support_on_face (i, neighbor_face);
+ for (unsigned int j=0; j<fe.dofs_per_cell; ++j)
+ {
+ const bool j_non_zero_i = support_on_face (j, face);
+ const bool j_non_zero_e = support_on_face (j, neighbor_face);
+ if (flux_dof_mask(i,j) == always)
+ {
+ sparsity.add (dofs_on_this_cell[i],
+ dofs_on_other_cell[j]);
+ sparsity.add (dofs_on_other_cell[i],
+ dofs_on_this_cell[j]);
+ sparsity.add (dofs_on_this_cell[i],
+ dofs_on_this_cell[j]);
+ sparsity.add (dofs_on_other_cell[i],
+ dofs_on_other_cell[j]);
+ }
+ if (flux_dof_mask(i,j) == nonzero)
+ {
+ if (i_non_zero_i && j_non_zero_e)
+ sparsity.add (dofs_on_this_cell[i],
+ dofs_on_other_cell[j]);
+ if (i_non_zero_e && j_non_zero_i)
+ sparsity.add (dofs_on_other_cell[i],
+ dofs_on_this_cell[j]);
+ if (i_non_zero_i && j_non_zero_i)
+ sparsity.add (dofs_on_this_cell[i],
+ dofs_on_this_cell[j]);
+ if (i_non_zero_e && j_non_zero_e)
+ sparsity.add (dofs_on_other_cell[i],
+ dofs_on_other_cell[j]);
+ }
+
+ if (flux_dof_mask(j,i) == always)
+ {
+ sparsity.add (dofs_on_this_cell[j],
+ dofs_on_other_cell[i]);
+ sparsity.add (dofs_on_other_cell[j],
+ dofs_on_this_cell[i]);
+ sparsity.add (dofs_on_this_cell[j],
+ dofs_on_this_cell[i]);
+ sparsity.add (dofs_on_other_cell[j],
+ dofs_on_other_cell[i]);
+ }
+ if (flux_dof_mask(j,i) == nonzero)
+ {
+ if (j_non_zero_i && i_non_zero_e)
+ sparsity.add (dofs_on_this_cell[j],
+ dofs_on_other_cell[i]);
+ if (j_non_zero_e && i_non_zero_i)
+ sparsity.add (dofs_on_other_cell[j],
+ dofs_on_this_cell[i]);
+ if (j_non_zero_i && i_non_zero_i)
+ sparsity.add (dofs_on_this_cell[j],
+ dofs_on_this_cell[i]);
+ if (j_non_zero_e && i_non_zero_e)
+ sparsity.add (dofs_on_other_cell[j],
+ dofs_on_other_cell[i]);
+ }
+ }
+ }
+ neighbor->face(neighbor_face)->set_user_flag ();
+ }
+ }
+ }
}
}
- // implementation of the same function in
- // namespace DoFTools for non-hp
- // DoFHandlers
+ // implementation of the same function in
+ // namespace DoFTools for non-hp
+ // DoFHandlers
template <int dim, int spacedim, class SparsityPattern>
void
make_flux_sparsity_pattern (const dealii::hp::DoFHandler<dim,spacedim> &dof,
- SparsityPattern &sparsity,
- const Table<2,Coupling> &int_mask,
- const Table<2,Coupling> &flux_mask)
+ SparsityPattern &sparsity,
+ const Table<2,Coupling> &int_mask,
+ const Table<2,Coupling> &flux_mask)
{
- // while the implementation above is
- // quite optimized and caches a lot of
- // data (see e.g. the int/flux_dof_mask
- // tables), this is no longer practical
- // for the hp version since we would
- // have to have it for all combinations
- // of elements in the
- // hp::FECollection. consequently, the
- // implementation here is simpler and
- // probably less efficient but at least
- // readable...
-
- const dealii::hp::FECollection<dim,spacedim> &fe = dof.get_fe();
-
- std::vector<unsigned int> dofs_on_this_cell(DoFTools::max_dofs_per_cell(dof));
- std::vector<unsigned int> dofs_on_other_cell(DoFTools::max_dofs_per_cell(dof));
-
- const std::vector<Table<2,Coupling> >
- int_dof_mask
- = dof_couplings_from_component_couplings(fe, int_mask);
-
- typename dealii::hp::DoFHandler<dim,spacedim>::active_cell_iterator
- cell = dof.begin_active(),
- endc = dof.end();
- for (; cell!=endc; ++cell)
- {
- dofs_on_this_cell.resize (cell->get_fe().dofs_per_cell);
- cell->get_dof_indices (dofs_on_this_cell);
- // make sparsity pattern for this cell
- for (unsigned int i=0; i<cell->get_fe().dofs_per_cell; ++i)
- for (unsigned int j=0; j<cell->get_fe().dofs_per_cell; ++j)
- if (int_dof_mask[cell->active_fe_index()](i,j) != none)
- sparsity.add (dofs_on_this_cell[i],
- dofs_on_this_cell[j]);
-
- // Loop over all interior neighbors
- for (unsigned int face = 0;
- face < GeometryInfo<dim>::faces_per_cell;
- ++face)
- {
- const typename dealii::hp::DoFHandler<dim,spacedim>::face_iterator
- cell_face = cell->face(face);
- if (cell_face->user_flag_set ())
- continue;
-
- if (cell->at_boundary (face) )
- {
- for (unsigned int i=0; i<cell->get_fe().dofs_per_cell; ++i)
- for (unsigned int j=0; j<cell->get_fe().dofs_per_cell; ++j)
- if ((flux_mask(cell->get_fe().system_to_component_index(i).first,
- cell->get_fe().system_to_component_index(j).first)
- == always)
- ||
- (flux_mask(cell->get_fe().system_to_component_index(i).first,
- cell->get_fe().system_to_component_index(j).first)
- == nonzero))
- sparsity.add (dofs_on_this_cell[i],
- dofs_on_this_cell[j]);
- }
- else
- {
- typename dealii::hp::DoFHandler<dim,spacedim>::cell_iterator
- neighbor = cell->neighbor(face);
- // Refinement edges are taken care of
- // by coarser cells
- if (cell->neighbor_is_coarser(face))
- continue;
-
- typename dealii::hp::DoFHandler<dim,spacedim>::face_iterator
- cell_face = cell->face(face);
- const unsigned int
- neighbor_face = cell->neighbor_of_neighbor(face);
-
- if (cell_face->has_children())
- {
- for (unsigned int sub_nr = 0;
- sub_nr != cell_face->n_children();
- ++sub_nr)
- {
- const typename dealii::hp::DoFHandler<dim,spacedim>::cell_iterator
- sub_neighbor
- = cell->neighbor_child_on_subface (face, sub_nr);
-
- dofs_on_other_cell.resize (sub_neighbor->get_fe().dofs_per_cell);
- sub_neighbor->get_dof_indices (dofs_on_other_cell);
- for (unsigned int i=0; i<cell->get_fe().dofs_per_cell; ++i)
- {
- for (unsigned int j=0; j<sub_neighbor->get_fe().dofs_per_cell;
- ++j)
- {
- if ((flux_mask(cell->get_fe().system_to_component_index(i).first,
- sub_neighbor->get_fe().system_to_component_index(j).first)
- == always)
- ||
- (flux_mask(cell->get_fe().system_to_component_index(i).first,
- sub_neighbor->get_fe().system_to_component_index(j).first)
- == nonzero))
- {
- sparsity.add (dofs_on_this_cell[i],
- dofs_on_other_cell[j]);
- sparsity.add (dofs_on_other_cell[i],
- dofs_on_this_cell[j]);
- sparsity.add (dofs_on_this_cell[i],
- dofs_on_this_cell[j]);
- sparsity.add (dofs_on_other_cell[i],
- dofs_on_other_cell[j]);
- }
-
- if ((flux_mask(sub_neighbor->get_fe().system_to_component_index(j).first,
- cell->get_fe().system_to_component_index(i).first)
- == always)
- ||
- (flux_mask(sub_neighbor->get_fe().system_to_component_index(j).first,
- cell->get_fe().system_to_component_index(i).first)
- == nonzero))
- {
- sparsity.add (dofs_on_this_cell[j],
- dofs_on_other_cell[i]);
- sparsity.add (dofs_on_other_cell[j],
- dofs_on_this_cell[i]);
- sparsity.add (dofs_on_this_cell[j],
- dofs_on_this_cell[i]);
- sparsity.add (dofs_on_other_cell[j],
- dofs_on_other_cell[i]);
- }
- }
- }
- sub_neighbor->face(neighbor_face)->set_user_flag ();
- }
- }
- else
- {
- dofs_on_other_cell.resize (neighbor->get_fe().dofs_per_cell);
- neighbor->get_dof_indices (dofs_on_other_cell);
- for (unsigned int i=0; i<cell->get_fe().dofs_per_cell; ++i)
- {
- for (unsigned int j=0; j<neighbor->get_fe().dofs_per_cell; ++j)
- {
- if ((flux_mask(cell->get_fe().system_to_component_index(i).first,
- neighbor->get_fe().system_to_component_index(j).first)
- == always)
- ||
- (flux_mask(cell->get_fe().system_to_component_index(i).first,
- neighbor->get_fe().system_to_component_index(j).first)
- == nonzero))
- {
- sparsity.add (dofs_on_this_cell[i],
- dofs_on_other_cell[j]);
- sparsity.add (dofs_on_other_cell[i],
- dofs_on_this_cell[j]);
- sparsity.add (dofs_on_this_cell[i],
- dofs_on_this_cell[j]);
- sparsity.add (dofs_on_other_cell[i],
- dofs_on_other_cell[j]);
- }
-
- if ((flux_mask(neighbor->get_fe().system_to_component_index(j).first,
- cell->get_fe().system_to_component_index(i).first)
- == always)
- ||
- (flux_mask(neighbor->get_fe().system_to_component_index(j).first,
- cell->get_fe().system_to_component_index(i).first)
- == nonzero))
- {
- sparsity.add (dofs_on_this_cell[j],
- dofs_on_other_cell[i]);
- sparsity.add (dofs_on_other_cell[j],
- dofs_on_this_cell[i]);
- sparsity.add (dofs_on_this_cell[j],
- dofs_on_this_cell[i]);
- sparsity.add (dofs_on_other_cell[j],
- dofs_on_other_cell[i]);
- }
- }
- }
- neighbor->face(neighbor_face)->set_user_flag ();
- }
- }
- }
- }
+ // while the implementation above is
+ // quite optimized and caches a lot of
+ // data (see e.g. the int/flux_dof_mask
+ // tables), this is no longer practical
+ // for the hp version since we would
+ // have to have it for all combinations
+ // of elements in the
+ // hp::FECollection. consequently, the
+ // implementation here is simpler and
+ // probably less efficient but at least
+ // readable...
+
+ const dealii::hp::FECollection<dim,spacedim> &fe = dof.get_fe();
+
+ std::vector<unsigned int> dofs_on_this_cell(DoFTools::max_dofs_per_cell(dof));
+ std::vector<unsigned int> dofs_on_other_cell(DoFTools::max_dofs_per_cell(dof));
+
+ const std::vector<Table<2,Coupling> >
+ int_dof_mask
+ = dof_couplings_from_component_couplings(fe, int_mask);
+
+ typename dealii::hp::DoFHandler<dim,spacedim>::active_cell_iterator
+ cell = dof.begin_active(),
+ endc = dof.end();
+ for (; cell!=endc; ++cell)
+ {
+ dofs_on_this_cell.resize (cell->get_fe().dofs_per_cell);
+ cell->get_dof_indices (dofs_on_this_cell);
+ // make sparsity pattern for this cell
+ for (unsigned int i=0; i<cell->get_fe().dofs_per_cell; ++i)
+ for (unsigned int j=0; j<cell->get_fe().dofs_per_cell; ++j)
+ if (int_dof_mask[cell->active_fe_index()](i,j) != none)
+ sparsity.add (dofs_on_this_cell[i],
+ dofs_on_this_cell[j]);
+
+ // Loop over all interior neighbors
+ for (unsigned int face = 0;
+ face < GeometryInfo<dim>::faces_per_cell;
+ ++face)
+ {
+ const typename dealii::hp::DoFHandler<dim,spacedim>::face_iterator
+ cell_face = cell->face(face);
+ if (cell_face->user_flag_set ())
+ continue;
+
+ if (cell->at_boundary (face) )
+ {
+ for (unsigned int i=0; i<cell->get_fe().dofs_per_cell; ++i)
+ for (unsigned int j=0; j<cell->get_fe().dofs_per_cell; ++j)
+ if ((flux_mask(cell->get_fe().system_to_component_index(i).first,
+ cell->get_fe().system_to_component_index(j).first)
+ == always)
+ ||
+ (flux_mask(cell->get_fe().system_to_component_index(i).first,
+ cell->get_fe().system_to_component_index(j).first)
+ == nonzero))
+ sparsity.add (dofs_on_this_cell[i],
+ dofs_on_this_cell[j]);
+ }
+ else
+ {
+ typename dealii::hp::DoFHandler<dim,spacedim>::cell_iterator
+ neighbor = cell->neighbor(face);
+ // Refinement edges are taken care of
+ // by coarser cells
+ if (cell->neighbor_is_coarser(face))
+ continue;
+
+ typename dealii::hp::DoFHandler<dim,spacedim>::face_iterator
+ cell_face = cell->face(face);
+ const unsigned int
+ neighbor_face = cell->neighbor_of_neighbor(face);
+
+ if (cell_face->has_children())
+ {
+ for (unsigned int sub_nr = 0;
+ sub_nr != cell_face->n_children();
+ ++sub_nr)
+ {
+ const typename dealii::hp::DoFHandler<dim,spacedim>::cell_iterator
+ sub_neighbor
+ = cell->neighbor_child_on_subface (face, sub_nr);
+
+ dofs_on_other_cell.resize (sub_neighbor->get_fe().dofs_per_cell);
+ sub_neighbor->get_dof_indices (dofs_on_other_cell);
+ for (unsigned int i=0; i<cell->get_fe().dofs_per_cell; ++i)
+ {
+ for (unsigned int j=0; j<sub_neighbor->get_fe().dofs_per_cell;
+ ++j)
+ {
+ if ((flux_mask(cell->get_fe().system_to_component_index(i).first,
+ sub_neighbor->get_fe().system_to_component_index(j).first)
+ == always)
+ ||
+ (flux_mask(cell->get_fe().system_to_component_index(i).first,
+ sub_neighbor->get_fe().system_to_component_index(j).first)
+ == nonzero))
+ {
+ sparsity.add (dofs_on_this_cell[i],
+ dofs_on_other_cell[j]);
+ sparsity.add (dofs_on_other_cell[i],
+ dofs_on_this_cell[j]);
+ sparsity.add (dofs_on_this_cell[i],
+ dofs_on_this_cell[j]);
+ sparsity.add (dofs_on_other_cell[i],
+ dofs_on_other_cell[j]);
+ }
+
+ if ((flux_mask(sub_neighbor->get_fe().system_to_component_index(j).first,
+ cell->get_fe().system_to_component_index(i).first)
+ == always)
+ ||
+ (flux_mask(sub_neighbor->get_fe().system_to_component_index(j).first,
+ cell->get_fe().system_to_component_index(i).first)
+ == nonzero))
+ {
+ sparsity.add (dofs_on_this_cell[j],
+ dofs_on_other_cell[i]);
+ sparsity.add (dofs_on_other_cell[j],
+ dofs_on_this_cell[i]);
+ sparsity.add (dofs_on_this_cell[j],
+ dofs_on_this_cell[i]);
+ sparsity.add (dofs_on_other_cell[j],
+ dofs_on_other_cell[i]);
+ }
+ }
+ }
+ sub_neighbor->face(neighbor_face)->set_user_flag ();
+ }
+ }
+ else
+ {
+ dofs_on_other_cell.resize (neighbor->get_fe().dofs_per_cell);
+ neighbor->get_dof_indices (dofs_on_other_cell);
+ for (unsigned int i=0; i<cell->get_fe().dofs_per_cell; ++i)
+ {
+ for (unsigned int j=0; j<neighbor->get_fe().dofs_per_cell; ++j)
+ {
+ if ((flux_mask(cell->get_fe().system_to_component_index(i).first,
+ neighbor->get_fe().system_to_component_index(j).first)
+ == always)
+ ||
+ (flux_mask(cell->get_fe().system_to_component_index(i).first,
+ neighbor->get_fe().system_to_component_index(j).first)
+ == nonzero))
+ {
+ sparsity.add (dofs_on_this_cell[i],
+ dofs_on_other_cell[j]);
+ sparsity.add (dofs_on_other_cell[i],
+ dofs_on_this_cell[j]);
+ sparsity.add (dofs_on_this_cell[i],
+ dofs_on_this_cell[j]);
+ sparsity.add (dofs_on_other_cell[i],
+ dofs_on_other_cell[j]);
+ }
+
+ if ((flux_mask(neighbor->get_fe().system_to_component_index(j).first,
+ cell->get_fe().system_to_component_index(i).first)
+ == always)
+ ||
+ (flux_mask(neighbor->get_fe().system_to_component_index(j).first,
+ cell->get_fe().system_to_component_index(i).first)
+ == nonzero))
+ {
+ sparsity.add (dofs_on_this_cell[j],
+ dofs_on_other_cell[i]);
+ sparsity.add (dofs_on_other_cell[j],
+ dofs_on_this_cell[i]);
+ sparsity.add (dofs_on_this_cell[j],
+ dofs_on_this_cell[i]);
+ sparsity.add (dofs_on_other_cell[j],
+ dofs_on_other_cell[i]);
+ }
+ }
+ }
+ neighbor->face(neighbor_face)->set_user_flag ();
+ }
+ }
+ }
+ }
}
}
template <class DH, class SparsityPattern>
void
make_flux_sparsity_pattern (const DH &dof,
- SparsityPattern &sparsity,
- const Table<2,Coupling> &int_mask,
- const Table<2,Coupling> &flux_mask)
+ SparsityPattern &sparsity,
+ const Table<2,Coupling> &int_mask,
+ const Table<2,Coupling> &flux_mask)
{
- // do the error checking and frame code
- // here, and then pass on to more
- // specialized functions in the internal
- // namespace
+ // do the error checking and frame code
+ // here, and then pass on to more
+ // specialized functions in the internal
+ // namespace
const unsigned int n_dofs = dof.n_dofs();
const unsigned int n_comp = dof.get_fe().n_components();
Assert (sparsity.n_rows() == n_dofs,
- ExcDimensionMismatch (sparsity.n_rows(), n_dofs));
+ ExcDimensionMismatch (sparsity.n_rows(), n_dofs));
Assert (sparsity.n_cols() == n_dofs,
- ExcDimensionMismatch (sparsity.n_cols(), n_dofs));
+ ExcDimensionMismatch (sparsity.n_cols(), n_dofs));
Assert (int_mask.n_rows() == n_comp,
- ExcDimensionMismatch (int_mask.n_rows(), n_comp));
+ ExcDimensionMismatch (int_mask.n_rows(), n_comp));
Assert (int_mask.n_cols() == n_comp,
- ExcDimensionMismatch (int_mask.n_cols(), n_comp));
+ ExcDimensionMismatch (int_mask.n_cols(), n_comp));
Assert (flux_mask.n_rows() == n_comp,
- ExcDimensionMismatch (flux_mask.n_rows(), n_comp));
+ ExcDimensionMismatch (flux_mask.n_rows(), n_comp));
Assert (flux_mask.n_cols() == n_comp,
- ExcDimensionMismatch (flux_mask.n_cols(), n_comp));
+ ExcDimensionMismatch (flux_mask.n_cols(), n_comp));
- // Clear user flags because we will
- // need them. But first we save
- // them and make sure that we
- // restore them later such that at
- // the end of this function the
- // Triangulation will be in the
- // same state as it was at the
- // beginning of this function.
+ // Clear user flags because we will
+ // need them. But first we save
+ // them and make sure that we
+ // restore them later such that at
+ // the end of this function the
+ // Triangulation will be in the
+ // same state as it was at the
+ // beginning of this function.
std::vector<bool> user_flags;
dof.get_tria().save_user_flags(user_flags);
const_cast<Triangulation<DH::dimension,DH::space_dimension> &>(dof.get_tria()).clear_user_flags ();
internal::make_flux_sparsity_pattern (dof, sparsity,
- int_mask, flux_mask);
+ int_mask, flux_mask);
- // finally restore the user flags
+ // finally restore the user flags
const_cast<Triangulation<DH::dimension,DH::space_dimension> &>(dof.get_tria()).load_user_flags(user_flags);
}
inline
bool
check_master_dof_list (const FullMatrix<double> &face_interpolation_matrix,
- const std::vector<unsigned int> &master_dof_list)
+ const std::vector<unsigned int> &master_dof_list)
{
- const unsigned int N = master_dof_list.size();
-
- FullMatrix<double> tmp (N,N);
- for (unsigned int i=0; i<N; ++i)
- for (unsigned int j=0; j<N; ++j)
- tmp(i,j) = face_interpolation_matrix (master_dof_list[i], j);
-
- // then use the algorithm
- // from
- // FullMatrix::gauss_jordan
- // on this matrix to find out
- // whether it is
- // singular. the algorithm
- // there does piviting and at
- // the end swaps rows back
- // into their proper order --
- // we omit this step here,
- // since we don't care about
- // the inverse matrix, all we
- // care about is whether the
- // matrix is regular or
- // singular
-
- // first get an estimate of the
- // size of the elements of this
- // matrix, for later checks whether
- // the pivot element is large
- // enough, or whether we have to
- // fear that the matrix is not
- // regular
- double diagonal_sum = 0;
- for (unsigned int i=0; i<N; ++i)
- diagonal_sum += std::fabs(tmp(i,i));
- const double typical_diagonal_element = diagonal_sum/N;
-
- // initialize the array that holds
- // the permutations that we find
- // during pivot search
- std::vector<unsigned int> p(N);
- for (unsigned int i=0; i<N; ++i)
- p[i] = i;
-
- for (unsigned int j=0; j<N; ++j)
- {
- // pivot search: search that
- // part of the line on and
- // right of the diagonal for
- // the largest element
- double max = std::fabs(tmp(j,j));
- unsigned int r = j;
- for (unsigned int i=j+1; i<N; ++i)
- {
- if (std::fabs(tmp(i,j)) > max)
- {
- max = std::fabs(tmp(i,j));
- r = i;
- }
- }
- // check whether the
- // pivot is too small. if
- // that is the case, then
- // the matrix is singular
- // and we shouldn't use
- // this set of master
- // dofs
- if (max < 1.e-12*typical_diagonal_element)
- return false;
-
- // row interchange
- if (r>j)
- {
- for (unsigned int k=0; k<N; ++k)
- std::swap (tmp(j,k), tmp(r,k));
-
- std::swap (p[j], p[r]);
- }
-
- // transformation
- const double hr = 1./tmp(j,j);
- tmp(j,j) = hr;
- for (unsigned int k=0; k<N; ++k)
- {
- if (k==j) continue;
- for (unsigned int i=0; i<N; ++i)
- {
- if (i==j) continue;
- tmp(i,k) -= tmp(i,j)*tmp(j,k)*hr;
- }
- }
- for (unsigned int i=0; i<N; ++i)
- {
- tmp(i,j) *= hr;
- tmp(j,i) *= -hr;
- }
- tmp(j,j) = hr;
- }
-
- // everything went fine, so
- // we can accept this set of
- // master dofs (at least as
- // far as they have already
- // been collected)
- return true;
+ const unsigned int N = master_dof_list.size();
+
+ FullMatrix<double> tmp (N,N);
+ for (unsigned int i=0; i<N; ++i)
+ for (unsigned int j=0; j<N; ++j)
+ tmp(i,j) = face_interpolation_matrix (master_dof_list[i], j);
+
+ // then use the algorithm
+ // from
+ // FullMatrix::gauss_jordan
+ // on this matrix to find out
+ // whether it is
+ // singular. the algorithm
+ // there does piviting and at
+ // the end swaps rows back
+ // into their proper order --
+ // we omit this step here,
+ // since we don't care about
+ // the inverse matrix, all we
+ // care about is whether the
+ // matrix is regular or
+ // singular
+
+ // first get an estimate of the
+ // size of the elements of this
+ // matrix, for later checks whether
+ // the pivot element is large
+ // enough, or whether we have to
+ // fear that the matrix is not
+ // regular
+ double diagonal_sum = 0;
+ for (unsigned int i=0; i<N; ++i)
+ diagonal_sum += std::fabs(tmp(i,i));
+ const double typical_diagonal_element = diagonal_sum/N;
+
+ // initialize the array that holds
+ // the permutations that we find
+ // during pivot search
+ std::vector<unsigned int> p(N);
+ for (unsigned int i=0; i<N; ++i)
+ p[i] = i;
+
+ for (unsigned int j=0; j<N; ++j)
+ {
+ // pivot search: search that
+ // part of the line on and
+ // right of the diagonal for
+ // the largest element
+ double max = std::fabs(tmp(j,j));
+ unsigned int r = j;
+ for (unsigned int i=j+1; i<N; ++i)
+ {
+ if (std::fabs(tmp(i,j)) > max)
+ {
+ max = std::fabs(tmp(i,j));
+ r = i;
+ }
+ }
+ // check whether the
+ // pivot is too small. if
+ // that is the case, then
+ // the matrix is singular
+ // and we shouldn't use
+ // this set of master
+ // dofs
+ if (max < 1.e-12*typical_diagonal_element)
+ return false;
+
+ // row interchange
+ if (r>j)
+ {
+ for (unsigned int k=0; k<N; ++k)
+ std::swap (tmp(j,k), tmp(r,k));
+
+ std::swap (p[j], p[r]);
+ }
+
+ // transformation
+ const double hr = 1./tmp(j,j);
+ tmp(j,j) = hr;
+ for (unsigned int k=0; k<N; ++k)
+ {
+ if (k==j) continue;
+ for (unsigned int i=0; i<N; ++i)
+ {
+ if (i==j) continue;
+ tmp(i,k) -= tmp(i,j)*tmp(j,k)*hr;
+ }
+ }
+ for (unsigned int i=0; i<N; ++i)
+ {
+ tmp(i,j) *= hr;
+ tmp(j,i) *= -hr;
+ }
+ tmp(j,j) = hr;
+ }
+
+ // everything went fine, so
+ // we can accept this set of
+ // master dofs (at least as
+ // far as they have already
+ // been collected)
+ return true;
}
- /**
- * When restricting, on a face, the
- * degrees of freedom of fe1 to the
- * space described by fe2 (for example
- * for the complex case described in
- * the @ref hp_paper "hp paper"), we have to select
- * fe2.dofs_per_face out of the
- * fe1.dofs_per_face face DoFs as the
- * master DoFs, and the rest become
- * slave dofs. This function selects
- * which ones will be masters, and
- * which ones will be slaves.
- *
- * The function assumes that
- * master_dofs already has size
- * fe1.dofs_per_face. After the
- * function, exactly fe2.dofs_per_face
- * entries will be true.
- *
- * The function is a bit
- * complicated since it has to
- * figure out a set a DoFs so
- * that the corresponding rows
- * in the face interpolation
- * matrix are all linearly
- * independent. we have a good
- * heuristic (see the function
- * body) for selecting these
- * rows, but there are cases
- * where this fails and we have
- * to pick them
- * differently. what we do is
- * to run the heuristic and
- * then go back to determine
- * whether we have a set of
- * rows with full row rank. if
- * this isn't the case, go back
- * and select dofs differently
- */
+ /**
+ * When restricting, on a face, the
+ * degrees of freedom of fe1 to the
+ * space described by fe2 (for example
+ * for the complex case described in
+ * the @ref hp_paper "hp paper"), we have to select
+ * fe2.dofs_per_face out of the
+ * fe1.dofs_per_face face DoFs as the
+ * master DoFs, and the rest become
+ * slave dofs. This function selects
+ * which ones will be masters, and
+ * which ones will be slaves.
+ *
+ * The function assumes that
+ * master_dofs already has size
+ * fe1.dofs_per_face. After the
+ * function, exactly fe2.dofs_per_face
+ * entries will be true.
+ *
+ * The function is a bit
+ * complicated since it has to
+ * figure out a set a DoFs so
+ * that the corresponding rows
+ * in the face interpolation
+ * matrix are all linearly
+ * independent. we have a good
+ * heuristic (see the function
+ * body) for selecting these
+ * rows, but there are cases
+ * where this fails and we have
+ * to pick them
+ * differently. what we do is
+ * to run the heuristic and
+ * then go back to determine
+ * whether we have a set of
+ * rows with full row rank. if
+ * this isn't the case, go back
+ * and select dofs differently
+ */
template <int dim, int spacedim>
void
select_master_dofs_for_face_restriction (const FiniteElement<dim,spacedim> &fe1,
- const FiniteElement<dim,spacedim> &fe2,
- const FullMatrix<double> &face_interpolation_matrix,
- std::vector<bool> &master_dof_mask)
+ const FiniteElement<dim,spacedim> &fe2,
+ const FullMatrix<double> &face_interpolation_matrix,
+ std::vector<bool> &master_dof_mask)
{
- Assert (fe1.dofs_per_face >= fe2.dofs_per_face,
- ExcInternalError());
- AssertDimension (master_dof_mask.size(), fe1.dofs_per_face);
-
- Assert (fe2.dofs_per_vertex <= fe1.dofs_per_vertex,
- ExcInternalError());
- Assert (fe2.dofs_per_line <= fe1.dofs_per_line,
- ExcInternalError());
- Assert ((dim < 3)
- ||
- (fe2.dofs_per_quad <= fe1.dofs_per_quad),
- ExcInternalError());
-
- // the idea here is to designate as
- // many DoFs in fe1 per object
- // (vertex, line, quad) as master as
- // there are such dofs in fe2
- // (indices are int, because we want
- // to avoid the 'unsigned int < 0 is
- // always false warning for the cases
- // at the bottom in 1d and 2d)
- //
- // as mentioned in the paper, it is
- // not always easy to find a set of
- // master dofs that produces an
- // invertible matrix. to this end, we
- // check in each step whether the
- // matrix is still invertible and
- // simply discard this dof if the
- // matrix is not invertible anymore.
- //
- // the cases where we did have
- // trouble in the past were with
- // adding more quad dofs when Q3 and
- // Q4 elements meet at a refined face
- // in 3d (see the hp/crash_12 test
- // that tests that we can do exactly
- // this, and failed before we had
- // code to compensate for this
- // case). the other case are system
- // elements: if we have say a Q1Q2 vs
- // a Q2Q3 element, then we can't just
- // take all master dofs on a line
- // from a single base element, since
- // the shape functions of that base
- // element are independent of that of
- // the other one. this latter case
- // shows up when running
- // hp/hp_constraints_q_system_06
- std::vector<unsigned int> master_dof_list;
- unsigned int index = 0;
- for (int v=0;
- v<static_cast<signed int>(GeometryInfo<dim>::vertices_per_face);
- ++v)
- {
- unsigned int dofs_added = 0;
- unsigned int i = 0;
- while (dofs_added < fe2.dofs_per_vertex)
- {
- // make sure that we
- // were able to find
- // a set of master
- // dofs and that the
- // code down below
- // didn't just reject
- // all our efforts
- Assert (i < fe1.dofs_per_vertex,
- ExcInternalError());
- // tentatively push
- // this vertex dof
- master_dof_list.push_back (index+i);
-
- // then see what
- // happens. if it
- // succeeds, fine
- if (check_master_dof_list (face_interpolation_matrix,
- master_dof_list)
- == true)
- ++dofs_added;
- else
- // well, it
- // didn't. simply
- // pop that dof
- // from the list
- // again and try
- // with the next
- // dof
- master_dof_list.pop_back ();
-
- // forward counter by
- // one
- ++i;
- }
- index += fe1.dofs_per_vertex;
- }
-
- for (int l=0;
- l<static_cast<signed int>(GeometryInfo<dim>::lines_per_face);
- ++l)
- {
- // same algorithm as above
- unsigned int dofs_added = 0;
- unsigned int i = 0;
- while (dofs_added < fe2.dofs_per_line)
- {
- Assert (i < fe1.dofs_per_line,
- ExcInternalError());
-
- master_dof_list.push_back (index+i);
- if (check_master_dof_list (face_interpolation_matrix,
- master_dof_list)
- == true)
- ++dofs_added;
- else
- master_dof_list.pop_back ();
-
- ++i;
- }
- index += fe1.dofs_per_line;
- }
-
- for (int q=0;
- q<static_cast<signed int>(GeometryInfo<dim>::quads_per_face);
- ++q)
- {
- // same algorithm as above
- unsigned int dofs_added = 0;
- unsigned int i = 0;
- while (dofs_added < fe2.dofs_per_quad)
- {
- Assert (i < fe1.dofs_per_quad,
- ExcInternalError());
-
- master_dof_list.push_back (index+i);
- if (check_master_dof_list (face_interpolation_matrix,
- master_dof_list)
- == true)
- ++dofs_added;
- else
- master_dof_list.pop_back ();
-
- ++i;
- }
- index += fe1.dofs_per_quad;
- }
-
- AssertDimension (index, fe1.dofs_per_face);
- AssertDimension (master_dof_list.size(), fe2.dofs_per_face);
-
- // finally copy the list into the
- // mask
- std::fill (master_dof_mask.begin(), master_dof_mask.end(), false);
- for (std::vector<unsigned int>::const_iterator i=master_dof_list.begin();
- i!=master_dof_list.end(); ++i)
- master_dof_mask[*i] = true;
+ Assert (fe1.dofs_per_face >= fe2.dofs_per_face,
+ ExcInternalError());
+ AssertDimension (master_dof_mask.size(), fe1.dofs_per_face);
+
+ Assert (fe2.dofs_per_vertex <= fe1.dofs_per_vertex,
+ ExcInternalError());
+ Assert (fe2.dofs_per_line <= fe1.dofs_per_line,
+ ExcInternalError());
+ Assert ((dim < 3)
+ ||
+ (fe2.dofs_per_quad <= fe1.dofs_per_quad),
+ ExcInternalError());
+
+ // the idea here is to designate as
+ // many DoFs in fe1 per object
+ // (vertex, line, quad) as master as
+ // there are such dofs in fe2
+ // (indices are int, because we want
+ // to avoid the 'unsigned int < 0 is
+ // always false warning for the cases
+ // at the bottom in 1d and 2d)
+ //
+ // as mentioned in the paper, it is
+ // not always easy to find a set of
+ // master dofs that produces an
+ // invertible matrix. to this end, we
+ // check in each step whether the
+ // matrix is still invertible and
+ // simply discard this dof if the
+ // matrix is not invertible anymore.
+ //
+ // the cases where we did have
+ // trouble in the past were with
+ // adding more quad dofs when Q3 and
+ // Q4 elements meet at a refined face
+ // in 3d (see the hp/crash_12 test
+ // that tests that we can do exactly
+ // this, and failed before we had
+ // code to compensate for this
+ // case). the other case are system
+ // elements: if we have say a Q1Q2 vs
+ // a Q2Q3 element, then we can't just
+ // take all master dofs on a line
+ // from a single base element, since
+ // the shape functions of that base
+ // element are independent of that of
+ // the other one. this latter case
+ // shows up when running
+ // hp/hp_constraints_q_system_06
+ std::vector<unsigned int> master_dof_list;
+ unsigned int index = 0;
+ for (int v=0;
+ v<static_cast<signed int>(GeometryInfo<dim>::vertices_per_face);
+ ++v)
+ {
+ unsigned int dofs_added = 0;
+ unsigned int i = 0;
+ while (dofs_added < fe2.dofs_per_vertex)
+ {
+ // make sure that we
+ // were able to find
+ // a set of master
+ // dofs and that the
+ // code down below
+ // didn't just reject
+ // all our efforts
+ Assert (i < fe1.dofs_per_vertex,
+ ExcInternalError());
+ // tentatively push
+ // this vertex dof
+ master_dof_list.push_back (index+i);
+
+ // then see what
+ // happens. if it
+ // succeeds, fine
+ if (check_master_dof_list (face_interpolation_matrix,
+ master_dof_list)
+ == true)
+ ++dofs_added;
+ else
+ // well, it
+ // didn't. simply
+ // pop that dof
+ // from the list
+ // again and try
+ // with the next
+ // dof
+ master_dof_list.pop_back ();
+
+ // forward counter by
+ // one
+ ++i;
+ }
+ index += fe1.dofs_per_vertex;
+ }
+
+ for (int l=0;
+ l<static_cast<signed int>(GeometryInfo<dim>::lines_per_face);
+ ++l)
+ {
+ // same algorithm as above
+ unsigned int dofs_added = 0;
+ unsigned int i = 0;
+ while (dofs_added < fe2.dofs_per_line)
+ {
+ Assert (i < fe1.dofs_per_line,
+ ExcInternalError());
+
+ master_dof_list.push_back (index+i);
+ if (check_master_dof_list (face_interpolation_matrix,
+ master_dof_list)
+ == true)
+ ++dofs_added;
+ else
+ master_dof_list.pop_back ();
+
+ ++i;
+ }
+ index += fe1.dofs_per_line;
+ }
+
+ for (int q=0;
+ q<static_cast<signed int>(GeometryInfo<dim>::quads_per_face);
+ ++q)
+ {
+ // same algorithm as above
+ unsigned int dofs_added = 0;
+ unsigned int i = 0;
+ while (dofs_added < fe2.dofs_per_quad)
+ {
+ Assert (i < fe1.dofs_per_quad,
+ ExcInternalError());
+
+ master_dof_list.push_back (index+i);
+ if (check_master_dof_list (face_interpolation_matrix,
+ master_dof_list)
+ == true)
+ ++dofs_added;
+ else
+ master_dof_list.pop_back ();
+
+ ++i;
+ }
+ index += fe1.dofs_per_quad;
+ }
+
+ AssertDimension (index, fe1.dofs_per_face);
+ AssertDimension (master_dof_list.size(), fe2.dofs_per_face);
+
+ // finally copy the list into the
+ // mask
+ std::fill (master_dof_mask.begin(), master_dof_mask.end(), false);
+ for (std::vector<unsigned int>::const_iterator i=master_dof_list.begin();
+ i!=master_dof_list.end(); ++i)
+ master_dof_mask[*i] = true;
}
- /**
- * Make sure that the mask exists that
- * determines which dofs will be the
- * masters on refined faces where an
- * fe1 and a fe2 meet.
- */
+ /**
+ * Make sure that the mask exists that
+ * determines which dofs will be the
+ * masters on refined faces where an
+ * fe1 and a fe2 meet.
+ */
template <int dim, int spacedim>
void
ensure_existence_of_master_dof_mask (const FiniteElement<dim,spacedim> &fe1,
- const FiniteElement<dim,spacedim> &fe2,
- const FullMatrix<double> &face_interpolation_matrix,
- std_cxx1x::shared_ptr<std::vector<bool> > &master_dof_mask)
+ const FiniteElement<dim,spacedim> &fe2,
+ const FullMatrix<double> &face_interpolation_matrix,
+ std_cxx1x::shared_ptr<std::vector<bool> > &master_dof_mask)
{
- if (master_dof_mask == std_cxx1x::shared_ptr<std::vector<bool> >())
- {
- master_dof_mask = std_cxx1x::shared_ptr<std::vector<bool> >
- (new std::vector<bool> (fe1.dofs_per_face));
- select_master_dofs_for_face_restriction (fe1,
- fe2,
- face_interpolation_matrix,
- *master_dof_mask);
- }
+ if (master_dof_mask == std_cxx1x::shared_ptr<std::vector<bool> >())
+ {
+ master_dof_mask = std_cxx1x::shared_ptr<std::vector<bool> >
+ (new std::vector<bool> (fe1.dofs_per_face));
+ select_master_dofs_for_face_restriction (fe1,
+ fe2,
+ face_interpolation_matrix,
+ *master_dof_mask);
+ }
}
- /**
- * Make sure that the given @p
- * face_interpolation_matrix
- * pointer points to a valid
- * matrix. If the pointer is zero
- * beforehand, create an entry
- * with the correct data. If it
- * is nonzero, don't touch it.
- */
+ /**
+ * Make sure that the given @p
+ * face_interpolation_matrix
+ * pointer points to a valid
+ * matrix. If the pointer is zero
+ * beforehand, create an entry
+ * with the correct data. If it
+ * is nonzero, don't touch it.
+ */
template <int dim, int spacedim>
void
ensure_existence_of_face_matrix (const FiniteElement<dim,spacedim> &fe1,
- const FiniteElement<dim,spacedim> &fe2,
- std_cxx1x::shared_ptr<FullMatrix<double> > &matrix)
+ const FiniteElement<dim,spacedim> &fe2,
+ std_cxx1x::shared_ptr<FullMatrix<double> > &matrix)
{
- if (matrix == std_cxx1x::shared_ptr<FullMatrix<double> >())
- {
- matrix = std_cxx1x::shared_ptr<FullMatrix<double> >
- (new FullMatrix<double> (fe2.dofs_per_face,
- fe1.dofs_per_face));
- fe1.get_face_interpolation_matrix (fe2,
- *matrix);
- }
+ if (matrix == std_cxx1x::shared_ptr<FullMatrix<double> >())
+ {
+ matrix = std_cxx1x::shared_ptr<FullMatrix<double> >
+ (new FullMatrix<double> (fe2.dofs_per_face,
+ fe1.dofs_per_face));
+ fe1.get_face_interpolation_matrix (fe2,
+ *matrix);
+ }
}
- /**
- * Same, but for subface
- * interpolation matrices.
- */
+ /**
+ * Same, but for subface
+ * interpolation matrices.
+ */
template <int dim, int spacedim>
void
ensure_existence_of_subface_matrix (const FiniteElement<dim,spacedim> &fe1,
- const FiniteElement<dim,spacedim> &fe2,
- const unsigned int subface,
- std_cxx1x::shared_ptr<FullMatrix<double> > &matrix)
+ const FiniteElement<dim,spacedim> &fe2,
+ const unsigned int subface,
+ std_cxx1x::shared_ptr<FullMatrix<double> > &matrix)
{
- if (matrix == std_cxx1x::shared_ptr<FullMatrix<double> >())
- {
- matrix = std_cxx1x::shared_ptr<FullMatrix<double> >
- (new FullMatrix<double> (fe2.dofs_per_face,
- fe1.dofs_per_face));
- fe1.get_subface_interpolation_matrix (fe2,
- subface,
- *matrix);
- }
+ if (matrix == std_cxx1x::shared_ptr<FullMatrix<double> >())
+ {
+ matrix = std_cxx1x::shared_ptr<FullMatrix<double> >
+ (new FullMatrix<double> (fe2.dofs_per_face,
+ fe1.dofs_per_face));
+ fe1.get_subface_interpolation_matrix (fe2,
+ subface,
+ *matrix);
+ }
}
- /**
- * Given the face interpolation
- * matrix between two elements,
- * split it into its master and
- * slave parts and invert the
- * master part as explained in
- * the @ref hp_paper "hp paper".
- */
+ /**
+ * Given the face interpolation
+ * matrix between two elements,
+ * split it into its master and
+ * slave parts and invert the
+ * master part as explained in
+ * the @ref hp_paper "hp paper".
+ */
void
ensure_existence_of_split_face_matrix (const FullMatrix<double> &face_interpolation_matrix,
- const std::vector<bool> &master_dof_mask,
- std_cxx1x::shared_ptr<std::pair<FullMatrix<double>,FullMatrix<double> > > &split_matrix)
+ const std::vector<bool> &master_dof_mask,
+ std_cxx1x::shared_ptr<std::pair<FullMatrix<double>,FullMatrix<double> > > &split_matrix)
{
- AssertDimension (master_dof_mask.size(), face_interpolation_matrix.m());
- Assert (std::count (master_dof_mask.begin(), master_dof_mask.end(), true) ==
- static_cast<signed int>(face_interpolation_matrix.n()),
- ExcInternalError());
-
- if (split_matrix ==
- std_cxx1x::shared_ptr<std::pair<FullMatrix<double>,FullMatrix<double> > >())
- {
- split_matrix
- = std_cxx1x::shared_ptr<std::pair<FullMatrix<double>,FullMatrix<double> > >
- (new std::pair<FullMatrix<double>,FullMatrix<double> >());
-
- const unsigned int n_master_dofs = face_interpolation_matrix.n();
- const unsigned int n_dofs = face_interpolation_matrix.m();
-
- Assert (n_master_dofs <= n_dofs, ExcInternalError());
-
- // copy and invert the master
- // component, copy the slave
- // component
- split_matrix->first.reinit (n_master_dofs, n_master_dofs);
- split_matrix->second.reinit (n_dofs-n_master_dofs, n_master_dofs);
-
- unsigned int nth_master_dof = 0,
- nth_slave_dof = 0;
-
- for (unsigned int i=0; i<n_dofs; ++i)
- if (master_dof_mask[i] == true)
- {
- for (unsigned int j=0; j<n_master_dofs; ++j)
- split_matrix->first(nth_master_dof,j)
- = face_interpolation_matrix(i,j);
- ++nth_master_dof;
- }
- else
- {
- for (unsigned int j=0; j<n_master_dofs; ++j)
- split_matrix->second(nth_slave_dof,j)
- = face_interpolation_matrix(i,j);
- ++nth_slave_dof;
- }
-
- AssertDimension (nth_master_dof, n_master_dofs);
- AssertDimension (nth_slave_dof, n_dofs-n_master_dofs);
+ AssertDimension (master_dof_mask.size(), face_interpolation_matrix.m());
+ Assert (std::count (master_dof_mask.begin(), master_dof_mask.end(), true) ==
+ static_cast<signed int>(face_interpolation_matrix.n()),
+ ExcInternalError());
+
+ if (split_matrix ==
+ std_cxx1x::shared_ptr<std::pair<FullMatrix<double>,FullMatrix<double> > >())
+ {
+ split_matrix
+ = std_cxx1x::shared_ptr<std::pair<FullMatrix<double>,FullMatrix<double> > >
+ (new std::pair<FullMatrix<double>,FullMatrix<double> >());
+
+ const unsigned int n_master_dofs = face_interpolation_matrix.n();
+ const unsigned int n_dofs = face_interpolation_matrix.m();
+
+ Assert (n_master_dofs <= n_dofs, ExcInternalError());
+
+ // copy and invert the master
+ // component, copy the slave
+ // component
+ split_matrix->first.reinit (n_master_dofs, n_master_dofs);
+ split_matrix->second.reinit (n_dofs-n_master_dofs, n_master_dofs);
+
+ unsigned int nth_master_dof = 0,
+ nth_slave_dof = 0;
+
+ for (unsigned int i=0; i<n_dofs; ++i)
+ if (master_dof_mask[i] == true)
+ {
+ for (unsigned int j=0; j<n_master_dofs; ++j)
+ split_matrix->first(nth_master_dof,j)
+ = face_interpolation_matrix(i,j);
+ ++nth_master_dof;
+ }
+ else
+ {
+ for (unsigned int j=0; j<n_master_dofs; ++j)
+ split_matrix->second(nth_slave_dof,j)
+ = face_interpolation_matrix(i,j);
+ ++nth_slave_dof;
+ }
+
+ AssertDimension (nth_master_dof, n_master_dofs);
+ AssertDimension (nth_slave_dof, n_dofs-n_master_dofs);
//TODO[WB]: We should make sure very small entries are removed after inversion
- split_matrix->first.gauss_jordan ();
- }
+ split_matrix->first.gauss_jordan ();
+ }
}
- // a template that can
- // determine statically whether
- // a given DoFHandler class
- // supports different finite
- // element elements
+ // a template that can
+ // determine statically whether
+ // a given DoFHandler class
+ // supports different finite
+ // element elements
template <typename>
struct DoFHandlerSupportsDifferentFEs
{
- static const bool value = true;
+ static const bool value = true;
};
template <int dim, int spacedim>
struct DoFHandlerSupportsDifferentFEs< dealii::DoFHandler<dim,spacedim> >
{
- static const bool value = false;
+ static const bool value = false;
};
template <int dim, int spacedim>
struct DoFHandlerSupportsDifferentFEs< dealii::MGDoFHandler<dim,spacedim> >
{
- static const bool value = false;
+ static const bool value = false;
};
- /**
- * A function that returns how
- * many different finite
- * elements a dof handler
- * uses. This is one for non-hp
- * DoFHandlers and
- * dof_handler.get_fe().size()
- * for the hp-versions.
- */
+ /**
+ * A function that returns how
+ * many different finite
+ * elements a dof handler
+ * uses. This is one for non-hp
+ * DoFHandlers and
+ * dof_handler.get_fe().size()
+ * for the hp-versions.
+ */
template <int dim, int spacedim>
unsigned int
n_finite_elements (const dealii::hp::DoFHandler<dim,spacedim> &dof_handler)
{
- return dof_handler.get_fe().size();
+ return dof_handler.get_fe().size();
}
unsigned int
n_finite_elements (const DH &)
{
- return 1;
+ return 1;
}
- /**
- * For a given face belonging
- * to an active cell that
- * borders to a more refined
- * cell, return the fe_index of
- * the most dominating finite
- * element used on any of the
- * face's subfaces.
- */
+ /**
+ * For a given face belonging
+ * to an active cell that
+ * borders to a more refined
+ * cell, return the fe_index of
+ * the most dominating finite
+ * element used on any of the
+ * face's subfaces.
+ */
template <typename face_iterator>
unsigned int
get_most_dominating_subface_fe_index (const face_iterator &face)
{
- const unsigned int dim
- = face_iterator::AccessorType::dimension;
- const unsigned int spacedim
- = face_iterator::AccessorType::space_dimension;
-
- unsigned int dominating_subface_no = 0;
- for (; dominating_subface_no<face->n_children();
- ++dominating_subface_no)
- {
- // each of the subfaces
- // can have only a single
- // fe_index associated
- // with them, since there
- // is no cell on the
- // other side
- Assert (face->child(dominating_subface_no)
- ->n_active_fe_indices()
- == 1,
- ExcInternalError());
-
- const FiniteElement<dim,spacedim> &
- this_subface_fe = (face->child(dominating_subface_no)
- ->get_fe (face->child(dominating_subface_no)
- ->nth_active_fe_index(0)));
-
- FiniteElementDomination::Domination
- domination = FiniteElementDomination::either_element_can_dominate;
- for (unsigned int sf=0; sf<face->n_children(); ++sf)
- if (sf != dominating_subface_no)
- {
- const FiniteElement<dim,spacedim> &
- that_subface_fe = (face->child(sf)
- ->get_fe (face->child(sf)
- ->nth_active_fe_index(0)));
-
- domination = domination &
- this_subface_fe.compare_for_face_domination(that_subface_fe);
- }
-
- // see if the element
- // on this subface is
- // able to dominate
- // the ones on all
- // other subfaces,
- // and if so take it
- if ((domination == FiniteElementDomination::this_element_dominates)
- ||
- (domination == FiniteElementDomination::either_element_can_dominate))
- break;
- }
-
- // check that we have
- // found one such subface
- Assert (dominating_subface_no < face->n_children(),
- ExcNotImplemented());
-
- // return the finite element
- // index used on it. note
- // that only a single fe can
- // be active on such subfaces
- return face->child (dominating_subface_no)->nth_active_fe_index(0);
+ const unsigned int dim
+ = face_iterator::AccessorType::dimension;
+ const unsigned int spacedim
+ = face_iterator::AccessorType::space_dimension;
+
+ unsigned int dominating_subface_no = 0;
+ for (; dominating_subface_no<face->n_children();
+ ++dominating_subface_no)
+ {
+ // each of the subfaces
+ // can have only a single
+ // fe_index associated
+ // with them, since there
+ // is no cell on the
+ // other side
+ Assert (face->child(dominating_subface_no)
+ ->n_active_fe_indices()
+ == 1,
+ ExcInternalError());
+
+ const FiniteElement<dim,spacedim> &
+ this_subface_fe = (face->child(dominating_subface_no)
+ ->get_fe (face->child(dominating_subface_no)
+ ->nth_active_fe_index(0)));
+
+ FiniteElementDomination::Domination
+ domination = FiniteElementDomination::either_element_can_dominate;
+ for (unsigned int sf=0; sf<face->n_children(); ++sf)
+ if (sf != dominating_subface_no)
+ {
+ const FiniteElement<dim,spacedim> &
+ that_subface_fe = (face->child(sf)
+ ->get_fe (face->child(sf)
+ ->nth_active_fe_index(0)));
+
+ domination = domination &
+ this_subface_fe.compare_for_face_domination(that_subface_fe);
+ }
+
+ // see if the element
+ // on this subface is
+ // able to dominate
+ // the ones on all
+ // other subfaces,
+ // and if so take it
+ if ((domination == FiniteElementDomination::this_element_dominates)
+ ||
+ (domination == FiniteElementDomination::either_element_can_dominate))
+ break;
+ }
+
+ // check that we have
+ // found one such subface
+ Assert (dominating_subface_no < face->n_children(),
+ ExcNotImplemented());
+
+ // return the finite element
+ // index used on it. note
+ // that only a single fe can
+ // be active on such subfaces
+ return face->child (dominating_subface_no)->nth_active_fe_index(0);
}
- /**
- * Copy constraints into a constraint
- * matrix object.
- *
- * This function removes zero
- * constraints and those, which
- * constrain a DoF which was
- * already eliminated in one of
- * the previous steps of the hp
- * hanging node procedure.
- *
- * It also suppresses very small
- * entries in the constraint matrix to
- * avoid making the sparsity pattern
- * fuller than necessary.
- */
+ /**
+ * Copy constraints into a constraint
+ * matrix object.
+ *
+ * This function removes zero
+ * constraints and those, which
+ * constrain a DoF which was
+ * already eliminated in one of
+ * the previous steps of the hp
+ * hanging node procedure.
+ *
+ * It also suppresses very small
+ * entries in the constraint matrix to
+ * avoid making the sparsity pattern
+ * fuller than necessary.
+ */
void
filter_constraints (const std::vector<unsigned int> &master_dofs,
- const std::vector<unsigned int> &slave_dofs,
- const FullMatrix<double> &face_constraints,
- ConstraintMatrix &constraints)
+ const std::vector<unsigned int> &slave_dofs,
+ const FullMatrix<double> &face_constraints,
+ ConstraintMatrix &constraints)
{
- Assert (face_constraints.n () == master_dofs.size (),
- ExcDimensionMismatch(master_dofs.size (),
- face_constraints.n()));
- Assert (face_constraints.m () == slave_dofs.size (),
- ExcDimensionMismatch(slave_dofs.size (),
- face_constraints.m()));
-
- const unsigned int n_master_dofs = master_dofs.size ();
- const unsigned int n_slave_dofs = slave_dofs.size ();
-
- // check for a couple
- // conditions that happened
- // in parallel distributed
- // mode
- for (unsigned int row=0; row!=n_slave_dofs; ++row)
- Assert (slave_dofs[row] != numbers::invalid_unsigned_int,
- ExcInternalError());
- for (unsigned int col=0; col!=n_master_dofs; ++col)
- Assert (master_dofs[col] != numbers::invalid_unsigned_int,
- ExcInternalError());
-
-
- for (unsigned int row=0; row!=n_slave_dofs; ++row)
- if (constraints.is_constrained (slave_dofs[row]) == false)
- {
- bool constraint_already_satisfied = false;
-
- // Check if we have an identity
- // constraint, which is already
- // satisfied by unification of
- // the corresponding global dof
- // indices
- for (unsigned int i=0; i<n_master_dofs; ++i)
- if (face_constraints (row,i) == 1.0)
- if (master_dofs[i] == slave_dofs[row])
- {
- constraint_already_satisfied = true;
- break;
- }
-
- if (constraint_already_satisfied == false)
- {
- // add up the absolute
- // values of all
- // constraints in this line
- // to get a measure of
- // their absolute size
- double abs_sum = 0;
- for (unsigned int i=0; i<n_master_dofs; ++i)
- abs_sum += std::abs (face_constraints(row,i));
-
- // then enter those
- // constraints that are
- // larger than
- // 1e-14*abs_sum. everything
- // else probably originated
- // from inexact inversion
- // of matrices and similar
- // effects. having those
- // constraints in here will
- // only lead to problems
- // because it makes
- // sparsity patterns fuller
- // than necessary without
- // producing any
- // significant effect
- constraints.add_line (slave_dofs[row]);
- for (unsigned int i=0; i<n_master_dofs; ++i)
- if ((face_constraints(row,i) != 0)
- &&
- (std::fabs(face_constraints(row,i)) >= 1e-14*abs_sum))
- constraints.add_entry (slave_dofs[row],
- master_dofs[i],
- face_constraints (row,i));
- constraints.set_inhomogeneity (slave_dofs[row], 0.);
- }
- }
+ Assert (face_constraints.n () == master_dofs.size (),
+ ExcDimensionMismatch(master_dofs.size (),
+ face_constraints.n()));
+ Assert (face_constraints.m () == slave_dofs.size (),
+ ExcDimensionMismatch(slave_dofs.size (),
+ face_constraints.m()));
+
+ const unsigned int n_master_dofs = master_dofs.size ();
+ const unsigned int n_slave_dofs = slave_dofs.size ();
+
+ // check for a couple
+ // conditions that happened
+ // in parallel distributed
+ // mode
+ for (unsigned int row=0; row!=n_slave_dofs; ++row)
+ Assert (slave_dofs[row] != numbers::invalid_unsigned_int,
+ ExcInternalError());
+ for (unsigned int col=0; col!=n_master_dofs; ++col)
+ Assert (master_dofs[col] != numbers::invalid_unsigned_int,
+ ExcInternalError());
+
+
+ for (unsigned int row=0; row!=n_slave_dofs; ++row)
+ if (constraints.is_constrained (slave_dofs[row]) == false)
+ {
+ bool constraint_already_satisfied = false;
+
+ // Check if we have an identity
+ // constraint, which is already
+ // satisfied by unification of
+ // the corresponding global dof
+ // indices
+ for (unsigned int i=0; i<n_master_dofs; ++i)
+ if (face_constraints (row,i) == 1.0)
+ if (master_dofs[i] == slave_dofs[row])
+ {
+ constraint_already_satisfied = true;
+ break;
+ }
+
+ if (constraint_already_satisfied == false)
+ {
+ // add up the absolute
+ // values of all
+ // constraints in this line
+ // to get a measure of
+ // their absolute size
+ double abs_sum = 0;
+ for (unsigned int i=0; i<n_master_dofs; ++i)
+ abs_sum += std::abs (face_constraints(row,i));
+
+ // then enter those
+ // constraints that are
+ // larger than
+ // 1e-14*abs_sum. everything
+ // else probably originated
+ // from inexact inversion
+ // of matrices and similar
+ // effects. having those
+ // constraints in here will
+ // only lead to problems
+ // because it makes
+ // sparsity patterns fuller
+ // than necessary without
+ // producing any
+ // significant effect
+ constraints.add_line (slave_dofs[row]);
+ for (unsigned int i=0; i<n_master_dofs; ++i)
+ if ((face_constraints(row,i) != 0)
+ &&
+ (std::fabs(face_constraints(row,i)) >= 1e-14*abs_sum))
+ constraints.add_entry (slave_dofs[row],
+ master_dofs[i],
+ face_constraints (row,i));
+ constraints.set_inhomogeneity (slave_dofs[row], 0.);
+ }
+ }
}
}
void
make_hp_hanging_node_constraints (const dealii::DoFHandler<1> &,
- ConstraintMatrix &)
+ ConstraintMatrix &)
{
- // nothing to do for regular
- // dof handlers in 1d
+ // nothing to do for regular
+ // dof handlers in 1d
}
void
make_oldstyle_hanging_node_constraints (const dealii::DoFHandler<1> &,
- ConstraintMatrix &,
- dealii::internal::int2type<1>)
+ ConstraintMatrix &,
+ dealii::internal::int2type<1>)
{
- // nothing to do for regular
- // dof handlers in 1d
+ // nothing to do for regular
+ // dof handlers in 1d
}
void
make_hp_hanging_node_constraints (const dealii::MGDoFHandler<1> &,
- ConstraintMatrix &)
+ ConstraintMatrix &)
{
- // nothing to do for regular
- // dof handlers in 1d
+ // nothing to do for regular
+ // dof handlers in 1d
}
void
make_oldstyle_hanging_node_constraints (const dealii::MGDoFHandler<1> &,
- ConstraintMatrix &,
- dealii::internal::int2type<1>)
+ ConstraintMatrix &,
+ dealii::internal::int2type<1>)
{
- // nothing to do for regular
- // dof handlers in 1d
+ // nothing to do for regular
+ // dof handlers in 1d
}
void
make_hp_hanging_node_constraints (const dealii::hp::DoFHandler<1> &/*dof_handler*/,
- ConstraintMatrix &/*constraints*/)
+ ConstraintMatrix &/*constraints*/)
{
- // we may have to compute
- // constraints for
- // vertices. gotta think about
- // that a bit more
+ // we may have to compute
+ // constraints for
+ // vertices. gotta think about
+ // that a bit more
//TODO[WB]: think about what to do here...
}
void
make_oldstyle_hanging_node_constraints (const dealii::hp::DoFHandler<1> &/*dof_handler*/,
- ConstraintMatrix &/*constraints*/,
- dealii::internal::int2type<1>)
+ ConstraintMatrix &/*constraints*/,
+ dealii::internal::int2type<1>)
{
- // we may have to compute
- // constraints for
- // vertices. gotta think about
- // that a bit more
+ // we may have to compute
+ // constraints for
+ // vertices. gotta think about
+ // that a bit more
//TODO[WB]: think about what to do here...
}
void
make_hp_hanging_node_constraints (const dealii::DoFHandler<1,2> &,
- ConstraintMatrix &)
+ ConstraintMatrix &)
{
- // nothing to do for regular
- // dof handlers in 1d
+ // nothing to do for regular
+ // dof handlers in 1d
}
void
make_oldstyle_hanging_node_constraints (const dealii::DoFHandler<1,2> &,
- ConstraintMatrix &,
- dealii::internal::int2type<1>)
+ ConstraintMatrix &,
+ dealii::internal::int2type<1>)
{
- // nothing to do for regular
- // dof handlers in 1d
+ // nothing to do for regular
+ // dof handlers in 1d
}
void
make_hp_hanging_node_constraints (const dealii::DoFHandler<1,3> &,
- ConstraintMatrix &)
+ ConstraintMatrix &)
{
- // nothing to do for regular
- // dof handlers in 1d
+ // nothing to do for regular
+ // dof handlers in 1d
}
-
+
void
make_oldstyle_hanging_node_constraints (const dealii::DoFHandler<1,3> &,
- ConstraintMatrix &,
- dealii::internal::int2type<1>)
+ ConstraintMatrix &,
+ dealii::internal::int2type<1>)
{
- // nothing to do for regular
- // dof handlers in 1d
+ // nothing to do for regular
+ // dof handlers in 1d
}
-
+
// currently not used but may be in the future:
// void
// make_hp_hanging_node_constraints (const dealii::MGDoFHandler<1,2> &,
-// ConstraintMatrix &)
+// ConstraintMatrix &)
// {
-// // nothing to do for regular
-// // dof handlers in 1d
+// // nothing to do for regular
+// // dof handlers in 1d
// }
// void
// make_oldstyle_hanging_node_constraints (const dealii::MGDoFHandler<1,2> &,
-// ConstraintMatrix &,
-// dealii::internal::int2type<1>)
+// ConstraintMatrix &,
+// dealii::internal::int2type<1>)
// {
-// // nothing to do for regular
-// // dof handlers in 1d
+// // nothing to do for regular
+// // dof handlers in 1d
// }
// void
// make_oldstyle_hanging_node_constraints (const dealii::hp::DoFHandler<1,2> &/*dof_handler*/,
-// ConstraintMatrix &/*constraints*/,
-// dealii::internal::int2type<1>)
+// ConstraintMatrix &/*constraints*/,
+// dealii::internal::int2type<1>)
// {
-// // we may have to compute
-// // constraints for
-// // vertices. gotta think about
-// // that a bit more
+// // we may have to compute
+// // constraints for
+// // vertices. gotta think about
+// // that a bit more
// //TODO[WB]: think about what to do here...
// }
//#endif
template <class DH>
void
make_oldstyle_hanging_node_constraints (const DH &dof_handler,
- ConstraintMatrix &constraints,
- dealii::internal::int2type<2>)
+ ConstraintMatrix &constraints,
+ dealii::internal::int2type<2>)
{
const unsigned int dim = 2;
std::vector<unsigned int> dofs_on_mother;
std::vector<unsigned int> dofs_on_children;
- // loop over all lines; only on
- // lines there can be constraints.
- // We do so by looping over all
- // active cells and checking
- // whether any of the faces are
- // refined which can only be from
- // the neighboring cell because
- // this one is active. In that
- // case, the face is subject to
- // constraints
- //
- // note that even though we may
- // visit a face twice if the
- // neighboring cells are equally
- // refined, we can only visit each
- // face with hanging nodes once
+ // loop over all lines; only on
+ // lines there can be constraints.
+ // We do so by looping over all
+ // active cells and checking
+ // whether any of the faces are
+ // refined which can only be from
+ // the neighboring cell because
+ // this one is active. In that
+ // case, the face is subject to
+ // constraints
+ //
+ // note that even though we may
+ // visit a face twice if the
+ // neighboring cells are equally
+ // refined, we can only visit each
+ // face with hanging nodes once
typename DH::active_cell_iterator cell = dof_handler.begin_active(),
- endc = dof_handler.end();
+ endc = dof_handler.end();
for (; cell!=endc; ++cell)
- // artificial cells can at
- // best neighbor ghost cells,
- // but we're not interested
- // in these interfaces
- if (!cell->is_artificial ())
- for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
- if (cell->face(face)->has_children())
- {
- // in any case, faces
- // can have at most two
- // active fe indices,
- // but here the face
- // can have only one
- // (namely the same as
- // that from the cell
- // we're sitting on),
- // and each of the
- // children can have
- // only one as
- // well. check this
- Assert (cell->face(face)->n_active_fe_indices() == 1,
- ExcInternalError());
- Assert (cell->face(face)->fe_index_is_active(cell->active_fe_index())
- == true,
- ExcInternalError());
- for (unsigned int c=0; c<cell->face(face)->n_children(); ++c)
- if (!cell->neighbor_child_on_subface(face,c)->is_artificial())
- Assert (cell->face(face)->child(c)->n_active_fe_indices() == 1,
- ExcInternalError());
-
- // right now, all that
- // is implemented is
- // the case that both
- // sides use the same
- // fe
- for (unsigned int c=0; c<cell->face(face)->n_children(); ++c)
- if (!cell->neighbor_child_on_subface(face,c)->is_artificial())
- Assert (cell->face(face)->child(c)
- ->fe_index_is_active(cell->active_fe_index()) == true,
- ExcNotImplemented());
-
- // ok, start up the work
- const FiniteElement<dim,spacedim> &fe = cell->get_fe();
- const unsigned int fe_index = cell->active_fe_index();
-
- const unsigned int
- n_dofs_on_mother = 2*fe.dofs_per_vertex + fe.dofs_per_line,
- n_dofs_on_children = fe.dofs_per_vertex + 2*fe.dofs_per_line;
-
- dofs_on_mother.resize (n_dofs_on_mother);
- dofs_on_children.resize (n_dofs_on_children);
-
- Assert(n_dofs_on_mother == fe.constraints().n(),
- ExcDimensionMismatch(n_dofs_on_mother,
- fe.constraints().n()));
- Assert(n_dofs_on_children == fe.constraints().m(),
- ExcDimensionMismatch(n_dofs_on_children,
- fe.constraints().m()));
-
- const typename DH::line_iterator this_face = cell->face(face);
-
- // fill the dofs indices. Use same
- // enumeration scheme as in
- // @p{FiniteElement::constraints()}
- unsigned int next_index = 0;
- for (unsigned int vertex=0; vertex<2; ++vertex)
- for (unsigned int dof=0; dof!=fe.dofs_per_vertex; ++dof)
- dofs_on_mother[next_index++] = this_face->vertex_dof_index(vertex,dof,
- fe_index);
- for (unsigned int dof=0; dof!=fe.dofs_per_line; ++dof)
- dofs_on_mother[next_index++] = this_face->dof_index(dof, fe_index);
- AssertDimension (next_index, dofs_on_mother.size());
-
- next_index = 0;
- for (unsigned int dof=0; dof!=fe.dofs_per_vertex; ++dof)
- dofs_on_children[next_index++]
- = this_face->child(0)->vertex_dof_index(1,dof,fe_index);
- for (unsigned int child=0; child<2; ++child)
- for (unsigned int dof=0; dof!=fe.dofs_per_line; ++dof)
- dofs_on_children[next_index++]
- = this_face->child(child)->dof_index(dof, fe_index);
- AssertDimension (next_index, dofs_on_children.size());
-
- // for each row in the constraint
- // matrix for this line:
- for (unsigned int row=0; row!=dofs_on_children.size(); ++row)
- {
- constraints.add_line (dofs_on_children[row]);
- for (unsigned int i=0; i!=dofs_on_mother.size(); ++i)
- constraints.add_entry (dofs_on_children[row],
- dofs_on_mother[i],
- fe.constraints()(row,i));
-
- constraints.set_inhomogeneity (dofs_on_children[row], 0.);
- }
- }
- else
- {
- // this face has no
- // children, but it
- // could still be
- // that it is shared
- // by two cells that
- // use a different fe
- // index. check a
- // couple of things,
- // but ignore the
- // case that the
- // neighbor is an
- // artificial cell
- if (!cell->at_boundary(face) &&
- !cell->neighbor(face)->is_artificial())
- {
- Assert (cell->face(face)->n_active_fe_indices() == 1,
- ExcNotImplemented());
- Assert (cell->face(face)
- ->fe_index_is_active(cell->active_fe_index()) == true,
- ExcInternalError());
- }
- }
+ // artificial cells can at
+ // best neighbor ghost cells,
+ // but we're not interested
+ // in these interfaces
+ if (!cell->is_artificial ())
+ for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
+ if (cell->face(face)->has_children())
+ {
+ // in any case, faces
+ // can have at most two
+ // active fe indices,
+ // but here the face
+ // can have only one
+ // (namely the same as
+ // that from the cell
+ // we're sitting on),
+ // and each of the
+ // children can have
+ // only one as
+ // well. check this
+ Assert (cell->face(face)->n_active_fe_indices() == 1,
+ ExcInternalError());
+ Assert (cell->face(face)->fe_index_is_active(cell->active_fe_index())
+ == true,
+ ExcInternalError());
+ for (unsigned int c=0; c<cell->face(face)->n_children(); ++c)
+ if (!cell->neighbor_child_on_subface(face,c)->is_artificial())
+ Assert (cell->face(face)->child(c)->n_active_fe_indices() == 1,
+ ExcInternalError());
+
+ // right now, all that
+ // is implemented is
+ // the case that both
+ // sides use the same
+ // fe
+ for (unsigned int c=0; c<cell->face(face)->n_children(); ++c)
+ if (!cell->neighbor_child_on_subface(face,c)->is_artificial())
+ Assert (cell->face(face)->child(c)
+ ->fe_index_is_active(cell->active_fe_index()) == true,
+ ExcNotImplemented());
+
+ // ok, start up the work
+ const FiniteElement<dim,spacedim> &fe = cell->get_fe();
+ const unsigned int fe_index = cell->active_fe_index();
+
+ const unsigned int
+ n_dofs_on_mother = 2*fe.dofs_per_vertex + fe.dofs_per_line,
+ n_dofs_on_children = fe.dofs_per_vertex + 2*fe.dofs_per_line;
+
+ dofs_on_mother.resize (n_dofs_on_mother);
+ dofs_on_children.resize (n_dofs_on_children);
+
+ Assert(n_dofs_on_mother == fe.constraints().n(),
+ ExcDimensionMismatch(n_dofs_on_mother,
+ fe.constraints().n()));
+ Assert(n_dofs_on_children == fe.constraints().m(),
+ ExcDimensionMismatch(n_dofs_on_children,
+ fe.constraints().m()));
+
+ const typename DH::line_iterator this_face = cell->face(face);
+
+ // fill the dofs indices. Use same
+ // enumeration scheme as in
+ // @p{FiniteElement::constraints()}
+ unsigned int next_index = 0;
+ for (unsigned int vertex=0; vertex<2; ++vertex)
+ for (unsigned int dof=0; dof!=fe.dofs_per_vertex; ++dof)
+ dofs_on_mother[next_index++] = this_face->vertex_dof_index(vertex,dof,
+ fe_index);
+ for (unsigned int dof=0; dof!=fe.dofs_per_line; ++dof)
+ dofs_on_mother[next_index++] = this_face->dof_index(dof, fe_index);
+ AssertDimension (next_index, dofs_on_mother.size());
+
+ next_index = 0;
+ for (unsigned int dof=0; dof!=fe.dofs_per_vertex; ++dof)
+ dofs_on_children[next_index++]
+ = this_face->child(0)->vertex_dof_index(1,dof,fe_index);
+ for (unsigned int child=0; child<2; ++child)
+ for (unsigned int dof=0; dof!=fe.dofs_per_line; ++dof)
+ dofs_on_children[next_index++]
+ = this_face->child(child)->dof_index(dof, fe_index);
+ AssertDimension (next_index, dofs_on_children.size());
+
+ // for each row in the constraint
+ // matrix for this line:
+ for (unsigned int row=0; row!=dofs_on_children.size(); ++row)
+ {
+ constraints.add_line (dofs_on_children[row]);
+ for (unsigned int i=0; i!=dofs_on_mother.size(); ++i)
+ constraints.add_entry (dofs_on_children[row],
+ dofs_on_mother[i],
+ fe.constraints()(row,i));
+
+ constraints.set_inhomogeneity (dofs_on_children[row], 0.);
+ }
+ }
+ else
+ {
+ // this face has no
+ // children, but it
+ // could still be
+ // that it is shared
+ // by two cells that
+ // use a different fe
+ // index. check a
+ // couple of things,
+ // but ignore the
+ // case that the
+ // neighbor is an
+ // artificial cell
+ if (!cell->at_boundary(face) &&
+ !cell->neighbor(face)->is_artificial())
+ {
+ Assert (cell->face(face)->n_active_fe_indices() == 1,
+ ExcNotImplemented());
+ Assert (cell->face(face)
+ ->fe_index_is_active(cell->active_fe_index()) == true,
+ ExcInternalError());
+ }
+ }
}
template <class DH>
void
make_oldstyle_hanging_node_constraints (const DH &dof_handler,
- ConstraintMatrix &constraints,
- dealii::internal::int2type<3>)
+ ConstraintMatrix &constraints,
+ dealii::internal::int2type<3>)
{
const unsigned int dim = 3;
std::vector<unsigned int> dofs_on_mother;
std::vector<unsigned int> dofs_on_children;
- // loop over all quads; only on
- // quads there can be constraints.
- // We do so by looping over all
- // active cells and checking
- // whether any of the faces are
- // refined which can only be from
- // the neighboring cell because
- // this one is active. In that
- // case, the face is subject to
- // constraints
- //
- // note that even though we may
- // visit a face twice if the
- // neighboring cells are equally
- // refined, we can only visit each
- // face with hanging nodes once
+ // loop over all quads; only on
+ // quads there can be constraints.
+ // We do so by looping over all
+ // active cells and checking
+ // whether any of the faces are
+ // refined which can only be from
+ // the neighboring cell because
+ // this one is active. In that
+ // case, the face is subject to
+ // constraints
+ //
+ // note that even though we may
+ // visit a face twice if the
+ // neighboring cells are equally
+ // refined, we can only visit each
+ // face with hanging nodes once
typename DH::active_cell_iterator cell = dof_handler.begin_active(),
- endc = dof_handler.end();
+ endc = dof_handler.end();
for (; cell!=endc; ++cell)
- // artificial cells can at
- // best neighbor ghost cells,
- // but we're not interested
- // in these interfaces
- if (!cell->is_artificial ())
- for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
- if (cell->face(face)->has_children())
- {
- // first of all, make sure that
- // we treat a case which is
- // possible, i.e. either no dofs
- // on the face at all or no
- // anisotropic refinement
- if (cell->get_fe().dofs_per_face == 0)
- continue;
-
- Assert(cell->face(face)->refinement_case()==RefinementCase<dim-1>::isotropic_refinement,
- ExcNotImplemented());
-
- // in any case, faces
- // can have at most two
- // active fe indices,
- // but here the face
- // can have only one
- // (namely the same as
- // that from the cell
- // we're sitting on),
- // and each of the
- // children can have
- // only one as
- // well. check this
- AssertDimension (cell->face(face)->n_active_fe_indices(), 1);
- Assert (cell->face(face)->fe_index_is_active(cell->active_fe_index())
- == true,
- ExcInternalError());
- for (unsigned int c=0; c<cell->face(face)->n_children(); ++c)
- AssertDimension (cell->face(face)->child(c)->n_active_fe_indices(), 1);
-
- // right now, all that
- // is implemented is
- // the case that both
- // sides use the same
- // fe, and not only
- // that but also that
- // all lines bounding
- // this face and the
- // children have the
- // same fe
- for (unsigned int c=0; c<cell->face(face)->n_children(); ++c)
- if (!cell->neighbor_child_on_subface(face,c)->is_artificial())
- {
- Assert (cell->face(face)->child(c)
- ->fe_index_is_active(cell->active_fe_index()) == true,
- ExcNotImplemented());
- for (unsigned int e=0; e<4; ++e)
- {
- Assert (cell->face(face)->child(c)->line(e)
- ->n_active_fe_indices() == 1,
- ExcNotImplemented());
- Assert (cell->face(face)->child(c)->line(e)
- ->fe_index_is_active(cell->active_fe_index()) == true,
- ExcNotImplemented());
- }
- }
- for (unsigned int e=0; e<4; ++e)
- {
- Assert (cell->face(face)->line(e)
- ->n_active_fe_indices() == 1,
- ExcNotImplemented());
- Assert (cell->face(face)->line(e)
- ->fe_index_is_active(cell->active_fe_index()) == true,
- ExcNotImplemented());
- }
-
- // ok, start up the work
- const FiniteElement<dim> &fe = cell->get_fe();
- const unsigned int fe_index = cell->active_fe_index();
-
- const unsigned int n_dofs_on_mother = fe.dofs_per_face;
- const unsigned int n_dofs_on_children = (5*fe.dofs_per_vertex+
- 12*fe.dofs_per_line+
- 4*fe.dofs_per_quad);
+ // artificial cells can at
+ // best neighbor ghost cells,
+ // but we're not interested
+ // in these interfaces
+ if (!cell->is_artificial ())
+ for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
+ if (cell->face(face)->has_children())
+ {
+ // first of all, make sure that
+ // we treat a case which is
+ // possible, i.e. either no dofs
+ // on the face at all or no
+ // anisotropic refinement
+ if (cell->get_fe().dofs_per_face == 0)
+ continue;
+
+ Assert(cell->face(face)->refinement_case()==RefinementCase<dim-1>::isotropic_refinement,
+ ExcNotImplemented());
+
+ // in any case, faces
+ // can have at most two
+ // active fe indices,
+ // but here the face
+ // can have only one
+ // (namely the same as
+ // that from the cell
+ // we're sitting on),
+ // and each of the
+ // children can have
+ // only one as
+ // well. check this
+ AssertDimension (cell->face(face)->n_active_fe_indices(), 1);
+ Assert (cell->face(face)->fe_index_is_active(cell->active_fe_index())
+ == true,
+ ExcInternalError());
+ for (unsigned int c=0; c<cell->face(face)->n_children(); ++c)
+ AssertDimension (cell->face(face)->child(c)->n_active_fe_indices(), 1);
+
+ // right now, all that
+ // is implemented is
+ // the case that both
+ // sides use the same
+ // fe, and not only
+ // that but also that
+ // all lines bounding
+ // this face and the
+ // children have the
+ // same fe
+ for (unsigned int c=0; c<cell->face(face)->n_children(); ++c)
+ if (!cell->neighbor_child_on_subface(face,c)->is_artificial())
+ {
+ Assert (cell->face(face)->child(c)
+ ->fe_index_is_active(cell->active_fe_index()) == true,
+ ExcNotImplemented());
+ for (unsigned int e=0; e<4; ++e)
+ {
+ Assert (cell->face(face)->child(c)->line(e)
+ ->n_active_fe_indices() == 1,
+ ExcNotImplemented());
+ Assert (cell->face(face)->child(c)->line(e)
+ ->fe_index_is_active(cell->active_fe_index()) == true,
+ ExcNotImplemented());
+ }
+ }
+ for (unsigned int e=0; e<4; ++e)
+ {
+ Assert (cell->face(face)->line(e)
+ ->n_active_fe_indices() == 1,
+ ExcNotImplemented());
+ Assert (cell->face(face)->line(e)
+ ->fe_index_is_active(cell->active_fe_index()) == true,
+ ExcNotImplemented());
+ }
+
+ // ok, start up the work
+ const FiniteElement<dim> &fe = cell->get_fe();
+ const unsigned int fe_index = cell->active_fe_index();
+
+ const unsigned int n_dofs_on_mother = fe.dofs_per_face;
+ const unsigned int n_dofs_on_children = (5*fe.dofs_per_vertex+
+ 12*fe.dofs_per_line+
+ 4*fe.dofs_per_quad);
//TODO[TL]: think about this and the following in case of anisotropic refinement
- dofs_on_mother.resize (n_dofs_on_mother);
- dofs_on_children.resize (n_dofs_on_children);
-
- Assert(n_dofs_on_mother == fe.constraints().n(),
- ExcDimensionMismatch(n_dofs_on_mother,
- fe.constraints().n()));
- Assert(n_dofs_on_children == fe.constraints().m(),
- ExcDimensionMismatch(n_dofs_on_children,
- fe.constraints().m()));
-
- const typename DH::face_iterator this_face = cell->face(face);
-
- // fill the dofs indices. Use same
- // enumeration scheme as in
- // @p{FiniteElement::constraints()}
- unsigned int next_index = 0;
- for (unsigned int vertex=0; vertex<4; ++vertex)
- for (unsigned int dof=0; dof!=fe.dofs_per_vertex; ++dof)
- dofs_on_mother[next_index++] = this_face->vertex_dof_index(vertex,dof,
- fe_index);
- for (unsigned int line=0; line<4; ++line)
- for (unsigned int dof=0; dof!=fe.dofs_per_line; ++dof)
- dofs_on_mother[next_index++]
- = this_face->line(line)->dof_index(dof, fe_index);
- for (unsigned int dof=0; dof!=fe.dofs_per_quad; ++dof)
- dofs_on_mother[next_index++] = this_face->dof_index(dof, fe_index);
- AssertDimension (next_index, dofs_on_mother.size());
-
- next_index = 0;
-
- // assert some consistency
- // assumptions
- //TODO[TL]: think about this in case of anisotropic refinement
- Assert (dof_handler.get_tria().get_anisotropic_refinement_flag() ||
- ((this_face->child(0)->vertex_index(3) ==
- this_face->child(1)->vertex_index(2)) &&
- (this_face->child(0)->vertex_index(3) ==
- this_face->child(2)->vertex_index(1)) &&
- (this_face->child(0)->vertex_index(3) ==
- this_face->child(3)->vertex_index(0))),
- ExcInternalError());
- for (unsigned int dof=0; dof!=fe.dofs_per_vertex; ++dof)
- dofs_on_children[next_index++]
- = this_face->child(0)->vertex_dof_index(3,dof);
-
- // dof numbers on the centers of
- // the lines bounding this face
- for (unsigned int line=0; line<4; ++line)
- for (unsigned int dof=0; dof!=fe.dofs_per_vertex; ++dof)
- dofs_on_children[next_index++]
- = this_face->line(line)->child(0)->vertex_dof_index(1,dof, fe_index);
-
- // next the dofs on the lines interior
- // to the face; the order of these
- // lines is laid down in the
- // FiniteElement class documentation
- for (unsigned int dof=0; dof<fe.dofs_per_line; ++dof)
- dofs_on_children[next_index++]
- = this_face->child(0)->line(1)->dof_index(dof, fe_index);
- for (unsigned int dof=0; dof<fe.dofs_per_line; ++dof)
- dofs_on_children[next_index++]
- = this_face->child(2)->line(1)->dof_index(dof, fe_index);
- for (unsigned int dof=0; dof<fe.dofs_per_line; ++dof)
- dofs_on_children[next_index++]
- = this_face->child(0)->line(3)->dof_index(dof, fe_index);
- for (unsigned int dof=0; dof<fe.dofs_per_line; ++dof)
- dofs_on_children[next_index++]
- = this_face->child(1)->line(3)->dof_index(dof, fe_index);
-
- // dofs on the bordering lines
- for (unsigned int line=0; line<4; ++line)
- for (unsigned int child=0; child<2; ++child)
- for (unsigned int dof=0; dof!=fe.dofs_per_line; ++dof)
- dofs_on_children[next_index++]
- = this_face->line(line)->child(child)->dof_index(dof, fe_index);
-
- // finally, for the dofs interior
- // to the four child faces
- for (unsigned int child=0; child<4; ++child)
- for (unsigned int dof=0; dof!=fe.dofs_per_quad; ++dof)
- dofs_on_children[next_index++]
- = this_face->child(child)->dof_index(dof, fe_index);
- AssertDimension (next_index, dofs_on_children.size());
-
- // for each row in the constraint
- // matrix for this line:
- for (unsigned int row=0; row!=dofs_on_children.size(); ++row)
- {
- constraints.add_line (dofs_on_children[row]);
- for (unsigned int i=0; i!=dofs_on_mother.size(); ++i)
- constraints.add_entry (dofs_on_children[row],
- dofs_on_mother[i],
- fe.constraints()(row,i));
-
- constraints.set_inhomogeneity(dofs_on_children[row], 0.);
- }
- }
- else
- {
- // this face has no
- // children, but it
- // could still be
- // that it is shared
- // by two cells that
- // use a different fe
- // index. check a
- // couple of things,
- // but ignore the
- // case that the
- // neighbor is an
- // artificial cell
- if (!cell->at_boundary(face) &&
- !cell->neighbor(face)->is_artificial())
- {
- Assert (cell->face(face)->n_active_fe_indices() == 1,
- ExcNotImplemented());
- Assert (cell->face(face)
- ->fe_index_is_active(cell->active_fe_index()) == true,
- ExcInternalError());
- }
- }
+ dofs_on_mother.resize (n_dofs_on_mother);
+ dofs_on_children.resize (n_dofs_on_children);
+
+ Assert(n_dofs_on_mother == fe.constraints().n(),
+ ExcDimensionMismatch(n_dofs_on_mother,
+ fe.constraints().n()));
+ Assert(n_dofs_on_children == fe.constraints().m(),
+ ExcDimensionMismatch(n_dofs_on_children,
+ fe.constraints().m()));
+
+ const typename DH::face_iterator this_face = cell->face(face);
+
+ // fill the dofs indices. Use same
+ // enumeration scheme as in
+ // @p{FiniteElement::constraints()}
+ unsigned int next_index = 0;
+ for (unsigned int vertex=0; vertex<4; ++vertex)
+ for (unsigned int dof=0; dof!=fe.dofs_per_vertex; ++dof)
+ dofs_on_mother[next_index++] = this_face->vertex_dof_index(vertex,dof,
+ fe_index);
+ for (unsigned int line=0; line<4; ++line)
+ for (unsigned int dof=0; dof!=fe.dofs_per_line; ++dof)
+ dofs_on_mother[next_index++]
+ = this_face->line(line)->dof_index(dof, fe_index);
+ for (unsigned int dof=0; dof!=fe.dofs_per_quad; ++dof)
+ dofs_on_mother[next_index++] = this_face->dof_index(dof, fe_index);
+ AssertDimension (next_index, dofs_on_mother.size());
+
+ next_index = 0;
+
+ // assert some consistency
+ // assumptions
+ //TODO[TL]: think about this in case of anisotropic refinement
+ Assert (dof_handler.get_tria().get_anisotropic_refinement_flag() ||
+ ((this_face->child(0)->vertex_index(3) ==
+ this_face->child(1)->vertex_index(2)) &&
+ (this_face->child(0)->vertex_index(3) ==
+ this_face->child(2)->vertex_index(1)) &&
+ (this_face->child(0)->vertex_index(3) ==
+ this_face->child(3)->vertex_index(0))),
+ ExcInternalError());
+ for (unsigned int dof=0; dof!=fe.dofs_per_vertex; ++dof)
+ dofs_on_children[next_index++]
+ = this_face->child(0)->vertex_dof_index(3,dof);
+
+ // dof numbers on the centers of
+ // the lines bounding this face
+ for (unsigned int line=0; line<4; ++line)
+ for (unsigned int dof=0; dof!=fe.dofs_per_vertex; ++dof)
+ dofs_on_children[next_index++]
+ = this_face->line(line)->child(0)->vertex_dof_index(1,dof, fe_index);
+
+ // next the dofs on the lines interior
+ // to the face; the order of these
+ // lines is laid down in the
+ // FiniteElement class documentation
+ for (unsigned int dof=0; dof<fe.dofs_per_line; ++dof)
+ dofs_on_children[next_index++]
+ = this_face->child(0)->line(1)->dof_index(dof, fe_index);
+ for (unsigned int dof=0; dof<fe.dofs_per_line; ++dof)
+ dofs_on_children[next_index++]
+ = this_face->child(2)->line(1)->dof_index(dof, fe_index);
+ for (unsigned int dof=0; dof<fe.dofs_per_line; ++dof)
+ dofs_on_children[next_index++]
+ = this_face->child(0)->line(3)->dof_index(dof, fe_index);
+ for (unsigned int dof=0; dof<fe.dofs_per_line; ++dof)
+ dofs_on_children[next_index++]
+ = this_face->child(1)->line(3)->dof_index(dof, fe_index);
+
+ // dofs on the bordering lines
+ for (unsigned int line=0; line<4; ++line)
+ for (unsigned int child=0; child<2; ++child)
+ for (unsigned int dof=0; dof!=fe.dofs_per_line; ++dof)
+ dofs_on_children[next_index++]
+ = this_face->line(line)->child(child)->dof_index(dof, fe_index);
+
+ // finally, for the dofs interior
+ // to the four child faces
+ for (unsigned int child=0; child<4; ++child)
+ for (unsigned int dof=0; dof!=fe.dofs_per_quad; ++dof)
+ dofs_on_children[next_index++]
+ = this_face->child(child)->dof_index(dof, fe_index);
+ AssertDimension (next_index, dofs_on_children.size());
+
+ // for each row in the constraint
+ // matrix for this line:
+ for (unsigned int row=0; row!=dofs_on_children.size(); ++row)
+ {
+ constraints.add_line (dofs_on_children[row]);
+ for (unsigned int i=0; i!=dofs_on_mother.size(); ++i)
+ constraints.add_entry (dofs_on_children[row],
+ dofs_on_mother[i],
+ fe.constraints()(row,i));
+
+ constraints.set_inhomogeneity(dofs_on_children[row], 0.);
+ }
+ }
+ else
+ {
+ // this face has no
+ // children, but it
+ // could still be
+ // that it is shared
+ // by two cells that
+ // use a different fe
+ // index. check a
+ // couple of things,
+ // but ignore the
+ // case that the
+ // neighbor is an
+ // artificial cell
+ if (!cell->at_boundary(face) &&
+ !cell->neighbor(face)->is_artificial())
+ {
+ Assert (cell->face(face)->n_active_fe_indices() == 1,
+ ExcNotImplemented());
+ Assert (cell->face(face)
+ ->fe_index_is_active(cell->active_fe_index()) == true,
+ ExcInternalError());
+ }
+ }
}
template <class DH>
void
make_hp_hanging_node_constraints (const DH &dof_handler,
- ConstraintMatrix &constraints)
+ ConstraintMatrix &constraints)
{
- // note: this function is going
- // to be hard to understand if
- // you haven't read the hp
- // paper. however, we try to
- // follow the notation laid out
- // there, so go read the paper
- // before you try to understand
- // what is going on here
+ // note: this function is going
+ // to be hard to understand if
+ // you haven't read the hp
+ // paper. however, we try to
+ // follow the notation laid out
+ // there, so go read the paper
+ // before you try to understand
+ // what is going on here
const unsigned int dim = DH::dimension;
const unsigned int spacedim = DH::space_dimension;
- // a matrix to be used for
- // constraints below. declared
- // here and simply resized down
- // below to avoid permanent
- // re-allocation of memory
+ // a matrix to be used for
+ // constraints below. declared
+ // here and simply resized down
+ // below to avoid permanent
+ // re-allocation of memory
FullMatrix<double> constraint_matrix;
- // similarly have arrays that
- // will hold master and slave
- // dof numbers, as well as a
- // scratch array needed for the
- // complicated case below
+ // similarly have arrays that
+ // will hold master and slave
+ // dof numbers, as well as a
+ // scratch array needed for the
+ // complicated case below
std::vector<unsigned int> master_dofs;
std::vector<unsigned int> slave_dofs;
std::vector<unsigned int> scratch_dofs;
- // caches for the face and
- // subface interpolation
- // matrices between different
- // (or the same) finite
- // elements. we compute them
- // only once, namely the first
- // time they are needed, and
- // then just reuse them
+ // caches for the face and
+ // subface interpolation
+ // matrices between different
+ // (or the same) finite
+ // elements. we compute them
+ // only once, namely the first
+ // time they are needed, and
+ // then just reuse them
Table<2,std_cxx1x::shared_ptr<FullMatrix<double> > >
- face_interpolation_matrices (n_finite_elements (dof_handler),
- n_finite_elements (dof_handler));
+ face_interpolation_matrices (n_finite_elements (dof_handler),
+ n_finite_elements (dof_handler));
Table<3,std_cxx1x::shared_ptr<FullMatrix<double> > >
- subface_interpolation_matrices (n_finite_elements (dof_handler),
- n_finite_elements (dof_handler),
- GeometryInfo<dim>::max_children_per_face);
-
- // similarly have a cache for
- // the matrices that are split
- // into their master and slave
- // parts, and for which the
- // master part is
- // inverted. these two matrices
- // are derived from the face
- // interpolation matrix as
- // described in the @ref hp_paper "hp paper"
+ subface_interpolation_matrices (n_finite_elements (dof_handler),
+ n_finite_elements (dof_handler),
+ GeometryInfo<dim>::max_children_per_face);
+
+ // similarly have a cache for
+ // the matrices that are split
+ // into their master and slave
+ // parts, and for which the
+ // master part is
+ // inverted. these two matrices
+ // are derived from the face
+ // interpolation matrix as
+ // described in the @ref hp_paper "hp paper"
Table<2,std_cxx1x::shared_ptr<std::pair<FullMatrix<double>,FullMatrix<double> > > >
- split_face_interpolation_matrices (n_finite_elements (dof_handler),
- n_finite_elements (dof_handler));
-
- // finally, for each pair of finite
- // elements, have a mask that states
- // which of the degrees of freedom on
- // the coarse side of a refined face
- // will act as master dofs.
+ split_face_interpolation_matrices (n_finite_elements (dof_handler),
+ n_finite_elements (dof_handler));
+
+ // finally, for each pair of finite
+ // elements, have a mask that states
+ // which of the degrees of freedom on
+ // the coarse side of a refined face
+ // will act as master dofs.
Table<2,std_cxx1x::shared_ptr<std::vector<bool> > >
- master_dof_masks (n_finite_elements (dof_handler),
- n_finite_elements (dof_handler));
-
- // loop over all faces
- //
- // note that even though we may
- // visit a face twice if the
- // neighboring cells are equally
- // refined, we can only visit each
- // face with hanging nodes once
+ master_dof_masks (n_finite_elements (dof_handler),
+ n_finite_elements (dof_handler));
+
+ // loop over all faces
+ //
+ // note that even though we may
+ // visit a face twice if the
+ // neighboring cells are equally
+ // refined, we can only visit each
+ // face with hanging nodes once
typename DH::active_cell_iterator cell = dof_handler.begin_active(),
- endc = dof_handler.end();
+ endc = dof_handler.end();
for (; cell!=endc; ++cell)
- // artificial cells can at
- // best neighbor ghost cells,
- // but we're not interested
- // in these interfaces
- if (!cell->is_artificial ())
- for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
- if (cell->face(face)->has_children())
- {
- // first of all, make sure that
- // we treat a case which is
- // possible, i.e. either no dofs
- // on the face at all or no
- // anisotropic refinement
- if (cell->get_fe().dofs_per_face == 0)
- continue;
-
- Assert(cell->face(face)->refinement_case()==RefinementCase<dim-1>::isotropic_refinement,
- ExcNotImplemented());
-
- // so now we've found a
- // face of an active
- // cell that has
- // children. that means
- // that there are
- // hanging nodes here.
-
- // in any case, faces
- // can have at most two
- // sets of active fe
- // indices, but here
- // the face can have
- // only one (namely the
- // same as that from
- // the cell we're
- // sitting on), and
- // each of the children
- // can have only one as
- // well. check this
- Assert (cell->face(face)->n_active_fe_indices() == 1,
- ExcInternalError());
- Assert (cell->face(face)->fe_index_is_active(cell->active_fe_index())
- == true,
- ExcInternalError());
- for (unsigned int c=0; c<cell->face(face)->n_children(); ++c)
- Assert (cell->face(face)->child(c)->n_active_fe_indices() == 1,
- ExcInternalError());
-
- // first find out
- // whether we can
- // constrain each of
- // the subfaces to the
- // mother face. in the
- // lingo of the hp
- // paper, this would be
- // the simple
- // case. note that we
- // can short-circuit
- // this decision if the
- // dof_handler doesn't
- // support hp at all
- //
- // ignore all
- // interfaces with
- // artificial cells
- FiniteElementDomination::Domination
- mother_face_dominates = FiniteElementDomination::either_element_can_dominate;
-
- if (DoFHandlerSupportsDifferentFEs<DH>::value == true)
- for (unsigned int c=0; c<cell->face(face)->number_of_children(); ++c)
- if (!cell->neighbor_child_on_subface (face, c)->is_artificial())
- mother_face_dominates = mother_face_dominates &
- (cell->get_fe().compare_for_face_domination
- (cell->neighbor_child_on_subface (face, c)->get_fe()));
-
- switch (mother_face_dominates)
- {
- case FiniteElementDomination::this_element_dominates:
- case FiniteElementDomination::either_element_can_dominate:
- {
- // Case 1 (the
- // simple case
- // and the only
- // case that can
- // happen for
- // non-hp
- // DoFHandlers):
- // The coarse
- // element
- // dominates the
- // elements on
- // the subfaces
- // (or they are
- // all the same)
- //
- // so we are
- // going to
- // constrain
- // the DoFs on
- // the face
- // children
- // against the
- // DoFs on the
- // face itself
- master_dofs.resize (cell->get_fe().dofs_per_face);
-
- cell->face(face)->get_dof_indices (master_dofs,
- cell->active_fe_index ());
-
- // Now create
- // constraint matrix
- // for the subfaces and
- // assemble it. ignore
- // all interfaces with
- // artificial cells
- // because we can only
- // get to such
- // interfaces if the
- // current cell is a
- // ghost cell. also
- // ignore the interface
- // if the neighboring
- // cell is a ghost cell
- // in 2d: what we would
- // compute here are the
- // constraints on the
- // ghost cell's DoFs,
- // but we are not
- // interested in those:
- // we only want
- // constraints on
- // *locally active*
- // DoFs, not on
- // *locally relevant*
- // DoFs. However, in 3d
- // we must still
- // compute those
- // constraints because
- // it might happen that
- // a constraint is
- // related to an edge
- // where the hanging
- // node is only
- // detected if we also
- // look between ghosts
- for (unsigned int c=0; c<cell->face(face)->n_children(); ++c)
- {
- if (cell->neighbor_child_on_subface (face, c)->is_artificial()
- ||
- (dim == 2 && cell->neighbor_child_on_subface (face, c)->is_ghost()))
- continue;
-
- const typename DH::active_face_iterator
- subface = cell->face(face)->child(c);
-
- Assert (subface->n_active_fe_indices() == 1,
- ExcInternalError());
-
- const unsigned int
- subface_fe_index = subface->nth_active_fe_index(0);
-
- // we sometime run
- // into the
- // situation where
- // for example on
- // one big cell we
- // have a FE_Q(1)
- // and on the
- // subfaces we have
- // a mixture of
- // FE_Q(1) and
- // FE_Nothing. In
- // that case, the
- // face domination
- // is
- // either_element_can_dominate
- // for the whole
- // collection of
- // subfaces, but on
- // the particular
- // subface between
- // FE_Q(1) and
- // FE_Nothing,
- // there are no
- // constraints that
- // we need to take
- // care of. in that
- // case, just
- // continue
- if (cell->get_fe().compare_for_face_domination
- (subface->get_fe(subface_fe_index))
- ==
- FiniteElementDomination::no_requirements)
- continue;
-
- // Same procedure as for the
- // mother cell. Extract the face
- // DoFs from the cell DoFs.
- slave_dofs.resize (subface->get_fe(subface_fe_index)
- .dofs_per_face);
- subface->get_dof_indices (slave_dofs, subface_fe_index);
-
- for (unsigned int i=0; i<slave_dofs.size(); ++i)
- Assert (slave_dofs[i] != numbers::invalid_unsigned_int,
- ExcInternalError());
-
- // Now create the
- // element constraint
- // for this subface.
- //
- // As a side remark,
- // one may wonder the
- // following:
- // neighbor_child is
- // clearly computed
- // correctly,
- // i.e. taking into
- // account
- // face_orientation
- // (just look at the
- // implementation of
- // that
- // function). however,
- // we don't care about
- // this here, when we
- // ask for
- // subface_interpolation
- // on subface c. the
- // question rather is:
- // do we have to
- // translate 'c' here
- // as well?
- //
- // the answer is in
- // fact 'no'. if one
- // does that, results
- // are wrong:
- // constraints are
- // added twice for the
- // same pair of nodes
- // but with differing
- // weights. in
- // addition, one can
- // look at the
- // deal.II/project_*_03
- // tests that look at
- // exactly this case:
- // there, we have a
- // mesh with at least
- // one
- // face_orientation==false
- // and hanging nodes,
- // and the results of
- // those tests show
- // that the result of
- // projection verifies
- // the approximation
- // properties of a
- // finite element onto
- // that mesh
- ensure_existence_of_subface_matrix
- (cell->get_fe(),
- subface->get_fe(subface_fe_index),
- c,
- subface_interpolation_matrices
- [cell->active_fe_index()][subface_fe_index][c]);
-
- // Add constraints to global constraint
- // matrix.
- filter_constraints (master_dofs,
- slave_dofs,
- *(subface_interpolation_matrices
- [cell->active_fe_index()][subface_fe_index][c]),
- constraints);
- }
-
- break;
- }
-
- case FiniteElementDomination::other_element_dominates:
- case FiniteElementDomination::neither_element_dominates:
- {
- // Case 2 (the "complex"
- // case): at least one
- // (the neither_... case)
- // of the finer elements
- // or all of them (the
- // other_... case) is
- // dominating. See the hp
- // paper for a way how to
- // deal with this
- // situation
- //
- // since this is
- // something that
- // can only
- // happen for hp
- // dof handlers,
- // add a check
- // here...
- Assert (DoFHandlerSupportsDifferentFEs<DH>::value == true,
- ExcInternalError());
-
- // we first have
- // to find the
- // finite element
- // that is able
- // to generate a
- // space that all
- // the other ones
- // can be
- // constrained to
- const unsigned int dominating_fe_index
- = get_most_dominating_subface_fe_index (cell->face(face));
-
- const FiniteElement<dim,spacedim> &dominating_fe
- = dof_handler.get_fe()[dominating_fe_index];
-
- // check also
- // that it is
- // able to
- // constrain the
- // mother
- // face. it
- // should be, or
- // we wouldn't
- // have gotten
- // into the
- // branch for the
- // 'complex' case
- Assert ((dominating_fe.compare_for_face_domination
- (cell->face(face)->get_fe(cell->face(face)->nth_active_fe_index(0)))
- == FiniteElementDomination::this_element_dominates)
- ||
- (dominating_fe.compare_for_face_domination
- (cell->face(face)->get_fe(cell->face(face)->nth_active_fe_index(0)))
- == FiniteElementDomination::either_element_can_dominate),
- ExcInternalError());
-
-
- // first get the
- // interpolation matrix
- // from the mother to the
- // virtual dofs
- Assert (dominating_fe.dofs_per_face <=
- cell->get_fe().dofs_per_face,
- ExcInternalError());
-
- ensure_existence_of_face_matrix
- (dominating_fe,
- cell->get_fe(),
- face_interpolation_matrices
- [dominating_fe_index][cell->active_fe_index()]);
-
- // split this matrix into
- // master and slave
- // components. invert the
- // master component
- ensure_existence_of_master_dof_mask
- (cell->get_fe(),
- dominating_fe,
- (*face_interpolation_matrices
- [dominating_fe_index]
- [cell->active_fe_index()]),
- master_dof_masks
- [dominating_fe_index]
- [cell->active_fe_index()]);
-
- ensure_existence_of_split_face_matrix
- (*face_interpolation_matrices
- [dominating_fe_index][cell->active_fe_index()],
- (*master_dof_masks
- [dominating_fe_index][cell->active_fe_index()]),
- split_face_interpolation_matrices
- [dominating_fe_index][cell->active_fe_index()]);
-
- const FullMatrix<double> &restrict_mother_to_virtual_master_inv
- = (split_face_interpolation_matrices
- [dominating_fe_index][cell->active_fe_index()]->first);
-
- const FullMatrix<double> &restrict_mother_to_virtual_slave
- = (split_face_interpolation_matrices
- [dominating_fe_index][cell->active_fe_index()]->second);
-
- // now compute
- // the constraint
- // matrix as the
- // product
- // between the
- // inverse matrix
- // and the slave
- // part
- constraint_matrix.reinit (cell->get_fe().dofs_per_face -
- dominating_fe.dofs_per_face,
- dominating_fe.dofs_per_face);
- restrict_mother_to_virtual_slave
- .mmult (constraint_matrix,
- restrict_mother_to_virtual_master_inv);
-
- // then figure
- // out the global
- // numbers of
- // master and
- // slave dofs and
- // apply
- // constraints
- scratch_dofs.resize (cell->get_fe().dofs_per_face);
- cell->face(face)->get_dof_indices (scratch_dofs,
- cell->active_fe_index ());
-
- // split dofs into master
- // and slave components
- master_dofs.clear ();
- slave_dofs.clear ();
- for (unsigned int i=0; i<cell->get_fe().dofs_per_face; ++i)
- if ((*master_dof_masks
- [dominating_fe_index][cell->active_fe_index()])[i] == true)
- master_dofs.push_back (scratch_dofs[i]);
- else
- slave_dofs.push_back (scratch_dofs[i]);
-
- AssertDimension (master_dofs.size(), dominating_fe.dofs_per_face);
- AssertDimension (slave_dofs.size(),
- cell->get_fe().dofs_per_face - dominating_fe.dofs_per_face);
-
- filter_constraints (master_dofs,
- slave_dofs,
- constraint_matrix,
- constraints);
-
-
-
- // next we have
- // to deal with
- // the
- // subfaces. do
- // as discussed
- // in the hp
- // paper
- for (unsigned int sf=0;
- sf<cell->face(face)->n_children(); ++sf)
- {
- // ignore
- // interfaces
- // with
- // artificial
- // cells as
- // well as
- // interfaces
- // between
- // ghost
- // cells in 2d
- if (cell->neighbor_child_on_subface (face, sf)->is_artificial()
- ||
- (dim==2 && cell->is_ghost()
- &&
- cell->neighbor_child_on_subface (face, sf)->is_ghost()))
- continue;
-
- Assert (cell->face(face)->child(sf)
- ->n_active_fe_indices() == 1,
- ExcInternalError());
-
- const unsigned int subface_fe_index
- = cell->face(face)->child(sf)->nth_active_fe_index(0);
- const FiniteElement<dim,spacedim> &subface_fe
- = dof_handler.get_fe()[subface_fe_index];
-
- // first get the
- // interpolation
- // matrix from the
- // subface to the
- // virtual dofs
- Assert (dominating_fe.dofs_per_face <=
- subface_fe.dofs_per_face,
- ExcInternalError());
- ensure_existence_of_subface_matrix
- (dominating_fe,
- subface_fe,
- sf,
- subface_interpolation_matrices
- [dominating_fe_index][subface_fe_index][sf]);
-
- const FullMatrix<double> &restrict_subface_to_virtual
- = *(subface_interpolation_matrices
- [dominating_fe_index][subface_fe_index][sf]);
-
- constraint_matrix.reinit (subface_fe.dofs_per_face,
- dominating_fe.dofs_per_face);
-
- restrict_subface_to_virtual
- .mmult (constraint_matrix,
- restrict_mother_to_virtual_master_inv);
-
- slave_dofs.resize (subface_fe.dofs_per_face);
- cell->face(face)->child(sf)->get_dof_indices (slave_dofs,
- subface_fe_index);
-
- filter_constraints (master_dofs,
- slave_dofs,
- constraint_matrix,
- constraints);
- }
-
- break;
- }
-
- case FiniteElementDomination::no_requirements:
- // there
- // are no
- // continuity
- // requirements
- // between
- // the two
- // elements. record
- // no
- // constraints
- break;
-
- default:
- // we shouldn't get here
- Assert (false, ExcInternalError());
- }
- }
- else
- {
- // this face has no
- // children, but it
- // could still be that
- // it is shared by two
- // cells that use a
- // different fe index
- Assert (cell->face(face)
- ->fe_index_is_active(cell->active_fe_index()) == true,
- ExcInternalError());
-
- // see if there is a
- // neighbor that is
- // an artificial
- // cell. in that
- // case, we're not
- // interested in this
- // interface. we test
- // this case first
- // since artificial
- // cells may not have
- // an active_fe_index
- // set, etc
- if (!cell->at_boundary(face)
- &&
- cell->neighbor(face)->is_artificial())
- continue;
-
- // Only if there is
- // a neighbor with
- // a different
- // active_fe_index
- // and the same h-level,
- // some action has
- // to be taken.
- if ((DoFHandlerSupportsDifferentFEs<DH>::value == true)
- &&
- !cell->face(face)->at_boundary ()
- &&
- (cell->neighbor(face)->active_fe_index () !=
- cell->active_fe_index ())
- &&
- (!cell->face(face)->has_children() &&
- !cell->neighbor_is_coarser(face) ))
- {
- const typename DH::cell_iterator neighbor = cell->neighbor (face);
-
- // see which side of the
- // face we have to
- // constrain
- switch (cell->get_fe().compare_for_face_domination (neighbor->get_fe ()))
- {
- case FiniteElementDomination::this_element_dominates:
- {
- // Get DoFs on
- // dominating and
- // dominated side of
- // the face
- master_dofs.resize (cell->get_fe().dofs_per_face);
- cell->face(face)->get_dof_indices (master_dofs,
- cell->active_fe_index ());
-
- slave_dofs.resize (neighbor->get_fe().dofs_per_face);
- cell->face(face)->get_dof_indices (slave_dofs,
- neighbor->active_fe_index ());
-
- // break if the n_master_dofs == 0,
- // because we are attempting to
- // constrain to an element that has
- // has no face dofs
- if(master_dofs.size() == 0) break;
-
- // make sure
- // the element
- // constraints
- // for this
- // face are
- // available
- ensure_existence_of_face_matrix
- (cell->get_fe(),
- neighbor->get_fe(),
- face_interpolation_matrices
- [cell->active_fe_index()][neighbor->active_fe_index()]);
-
- // Add constraints to global constraint
- // matrix.
- filter_constraints (master_dofs,
- slave_dofs,
- *(face_interpolation_matrices
- [cell->active_fe_index()]
- [neighbor->active_fe_index()]),
- constraints);
-
- break;
- }
-
- case FiniteElementDomination::other_element_dominates:
- {
- // we don't do anything
- // here since we will
- // come back to this
- // face from the other
- // cell, at which time
- // we will fall into
- // the first case
- // clause above
- break;
- }
-
- case FiniteElementDomination::either_element_can_dominate:
- {
- // it appears as if
- // neither element has
- // any constraints on
- // its neighbor. this
- // may be because
- // neither element has
- // any DoFs on faces at
- // all. or that the two
- // elements are
- // actually the same,
- // although they happen
- // to run under
- // different fe_indices
- // (this is what
- // happens in
- // hp/hp_hanging_nodes_01
- // for example).
- //
- // another possibility
- // is what happens in
- // crash_13. there, we
- // have
- // FESystem(FE_Q(1),FE_DGQ(0))
- // vs. FESystem(FE_Q(1),FE_DGQ(1)).
- // neither of them
- // dominates the
- // other. the point is
- // that it doesn't
- // matter, since
- // hopefully for this
- // case, both sides'
- // dofs should have
- // been unified.
- //
- // make sure this is
- // actually true. this
- // actually only
- // matters, of course,
- // if either of the two
- // finite elements
- // actually do have
- // dofs on the face
- if ((cell->get_fe().dofs_per_face != 0)
- ||
- (cell->neighbor(face)->get_fe().dofs_per_face != 0))
- {
- Assert (cell->get_fe().dofs_per_face
- ==
- cell->neighbor(face)->get_fe().dofs_per_face,
- ExcNotImplemented());
-
- // (ab)use the master
- // and slave dofs
- // arrays for a
- // moment here
- master_dofs.resize (cell->get_fe().dofs_per_face);
- cell->face(face)
- ->get_dof_indices (master_dofs,
- cell->active_fe_index ());
-
- slave_dofs.resize (cell->neighbor(face)->get_fe().dofs_per_face);
- cell->face(face)
- ->get_dof_indices (slave_dofs,
- cell->neighbor(face)->active_fe_index ());
-
- for (unsigned int i=0; i<cell->get_fe().dofs_per_face; ++i)
- AssertDimension (master_dofs[i], slave_dofs[i]);
- }
-
- break;
- }
-
- case FiniteElementDomination::neither_element_dominates:
- {
- // we don't presently
- // know what exactly to
- // do here. it isn't quite
- // clear what exactly we
- // would have to do
- // here. sit tight until
- // someone trips over the
- // following statement
- // and see what exactly
- // is going on
- Assert (false, ExcNotImplemented());
- break;
- }
-
- case FiniteElementDomination::no_requirements:
- {
- // nothing to do here
- break;
- }
-
- default:
- // we shouldn't get
- // here
- Assert (false, ExcInternalError());
- }
- }
- }
+ // artificial cells can at
+ // best neighbor ghost cells,
+ // but we're not interested
+ // in these interfaces
+ if (!cell->is_artificial ())
+ for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
+ if (cell->face(face)->has_children())
+ {
+ // first of all, make sure that
+ // we treat a case which is
+ // possible, i.e. either no dofs
+ // on the face at all or no
+ // anisotropic refinement
+ if (cell->get_fe().dofs_per_face == 0)
+ continue;
+
+ Assert(cell->face(face)->refinement_case()==RefinementCase<dim-1>::isotropic_refinement,
+ ExcNotImplemented());
+
+ // so now we've found a
+ // face of an active
+ // cell that has
+ // children. that means
+ // that there are
+ // hanging nodes here.
+
+ // in any case, faces
+ // can have at most two
+ // sets of active fe
+ // indices, but here
+ // the face can have
+ // only one (namely the
+ // same as that from
+ // the cell we're
+ // sitting on), and
+ // each of the children
+ // can have only one as
+ // well. check this
+ Assert (cell->face(face)->n_active_fe_indices() == 1,
+ ExcInternalError());
+ Assert (cell->face(face)->fe_index_is_active(cell->active_fe_index())
+ == true,
+ ExcInternalError());
+ for (unsigned int c=0; c<cell->face(face)->n_children(); ++c)
+ Assert (cell->face(face)->child(c)->n_active_fe_indices() == 1,
+ ExcInternalError());
+
+ // first find out
+ // whether we can
+ // constrain each of
+ // the subfaces to the
+ // mother face. in the
+ // lingo of the hp
+ // paper, this would be
+ // the simple
+ // case. note that we
+ // can short-circuit
+ // this decision if the
+ // dof_handler doesn't
+ // support hp at all
+ //
+ // ignore all
+ // interfaces with
+ // artificial cells
+ FiniteElementDomination::Domination
+ mother_face_dominates = FiniteElementDomination::either_element_can_dominate;
+
+ if (DoFHandlerSupportsDifferentFEs<DH>::value == true)
+ for (unsigned int c=0; c<cell->face(face)->number_of_children(); ++c)
+ if (!cell->neighbor_child_on_subface (face, c)->is_artificial())
+ mother_face_dominates = mother_face_dominates &
+ (cell->get_fe().compare_for_face_domination
+ (cell->neighbor_child_on_subface (face, c)->get_fe()));
+
+ switch (mother_face_dominates)
+ {
+ case FiniteElementDomination::this_element_dominates:
+ case FiniteElementDomination::either_element_can_dominate:
+ {
+ // Case 1 (the
+ // simple case
+ // and the only
+ // case that can
+ // happen for
+ // non-hp
+ // DoFHandlers):
+ // The coarse
+ // element
+ // dominates the
+ // elements on
+ // the subfaces
+ // (or they are
+ // all the same)
+ //
+ // so we are
+ // going to
+ // constrain
+ // the DoFs on
+ // the face
+ // children
+ // against the
+ // DoFs on the
+ // face itself
+ master_dofs.resize (cell->get_fe().dofs_per_face);
+
+ cell->face(face)->get_dof_indices (master_dofs,
+ cell->active_fe_index ());
+
+ // Now create
+ // constraint matrix
+ // for the subfaces and
+ // assemble it. ignore
+ // all interfaces with
+ // artificial cells
+ // because we can only
+ // get to such
+ // interfaces if the
+ // current cell is a
+ // ghost cell. also
+ // ignore the interface
+ // if the neighboring
+ // cell is a ghost cell
+ // in 2d: what we would
+ // compute here are the
+ // constraints on the
+ // ghost cell's DoFs,
+ // but we are not
+ // interested in those:
+ // we only want
+ // constraints on
+ // *locally active*
+ // DoFs, not on
+ // *locally relevant*
+ // DoFs. However, in 3d
+ // we must still
+ // compute those
+ // constraints because
+ // it might happen that
+ // a constraint is
+ // related to an edge
+ // where the hanging
+ // node is only
+ // detected if we also
+ // look between ghosts
+ for (unsigned int c=0; c<cell->face(face)->n_children(); ++c)
+ {
+ if (cell->neighbor_child_on_subface (face, c)->is_artificial()
+ ||
+ (dim == 2 && cell->neighbor_child_on_subface (face, c)->is_ghost()))
+ continue;
+
+ const typename DH::active_face_iterator
+ subface = cell->face(face)->child(c);
+
+ Assert (subface->n_active_fe_indices() == 1,
+ ExcInternalError());
+
+ const unsigned int
+ subface_fe_index = subface->nth_active_fe_index(0);
+
+ // we sometime run
+ // into the
+ // situation where
+ // for example on
+ // one big cell we
+ // have a FE_Q(1)
+ // and on the
+ // subfaces we have
+ // a mixture of
+ // FE_Q(1) and
+ // FE_Nothing. In
+ // that case, the
+ // face domination
+ // is
+ // either_element_can_dominate
+ // for the whole
+ // collection of
+ // subfaces, but on
+ // the particular
+ // subface between
+ // FE_Q(1) and
+ // FE_Nothing,
+ // there are no
+ // constraints that
+ // we need to take
+ // care of. in that
+ // case, just
+ // continue
+ if (cell->get_fe().compare_for_face_domination
+ (subface->get_fe(subface_fe_index))
+ ==
+ FiniteElementDomination::no_requirements)
+ continue;
+
+ // Same procedure as for the
+ // mother cell. Extract the face
+ // DoFs from the cell DoFs.
+ slave_dofs.resize (subface->get_fe(subface_fe_index)
+ .dofs_per_face);
+ subface->get_dof_indices (slave_dofs, subface_fe_index);
+
+ for (unsigned int i=0; i<slave_dofs.size(); ++i)
+ Assert (slave_dofs[i] != numbers::invalid_unsigned_int,
+ ExcInternalError());
+
+ // Now create the
+ // element constraint
+ // for this subface.
+ //
+ // As a side remark,
+ // one may wonder the
+ // following:
+ // neighbor_child is
+ // clearly computed
+ // correctly,
+ // i.e. taking into
+ // account
+ // face_orientation
+ // (just look at the
+ // implementation of
+ // that
+ // function). however,
+ // we don't care about
+ // this here, when we
+ // ask for
+ // subface_interpolation
+ // on subface c. the
+ // question rather is:
+ // do we have to
+ // translate 'c' here
+ // as well?
+ //
+ // the answer is in
+ // fact 'no'. if one
+ // does that, results
+ // are wrong:
+ // constraints are
+ // added twice for the
+ // same pair of nodes
+ // but with differing
+ // weights. in
+ // addition, one can
+ // look at the
+ // deal.II/project_*_03
+ // tests that look at
+ // exactly this case:
+ // there, we have a
+ // mesh with at least
+ // one
+ // face_orientation==false
+ // and hanging nodes,
+ // and the results of
+ // those tests show
+ // that the result of
+ // projection verifies
+ // the approximation
+ // properties of a
+ // finite element onto
+ // that mesh
+ ensure_existence_of_subface_matrix
+ (cell->get_fe(),
+ subface->get_fe(subface_fe_index),
+ c,
+ subface_interpolation_matrices
+ [cell->active_fe_index()][subface_fe_index][c]);
+
+ // Add constraints to global constraint
+ // matrix.
+ filter_constraints (master_dofs,
+ slave_dofs,
+ *(subface_interpolation_matrices
+ [cell->active_fe_index()][subface_fe_index][c]),
+ constraints);
+ }
+
+ break;
+ }
+
+ case FiniteElementDomination::other_element_dominates:
+ case FiniteElementDomination::neither_element_dominates:
+ {
+ // Case 2 (the "complex"
+ // case): at least one
+ // (the neither_... case)
+ // of the finer elements
+ // or all of them (the
+ // other_... case) is
+ // dominating. See the hp
+ // paper for a way how to
+ // deal with this
+ // situation
+ //
+ // since this is
+ // something that
+ // can only
+ // happen for hp
+ // dof handlers,
+ // add a check
+ // here...
+ Assert (DoFHandlerSupportsDifferentFEs<DH>::value == true,
+ ExcInternalError());
+
+ // we first have
+ // to find the
+ // finite element
+ // that is able
+ // to generate a
+ // space that all
+ // the other ones
+ // can be
+ // constrained to
+ const unsigned int dominating_fe_index
+ = get_most_dominating_subface_fe_index (cell->face(face));
+
+ const FiniteElement<dim,spacedim> &dominating_fe
+ = dof_handler.get_fe()[dominating_fe_index];
+
+ // check also
+ // that it is
+ // able to
+ // constrain the
+ // mother
+ // face. it
+ // should be, or
+ // we wouldn't
+ // have gotten
+ // into the
+ // branch for the
+ // 'complex' case
+ Assert ((dominating_fe.compare_for_face_domination
+ (cell->face(face)->get_fe(cell->face(face)->nth_active_fe_index(0)))
+ == FiniteElementDomination::this_element_dominates)
+ ||
+ (dominating_fe.compare_for_face_domination
+ (cell->face(face)->get_fe(cell->face(face)->nth_active_fe_index(0)))
+ == FiniteElementDomination::either_element_can_dominate),
+ ExcInternalError());
+
+
+ // first get the
+ // interpolation matrix
+ // from the mother to the
+ // virtual dofs
+ Assert (dominating_fe.dofs_per_face <=
+ cell->get_fe().dofs_per_face,
+ ExcInternalError());
+
+ ensure_existence_of_face_matrix
+ (dominating_fe,
+ cell->get_fe(),
+ face_interpolation_matrices
+ [dominating_fe_index][cell->active_fe_index()]);
+
+ // split this matrix into
+ // master and slave
+ // components. invert the
+ // master component
+ ensure_existence_of_master_dof_mask
+ (cell->get_fe(),
+ dominating_fe,
+ (*face_interpolation_matrices
+ [dominating_fe_index]
+ [cell->active_fe_index()]),
+ master_dof_masks
+ [dominating_fe_index]
+ [cell->active_fe_index()]);
+
+ ensure_existence_of_split_face_matrix
+ (*face_interpolation_matrices
+ [dominating_fe_index][cell->active_fe_index()],
+ (*master_dof_masks
+ [dominating_fe_index][cell->active_fe_index()]),
+ split_face_interpolation_matrices
+ [dominating_fe_index][cell->active_fe_index()]);
+
+ const FullMatrix<double> &restrict_mother_to_virtual_master_inv
+ = (split_face_interpolation_matrices
+ [dominating_fe_index][cell->active_fe_index()]->first);
+
+ const FullMatrix<double> &restrict_mother_to_virtual_slave
+ = (split_face_interpolation_matrices
+ [dominating_fe_index][cell->active_fe_index()]->second);
+
+ // now compute
+ // the constraint
+ // matrix as the
+ // product
+ // between the
+ // inverse matrix
+ // and the slave
+ // part
+ constraint_matrix.reinit (cell->get_fe().dofs_per_face -
+ dominating_fe.dofs_per_face,
+ dominating_fe.dofs_per_face);
+ restrict_mother_to_virtual_slave
+ .mmult (constraint_matrix,
+ restrict_mother_to_virtual_master_inv);
+
+ // then figure
+ // out the global
+ // numbers of
+ // master and
+ // slave dofs and
+ // apply
+ // constraints
+ scratch_dofs.resize (cell->get_fe().dofs_per_face);
+ cell->face(face)->get_dof_indices (scratch_dofs,
+ cell->active_fe_index ());
+
+ // split dofs into master
+ // and slave components
+ master_dofs.clear ();
+ slave_dofs.clear ();
+ for (unsigned int i=0; i<cell->get_fe().dofs_per_face; ++i)
+ if ((*master_dof_masks
+ [dominating_fe_index][cell->active_fe_index()])[i] == true)
+ master_dofs.push_back (scratch_dofs[i]);
+ else
+ slave_dofs.push_back (scratch_dofs[i]);
+
+ AssertDimension (master_dofs.size(), dominating_fe.dofs_per_face);
+ AssertDimension (slave_dofs.size(),
+ cell->get_fe().dofs_per_face - dominating_fe.dofs_per_face);
+
+ filter_constraints (master_dofs,
+ slave_dofs,
+ constraint_matrix,
+ constraints);
+
+
+
+ // next we have
+ // to deal with
+ // the
+ // subfaces. do
+ // as discussed
+ // in the hp
+ // paper
+ for (unsigned int sf=0;
+ sf<cell->face(face)->n_children(); ++sf)
+ {
+ // ignore
+ // interfaces
+ // with
+ // artificial
+ // cells as
+ // well as
+ // interfaces
+ // between
+ // ghost
+ // cells in 2d
+ if (cell->neighbor_child_on_subface (face, sf)->is_artificial()
+ ||
+ (dim==2 && cell->is_ghost()
+ &&
+ cell->neighbor_child_on_subface (face, sf)->is_ghost()))
+ continue;
+
+ Assert (cell->face(face)->child(sf)
+ ->n_active_fe_indices() == 1,
+ ExcInternalError());
+
+ const unsigned int subface_fe_index
+ = cell->face(face)->child(sf)->nth_active_fe_index(0);
+ const FiniteElement<dim,spacedim> &subface_fe
+ = dof_handler.get_fe()[subface_fe_index];
+
+ // first get the
+ // interpolation
+ // matrix from the
+ // subface to the
+ // virtual dofs
+ Assert (dominating_fe.dofs_per_face <=
+ subface_fe.dofs_per_face,
+ ExcInternalError());
+ ensure_existence_of_subface_matrix
+ (dominating_fe,
+ subface_fe,
+ sf,
+ subface_interpolation_matrices
+ [dominating_fe_index][subface_fe_index][sf]);
+
+ const FullMatrix<double> &restrict_subface_to_virtual
+ = *(subface_interpolation_matrices
+ [dominating_fe_index][subface_fe_index][sf]);
+
+ constraint_matrix.reinit (subface_fe.dofs_per_face,
+ dominating_fe.dofs_per_face);
+
+ restrict_subface_to_virtual
+ .mmult (constraint_matrix,
+ restrict_mother_to_virtual_master_inv);
+
+ slave_dofs.resize (subface_fe.dofs_per_face);
+ cell->face(face)->child(sf)->get_dof_indices (slave_dofs,
+ subface_fe_index);
+
+ filter_constraints (master_dofs,
+ slave_dofs,
+ constraint_matrix,
+ constraints);
+ }
+
+ break;
+ }
+
+ case FiniteElementDomination::no_requirements:
+ // there
+ // are no
+ // continuity
+ // requirements
+ // between
+ // the two
+ // elements. record
+ // no
+ // constraints
+ break;
+
+ default:
+ // we shouldn't get here
+ Assert (false, ExcInternalError());
+ }
+ }
+ else
+ {
+ // this face has no
+ // children, but it
+ // could still be that
+ // it is shared by two
+ // cells that use a
+ // different fe index
+ Assert (cell->face(face)
+ ->fe_index_is_active(cell->active_fe_index()) == true,
+ ExcInternalError());
+
+ // see if there is a
+ // neighbor that is
+ // an artificial
+ // cell. in that
+ // case, we're not
+ // interested in this
+ // interface. we test
+ // this case first
+ // since artificial
+ // cells may not have
+ // an active_fe_index
+ // set, etc
+ if (!cell->at_boundary(face)
+ &&
+ cell->neighbor(face)->is_artificial())
+ continue;
+
+ // Only if there is
+ // a neighbor with
+ // a different
+ // active_fe_index
+ // and the same h-level,
+ // some action has
+ // to be taken.
+ if ((DoFHandlerSupportsDifferentFEs<DH>::value == true)
+ &&
+ !cell->face(face)->at_boundary ()
+ &&
+ (cell->neighbor(face)->active_fe_index () !=
+ cell->active_fe_index ())
+ &&
+ (!cell->face(face)->has_children() &&
+ !cell->neighbor_is_coarser(face) ))
+ {
+ const typename DH::cell_iterator neighbor = cell->neighbor (face);
+
+ // see which side of the
+ // face we have to
+ // constrain
+ switch (cell->get_fe().compare_for_face_domination (neighbor->get_fe ()))
+ {
+ case FiniteElementDomination::this_element_dominates:
+ {
+ // Get DoFs on
+ // dominating and
+ // dominated side of
+ // the face
+ master_dofs.resize (cell->get_fe().dofs_per_face);
+ cell->face(face)->get_dof_indices (master_dofs,
+ cell->active_fe_index ());
+
+ slave_dofs.resize (neighbor->get_fe().dofs_per_face);
+ cell->face(face)->get_dof_indices (slave_dofs,
+ neighbor->active_fe_index ());
+
+ // break if the n_master_dofs == 0,
+ // because we are attempting to
+ // constrain to an element that has
+ // has no face dofs
+ if(master_dofs.size() == 0) break;
+
+ // make sure
+ // the element
+ // constraints
+ // for this
+ // face are
+ // available
+ ensure_existence_of_face_matrix
+ (cell->get_fe(),
+ neighbor->get_fe(),
+ face_interpolation_matrices
+ [cell->active_fe_index()][neighbor->active_fe_index()]);
+
+ // Add constraints to global constraint
+ // matrix.
+ filter_constraints (master_dofs,
+ slave_dofs,
+ *(face_interpolation_matrices
+ [cell->active_fe_index()]
+ [neighbor->active_fe_index()]),
+ constraints);
+
+ break;
+ }
+
+ case FiniteElementDomination::other_element_dominates:
+ {
+ // we don't do anything
+ // here since we will
+ // come back to this
+ // face from the other
+ // cell, at which time
+ // we will fall into
+ // the first case
+ // clause above
+ break;
+ }
+
+ case FiniteElementDomination::either_element_can_dominate:
+ {
+ // it appears as if
+ // neither element has
+ // any constraints on
+ // its neighbor. this
+ // may be because
+ // neither element has
+ // any DoFs on faces at
+ // all. or that the two
+ // elements are
+ // actually the same,
+ // although they happen
+ // to run under
+ // different fe_indices
+ // (this is what
+ // happens in
+ // hp/hp_hanging_nodes_01
+ // for example).
+ //
+ // another possibility
+ // is what happens in
+ // crash_13. there, we
+ // have
+ // FESystem(FE_Q(1),FE_DGQ(0))
+ // vs. FESystem(FE_Q(1),FE_DGQ(1)).
+ // neither of them
+ // dominates the
+ // other. the point is
+ // that it doesn't
+ // matter, since
+ // hopefully for this
+ // case, both sides'
+ // dofs should have
+ // been unified.
+ //
+ // make sure this is
+ // actually true. this
+ // actually only
+ // matters, of course,
+ // if either of the two
+ // finite elements
+ // actually do have
+ // dofs on the face
+ if ((cell->get_fe().dofs_per_face != 0)
+ ||
+ (cell->neighbor(face)->get_fe().dofs_per_face != 0))
+ {
+ Assert (cell->get_fe().dofs_per_face
+ ==
+ cell->neighbor(face)->get_fe().dofs_per_face,
+ ExcNotImplemented());
+
+ // (ab)use the master
+ // and slave dofs
+ // arrays for a
+ // moment here
+ master_dofs.resize (cell->get_fe().dofs_per_face);
+ cell->face(face)
+ ->get_dof_indices (master_dofs,
+ cell->active_fe_index ());
+
+ slave_dofs.resize (cell->neighbor(face)->get_fe().dofs_per_face);
+ cell->face(face)
+ ->get_dof_indices (slave_dofs,
+ cell->neighbor(face)->active_fe_index ());
+
+ for (unsigned int i=0; i<cell->get_fe().dofs_per_face; ++i)
+ AssertDimension (master_dofs[i], slave_dofs[i]);
+ }
+
+ break;
+ }
+
+ case FiniteElementDomination::neither_element_dominates:
+ {
+ // we don't presently
+ // know what exactly to
+ // do here. it isn't quite
+ // clear what exactly we
+ // would have to do
+ // here. sit tight until
+ // someone trips over the
+ // following statement
+ // and see what exactly
+ // is going on
+ Assert (false, ExcNotImplemented());
+ break;
+ }
+
+ case FiniteElementDomination::no_requirements:
+ {
+ // nothing to do here
+ break;
+ }
+
+ default:
+ // we shouldn't get
+ // here
+ Assert (false, ExcInternalError());
+ }
+ }
+ }
}
}
template <class DH>
void
make_hanging_node_constraints (const DH &dof_handler,
- ConstraintMatrix &constraints)
+ ConstraintMatrix &constraints)
{
- // Decide whether to use the
- // new or old make_hanging_node_constraints
- // function. If all the FiniteElement
- // or all elements in a FECollection support
- // the new face constraint matrix, the
- // new code will be used.
- // Otherwise, the old implementation is used
- // for the moment.
+ // Decide whether to use the
+ // new or old make_hanging_node_constraints
+ // function. If all the FiniteElement
+ // or all elements in a FECollection support
+ // the new face constraint matrix, the
+ // new code will be used.
+ // Otherwise, the old implementation is used
+ // for the moment.
if (dof_handler.get_fe().hp_constraints_are_implemented ())
internal::
- make_hp_hanging_node_constraints (dof_handler,
- constraints);
+ make_hp_hanging_node_constraints (dof_handler,
+ constraints);
else
internal::
- make_oldstyle_hanging_node_constraints (dof_handler,
- constraints,
- dealii::internal::int2type<DH::dimension>());
+ make_oldstyle_hanging_node_constraints (dof_handler,
+ constraints,
+ dealii::internal::int2type<DH::dimension>());
}
namespace internal
{
- // this internal function assigns to each dof
- // the respective component of the vector
- // system. if use_blocks is set, then the
- // assignment is done by blocks, not by
- // components, as specified by
- // component_select. The additional argument
- // component_select only is used for
- // non-primitive FEs, where we need it since
- // more components couple, and no unique
- // component can be assigned. Then, we sort
- // them to the first selected component of the
- // vector system.
+ // this internal function assigns to each dof
+ // the respective component of the vector
+ // system. if use_blocks is set, then the
+ // assignment is done by blocks, not by
+ // components, as specified by
+ // component_select. The additional argument
+ // component_select only is used for
+ // non-primitive FEs, where we need it since
+ // more components couple, and no unique
+ // component can be assigned. Then, we sort
+ // them to the first selected component of the
+ // vector system.
template <class DH>
inline
void
extract_dofs_by_component (const DH &dof,
- const std::vector<bool> &component_select,
- const bool sort_by_blocks,
- std::vector<unsigned char> &dofs_by_component)
+ const std::vector<bool> &component_select,
+ const bool sort_by_blocks,
+ std::vector<unsigned char> &dofs_by_component)
{
const dealii::hp::FECollection<DH::dimension,DH::space_dimension>
- fe_collection (dof.get_fe());
+ fe_collection (dof.get_fe());
Assert (fe_collection.n_components() < 256, ExcNotImplemented());
Assert (dofs_by_component.size() == dof.n_locally_owned_dofs(),
- ExcDimensionMismatch(dofs_by_component.size(),
- dof.n_locally_owned_dofs()));
+ ExcDimensionMismatch(dofs_by_component.size(),
+ dof.n_locally_owned_dofs()));
- // next set up a table for the
- // degrees of freedom on each of
- // the cells whether it is
- // something interesting or not
+ // next set up a table for the
+ // degrees of freedom on each of
+ // the cells whether it is
+ // something interesting or not
std::vector<std::vector<unsigned char> > local_component_association
- (fe_collection.size());
+ (fe_collection.size());
for (unsigned int f=0; f<fe_collection.size(); ++f)
- {
- const FiniteElement<DH::dimension,DH::space_dimension> &fe =
- fe_collection[f];
- local_component_association[f].resize(fe.dofs_per_cell);
- if (sort_by_blocks == true)
- {
- for (unsigned int i=0; i<fe.dofs_per_cell; ++i)
- local_component_association[f][i]
- = fe.system_to_block_index(i).first;
- }
- else
- for (unsigned int i=0; i<fe.dofs_per_cell; ++i)
- if (fe.is_primitive(i))
- local_component_association[f][i] =
- fe.system_to_component_index(i).first;
- else
- // if this shape function is
- // not primitive, then we have
- // to work harder. we have to
- // find out whether _any_ of
- // the vector components of
- // this element is selected or
- // not
- //
- // to do so, get the a list of
- // nonzero elements and see which are
- // actually active
- {
- const unsigned int first_comp =
- (std::find(fe.get_nonzero_components(i).begin(),
- fe.get_nonzero_components(i).end(),
- true) -
- fe.get_nonzero_components(i).begin());
- const unsigned int end_comp =
- (std::find(fe.get_nonzero_components(i).begin()+first_comp,
- fe.get_nonzero_components(i).end(),
- false)-
- fe.get_nonzero_components(i).begin());
-
- // now check whether any of
- // the components in between
- // is set
- if (component_select.size() == 0 ||
- (component_select[first_comp] == true ||
- std::count(component_select.begin()+first_comp,
- component_select.begin()+end_comp, true) == 0))
- local_component_association[f][i] = first_comp;
- else
- for (unsigned int c=first_comp; c<end_comp; ++c)
- if (component_select[c] == true)
- {
- local_component_association[f][i] = c;
- break;
- }
- }
- }
-
- // then loop over all cells and do
- // the work
+ {
+ const FiniteElement<DH::dimension,DH::space_dimension> &fe =
+ fe_collection[f];
+ local_component_association[f].resize(fe.dofs_per_cell);
+ if (sort_by_blocks == true)
+ {
+ for (unsigned int i=0; i<fe.dofs_per_cell; ++i)
+ local_component_association[f][i]
+ = fe.system_to_block_index(i).first;
+ }
+ else
+ for (unsigned int i=0; i<fe.dofs_per_cell; ++i)
+ if (fe.is_primitive(i))
+ local_component_association[f][i] =
+ fe.system_to_component_index(i).first;
+ else
+ // if this shape function is
+ // not primitive, then we have
+ // to work harder. we have to
+ // find out whether _any_ of
+ // the vector components of
+ // this element is selected or
+ // not
+ //
+ // to do so, get the a list of
+ // nonzero elements and see which are
+ // actually active
+ {
+ const unsigned int first_comp =
+ (std::find(fe.get_nonzero_components(i).begin(),
+ fe.get_nonzero_components(i).end(),
+ true) -
+ fe.get_nonzero_components(i).begin());
+ const unsigned int end_comp =
+ (std::find(fe.get_nonzero_components(i).begin()+first_comp,
+ fe.get_nonzero_components(i).end(),
+ false)-
+ fe.get_nonzero_components(i).begin());
+
+ // now check whether any of
+ // the components in between
+ // is set
+ if (component_select.size() == 0 ||
+ (component_select[first_comp] == true ||
+ std::count(component_select.begin()+first_comp,
+ component_select.begin()+end_comp, true) == 0))
+ local_component_association[f][i] = first_comp;
+ else
+ for (unsigned int c=first_comp; c<end_comp; ++c)
+ if (component_select[c] == true)
+ {
+ local_component_association[f][i] = c;
+ break;
+ }
+ }
+ }
+
+ // then loop over all cells and do
+ // the work
std::vector<unsigned int> indices;
for (typename DH::active_cell_iterator c=dof.begin_active();
- c!=dof.end(); ++ c)
- if (c->is_locally_owned())
- {
- const unsigned int fe_index = c->active_fe_index();
- const unsigned int dofs_per_cell = c->get_fe().dofs_per_cell;
- indices.resize(dofs_per_cell);
- c->get_dof_indices(indices);
- for (unsigned int i=0; i<dofs_per_cell; ++i)
- if (dof.locally_owned_dofs().is_element(indices[i]))
- dofs_by_component[dof.locally_owned_dofs().index_within_set(indices[i])]
- = local_component_association[fe_index][i];
- }
+ c!=dof.end(); ++ c)
+ if (c->is_locally_owned())
+ {
+ const unsigned int fe_index = c->active_fe_index();
+ const unsigned int dofs_per_cell = c->get_fe().dofs_per_cell;
+ indices.resize(dofs_per_cell);
+ c->get_dof_indices(indices);
+ for (unsigned int i=0; i<dofs_per_cell; ++i)
+ if (dof.locally_owned_dofs().is_element(indices[i]))
+ dofs_by_component[dof.locally_owned_dofs().index_within_set(indices[i])]
+ = local_component_association[fe_index][i];
+ }
}
}
AssertDimension (dof_data.size(), dof_handler.n_dofs());
AssertIndexRange (component, n_components(dof_handler));
Assert (fe_is_primitive(dof_handler) == true,
- typename FiniteElement<dim>::ExcFENotPrimitive());
+ typename FiniteElement<dim>::ExcFENotPrimitive());
- // store a flag whether we should care
- // about different components. this is
- // just a simplification, we could ask
- // for this at every single place
- // equally well
+ // store a flag whether we should care
+ // about different components. this is
+ // just a simplification, we could ask
+ // for this at every single place
+ // equally well
const bool consider_components = (n_components(dof_handler) != 1);
- // zero out the components that we
- // will touch
+ // zero out the components that we
+ // will touch
if (consider_components == false)
dof_data = 0;
else
{
- std::vector<unsigned char> component_dofs (dof_handler.n_locally_owned_dofs());
- std::vector<bool> component_mask (dof_handler.get_fe().n_components(),
- false);
- component_mask[component] = true;
- internal::extract_dofs_by_component (dof_handler, component_mask,
- false, component_dofs);
-
- for (unsigned int i=0; i<dof_data.size(); ++i)
- if (component_dofs[i] == static_cast<unsigned char>(component))
- dof_data(i) = 0;
+ std::vector<unsigned char> component_dofs (dof_handler.n_locally_owned_dofs());
+ std::vector<bool> component_mask (dof_handler.get_fe().n_components(),
+ false);
+ component_mask[component] = true;
+ internal::extract_dofs_by_component (dof_handler, component_mask,
+ false, component_dofs);
+
+ for (unsigned int i=0; i<dof_data.size(); ++i)
+ if (component_dofs[i] == static_cast<unsigned char>(component))
+ dof_data(i) = 0;
}
- // count how often we have added a value
- // in the sum for each dof
+ // count how often we have added a value
+ // in the sum for each dof
std::vector<unsigned char> touch_count (dof_handler.n_dofs(), 0);
typename DH::active_cell_iterator cell = dof_handler.begin_active(),
- endc = dof_handler.end();
+ endc = dof_handler.end();
std::vector<unsigned int> dof_indices;
dof_indices.reserve (max_dofs_per_cell(dof_handler));
for (unsigned int present_cell = 0; cell!=endc; ++cell, ++present_cell)
{
- const unsigned int dofs_per_cell = cell->get_fe().dofs_per_cell;
- dof_indices.resize (dofs_per_cell);
- cell->get_dof_indices (dof_indices);
-
- for (unsigned int i=0; i<dofs_per_cell; ++i)
- // consider this dof only if it
- // is the right component. if there
- // is only one component, short cut
- // the test
- if (!consider_components ||
- (cell->get_fe().system_to_component_index(i).first == component))
- {
- // sum up contribution of the
- // present_cell to this dof
- dof_data(dof_indices[i]) += cell_data(present_cell);
- // note that we added another
- // summand
- ++touch_count[dof_indices[i]];
- }
+ const unsigned int dofs_per_cell = cell->get_fe().dofs_per_cell;
+ dof_indices.resize (dofs_per_cell);
+ cell->get_dof_indices (dof_indices);
+
+ for (unsigned int i=0; i<dofs_per_cell; ++i)
+ // consider this dof only if it
+ // is the right component. if there
+ // is only one component, short cut
+ // the test
+ if (!consider_components ||
+ (cell->get_fe().system_to_component_index(i).first == component))
+ {
+ // sum up contribution of the
+ // present_cell to this dof
+ dof_data(dof_indices[i]) += cell_data(present_cell);
+ // note that we added another
+ // summand
+ ++touch_count[dof_indices[i]];
+ }
}
- // compute the mean value on all the
- // dofs by dividing with the number
- // of summands.
+ // compute the mean value on all the
+ // dofs by dividing with the number
+ // of summands.
for (unsigned int i=0; i<dof_handler.n_dofs(); ++i)
{
- // assert that each dof was used
- // at least once. this needs not be
- // the case if the vector has more than
- // one component
- Assert (consider_components || (touch_count[i]!=0),
- ExcInternalError());
- if (touch_count[i] != 0)
- dof_data(i) /= touch_count[i];
+ // assert that each dof was used
+ // at least once. this needs not be
+ // the case if the vector has more than
+ // one component
+ Assert (consider_components || (touch_count[i]!=0),
+ ExcInternalError());
+ if (touch_count[i] != 0)
+ dof_data(i) /= touch_count[i];
}
}
if (count_by_blocks == true)
{
- Assert(component_select.size() == fe.n_blocks(),
- ExcDimensionMismatch(component_select.size(), fe.n_blocks()));
+ Assert(component_select.size() == fe.n_blocks(),
+ ExcDimensionMismatch(component_select.size(), fe.n_blocks()));
}
else
{
- Assert(component_select.size() == n_components(dof),
- ExcDimensionMismatch(component_select.size(), n_components(dof)));
+ Assert(component_select.size() == n_components(dof),
+ ExcDimensionMismatch(component_select.size(), n_components(dof)));
}
Assert(selected_dofs.size() == dof.n_locally_owned_dofs(),
- ExcDimensionMismatch(selected_dofs.size(), dof.n_locally_owned_dofs()));
+ ExcDimensionMismatch(selected_dofs.size(), dof.n_locally_owned_dofs()));
- // two special cases: no component
- // is selected, and all components
- // are selected; both rather
- // stupid, but easy to catch
+ // two special cases: no component
+ // is selected, and all components
+ // are selected; both rather
+ // stupid, but easy to catch
if (std::count (component_select.begin(), component_select.end(), true)
- == 0)
+ == 0)
{
- std::fill_n (selected_dofs.begin(), dof.n_locally_owned_dofs(), false);
- return;
+ std::fill_n (selected_dofs.begin(), dof.n_locally_owned_dofs(), false);
+ return;
}
else if (std::count (component_select.begin(), component_select.end(), true)
- == static_cast<signed int>(component_select.size()))
+ == static_cast<signed int>(component_select.size()))
{
- std::fill_n (selected_dofs.begin(), dof.n_locally_owned_dofs(), true);
- return;
+ std::fill_n (selected_dofs.begin(), dof.n_locally_owned_dofs(), true);
+ return;
}
- // preset all values by false
+ // preset all values by false
std::fill_n (selected_dofs.begin(), dof.n_locally_owned_dofs(), false);
- // if we count by blocks, we need to extract
- // the association of blocks with local dofs,
- // and then go through all the cells and set
- // the properties according to this
- // info. Otherwise, we let the function
- // extract_dofs_by_component function do the
- // job.
+ // if we count by blocks, we need to extract
+ // the association of blocks with local dofs,
+ // and then go through all the cells and set
+ // the properties according to this
+ // info. Otherwise, we let the function
+ // extract_dofs_by_component function do the
+ // job.
std::vector<unsigned char> dofs_by_component (dof.n_locally_owned_dofs());
internal::extract_dofs_by_component (dof, component_select, count_by_blocks,
- dofs_by_component);
+ dofs_by_component);
for (unsigned int i=0; i<dof.n_locally_owned_dofs(); ++i)
if (component_select[dofs_by_component[i]] == true)
- selected_dofs[i] = true;
+ selected_dofs[i] = true;
}
if (count_by_blocks == true)
{
- Assert(component_select.size() == fe.n_blocks(),
- ExcDimensionMismatch(component_select.size(), fe.n_blocks()));
+ Assert(component_select.size() == fe.n_blocks(),
+ ExcDimensionMismatch(component_select.size(), fe.n_blocks()));
}
else
{
- Assert(component_select.size() == n_components(dof),
- ExcDimensionMismatch(component_select.size(), n_components(dof)));
+ Assert(component_select.size() == n_components(dof),
+ ExcDimensionMismatch(component_select.size(), n_components(dof)));
}
Assert(selected_dofs.size() == dof.n_dofs(),
- ExcDimensionMismatch(selected_dofs.size(), dof.n_dofs()));
+ ExcDimensionMismatch(selected_dofs.size(), dof.n_dofs()));
- // two special cases: no component
- // is selected, and all components
- // are selected; both rather
- // stupid, but easy to catch
+ // two special cases: no component
+ // is selected, and all components
+ // are selected; both rather
+ // stupid, but easy to catch
if (std::count (component_select.begin(), component_select.end(), true)
- == 0)
+ == 0)
{
- std::fill_n (selected_dofs.begin(), dof.n_dofs(), false);
- return;
+ std::fill_n (selected_dofs.begin(), dof.n_dofs(), false);
+ return;
};
if (std::count (component_select.begin(), component_select.end(), true)
- == static_cast<signed int>(component_select.size()))
+ == static_cast<signed int>(component_select.size()))
{
- std::fill_n (selected_dofs.begin(), dof.n_dofs(), true);
- return;
+ std::fill_n (selected_dofs.begin(), dof.n_dofs(), true);
+ return;
};
- // preset all values by false
+ // preset all values by false
std::fill_n (selected_dofs.begin(), dof.n_dofs(), false);
- // if we count by blocks, we need to extract
- // the association of blocks with local dofs,
- // and then go through all the cells and set
- // the properties according to this
- // info. Otherwise, we let the function
- // extract_dofs_by_component function do the
- // job.
+ // if we count by blocks, we need to extract
+ // the association of blocks with local dofs,
+ // and then go through all the cells and set
+ // the properties according to this
+ // info. Otherwise, we let the function
+ // extract_dofs_by_component function do the
+ // job.
std::vector<unsigned char> dofs_by_component (dof.n_dofs());
internal::extract_dofs_by_component (dof, component_select, count_by_blocks,
- dofs_by_component);
+ dofs_by_component);
for (unsigned int i=0; i<dof.n_dofs(); ++i)
if (component_select[dofs_by_component[i]] == true)
- selected_dofs[i] = true;
+ selected_dofs[i] = true;
}
if (count_by_blocks == true)
{
- Assert(component_select.size() == fe.n_blocks(),
- ExcDimensionMismatch(component_select.size(), fe.n_blocks()));
+ Assert(component_select.size() == fe.n_blocks(),
+ ExcDimensionMismatch(component_select.size(), fe.n_blocks()));
}
else
{
- Assert(component_select.size() == fe.n_components(),
- ExcDimensionMismatch(component_select.size(), fe.n_components()));
+ Assert(component_select.size() == fe.n_components(),
+ ExcDimensionMismatch(component_select.size(), fe.n_components()));
}
Assert(selected_dofs.size() == dof.n_dofs(level),
- ExcDimensionMismatch(selected_dofs.size(), dof.n_dofs(level)));
+ ExcDimensionMismatch(selected_dofs.size(), dof.n_dofs(level)));
- // two special cases: no component
- // is selected, and all components
- // are selected, both rather
- // stupid, but easy to catch
+ // two special cases: no component
+ // is selected, and all components
+ // are selected, both rather
+ // stupid, but easy to catch
if (std::count (component_select.begin(), component_select.end(), true)
- == 0)
+ == 0)
{
- std::fill_n (selected_dofs.begin(), dof.n_dofs(level), false);
- return;
+ std::fill_n (selected_dofs.begin(), dof.n_dofs(level), false);
+ return;
};
if (std::count (component_select.begin(), component_select.end(), true)
- == static_cast<signed int>(component_select.size()))
+ == static_cast<signed int>(component_select.size()))
{
- std::fill_n (selected_dofs.begin(), dof.n_dofs(level), true);
- return;
+ std::fill_n (selected_dofs.begin(), dof.n_dofs(level), true);
+ return;
};
- // preset all values by false
+ // preset all values by false
std::fill_n (selected_dofs.begin(), dof.n_dofs(level), false);
- // next set up a table for the
- // degrees of freedom on each of
- // the cells whether it is
- // something interesting or not
+ // next set up a table for the
+ // degrees of freedom on each of
+ // the cells whether it is
+ // something interesting or not
std::vector<bool> local_selected_dofs (fe.dofs_per_cell, false);
for (unsigned int i=0; i<fe.dofs_per_cell; ++i)
if (count_by_blocks == true)
- local_selected_dofs[i]
- = component_select[fe.system_to_block_index(i).first];
+ local_selected_dofs[i]
+ = component_select[fe.system_to_block_index(i).first];
else
- if (fe.is_primitive(i))
- local_selected_dofs[i]
- = component_select[fe.system_to_component_index(i).first];
- else
- // if this shape function is
- // not primitive, then we have
- // to work harder. we have to
- // find out whether _any_ of
- // the vector components of
- // this element is selected or
- // not
- //
- // to do so, get the first and
- // last vector components of
- // the base element to which
- // the local dof with index i
- // belongs
- {
- unsigned int first_comp = 0;
- const unsigned int this_base = fe.system_to_base_index(i).first.first;
- const unsigned int this_multiplicity
- = fe.system_to_base_index(i).first.second;
-
- for (unsigned int b=0; b<this_base; ++b)
- first_comp += fe.base_element(b).n_components() *
- fe.element_multiplicity(b);
- for (unsigned int m=0; m<this_multiplicity; ++m)
- first_comp += fe.base_element(this_base).n_components();
- const unsigned int end_comp = first_comp +
- fe.base_element(this_base).n_components();
-
- Assert (first_comp < fe.n_components(), ExcInternalError());
- Assert (end_comp <= fe.n_components(), ExcInternalError());
-
- // now check whether any of
- // the components in between
- // is set
- for (unsigned int c=first_comp; c<end_comp; ++c)
- if (component_select[c] == true)
- {
- local_selected_dofs[i] = true;
- break;
- }
- }
-
- // then loop over all cells and do
- // work
+ if (fe.is_primitive(i))
+ local_selected_dofs[i]
+ = component_select[fe.system_to_component_index(i).first];
+ else
+ // if this shape function is
+ // not primitive, then we have
+ // to work harder. we have to
+ // find out whether _any_ of
+ // the vector components of
+ // this element is selected or
+ // not
+ //
+ // to do so, get the first and
+ // last vector components of
+ // the base element to which
+ // the local dof with index i
+ // belongs
+ {
+ unsigned int first_comp = 0;
+ const unsigned int this_base = fe.system_to_base_index(i).first.first;
+ const unsigned int this_multiplicity
+ = fe.system_to_base_index(i).first.second;
+
+ for (unsigned int b=0; b<this_base; ++b)
+ first_comp += fe.base_element(b).n_components() *
+ fe.element_multiplicity(b);
+ for (unsigned int m=0; m<this_multiplicity; ++m)
+ first_comp += fe.base_element(this_base).n_components();
+ const unsigned int end_comp = first_comp +
+ fe.base_element(this_base).n_components();
+
+ Assert (first_comp < fe.n_components(), ExcInternalError());
+ Assert (end_comp <= fe.n_components(), ExcInternalError());
+
+ // now check whether any of
+ // the components in between
+ // is set
+ for (unsigned int c=first_comp; c<end_comp; ++c)
+ if (component_select[c] == true)
+ {
+ local_selected_dofs[i] = true;
+ break;
+ }
+ }
+
+ // then loop over all cells and do
+ // work
std::vector<unsigned int> indices(fe.dofs_per_cell);
typename MGDoFHandler<dim,spacedim>::cell_iterator c;
for (c = dof.begin(level) ; c != dof.end(level) ; ++ c)
{
- c->get_mg_dof_indices(indices);
- for (unsigned int i=0; i<fe.dofs_per_cell; ++i)
- selected_dofs[indices[i]] = local_selected_dofs[i];
+ c->get_mg_dof_indices(indices);
+ for (unsigned int i=0; i<fe.dofs_per_cell; ++i)
+ selected_dofs[indices[i]] = local_selected_dofs[i];
}
}
template <class DH>
void
extract_boundary_dofs (const DH &dof_handler,
- const std::vector<bool> &component_select,
- std::vector<bool> &selected_dofs,
- const std::set<types::boundary_id_t> &boundary_indicators)
+ const std::vector<bool> &component_select,
+ std::vector<bool> &selected_dofs,
+ const std::set<types::boundary_id_t> &boundary_indicators)
{
AssertDimension (component_select.size(),n_components(dof_handler));
Assert (boundary_indicators.find (types::internal_face_boundary_id) == boundary_indicators.end(),
- ExcInvalidBoundaryIndicator());
+ ExcInvalidBoundaryIndicator());
const unsigned int dim=DH::dimension;
- // let's see whether we have to
- // check for certain boundary
- // indicators or whether we can
- // accept all
+ // let's see whether we have to
+ // check for certain boundary
+ // indicators or whether we can
+ // accept all
const bool check_boundary_indicator = (boundary_indicators.size() != 0);
- // also see whether we have to
- // check whether a certain vector
- // component is selected, or all
+ // also see whether we have to
+ // check whether a certain vector
+ // component is selected, or all
const bool check_vector_component
= (component_select != std::vector<bool>(component_select.size(),
- true));
+ true));
- // clear and reset array by default
- // values
+ // clear and reset array by default
+ // values
selected_dofs.clear ();
selected_dofs.resize (dof_handler.n_dofs(), false);
std::vector<unsigned int> face_dof_indices;
face_dof_indices.reserve (max_dofs_per_face(dof_handler));
- // now loop over all cells and
- // check whether their faces are at
- // the boundary. note that we need
- // not take special care of single
- // lines being at the boundary
- // (using
- // @p{cell->has_boundary_lines}),
- // since we do not support
- // boundaries of dimension dim-2,
- // and so every isolated boundary
- // line is also part of a boundary
- // face which we will be visiting
- // sooner or later
+ // now loop over all cells and
+ // check whether their faces are at
+ // the boundary. note that we need
+ // not take special care of single
+ // lines being at the boundary
+ // (using
+ // @p{cell->has_boundary_lines}),
+ // since we do not support
+ // boundaries of dimension dim-2,
+ // and so every isolated boundary
+ // line is also part of a boundary
+ // face which we will be visiting
+ // sooner or later
for (typename DH::active_cell_iterator cell=dof_handler.begin_active();
- cell!=dof_handler.end(); ++cell)
+ cell!=dof_handler.end(); ++cell)
for (unsigned int face=0;
- face<GeometryInfo<DH::dimension>::faces_per_cell; ++face)
- if (cell->at_boundary(face))
- if (! check_boundary_indicator ||
- (boundary_indicators.find (cell->face(face)->boundary_indicator())
- != boundary_indicators.end()))
- {
- const FiniteElement<DH::dimension, DH::space_dimension> &fe = cell->get_fe();
-
- const unsigned int dofs_per_face = fe.dofs_per_face;
- face_dof_indices.resize (dofs_per_face);
- cell->face(face)->get_dof_indices (face_dof_indices,
- cell->active_fe_index());
-
- for (unsigned int i=0; i<fe.dofs_per_face; ++i)
- if (!check_vector_component)
- selected_dofs[face_dof_indices[i]] = true;
- else
- // check for
- // component is
- // required. somewhat
- // tricky as usual
- // for the case that
- // the shape function
- // is non-primitive,
- // but use usual
- // convention (see
- // docs)
- {
- // first get at the
- // cell-global
- // number of a face
- // dof, to ask the
- // fe certain
- // questions
- const unsigned int cell_index
- = (dim == 1 ?
- i
- :
- (dim == 2 ?
- (i<2*fe.dofs_per_vertex ? i : i+2*fe.dofs_per_vertex)
- :
- (dim == 3 ?
- (i<4*fe.dofs_per_vertex ?
- i
- :
- (i<4*fe.dofs_per_vertex+4*fe.dofs_per_line ?
- i+4*fe.dofs_per_vertex
- :
- i+4*fe.dofs_per_vertex+8*fe.dofs_per_line))
- :
- numbers::invalid_unsigned_int)));
- if (fe.is_primitive (cell_index))
- selected_dofs[face_dof_indices[i]]
- = (component_select[fe.face_system_to_component_index(i).first]
- == true);
- else // not primitive
- {
- const unsigned int first_nonzero_comp
- = (std::find (fe.get_nonzero_components(cell_index).begin(),
- fe.get_nonzero_components(cell_index).end(),
- true)
- -
- fe.get_nonzero_components(cell_index).begin());
- Assert (first_nonzero_comp < fe.n_components(),
- ExcInternalError());
-
- selected_dofs[face_dof_indices[i]]
- = (component_select[first_nonzero_comp]
- == true);
- }
- }
- }
+ face<GeometryInfo<DH::dimension>::faces_per_cell; ++face)
+ if (cell->at_boundary(face))
+ if (! check_boundary_indicator ||
+ (boundary_indicators.find (cell->face(face)->boundary_indicator())
+ != boundary_indicators.end()))
+ {
+ const FiniteElement<DH::dimension, DH::space_dimension> &fe = cell->get_fe();
+
+ const unsigned int dofs_per_face = fe.dofs_per_face;
+ face_dof_indices.resize (dofs_per_face);
+ cell->face(face)->get_dof_indices (face_dof_indices,
+ cell->active_fe_index());
+
+ for (unsigned int i=0; i<fe.dofs_per_face; ++i)
+ if (!check_vector_component)
+ selected_dofs[face_dof_indices[i]] = true;
+ else
+ // check for
+ // component is
+ // required. somewhat
+ // tricky as usual
+ // for the case that
+ // the shape function
+ // is non-primitive,
+ // but use usual
+ // convention (see
+ // docs)
+ {
+ // first get at the
+ // cell-global
+ // number of a face
+ // dof, to ask the
+ // fe certain
+ // questions
+ const unsigned int cell_index
+ = (dim == 1 ?
+ i
+ :
+ (dim == 2 ?
+ (i<2*fe.dofs_per_vertex ? i : i+2*fe.dofs_per_vertex)
+ :
+ (dim == 3 ?
+ (i<4*fe.dofs_per_vertex ?
+ i
+ :
+ (i<4*fe.dofs_per_vertex+4*fe.dofs_per_line ?
+ i+4*fe.dofs_per_vertex
+ :
+ i+4*fe.dofs_per_vertex+8*fe.dofs_per_line))
+ :
+ numbers::invalid_unsigned_int)));
+ if (fe.is_primitive (cell_index))
+ selected_dofs[face_dof_indices[i]]
+ = (component_select[fe.face_system_to_component_index(i).first]
+ == true);
+ else // not primitive
+ {
+ const unsigned int first_nonzero_comp
+ = (std::find (fe.get_nonzero_components(cell_index).begin(),
+ fe.get_nonzero_components(cell_index).end(),
+ true)
+ -
+ fe.get_nonzero_components(cell_index).begin());
+ Assert (first_nonzero_comp < fe.n_components(),
+ ExcInternalError());
+
+ selected_dofs[face_dof_indices[i]]
+ = (component_select[first_nonzero_comp]
+ == true);
+ }
+ }
+ }
}
template <class DH>
void
extract_dofs_with_support_on_boundary (const DH &dof_handler,
- const std::vector<bool> &component_select,
- std::vector<bool> &selected_dofs,
- const std::set<types::boundary_id_t> &boundary_indicators)
+ const std::vector<bool> &component_select,
+ std::vector<bool> &selected_dofs,
+ const std::set<types::boundary_id_t> &boundary_indicators)
{
AssertDimension (component_select.size(), n_components(dof_handler));
Assert (boundary_indicators.find (types::internal_face_boundary_id) == boundary_indicators.end(),
- ExcInvalidBoundaryIndicator());
+ ExcInvalidBoundaryIndicator());
- // let's see whether we have to
- // check for certain boundary
- // indicators or whether we can
- // accept all
+ // let's see whether we have to
+ // check for certain boundary
+ // indicators or whether we can
+ // accept all
const bool check_boundary_indicator = (boundary_indicators.size() != 0);
- // also see whether we have to
- // check whether a certain vector
- // component is selected, or all
+ // also see whether we have to
+ // check whether a certain vector
+ // component is selected, or all
const bool check_vector_component
= (component_select != std::vector<bool>(component_select.size(),
- true));
+ true));
- // clear and reset array by default
- // values
+ // clear and reset array by default
+ // values
selected_dofs.clear ();
selected_dofs.resize (dof_handler.n_dofs(), false);
std::vector<unsigned int> cell_dof_indices;
cell_dof_indices.reserve (max_dofs_per_cell(dof_handler));
- // now loop over all cells and
- // check whether their faces are at
- // the boundary. note that we need
- // not take special care of single
- // lines being at the boundary
- // (using
- // @p{cell->has_boundary_lines}),
- // since we do not support
- // boundaries of dimension dim-2,
- // and so every isolated boundary
- // line is also part of a boundary
- // face which we will be visiting
- // sooner or later
+ // now loop over all cells and
+ // check whether their faces are at
+ // the boundary. note that we need
+ // not take special care of single
+ // lines being at the boundary
+ // (using
+ // @p{cell->has_boundary_lines}),
+ // since we do not support
+ // boundaries of dimension dim-2,
+ // and so every isolated boundary
+ // line is also part of a boundary
+ // face which we will be visiting
+ // sooner or later
for (typename DH::active_cell_iterator cell=dof_handler.begin_active();
- cell!=dof_handler.end(); ++cell)
+ cell!=dof_handler.end(); ++cell)
for (unsigned int face=0;
- face<GeometryInfo<DH::dimension>::faces_per_cell; ++face)
- if (cell->at_boundary(face))
- if (! check_boundary_indicator ||
- (boundary_indicators.find (cell->face(face)->boundary_indicator())
- != boundary_indicators.end()))
- {
- const FiniteElement<DH::dimension, DH::space_dimension> &fe = cell->get_fe();
-
- const unsigned int dofs_per_cell = fe.dofs_per_cell;
- cell_dof_indices.resize (dofs_per_cell);
- cell->get_dof_indices (cell_dof_indices);
-
- for (unsigned int i=0; i<fe.dofs_per_cell; ++i)
- if (fe.has_support_on_face(i,face))
- {
- if (!check_vector_component)
- selected_dofs[cell_dof_indices[i]] = true;
- else
- // check for
- // component is
- // required. somewhat
- // tricky as usual
- // for the case that
- // the shape function
- // is non-primitive,
- // but use usual
- // convention (see
- // docs)
- {
- if (fe.is_primitive (i))
- selected_dofs[cell_dof_indices[i]]
- = (component_select[fe.system_to_component_index(i).first]
- == true);
- else // not primitive
- {
- const unsigned int first_nonzero_comp
- = (std::find (fe.get_nonzero_components(i).begin(),
- fe.get_nonzero_components(i).end(),
- true)
- -
- fe.get_nonzero_components(i).begin());
- Assert (first_nonzero_comp < fe.n_components(),
- ExcInternalError());
-
- selected_dofs[cell_dof_indices[i]]
- = (component_select[first_nonzero_comp]
- == true);
- }
- }
- }
- }
+ face<GeometryInfo<DH::dimension>::faces_per_cell; ++face)
+ if (cell->at_boundary(face))
+ if (! check_boundary_indicator ||
+ (boundary_indicators.find (cell->face(face)->boundary_indicator())
+ != boundary_indicators.end()))
+ {
+ const FiniteElement<DH::dimension, DH::space_dimension> &fe = cell->get_fe();
+
+ const unsigned int dofs_per_cell = fe.dofs_per_cell;
+ cell_dof_indices.resize (dofs_per_cell);
+ cell->get_dof_indices (cell_dof_indices);
+
+ for (unsigned int i=0; i<fe.dofs_per_cell; ++i)
+ if (fe.has_support_on_face(i,face))
+ {
+ if (!check_vector_component)
+ selected_dofs[cell_dof_indices[i]] = true;
+ else
+ // check for
+ // component is
+ // required. somewhat
+ // tricky as usual
+ // for the case that
+ // the shape function
+ // is non-primitive,
+ // but use usual
+ // convention (see
+ // docs)
+ {
+ if (fe.is_primitive (i))
+ selected_dofs[cell_dof_indices[i]]
+ = (component_select[fe.system_to_component_index(i).first]
+ == true);
+ else // not primitive
+ {
+ const unsigned int first_nonzero_comp
+ = (std::find (fe.get_nonzero_components(i).begin(),
+ fe.get_nonzero_components(i).end(),
+ true)
+ -
+ fe.get_nonzero_components(i).begin());
+ Assert (first_nonzero_comp < fe.n_components(),
+ ExcInternalError());
+
+ selected_dofs[cell_dof_indices[i]]
+ = (component_select[first_nonzero_comp]
+ == true);
+ }
+ }
+ }
+ }
}
{
template <int spacedim>
void extract_hanging_node_dofs (const dealii::DoFHandler<1,spacedim> &dof_handler,
- std::vector<bool> &selected_dofs)
+ std::vector<bool> &selected_dofs)
{
- Assert(selected_dofs.size() == dof_handler.n_dofs(),
- ExcDimensionMismatch(selected_dofs.size(), dof_handler.n_dofs()));
- // preset all values by false
- std::fill_n (selected_dofs.begin(), dof_handler.n_dofs(), false);
+ Assert(selected_dofs.size() == dof_handler.n_dofs(),
+ ExcDimensionMismatch(selected_dofs.size(), dof_handler.n_dofs()));
+ // preset all values by false
+ std::fill_n (selected_dofs.begin(), dof_handler.n_dofs(), false);
- // there are no hanging nodes in 1d
+ // there are no hanging nodes in 1d
}
template <int spacedim>
void extract_hanging_node_dofs (const dealii::DoFHandler<2,spacedim> &dof_handler,
- std::vector<bool> &selected_dofs)
+ std::vector<bool> &selected_dofs)
{
- const unsigned int dim = 2;
-
- Assert(selected_dofs.size() == dof_handler.n_dofs(),
- ExcDimensionMismatch(selected_dofs.size(), dof_handler.n_dofs()));
- // preset all values by false
- std::fill_n (selected_dofs.begin(), dof_handler.n_dofs(), false);
-
- const FiniteElement<dim,spacedim> &fe = dof_handler.get_fe();
-
- // this function is similar to the
- // make_sparsity_pattern function,
- // see there for more information
- typename dealii::DoFHandler<dim,spacedim>::active_cell_iterator
- cell = dof_handler.begin_active(),
- endc = dof_handler.end();
- for (; cell!=endc; ++cell)
- for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
- if (cell->face(face)->has_children())
- {
- const typename dealii::DoFHandler<dim,spacedim>::line_iterator
- line = cell->face(face);
-
- for (unsigned int dof=0; dof!=fe.dofs_per_vertex; ++dof)
- selected_dofs[line->child(0)->vertex_dof_index(1,dof)] = true;
-
- for (unsigned int child=0; child<2; ++child)
- for (unsigned int dof=0; dof!=fe.dofs_per_line; ++dof)
- selected_dofs[line->child(child)->dof_index(dof)] = true;
- }
+ const unsigned int dim = 2;
+
+ Assert(selected_dofs.size() == dof_handler.n_dofs(),
+ ExcDimensionMismatch(selected_dofs.size(), dof_handler.n_dofs()));
+ // preset all values by false
+ std::fill_n (selected_dofs.begin(), dof_handler.n_dofs(), false);
+
+ const FiniteElement<dim,spacedim> &fe = dof_handler.get_fe();
+
+ // this function is similar to the
+ // make_sparsity_pattern function,
+ // see there for more information
+ typename dealii::DoFHandler<dim,spacedim>::active_cell_iterator
+ cell = dof_handler.begin_active(),
+ endc = dof_handler.end();
+ for (; cell!=endc; ++cell)
+ for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
+ if (cell->face(face)->has_children())
+ {
+ const typename dealii::DoFHandler<dim,spacedim>::line_iterator
+ line = cell->face(face);
+
+ for (unsigned int dof=0; dof!=fe.dofs_per_vertex; ++dof)
+ selected_dofs[line->child(0)->vertex_dof_index(1,dof)] = true;
+
+ for (unsigned int child=0; child<2; ++child)
+ for (unsigned int dof=0; dof!=fe.dofs_per_line; ++dof)
+ selected_dofs[line->child(child)->dof_index(dof)] = true;
+ }
}
template <int spacedim>
void extract_hanging_node_dofs (const dealii::DoFHandler<3,spacedim> &dof_handler,
- std::vector<bool> &selected_dofs)
+ std::vector<bool> &selected_dofs)
{
- const unsigned int dim = 3;
-
- Assert(selected_dofs.size() == dof_handler.n_dofs(),
- ExcDimensionMismatch(selected_dofs.size(), dof_handler.n_dofs()));
- // preset all values by false
- std::fill_n (selected_dofs.begin(), dof_handler.n_dofs(), false);
-
- const FiniteElement<dim,spacedim> &fe = dof_handler.get_fe();
-
- // this function is similar to the
- // make_sparsity_pattern function,
- // see there for more information
-
- typename dealii::DoFHandler<dim,spacedim>::active_cell_iterator
- cell = dof_handler.begin_active(),
- endc = dof_handler.end();
- for (; cell!=endc; ++cell)
- for (unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell; ++f)
- if (cell->face(f)->has_children())
- {
- const typename dealii::DoFHandler<dim,spacedim>::face_iterator
- face = cell->face(f);
-
- for (unsigned int dof=0; dof!=fe.dofs_per_vertex; ++dof)
- selected_dofs[face->child(0)->vertex_dof_index(2,dof)] = true;
-
- // dof numbers on the centers of
- // the lines bounding this face
- for (unsigned int line=0; line<4; ++line)
- for (unsigned int dof=0; dof!=fe.dofs_per_vertex; ++dof)
- selected_dofs[face->line(line)->child(0)->vertex_dof_index(1,dof)] = true;
-
- // next the dofs on the lines interior
- // to the face; the order of these
- // lines is laid down in the
- // FiniteElement class documentation
- for (unsigned int dof=0; dof<fe.dofs_per_line; ++dof)
- selected_dofs[face->child(0)->line(1)->dof_index(dof)] = true;
- for (unsigned int dof=0; dof<fe.dofs_per_line; ++dof)
- selected_dofs[face->child(1)->line(2)->dof_index(dof)] = true;
- for (unsigned int dof=0; dof<fe.dofs_per_line; ++dof)
- selected_dofs[face->child(2)->line(3)->dof_index(dof)] = true;
- for (unsigned int dof=0; dof<fe.dofs_per_line; ++dof)
- selected_dofs[face->child(3)->line(0)->dof_index(dof)] = true;
-
- // dofs on the bordering lines
- for (unsigned int line=0; line<4; ++line)
- for (unsigned int child=0; child<2; ++child)
- for (unsigned int dof=0; dof!=fe.dofs_per_line; ++dof)
- selected_dofs[face->line(line)->child(child)->dof_index(dof)] = true;
-
- // finally, for the dofs interior
- // to the four child faces
- for (unsigned int child=0; child<4; ++child)
- for (unsigned int dof=0; dof!=fe.dofs_per_quad; ++dof)
- selected_dofs[face->child(child)->dof_index(dof)] = true;
- }
+ const unsigned int dim = 3;
+
+ Assert(selected_dofs.size() == dof_handler.n_dofs(),
+ ExcDimensionMismatch(selected_dofs.size(), dof_handler.n_dofs()));
+ // preset all values by false
+ std::fill_n (selected_dofs.begin(), dof_handler.n_dofs(), false);
+
+ const FiniteElement<dim,spacedim> &fe = dof_handler.get_fe();
+
+ // this function is similar to the
+ // make_sparsity_pattern function,
+ // see there for more information
+
+ typename dealii::DoFHandler<dim,spacedim>::active_cell_iterator
+ cell = dof_handler.begin_active(),
+ endc = dof_handler.end();
+ for (; cell!=endc; ++cell)
+ for (unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell; ++f)
+ if (cell->face(f)->has_children())
+ {
+ const typename dealii::DoFHandler<dim,spacedim>::face_iterator
+ face = cell->face(f);
+
+ for (unsigned int dof=0; dof!=fe.dofs_per_vertex; ++dof)
+ selected_dofs[face->child(0)->vertex_dof_index(2,dof)] = true;
+
+ // dof numbers on the centers of
+ // the lines bounding this face
+ for (unsigned int line=0; line<4; ++line)
+ for (unsigned int dof=0; dof!=fe.dofs_per_vertex; ++dof)
+ selected_dofs[face->line(line)->child(0)->vertex_dof_index(1,dof)] = true;
+
+ // next the dofs on the lines interior
+ // to the face; the order of these
+ // lines is laid down in the
+ // FiniteElement class documentation
+ for (unsigned int dof=0; dof<fe.dofs_per_line; ++dof)
+ selected_dofs[face->child(0)->line(1)->dof_index(dof)] = true;
+ for (unsigned int dof=0; dof<fe.dofs_per_line; ++dof)
+ selected_dofs[face->child(1)->line(2)->dof_index(dof)] = true;
+ for (unsigned int dof=0; dof<fe.dofs_per_line; ++dof)
+ selected_dofs[face->child(2)->line(3)->dof_index(dof)] = true;
+ for (unsigned int dof=0; dof<fe.dofs_per_line; ++dof)
+ selected_dofs[face->child(3)->line(0)->dof_index(dof)] = true;
+
+ // dofs on the bordering lines
+ for (unsigned int line=0; line<4; ++line)
+ for (unsigned int child=0; child<2; ++child)
+ for (unsigned int dof=0; dof!=fe.dofs_per_line; ++dof)
+ selected_dofs[face->line(line)->child(child)->dof_index(dof)] = true;
+
+ // finally, for the dofs interior
+ // to the four child faces
+ for (unsigned int child=0; child<4; ++child)
+ for (unsigned int dof=0; dof!=fe.dofs_per_quad; ++dof)
+ selected_dofs[face->child(child)->dof_index(dof)] = true;
+ }
}
}
}
void
extract_hanging_node_dofs (const DoFHandler<dim,spacedim> &dof_handler,
- std::vector<bool> &selected_dofs)
+ std::vector<bool> &selected_dofs)
{
internal::extract_hanging_node_dofs (dof_handler,
- selected_dofs);
+ selected_dofs);
}
template <class DH>
void
extract_subdomain_dofs (const DH &dof_handler,
- const types::subdomain_id_t subdomain_id,
- std::vector<bool> &selected_dofs)
+ const types::subdomain_id_t subdomain_id,
+ std::vector<bool> &selected_dofs)
{
Assert(selected_dofs.size() == dof_handler.n_dofs(),
- ExcDimensionMismatch(selected_dofs.size(), dof_handler.n_dofs()));
+ ExcDimensionMismatch(selected_dofs.size(), dof_handler.n_dofs()));
- // preset all values by false
+ // preset all values by false
std::fill_n (selected_dofs.begin(), dof_handler.n_dofs(), false);
std::vector<unsigned int> local_dof_indices;
local_dof_indices.reserve (max_dofs_per_cell(dof_handler));
- // this function is similar to the
- // make_sparsity_pattern function,
- // see there for more information
+ // this function is similar to the
+ // make_sparsity_pattern function,
+ // see there for more information
typename DH::active_cell_iterator
cell = dof_handler.begin_active(),
endc = dof_handler.end();
for (; cell!=endc; ++cell)
if (cell->subdomain_id() == subdomain_id)
- {
- const unsigned int dofs_per_cell = cell->get_fe().dofs_per_cell;
- local_dof_indices.resize (dofs_per_cell);
- cell->get_dof_indices (local_dof_indices);
- for (unsigned int i=0; i<dofs_per_cell; ++i)
- selected_dofs[local_dof_indices[i]] = true;
- };
+ {
+ const unsigned int dofs_per_cell = cell->get_fe().dofs_per_cell;
+ local_dof_indices.resize (dofs_per_cell);
+ cell->get_dof_indices (local_dof_indices);
+ for (unsigned int i=0; i<dofs_per_cell; ++i)
+ selected_dofs[local_dof_indices[i]] = true;
+ };
}
template <class DH>
void
extract_locally_owned_dofs (const DH & dof_handler,
- IndexSet & dof_set)
+ IndexSet & dof_set)
{
- // collect all the locally owned dofs
+ // collect all the locally owned dofs
dof_set = dof_handler.locally_owned_dofs();
dof_set.compress ();
}
template <class DH>
void
extract_locally_active_dofs (const DH & dof_handler,
- IndexSet & dof_set)
+ IndexSet & dof_set)
{
- // collect all the locally owned dofs
+ // collect all the locally owned dofs
dof_set = dof_handler.locally_owned_dofs();
- // add the DoF on the adjacent ghost cells
- // to the IndexSet, cache them in a
- // set. need to check each dof manually
- // because we can't be sure that the dof
- // range of locally_owned_dofs is really
- // contiguous.
+ // add the DoF on the adjacent ghost cells
+ // to the IndexSet, cache them in a
+ // set. need to check each dof manually
+ // because we can't be sure that the dof
+ // range of locally_owned_dofs is really
+ // contiguous.
std::vector<unsigned int> dof_indices;
std::set<unsigned int> global_dof_indices;
typename DH::active_cell_iterator cell = dof_handler.begin_active(),
- endc = dof_handler.end();
+ endc = dof_handler.end();
for (; cell!=endc; ++cell)
if (cell->is_locally_owned())
- {
- dof_indices.resize(cell->get_fe().dofs_per_cell);
- cell->get_dof_indices(dof_indices);
-
- for (std::vector<unsigned int>::iterator it=dof_indices.begin();
- it!=dof_indices.end();
- ++it)
- if (!dof_set.is_element(*it))
- global_dof_indices.insert(*it);
- }
+ {
+ dof_indices.resize(cell->get_fe().dofs_per_cell);
+ cell->get_dof_indices(dof_indices);
+
+ for (std::vector<unsigned int>::iterator it=dof_indices.begin();
+ it!=dof_indices.end();
+ ++it)
+ if (!dof_set.is_element(*it))
+ global_dof_indices.insert(*it);
+ }
dof_set.add_indices(global_dof_indices.begin(), global_dof_indices.end());
template <class DH>
void
extract_locally_relevant_dofs (const DH & dof_handler,
- IndexSet & dof_set)
+ IndexSet & dof_set)
{
- // collect all the locally owned dofs
+ // collect all the locally owned dofs
dof_set = dof_handler.locally_owned_dofs();
- // add the DoF on the adjacent ghost cells
- // to the IndexSet, cache them in a
- // set. need to check each dof manually
- // because we can't be sure that the dof
- // range of locally_owned_dofs is really
- // contiguous.
+ // add the DoF on the adjacent ghost cells
+ // to the IndexSet, cache them in a
+ // set. need to check each dof manually
+ // because we can't be sure that the dof
+ // range of locally_owned_dofs is really
+ // contiguous.
std::vector<unsigned int> dof_indices;
std::set<unsigned int> global_dof_indices;
typename DH::active_cell_iterator cell = dof_handler.begin_active(),
- endc = dof_handler.end();
+ endc = dof_handler.end();
for (; cell!=endc; ++cell)
if (cell->is_ghost())
- {
- dof_indices.resize(cell->get_fe().dofs_per_cell);
- cell->get_dof_indices(dof_indices);
-
- for (std::vector<unsigned int>::iterator it=dof_indices.begin();
- it!=dof_indices.end();
- ++it)
- if (!dof_set.is_element(*it))
- global_dof_indices.insert(*it);
- }
+ {
+ dof_indices.resize(cell->get_fe().dofs_per_cell);
+ cell->get_dof_indices(dof_indices);
+
+ for (std::vector<unsigned int>::iterator it=dof_indices.begin();
+ it!=dof_indices.end();
+ ++it)
+ if (!dof_set.is_element(*it))
+ global_dof_indices.insert(*it);
+ }
dof_set.add_indices(global_dof_indices.begin(), global_dof_indices.end());
template <class DH>
void
extract_constant_modes (const DH &dof_handler,
- const std::vector<bool> &component_select,
- std::vector<std::vector<bool> > &constant_modes)
+ const std::vector<bool> &component_select,
+ std::vector<std::vector<bool> > &constant_modes)
{
const unsigned int n_components = dof_handler.get_fe().n_components();
Assert (n_components == component_select.size(),
- ExcDimensionMismatch(n_components,
- component_select.size()));
+ ExcDimensionMismatch(n_components,
+ component_select.size()));
std::vector<unsigned int> localized_component (n_components,
- numbers::invalid_unsigned_int);
+ numbers::invalid_unsigned_int);
unsigned int n_components_selected = 0;
for (unsigned int i=0; i<n_components; ++i)
if (component_select[i] == true)
- localized_component[i] = n_components_selected++;
+ localized_component[i] = n_components_selected++;
std::vector<unsigned char> dofs_by_component (dof_handler.n_locally_owned_dofs());
internal::extract_dofs_by_component (dof_handler, component_select, false,
- dofs_by_component);
+ dofs_by_component);
unsigned int n_selected_dofs = 0;
for (unsigned int i=0; i<n_components; ++i)
if (component_select[i] == true)
- n_selected_dofs += std::count (dofs_by_component.begin(),
- dofs_by_component.end(), i);
+ n_selected_dofs += std::count (dofs_by_component.begin(),
+ dofs_by_component.end(), i);
- // First count the number of dofs
- // in the current component.
+ // First count the number of dofs
+ // in the current component.
constant_modes.resize (n_components_selected, std::vector<bool>(n_selected_dofs,
- false));
+ false));
std::vector<unsigned int> component_list (n_components, 0);
for (unsigned int d=0; d<n_components; ++d)
component_list[d] = component_select[d];
unsigned int counter = 0;
for (unsigned int i=0; i<dof_handler.n_locally_owned_dofs(); ++i)
if (component_select[dofs_by_component[i]])
- {
- constant_modes[localized_component[dofs_by_component[i]]][counter] = true;
- ++counter;
- }
+ {
+ constant_modes[localized_component[dofs_by_component[i]]][counter] = true;
+ ++counter;
+ }
}
template <class DH>
void
get_active_fe_indices (const DH &dof_handler,
- std::vector<unsigned int> &active_fe_indices)
+ std::vector<unsigned int> &active_fe_indices)
{
AssertDimension (active_fe_indices.size(), dof_handler.get_tria().n_active_cells());
template <class DH>
void
get_subdomain_association (const DH &dof_handler,
- std::vector<types::subdomain_id_t> &subdomain_association)
+ std::vector<types::subdomain_id_t> &subdomain_association)
{
- // if the Triangulation is distributed, the
- // only thing we can usefully ask is for
- // its locally owned subdomain
+ // if the Triangulation is distributed, the
+ // only thing we can usefully ask is for
+ // its locally owned subdomain
Assert ((dynamic_cast<const parallel::distributed::
- Triangulation<DH::dimension,DH::space_dimension>*>
- (&dof_handler.get_tria()) == 0),
- ExcMessage ("For parallel::distributed::Triangulation objects and "
- "associated DoF handler objects, asking for any subdomain other "
- "than the locally owned one does not make sense."));
+ Triangulation<DH::dimension,DH::space_dimension>*>
+ (&dof_handler.get_tria()) == 0),
+ ExcMessage ("For parallel::distributed::Triangulation objects and "
+ "associated DoF handler objects, asking for any subdomain other "
+ "than the locally owned one does not make sense."));
Assert(subdomain_association.size() == dof_handler.n_dofs(),
- ExcDimensionMismatch(subdomain_association.size(),
- dof_handler.n_dofs()));
+ ExcDimensionMismatch(subdomain_association.size(),
+ dof_handler.n_dofs()));
- // preset all values by an invalid value
+ // preset all values by an invalid value
std::fill_n (subdomain_association.begin(), dof_handler.n_dofs(),
- types::invalid_subdomain_id);
+ types::invalid_subdomain_id);
std::vector<unsigned int> local_dof_indices;
local_dof_indices.reserve (max_dofs_per_cell(dof_handler));
- // pseudo-randomly assign variables
- // which lie on the interface
- // between subdomains to each of
- // the two or more
+ // pseudo-randomly assign variables
+ // which lie on the interface
+ // between subdomains to each of
+ // the two or more
bool coin_flip = true;
- // loop over all cells and record
- // which subdomain a DoF belongs
- // to. toss a coin in case it is on
- // an interface
+ // loop over all cells and record
+ // which subdomain a DoF belongs
+ // to. toss a coin in case it is on
+ // an interface
typename DH::active_cell_iterator
cell = dof_handler.begin_active(),
endc = dof_handler.end();
for (; cell!=endc; ++cell)
{
- Assert (cell->is_artificial() == false,
- ExcMessage ("You can't call this function for meshes that "
- "have artificial cells."));
-
- const types::subdomain_id_t subdomain_id = cell->subdomain_id();
- const unsigned int dofs_per_cell = cell->get_fe().dofs_per_cell;
- local_dof_indices.resize (dofs_per_cell);
- cell->get_dof_indices (local_dof_indices);
-
- // set subdomain ids. if dofs
- // already have their values
- // set then they must be on
- // partition interfaces. in
- // that case randomly assign
- // them to either the previous
- // association or the current
- // one, where we take "random"
- // to be "once this way once
- // that way"
- for (unsigned int i=0; i<dofs_per_cell; ++i)
- if (subdomain_association[local_dof_indices[i]] ==
- numbers::invalid_unsigned_int)
- subdomain_association[local_dof_indices[i]] = subdomain_id;
- else
- {
- if (coin_flip == true)
- subdomain_association[local_dof_indices[i]] = subdomain_id;
- coin_flip = !coin_flip;
- }
+ Assert (cell->is_artificial() == false,
+ ExcMessage ("You can't call this function for meshes that "
+ "have artificial cells."));
+
+ const types::subdomain_id_t subdomain_id = cell->subdomain_id();
+ const unsigned int dofs_per_cell = cell->get_fe().dofs_per_cell;
+ local_dof_indices.resize (dofs_per_cell);
+ cell->get_dof_indices (local_dof_indices);
+
+ // set subdomain ids. if dofs
+ // already have their values
+ // set then they must be on
+ // partition interfaces. in
+ // that case randomly assign
+ // them to either the previous
+ // association or the current
+ // one, where we take "random"
+ // to be "once this way once
+ // that way"
+ for (unsigned int i=0; i<dofs_per_cell; ++i)
+ if (subdomain_association[local_dof_indices[i]] ==
+ numbers::invalid_unsigned_int)
+ subdomain_association[local_dof_indices[i]] = subdomain_id;
+ else
+ {
+ if (coin_flip == true)
+ subdomain_association[local_dof_indices[i]] = subdomain_id;
+ coin_flip = !coin_flip;
+ }
}
Assert (std::find (subdomain_association.begin(),
- subdomain_association.end(),
- types::invalid_subdomain_id)
- == subdomain_association.end(),
- ExcInternalError());
+ subdomain_association.end(),
+ types::invalid_subdomain_id)
+ == subdomain_association.end(),
+ ExcInternalError());
}
template <class DH>
unsigned int
count_dofs_with_subdomain_association (const DH &dof_handler,
- const types::subdomain_id_t subdomain)
+ const types::subdomain_id_t subdomain)
{
std::vector<types::subdomain_id_t> subdomain_association (dof_handler.n_dofs());
get_subdomain_association (dof_handler, subdomain_association);
return std::count (subdomain_association.begin(),
- subdomain_association.end(),
- subdomain);
+ subdomain_association.end(),
+ subdomain);
}
template <class DH>
IndexSet
dof_indices_with_subdomain_association (const DH &dof_handler,
- const types::subdomain_id_t subdomain)
+ const types::subdomain_id_t subdomain)
{
- // If we have a distributed::Triangulation only
- // allow locally_owned subdomain.
+ // If we have a distributed::Triangulation only
+ // allow locally_owned subdomain.
Assert (
(dof_handler.get_tria().locally_owned_subdomain() == types::invalid_subdomain_id)
||
(subdomain == dof_handler.get_tria().locally_owned_subdomain()),
ExcMessage ("For parallel::distributed::Triangulation objects and "
- "associated DoF handler objects, asking for any subdomain other "
- "than the locally owned one does not make sense."));
+ "associated DoF handler objects, asking for any subdomain other "
+ "than the locally owned one does not make sense."));
IndexSet index_set (dof_handler.n_dofs());
std::vector<unsigned int> local_dof_indices;
local_dof_indices.reserve (max_dofs_per_cell(dof_handler));
- // first generate an unsorted list of all
- // indices which we fill from the back. could
- // also insert them directly into the
- // IndexSet, but that inserts indices in the
- // middle, which is an O(n^2) algorithm and
- // hence too expensive. Could also use
- // std::set, but that is in general more
- // expensive than a vector
+ // first generate an unsorted list of all
+ // indices which we fill from the back. could
+ // also insert them directly into the
+ // IndexSet, but that inserts indices in the
+ // middle, which is an O(n^2) algorithm and
+ // hence too expensive. Could also use
+ // std::set, but that is in general more
+ // expensive than a vector
std::vector<unsigned int> subdomain_indices;
typename DH::active_cell_iterator
endc = dof_handler.end();
for (; cell!=endc; ++cell)
if ((cell->is_artificial() == false)
- &&
- (cell->subdomain_id() == subdomain))
- {
- const unsigned int dofs_per_cell = cell->get_fe().dofs_per_cell;
- local_dof_indices.resize (dofs_per_cell);
- cell->get_dof_indices (local_dof_indices);
- subdomain_indices.insert(subdomain_indices.end(),
- local_dof_indices.begin(),
- local_dof_indices.end());
- }
- // sort indices and remove duplicates
+ &&
+ (cell->subdomain_id() == subdomain))
+ {
+ const unsigned int dofs_per_cell = cell->get_fe().dofs_per_cell;
+ local_dof_indices.resize (dofs_per_cell);
+ cell->get_dof_indices (local_dof_indices);
+ subdomain_indices.insert(subdomain_indices.end(),
+ local_dof_indices.begin(),
+ local_dof_indices.end());
+ }
+ // sort indices and remove duplicates
std::sort (subdomain_indices.begin(), subdomain_indices.end());
subdomain_indices.erase (std::unique(subdomain_indices.begin(),
- subdomain_indices.end()),
- subdomain_indices.end());
+ subdomain_indices.end()),
+ subdomain_indices.end());
- // insert into IndexSet
+ // insert into IndexSet
index_set.add_indices (subdomain_indices.begin(), subdomain_indices.end());
index_set.compress ();
template <class DH>
void
count_dofs_with_subdomain_association (const DH &dof_handler,
- const types::subdomain_id_t subdomain,
- std::vector<unsigned int> &n_dofs_on_subdomain)
+ const types::subdomain_id_t subdomain,
+ std::vector<unsigned int> &n_dofs_on_subdomain)
{
Assert (n_dofs_on_subdomain.size() == dof_handler.get_fe().n_components(),
- ExcDimensionMismatch (n_dofs_on_subdomain.size(),
- dof_handler.get_fe().n_components()));
+ ExcDimensionMismatch (n_dofs_on_subdomain.size(),
+ dof_handler.get_fe().n_components()));
std::fill (n_dofs_on_subdomain.begin(), n_dofs_on_subdomain.end(), 0);
- // in debug mode, make sure that there are
- // some cells at least with this subdomain
- // id
+ // in debug mode, make sure that there are
+ // some cells at least with this subdomain
+ // id
#ifdef DEBUG
{
bool found = false;
for (typename Triangulation<DH::dimension,DH::space_dimension>::active_cell_iterator
- cell=dof_handler.get_tria().begin_active();
- cell!=dof_handler.get_tria().end(); ++cell)
- if (cell->subdomain_id() == subdomain)
- {
- found = true;
- break;
- }
+ cell=dof_handler.get_tria().begin_active();
+ cell!=dof_handler.get_tria().end(); ++cell)
+ if (cell->subdomain_id() == subdomain)
+ {
+ found = true;
+ break;
+ }
Assert (found == true,
- ExcMessage ("There are no cells for the given subdomain!"));
+ ExcMessage ("There are no cells for the given subdomain!"));
}
#endif
std::vector<unsigned char> component_association (dof_handler.n_dofs());
internal::extract_dofs_by_component (dof_handler, std::vector<bool>(), false,
- component_association);
+ component_association);
for (unsigned int c=0; c<dof_handler.get_fe().n_components(); ++c)
{
- for (unsigned int i=0; i<dof_handler.n_dofs(); ++i)
- if ((subdomain_association[i] == subdomain) &&
- (component_association[i] == static_cast<unsigned char>(c)))
- ++n_dofs_on_subdomain[c];
+ for (unsigned int i=0; i<dof_handler.n_dofs(); ++i)
+ if ((subdomain_association[i] == subdomain) &&
+ (component_association[i] == static_cast<unsigned char>(c)))
+ ++n_dofs_on_subdomain[c];
}
}
template <int dim, int spacedim>
void
resolve_components (const FiniteElement<dim,spacedim>&fe,
- const std::vector<unsigned char> &dofs_by_component,
- const std::vector<unsigned int> &target_component,
- const bool only_once,
- std::vector<unsigned int> &dofs_per_component,
- unsigned int &component)
+ const std::vector<unsigned char> &dofs_by_component,
+ const std::vector<unsigned int> &target_component,
+ const bool only_once,
+ std::vector<unsigned int> &dofs_per_component,
+ unsigned int &component)
{
for (unsigned int b=0;b<fe.n_base_elements();++b)
- {
- const FiniteElement<dim,spacedim>& base = fe.base_element(b);
- // Dimension of base element
- unsigned int d = base.n_components();
-
- for (unsigned int m=0;m<fe.element_multiplicity(b);++m)
- {
- if (base.n_base_elements() > 1)
- resolve_components(base, dofs_by_component, target_component,
- only_once, dofs_per_component, component);
- else
- {
- for (unsigned int dd=0;dd<d;++dd,++component)
- dofs_per_component[target_component[component]]
- += std::count(dofs_by_component.begin(),
- dofs_by_component.end(),
- component);
-
- // if we have non-primitive FEs and want all
- // components to show the number of dofs, need
- // to copy the result to those components
- if (!base.is_primitive() && !only_once)
- for (unsigned int dd=1;dd<d;++dd)
- dofs_per_component[target_component[component-d+dd]] =
- dofs_per_component[target_component[component-d]];
- }
- }
- }
+ {
+ const FiniteElement<dim,spacedim>& base = fe.base_element(b);
+ // Dimension of base element
+ unsigned int d = base.n_components();
+
+ for (unsigned int m=0;m<fe.element_multiplicity(b);++m)
+ {
+ if (base.n_base_elements() > 1)
+ resolve_components(base, dofs_by_component, target_component,
+ only_once, dofs_per_component, component);
+ else
+ {
+ for (unsigned int dd=0;dd<d;++dd,++component)
+ dofs_per_component[target_component[component]]
+ += std::count(dofs_by_component.begin(),
+ dofs_by_component.end(),
+ component);
+
+ // if we have non-primitive FEs and want all
+ // components to show the number of dofs, need
+ // to copy the result to those components
+ if (!base.is_primitive() && !only_once)
+ for (unsigned int dd=1;dd<d;++dd)
+ dofs_per_component[target_component[component-d+dd]] =
+ dofs_per_component[target_component[component-d]];
+ }
+ }
+ }
}
template <int dim, int spacedim>
std::fill (dofs_per_component.begin(), dofs_per_component.end(), 0U);
- // If the empty vector was given as
- // default argument, set up this
- // vector as identity.
+ // If the empty vector was given as
+ // default argument, set up this
+ // vector as identity.
if (target_component.size()==0)
{
- target_component.resize(n_components);
- for (unsigned int i=0; i<n_components; ++i)
- target_component[i] = i;
+ target_component.resize(n_components);
+ for (unsigned int i=0; i<n_components; ++i)
+ target_component[i] = i;
}
else
Assert (target_component.size()==n_components,
- ExcDimensionMismatch(target_component.size(),
- n_components));
+ ExcDimensionMismatch(target_component.size(),
+ n_components));
const unsigned int max_component
= *std::max_element (target_component.begin(),
- target_component.end());
+ target_component.end());
const unsigned int n_target_components = max_component + 1;
AssertDimension (dofs_per_component.size(), n_target_components);
- // special case for only one
- // component. treat this first
- // since it does not require any
- // computations
+ // special case for only one
+ // component. treat this first
+ // since it does not require any
+ // computations
if (n_components == 1)
{
- dofs_per_component[0] = dof_handler.n_locally_owned_dofs();
- return;
+ dofs_per_component[0] = dof_handler.n_locally_owned_dofs();
+ return;
}
- // otherwise determine the number
- // of dofs in each component
- // separately. do so in parallel
+ // otherwise determine the number
+ // of dofs in each component
+ // separately. do so in parallel
std::vector<unsigned char> dofs_by_component (dof_handler.n_locally_owned_dofs());
internal::extract_dofs_by_component (dof_handler, std::vector<bool>(), false,
- dofs_by_component);
+ dofs_by_component);
- // next count what we got
+ // next count what we got
unsigned int component = 0;
internal::resolve_components(dof_handler.get_fe(),
dofs_by_component, target_component,
- only_once, dofs_per_component, component);
+ only_once, dofs_per_component, component);
Assert (n_components == component, ExcInternalError());
- // finally sanity check. this is
- // only valid if the finite element
- // is actually primitive, so
- // exclude other elements from this
+ // finally sanity check. this is
+ // only valid if the finite element
+ // is actually primitive, so
+ // exclude other elements from this
Assert ((internal::all_elements_are_primitive(dof_handler.get_fe()) == false)
- ||
- (std::accumulate (dofs_per_component.begin(),
- dofs_per_component.end(), 0U)
- == dof_handler.n_locally_owned_dofs()),
- ExcInternalError());
+ ||
+ (std::accumulate (dofs_per_component.begin(),
+ dofs_per_component.end(), 0U)
+ == dof_handler.n_locally_owned_dofs()),
+ ExcInternalError());
- // reduce information from all CPUs
+ // reduce information from all CPUs
#if defined(DEAL_II_USE_P4EST) && defined(DEAL_II_COMPILER_SUPPORTS_MPI)
const unsigned int dim = DH::dimension;
const unsigned int spacedim = DH::space_dimension;
if (const parallel::distributed::Triangulation<dim,spacedim> * tria
- = (dynamic_cast<const parallel::distributed::Triangulation<dim,spacedim>*>
- (&dof_handler.get_tria())))
+ = (dynamic_cast<const parallel::distributed::Triangulation<dim,spacedim>*>
+ (&dof_handler.get_tria())))
{
- std::vector<unsigned int> local_dof_count = dofs_per_component;
+ std::vector<unsigned int> local_dof_count = dofs_per_component;
- MPI_Allreduce ( &local_dof_count[0], &dofs_per_component[0], n_target_components,
- MPI_UNSIGNED, MPI_SUM, tria->get_communicator());
+ MPI_Allreduce ( &local_dof_count[0], &dofs_per_component[0], n_target_components,
+ MPI_UNSIGNED, MPI_SUM, tria->get_communicator());
}
#endif
}
const FiniteElement<DH::dimension,DH::space_dimension>& fe = fe_collection[this_fe];
std::fill (dofs_per_block.begin(), dofs_per_block.end(), 0U);
- // If the empty vector was given as
- // default argument, set up this
- // vector as identity.
+ // If the empty vector was given as
+ // default argument, set up this
+ // vector as identity.
if (target_block.size()==0)
- {
+ {
target_block.resize(fe.n_blocks());
for (unsigned int i=0; i<fe.n_blocks(); ++i)
- target_block[i] = i;
- }
+ target_block[i] = i;
+ }
else
- Assert (target_block.size()==fe.n_blocks(),
- ExcDimensionMismatch(target_block.size(),
- fe.n_blocks()));
+ Assert (target_block.size()==fe.n_blocks(),
+ ExcDimensionMismatch(target_block.size(),
+ fe.n_blocks()));
const unsigned int max_block
- = *std::max_element (target_block.begin(),
- target_block.end());
+ = *std::max_element (target_block.begin(),
+ target_block.end());
const unsigned int n_target_blocks = max_block + 1;
const unsigned int n_blocks = fe.n_blocks();
AssertDimension (dofs_per_block.size(), n_target_blocks);
- // special case for only one
- // block. treat this first
- // since it does not require any
- // computations
+ // special case for only one
+ // block. treat this first
+ // since it does not require any
+ // computations
if (n_blocks == 1)
- {
+ {
dofs_per_block[0] = dof_handler.n_dofs();
return;
- }
- // otherwise determine the number
- // of dofs in each block
- // separately.
+ }
+ // otherwise determine the number
+ // of dofs in each block
+ // separately.
std::vector<unsigned char> dofs_by_block (dof_handler.n_locally_owned_dofs());
internal::extract_dofs_by_component (dof_handler, std::vector<bool>(),
- true, dofs_by_block);
+ true, dofs_by_block);
- // next count what we got
+ // next count what we got
for (unsigned int block=0; block<fe.n_blocks(); ++block)
- dofs_per_block[target_block[block]]
- += std::count(dofs_by_block.begin(), dofs_by_block.end(),
- block);
+ dofs_per_block[target_block[block]]
+ += std::count(dofs_by_block.begin(), dofs_by_block.end(),
+ block);
#ifdef DEAL_II_USE_P4EST
#if DEAL_II_COMPILER_SUPPORTS_MPI
- // if we are working on a parallel
- // mesh, we now need to collect
- // this information from all
- // processors
+ // if we are working on a parallel
+ // mesh, we now need to collect
+ // this information from all
+ // processors
if (const parallel::distributed::Triangulation<DH::dimension,DH::space_dimension> * tria
- = (dynamic_cast<const parallel::distributed::Triangulation<DH::dimension,DH::space_dimension>*>
- (&dof_handler.get_tria())))
- {
+ = (dynamic_cast<const parallel::distributed::Triangulation<DH::dimension,DH::space_dimension>*>
+ (&dof_handler.get_tria())))
+ {
std::vector<unsigned int> local_dof_count = dofs_per_block;
MPI_Allreduce ( &local_dof_count[0], &dofs_per_block[0], n_target_blocks,
- MPI_UNSIGNED, MPI_SUM, tria->get_communicator());
- }
+ MPI_UNSIGNED, MPI_SUM, tria->get_communicator());
+ }
#endif
#endif
}
template <int dim, int spacedim>
void
count_dofs_per_component (const DoFHandler<dim,spacedim> &dof_handler,
- std::vector<unsigned int> &dofs_per_component,
- std::vector<unsigned int> target_component)
+ std::vector<unsigned int> &dofs_per_component,
+ std::vector<unsigned int> target_component)
{
count_dofs_per_component (dof_handler, dofs_per_component,
- false, target_component);
+ false, target_component);
}
{
namespace
{
- /**
- * This is a function that is
- * called by the _2 function and
- * that operates on a range of
- * cells only. It is used to
- * split up the whole range of
- * cells into chunks which are
- * then worked on in parallel, if
- * multithreading is available.
- */
+ /**
+ * This is a function that is
+ * called by the _2 function and
+ * that operates on a range of
+ * cells only. It is used to
+ * split up the whole range of
+ * cells into chunks which are
+ * then worked on in parallel, if
+ * multithreading is available.
+ */
template <int dim, int spacedim>
void
compute_intergrid_weights_3 (
- const dealii::DoFHandler<dim,spacedim> &coarse_grid,
- const unsigned int coarse_component,
- const InterGridMap<dealii::DoFHandler<dim,spacedim> > &coarse_to_fine_grid_map,
- const std::vector<dealii::Vector<double> > ¶meter_dofs,
- const std::vector<int> &weight_mapping,
- std::vector<std::map<unsigned int, float> > &weights,
- const typename dealii::DoFHandler<dim,spacedim>::active_cell_iterator &begin,
- const typename dealii::DoFHandler<dim,spacedim>::active_cell_iterator &end)
+ const dealii::DoFHandler<dim,spacedim> &coarse_grid,
+ const unsigned int coarse_component,
+ const InterGridMap<dealii::DoFHandler<dim,spacedim> > &coarse_to_fine_grid_map,
+ const std::vector<dealii::Vector<double> > ¶meter_dofs,
+ const std::vector<int> &weight_mapping,
+ std::vector<std::map<unsigned int, float> > &weights,
+ const typename dealii::DoFHandler<dim,spacedim>::active_cell_iterator &begin,
+ const typename dealii::DoFHandler<dim,spacedim>::active_cell_iterator &end)
{
- // aliases to the finite elements
- // used by the dof handlers:
- const FiniteElement<dim,spacedim> &coarse_fe = coarse_grid.get_fe();
-
- // for each cell on the parameter grid:
- // find out which degrees of freedom on the
- // fine grid correspond in which way to
- // the degrees of freedom on the parameter
- // grid
- //
- // since for continuous FEs some
- // dofs exist on more than one
- // cell, we have to track which
- // ones were already visited. the
- // problem is that if we visit a
- // dof first on one cell and
- // compute its weight with respect
- // to some global dofs to be
- // non-zero, and later visit the
- // dof again on another cell and
- // (since we are on another cell)
- // recompute the weights with
- // respect to the same dofs as
- // above to be zero now, we have to
- // preserve them. we therefore
- // overwrite all weights if they
- // are nonzero and do not enforce
- // zero weights since that might be
- // only due to the fact that we are
- // on another cell.
- //
- // example:
- // coarse grid
- // | | |
- // *-----*-----*
- // | cell|cell |
- // | 1 | 2 |
- // | | |
- // 0-----1-----*
- //
- // fine grid
- // | | | | |
- // *--*--*--*--*
- // | | | | |
- // *--*--*--*--*
- // | | | | |
- // *--x--y--*--*
- //
- // when on cell 1, we compute the
- // weights of dof 'x' to be 1/2
- // from parameter dofs 0 and 1,
- // respectively. however, when
- // later we are on cell 2, we again
- // compute the prolongation of
- // shape function 1 restricted to
- // cell 2 to the globla grid and
- // find that the weight of global
- // dof 'x' now is zero. however, we
- // should not overwrite the old
- // value.
- //
- // we therefore always only set
- // nonzero values. why adding up is
- // not useful: dof 'y' would get
- // weight 1 from parameter dof 1 on
- // both cells 1 and 2, but the
- // correct weight is nevertheless
- // only 1.
-
- // vector to hold the representation of
- // a single degree of freedom on the
- // coarse grid (for the selected fe)
- // on the fine grid
- const unsigned int n_fine_dofs = weight_mapping.size();
- dealii::Vector<double> global_parameter_representation (n_fine_dofs);
-
- typename dealii::DoFHandler<dim,spacedim>::active_cell_iterator cell;
- std::vector<unsigned int> parameter_dof_indices (coarse_fe.dofs_per_cell);
-
- for (cell=begin; cell!=end; ++cell)
- {
- // get the global indices of the
- // parameter dofs on this parameter
- // grid cell
- cell->get_dof_indices (parameter_dof_indices);
-
- // loop over all dofs on this
- // cell and check whether they
- // are interesting for us
- for (unsigned int local_dof=0;
- local_dof<coarse_fe.dofs_per_cell;
- ++local_dof)
- if (coarse_fe.system_to_component_index(local_dof).first
- ==
- coarse_component)
- {
- // the how-many-th
- // parameter is this on
- // this cell?
- const unsigned int local_parameter_dof
- = coarse_fe.system_to_component_index(local_dof).second;
-
- global_parameter_representation = 0;
-
- // distribute the representation of
- // @p{local_parameter_dof} on the
- // parameter grid cell @p{cell} to
- // the global data space
- coarse_to_fine_grid_map[cell]->
- set_dof_values_by_interpolation (parameter_dofs[local_parameter_dof],
- global_parameter_representation);
- // now that we've got the global
- // representation of each parameter
- // dof, we've only got to clobber the
- // non-zero entries in that vector and
- // store the result
- //
- // what we have learned: if entry @p{i}
- // of the global vector holds the value
- // @p{v[i]}, then this is the weight with
- // which the present dof contributes
- // to @p{i}. there may be several such
- // @p{i}s and their weights' sum should
- // be one. Then, @p{v[i]} should be
- // equal to @p{\sum_j w_{ij} p[j]} with
- // @p{p[j]} be the values of the degrees
- // of freedom on the coarse grid. we
- // can thus compute constraints which
- // link the degrees of freedom @p{v[i]}
- // on the fine grid to those on the
- // coarse grid, @p{p[j]}. Now to use
- // these as real constraints, rather
- // than as additional equations, we
- // have to identify representants
- // among the @p{i} for each @p{j}. this will
- // be done by simply taking the first
- // @p{i} for which @p{w_{ij}==1}.
- //
- // guard modification of
- // the weights array by a
- // Mutex. since it should
- // happen rather rarely
- // that there are several
- // threads operating on
- // different intergrid
- // weights, have only one
- // mutex for all of them
- static Threads::ThreadMutex mutex;
- Threads::ThreadMutex::ScopedLock lock (mutex);
- for (unsigned int i=0; i<global_parameter_representation.size(); ++i)
- // set this weight if it belongs
- // to a parameter dof.
- if (weight_mapping[i] != -1)
- {
- // only overwrite old
- // value if not by
- // zero
- if (global_parameter_representation(i) != 0)
- {
- const unsigned int wi = parameter_dof_indices[local_dof],
- wj = weight_mapping[i];
- weights[wi][wj] = global_parameter_representation(i);
- };
- }
- else
- Assert (global_parameter_representation(i) == 0,
- ExcInternalError());
- }
- }
+ // aliases to the finite elements
+ // used by the dof handlers:
+ const FiniteElement<dim,spacedim> &coarse_fe = coarse_grid.get_fe();
+
+ // for each cell on the parameter grid:
+ // find out which degrees of freedom on the
+ // fine grid correspond in which way to
+ // the degrees of freedom on the parameter
+ // grid
+ //
+ // since for continuous FEs some
+ // dofs exist on more than one
+ // cell, we have to track which
+ // ones were already visited. the
+ // problem is that if we visit a
+ // dof first on one cell and
+ // compute its weight with respect
+ // to some global dofs to be
+ // non-zero, and later visit the
+ // dof again on another cell and
+ // (since we are on another cell)
+ // recompute the weights with
+ // respect to the same dofs as
+ // above to be zero now, we have to
+ // preserve them. we therefore
+ // overwrite all weights if they
+ // are nonzero and do not enforce
+ // zero weights since that might be
+ // only due to the fact that we are
+ // on another cell.
+ //
+ // example:
+ // coarse grid
+ // | | |
+ // *-----*-----*
+ // | cell|cell |
+ // | 1 | 2 |
+ // | | |
+ // 0-----1-----*
+ //
+ // fine grid
+ // | | | | |
+ // *--*--*--*--*
+ // | | | | |
+ // *--*--*--*--*
+ // | | | | |
+ // *--x--y--*--*
+ //
+ // when on cell 1, we compute the
+ // weights of dof 'x' to be 1/2
+ // from parameter dofs 0 and 1,
+ // respectively. however, when
+ // later we are on cell 2, we again
+ // compute the prolongation of
+ // shape function 1 restricted to
+ // cell 2 to the globla grid and
+ // find that the weight of global
+ // dof 'x' now is zero. however, we
+ // should not overwrite the old
+ // value.
+ //
+ // we therefore always only set
+ // nonzero values. why adding up is
+ // not useful: dof 'y' would get
+ // weight 1 from parameter dof 1 on
+ // both cells 1 and 2, but the
+ // correct weight is nevertheless
+ // only 1.
+
+ // vector to hold the representation of
+ // a single degree of freedom on the
+ // coarse grid (for the selected fe)
+ // on the fine grid
+ const unsigned int n_fine_dofs = weight_mapping.size();
+ dealii::Vector<double> global_parameter_representation (n_fine_dofs);
+
+ typename dealii::DoFHandler<dim,spacedim>::active_cell_iterator cell;
+ std::vector<unsigned int> parameter_dof_indices (coarse_fe.dofs_per_cell);
+
+ for (cell=begin; cell!=end; ++cell)
+ {
+ // get the global indices of the
+ // parameter dofs on this parameter
+ // grid cell
+ cell->get_dof_indices (parameter_dof_indices);
+
+ // loop over all dofs on this
+ // cell and check whether they
+ // are interesting for us
+ for (unsigned int local_dof=0;
+ local_dof<coarse_fe.dofs_per_cell;
+ ++local_dof)
+ if (coarse_fe.system_to_component_index(local_dof).first
+ ==
+ coarse_component)
+ {
+ // the how-many-th
+ // parameter is this on
+ // this cell?
+ const unsigned int local_parameter_dof
+ = coarse_fe.system_to_component_index(local_dof).second;
+
+ global_parameter_representation = 0;
+
+ // distribute the representation of
+ // @p{local_parameter_dof} on the
+ // parameter grid cell @p{cell} to
+ // the global data space
+ coarse_to_fine_grid_map[cell]->
+ set_dof_values_by_interpolation (parameter_dofs[local_parameter_dof],
+ global_parameter_representation);
+ // now that we've got the global
+ // representation of each parameter
+ // dof, we've only got to clobber the
+ // non-zero entries in that vector and
+ // store the result
+ //
+ // what we have learned: if entry @p{i}
+ // of the global vector holds the value
+ // @p{v[i]}, then this is the weight with
+ // which the present dof contributes
+ // to @p{i}. there may be several such
+ // @p{i}s and their weights' sum should
+ // be one. Then, @p{v[i]} should be
+ // equal to @p{\sum_j w_{ij} p[j]} with
+ // @p{p[j]} be the values of the degrees
+ // of freedom on the coarse grid. we
+ // can thus compute constraints which
+ // link the degrees of freedom @p{v[i]}
+ // on the fine grid to those on the
+ // coarse grid, @p{p[j]}. Now to use
+ // these as real constraints, rather
+ // than as additional equations, we
+ // have to identify representants
+ // among the @p{i} for each @p{j}. this will
+ // be done by simply taking the first
+ // @p{i} for which @p{w_{ij}==1}.
+ //
+ // guard modification of
+ // the weights array by a
+ // Mutex. since it should
+ // happen rather rarely
+ // that there are several
+ // threads operating on
+ // different intergrid
+ // weights, have only one
+ // mutex for all of them
+ static Threads::ThreadMutex mutex;
+ Threads::ThreadMutex::ScopedLock lock (mutex);
+ for (unsigned int i=0; i<global_parameter_representation.size(); ++i)
+ // set this weight if it belongs
+ // to a parameter dof.
+ if (weight_mapping[i] != -1)
+ {
+ // only overwrite old
+ // value if not by
+ // zero
+ if (global_parameter_representation(i) != 0)
+ {
+ const unsigned int wi = parameter_dof_indices[local_dof],
+ wj = weight_mapping[i];
+ weights[wi][wj] = global_parameter_representation(i);
+ };
+ }
+ else
+ Assert (global_parameter_representation(i) == 0,
+ ExcInternalError());
+ }
+ }
}
- /**
- * This is a helper function that
- * is used in the computation of
- * integrid constraints. See the
- * function for a thorough
- * description of how it works.
- */
+ /**
+ * This is a helper function that
+ * is used in the computation of
+ * integrid constraints. See the
+ * function for a thorough
+ * description of how it works.
+ */
template <int dim, int spacedim>
void
compute_intergrid_weights_2 (
- const dealii::DoFHandler<dim,spacedim> &coarse_grid,
- const unsigned int coarse_component,
- const InterGridMap<dealii::DoFHandler<dim,spacedim> > &coarse_to_fine_grid_map,
- const std::vector<dealii::Vector<double> > ¶meter_dofs,
- const std::vector<int> &weight_mapping,
- std::vector<std::map<unsigned int,float> > &weights)
+ const dealii::DoFHandler<dim,spacedim> &coarse_grid,
+ const unsigned int coarse_component,
+ const InterGridMap<dealii::DoFHandler<dim,spacedim> > &coarse_to_fine_grid_map,
+ const std::vector<dealii::Vector<double> > ¶meter_dofs,
+ const std::vector<int> &weight_mapping,
+ std::vector<std::map<unsigned int,float> > &weights)
{
- // simply distribute the range of
- // cells to different threads
- typedef typename dealii::DoFHandler<dim,spacedim>::active_cell_iterator active_cell_iterator;
- std::vector<std::pair<active_cell_iterator,active_cell_iterator> >
- cell_intervals = Threads::split_range<active_cell_iterator> (coarse_grid.begin_active(),
- coarse_grid.end(),
- multithread_info.n_default_threads);
+ // simply distribute the range of
+ // cells to different threads
+ typedef typename dealii::DoFHandler<dim,spacedim>::active_cell_iterator active_cell_iterator;
+ std::vector<std::pair<active_cell_iterator,active_cell_iterator> >
+ cell_intervals = Threads::split_range<active_cell_iterator> (coarse_grid.begin_active(),
+ coarse_grid.end(),
+ multithread_info.n_default_threads);
//TODO: use WorkStream here
- Threads::TaskGroup<> tasks;
- void (*fun_ptr) (const dealii::DoFHandler<dim,spacedim> &,
- const unsigned int ,
- const InterGridMap<dealii::DoFHandler<dim,spacedim> > &,
- const std::vector<dealii::Vector<double> > &,
- const std::vector<int> &,
- std::vector<std::map<unsigned int, float> > &,
- const typename dealii::DoFHandler<dim,spacedim>::active_cell_iterator &,
- const typename dealii::DoFHandler<dim,spacedim>::active_cell_iterator &)
- = &compute_intergrid_weights_3<dim>;
- for (unsigned int i=0; i<multithread_info.n_default_threads; ++i)
- tasks += Threads::new_task (fun_ptr,
- coarse_grid, coarse_component,
- coarse_to_fine_grid_map, parameter_dofs,
- weight_mapping, weights,
- cell_intervals[i].first,
- cell_intervals[i].second);
-
- // wait for the tasks to finish
- tasks.join_all ();
+ Threads::TaskGroup<> tasks;
+ void (*fun_ptr) (const dealii::DoFHandler<dim,spacedim> &,
+ const unsigned int ,
+ const InterGridMap<dealii::DoFHandler<dim,spacedim> > &,
+ const std::vector<dealii::Vector<double> > &,
+ const std::vector<int> &,
+ std::vector<std::map<unsigned int, float> > &,
+ const typename dealii::DoFHandler<dim,spacedim>::active_cell_iterator &,
+ const typename dealii::DoFHandler<dim,spacedim>::active_cell_iterator &)
+ = &compute_intergrid_weights_3<dim>;
+ for (unsigned int i=0; i<multithread_info.n_default_threads; ++i)
+ tasks += Threads::new_task (fun_ptr,
+ coarse_grid, coarse_component,
+ coarse_to_fine_grid_map, parameter_dofs,
+ weight_mapping, weights,
+ cell_intervals[i].first,
+ cell_intervals[i].second);
+
+ // wait for the tasks to finish
+ tasks.join_all ();
}
- /**
- * This is a helper function that
- * is used in the computation of
- * integrid constraints. See the
- * function for a thorough
- * description of how it works.
- */
+ /**
+ * This is a helper function that
+ * is used in the computation of
+ * integrid constraints. See the
+ * function for a thorough
+ * description of how it works.
+ */
template <int dim, int spacedim>
unsigned int
compute_intergrid_weights_1 (
- const dealii::DoFHandler<dim,spacedim> &coarse_grid,
- const unsigned int coarse_component,
- const dealii::DoFHandler<dim,spacedim> &fine_grid,
- const unsigned int fine_component,
- const InterGridMap<dealii::DoFHandler<dim,spacedim> > &coarse_to_fine_grid_map,
- std::vector<std::map<unsigned int, float> > &weights,
- std::vector<int> &weight_mapping)
+ const dealii::DoFHandler<dim,spacedim> &coarse_grid,
+ const unsigned int coarse_component,
+ const dealii::DoFHandler<dim,spacedim> &fine_grid,
+ const unsigned int fine_component,
+ const InterGridMap<dealii::DoFHandler<dim,spacedim> > &coarse_to_fine_grid_map,
+ std::vector<std::map<unsigned int, float> > &weights,
+ std::vector<int> &weight_mapping)
{
- // aliases to the finite elements
- // used by the dof handlers:
- const FiniteElement<dim,spacedim> &coarse_fe = coarse_grid.get_fe(),
- &fine_fe = fine_grid.get_fe();
-
- // global numbers of dofs
- const unsigned int n_coarse_dofs = coarse_grid.n_dofs(),
- n_fine_dofs = fine_grid.n_dofs();
-
- // local numbers of dofs
- const unsigned int fine_dofs_per_cell = fine_fe.dofs_per_cell;
-
- // alias the number of dofs per
- // cell belonging to the
- // coarse_component which is to be
- // the restriction of the fine
- // grid:
- const unsigned int coarse_dofs_per_cell_component
- = coarse_fe.base_element(coarse_fe.component_to_base_index(coarse_component).first).dofs_per_cell;
-
-
- // Try to find out whether the
- // grids stem from the same coarse
- // grid. This is a rather crude
- // test, but better than nothing
- Assert (coarse_grid.get_tria().n_cells(0) == fine_grid.get_tria().n_cells(0),
- ExcGridsDontMatch());
-
- // check whether the map correlates
- // the right objects
- Assert (&coarse_to_fine_grid_map.get_source_grid() == &coarse_grid,
- ExcGridsDontMatch ());
- Assert (&coarse_to_fine_grid_map.get_destination_grid() == &fine_grid,
- ExcGridsDontMatch ());
-
-
- // check whether component numbers
- // are valid
- AssertIndexRange (coarse_component,coarse_fe.n_components());
- AssertIndexRange (fine_component, fine_fe.n_components());
- // check whether respective finite
- // elements are equal
- Assert (coarse_fe.base_element (coarse_fe.component_to_base_index(coarse_component).first)
- ==
- fine_fe.base_element (fine_fe.component_to_base_index(fine_component).first),
- ExcFiniteElementsDontMatch());
+ // aliases to the finite elements
+ // used by the dof handlers:
+ const FiniteElement<dim,spacedim> &coarse_fe = coarse_grid.get_fe(),
+ &fine_fe = fine_grid.get_fe();
+
+ // global numbers of dofs
+ const unsigned int n_coarse_dofs = coarse_grid.n_dofs(),
+ n_fine_dofs = fine_grid.n_dofs();
+
+ // local numbers of dofs
+ const unsigned int fine_dofs_per_cell = fine_fe.dofs_per_cell;
+
+ // alias the number of dofs per
+ // cell belonging to the
+ // coarse_component which is to be
+ // the restriction of the fine
+ // grid:
+ const unsigned int coarse_dofs_per_cell_component
+ = coarse_fe.base_element(coarse_fe.component_to_base_index(coarse_component).first).dofs_per_cell;
+
+
+ // Try to find out whether the
+ // grids stem from the same coarse
+ // grid. This is a rather crude
+ // test, but better than nothing
+ Assert (coarse_grid.get_tria().n_cells(0) == fine_grid.get_tria().n_cells(0),
+ ExcGridsDontMatch());
+
+ // check whether the map correlates
+ // the right objects
+ Assert (&coarse_to_fine_grid_map.get_source_grid() == &coarse_grid,
+ ExcGridsDontMatch ());
+ Assert (&coarse_to_fine_grid_map.get_destination_grid() == &fine_grid,
+ ExcGridsDontMatch ());
+
+
+ // check whether component numbers
+ // are valid
+ AssertIndexRange (coarse_component,coarse_fe.n_components());
+ AssertIndexRange (fine_component, fine_fe.n_components());
+ // check whether respective finite
+ // elements are equal
+ Assert (coarse_fe.base_element (coarse_fe.component_to_base_index(coarse_component).first)
+ ==
+ fine_fe.base_element (fine_fe.component_to_base_index(fine_component).first),
+ ExcFiniteElementsDontMatch());
#ifdef DEBUG
- // if in debug mode, check whether
- // the coarse grid is indeed
- // coarser everywhere than the fine
- // grid
- for (typename dealii::DoFHandler<dim,spacedim>::active_cell_iterator
- cell=coarse_grid.begin_active();
- cell != coarse_grid.end(); ++cell)
- Assert (cell->level() <= coarse_to_fine_grid_map[cell]->level(),
- ExcGridNotCoarser());
+ // if in debug mode, check whether
+ // the coarse grid is indeed
+ // coarser everywhere than the fine
+ // grid
+ for (typename dealii::DoFHandler<dim,spacedim>::active_cell_iterator
+ cell=coarse_grid.begin_active();
+ cell != coarse_grid.end(); ++cell)
+ Assert (cell->level() <= coarse_to_fine_grid_map[cell]->level(),
+ ExcGridNotCoarser());
#endif
- // set up vectors of cell-local
- // data; each vector represents one
- // degree of freedom of the
- // coarse-grid variable in the
- // fine-grid element
- std::vector<dealii::Vector<double> >
- parameter_dofs (coarse_dofs_per_cell_component,
- dealii::Vector<double>(fine_dofs_per_cell));
- // for each coarse dof: find its
- // position within the fine element
- // and set this value to one in the
- // respective vector (all other values
- // are zero by construction)
- for (unsigned int local_coarse_dof=0;
- local_coarse_dof<coarse_dofs_per_cell_component;
- ++local_coarse_dof)
- for (unsigned int fine_dof=0; fine_dof<fine_fe.dofs_per_cell; ++fine_dof)
- if (fine_fe.system_to_component_index(fine_dof)
- ==
- std::make_pair (fine_component, local_coarse_dof))
- {
- parameter_dofs[local_coarse_dof](fine_dof) = 1.;
- break;
- };
-
-
- // find out how many DoFs there are
- // on the grids belonging to the
- // components we want to match
- unsigned int n_parameters_on_fine_grid=0;
- if (true)
- {
- // have a flag for each dof on
- // the fine grid and set it
- // to true if this is an
- // interesting dof. finally count
- // how many true's there
- std::vector<bool> dof_is_interesting (fine_grid.n_dofs(), false);
- std::vector<unsigned int> local_dof_indices (fine_fe.dofs_per_cell);
-
- for (typename dealii::DoFHandler<dim,spacedim>::active_cell_iterator
- cell=fine_grid.begin_active();
- cell!=fine_grid.end(); ++cell)
- {
- cell->get_dof_indices (local_dof_indices);
- for (unsigned int i=0; i<fine_fe.dofs_per_cell; ++i)
- if (fine_fe.system_to_component_index(i).first == fine_component)
- dof_is_interesting[local_dof_indices[i]] = true;
- };
-
- n_parameters_on_fine_grid = std::count (dof_is_interesting.begin(),
- dof_is_interesting.end(),
- true);
- };
-
-
- // set up the weights mapping
- weights.clear ();
- weights.resize (n_coarse_dofs);
-
- weight_mapping.clear ();
- weight_mapping.resize (n_fine_dofs, -1);
-
- if (true)
- {
- std::vector<unsigned int> local_dof_indices(fine_fe.dofs_per_cell);
- unsigned int next_free_index=0;
- for (typename dealii::DoFHandler<dim,spacedim>::active_cell_iterator
- cell=fine_grid.begin_active();
- cell != fine_grid.end(); ++cell)
- {
- cell->get_dof_indices (local_dof_indices);
- for (unsigned int i=0; i<fine_fe.dofs_per_cell; ++i)
- // if this DoF is a
- // parameter dof and has
- // not yet been numbered,
- // then do so
- if ((fine_fe.system_to_component_index(i).first == fine_component) &&
- (weight_mapping[local_dof_indices[i]] == -1))
- {
- weight_mapping[local_dof_indices[i]] = next_free_index;
- ++next_free_index;
- };
- };
-
- Assert (next_free_index == n_parameters_on_fine_grid,
- ExcInternalError());
- };
-
-
- // for each cell on the parameter grid:
- // find out which degrees of freedom on the
- // fine grid correspond in which way to
- // the degrees of freedom on the parameter
- // grid
- //
- // do this in a separate function
- // to allow for multithreading
- // there. see this function also if
- // you want to read more
- // information on the algorithm
- // used.
- compute_intergrid_weights_2 (coarse_grid, coarse_component,
- coarse_to_fine_grid_map, parameter_dofs,
- weight_mapping, weights);
-
-
- // ok, now we have all weights for each
- // dof on the fine grid. if in debug
- // mode lets see if everything went smooth,
- // i.e. each dof has sum of weights one
- //
- // in other words this means that
- // if the sum of all shape
- // functions on the parameter grid
- // is one (which is always the
- // case), then the representation
- // on the state grid should be as
- // well (division of unity)
- //
- // if the parameter grid has more
- // than one component, then the
- // respective dofs of the other
- // components have sum of weights
- // zero, of course. we do not
- // explicitly ask which component
- // a dof belongs to, but this at
- // least tests some errors
+ // set up vectors of cell-local
+ // data; each vector represents one
+ // degree of freedom of the
+ // coarse-grid variable in the
+ // fine-grid element
+ std::vector<dealii::Vector<double> >
+ parameter_dofs (coarse_dofs_per_cell_component,
+ dealii::Vector<double>(fine_dofs_per_cell));
+ // for each coarse dof: find its
+ // position within the fine element
+ // and set this value to one in the
+ // respective vector (all other values
+ // are zero by construction)
+ for (unsigned int local_coarse_dof=0;
+ local_coarse_dof<coarse_dofs_per_cell_component;
+ ++local_coarse_dof)
+ for (unsigned int fine_dof=0; fine_dof<fine_fe.dofs_per_cell; ++fine_dof)
+ if (fine_fe.system_to_component_index(fine_dof)
+ ==
+ std::make_pair (fine_component, local_coarse_dof))
+ {
+ parameter_dofs[local_coarse_dof](fine_dof) = 1.;
+ break;
+ };
+
+
+ // find out how many DoFs there are
+ // on the grids belonging to the
+ // components we want to match
+ unsigned int n_parameters_on_fine_grid=0;
+ if (true)
+ {
+ // have a flag for each dof on
+ // the fine grid and set it
+ // to true if this is an
+ // interesting dof. finally count
+ // how many true's there
+ std::vector<bool> dof_is_interesting (fine_grid.n_dofs(), false);
+ std::vector<unsigned int> local_dof_indices (fine_fe.dofs_per_cell);
+
+ for (typename dealii::DoFHandler<dim,spacedim>::active_cell_iterator
+ cell=fine_grid.begin_active();
+ cell!=fine_grid.end(); ++cell)
+ {
+ cell->get_dof_indices (local_dof_indices);
+ for (unsigned int i=0; i<fine_fe.dofs_per_cell; ++i)
+ if (fine_fe.system_to_component_index(i).first == fine_component)
+ dof_is_interesting[local_dof_indices[i]] = true;
+ };
+
+ n_parameters_on_fine_grid = std::count (dof_is_interesting.begin(),
+ dof_is_interesting.end(),
+ true);
+ };
+
+
+ // set up the weights mapping
+ weights.clear ();
+ weights.resize (n_coarse_dofs);
+
+ weight_mapping.clear ();
+ weight_mapping.resize (n_fine_dofs, -1);
+
+ if (true)
+ {
+ std::vector<unsigned int> local_dof_indices(fine_fe.dofs_per_cell);
+ unsigned int next_free_index=0;
+ for (typename dealii::DoFHandler<dim,spacedim>::active_cell_iterator
+ cell=fine_grid.begin_active();
+ cell != fine_grid.end(); ++cell)
+ {
+ cell->get_dof_indices (local_dof_indices);
+ for (unsigned int i=0; i<fine_fe.dofs_per_cell; ++i)
+ // if this DoF is a
+ // parameter dof and has
+ // not yet been numbered,
+ // then do so
+ if ((fine_fe.system_to_component_index(i).first == fine_component) &&
+ (weight_mapping[local_dof_indices[i]] == -1))
+ {
+ weight_mapping[local_dof_indices[i]] = next_free_index;
+ ++next_free_index;
+ };
+ };
+
+ Assert (next_free_index == n_parameters_on_fine_grid,
+ ExcInternalError());
+ };
+
+
+ // for each cell on the parameter grid:
+ // find out which degrees of freedom on the
+ // fine grid correspond in which way to
+ // the degrees of freedom on the parameter
+ // grid
+ //
+ // do this in a separate function
+ // to allow for multithreading
+ // there. see this function also if
+ // you want to read more
+ // information on the algorithm
+ // used.
+ compute_intergrid_weights_2 (coarse_grid, coarse_component,
+ coarse_to_fine_grid_map, parameter_dofs,
+ weight_mapping, weights);
+
+
+ // ok, now we have all weights for each
+ // dof on the fine grid. if in debug
+ // mode lets see if everything went smooth,
+ // i.e. each dof has sum of weights one
+ //
+ // in other words this means that
+ // if the sum of all shape
+ // functions on the parameter grid
+ // is one (which is always the
+ // case), then the representation
+ // on the state grid should be as
+ // well (division of unity)
+ //
+ // if the parameter grid has more
+ // than one component, then the
+ // respective dofs of the other
+ // components have sum of weights
+ // zero, of course. we do not
+ // explicitly ask which component
+ // a dof belongs to, but this at
+ // least tests some errors
#ifdef DEBUG
- for (unsigned int col=0; col<n_parameters_on_fine_grid; ++col)
- {
- double sum=0;
- for (unsigned int row=0; row<n_coarse_dofs; ++row)
- if (weights[row].find(col) != weights[row].end())
- sum += weights[row][col];
- Assert ((std::fabs(sum-1) < 1.e-12) ||
- ((coarse_fe.n_components()>1) && (sum==0)), ExcInternalError());
- };
+ for (unsigned int col=0; col<n_parameters_on_fine_grid; ++col)
+ {
+ double sum=0;
+ for (unsigned int row=0; row<n_coarse_dofs; ++row)
+ if (weights[row].find(col) != weights[row].end())
+ sum += weights[row][col];
+ Assert ((std::fabs(sum-1) < 1.e-12) ||
+ ((coarse_fe.n_components()>1) && (sum==0)), ExcInternalError());
+ };
#endif
- return n_parameters_on_fine_grid;
+ return n_parameters_on_fine_grid;
}
const InterGridMap<DoFHandler<dim,spacedim> > &coarse_to_fine_grid_map,
ConstraintMatrix &constraints)
{
- // store the weights with which a dof
- // on the parameter grid contributes
- // to a dof on the fine grid. see the
- // long doc below for more info
- //
- // allocate as many rows as there are
- // parameter dofs on the coarse grid
- // and as many columns as there are
- // parameter dofs on the fine grid.
- //
- // weight_mapping is used to map the
- // global (fine grid) parameter dof
- // indices to the columns
- //
- // in the original implementation,
- // the weights array was actually
- // of FullMatrix<double> type. this
- // wasted huge amounts of memory,
- // but was fast. nonetheless, since
- // the memory consumption was
- // quadratic in the number of
- // degrees of freedom, this was not
- // very practical, so we now use a
- // vector of rows of the matrix,
- // and in each row a vector of
- // pairs (colnum,value). this seems
- // like the best tradeoff between
- // memory and speed, as it is now
- // linear in memory and still fast
- // enough.
- //
- // to save some memory and since
- // the weights are usually
- // (negative) powers of 2, we
- // choose the value type of the
- // matrix to be @p{float} rather
- // than @p{double}.
+ // store the weights with which a dof
+ // on the parameter grid contributes
+ // to a dof on the fine grid. see the
+ // long doc below for more info
+ //
+ // allocate as many rows as there are
+ // parameter dofs on the coarse grid
+ // and as many columns as there are
+ // parameter dofs on the fine grid.
+ //
+ // weight_mapping is used to map the
+ // global (fine grid) parameter dof
+ // indices to the columns
+ //
+ // in the original implementation,
+ // the weights array was actually
+ // of FullMatrix<double> type. this
+ // wasted huge amounts of memory,
+ // but was fast. nonetheless, since
+ // the memory consumption was
+ // quadratic in the number of
+ // degrees of freedom, this was not
+ // very practical, so we now use a
+ // vector of rows of the matrix,
+ // and in each row a vector of
+ // pairs (colnum,value). this seems
+ // like the best tradeoff between
+ // memory and speed, as it is now
+ // linear in memory and still fast
+ // enough.
+ //
+ // to save some memory and since
+ // the weights are usually
+ // (negative) powers of 2, we
+ // choose the value type of the
+ // matrix to be @p{float} rather
+ // than @p{double}.
std::vector<std::map<unsigned int, float> > weights;
- // this is this mapping. there is one
- // entry for each dof on the fine grid;
- // if it is a parameter dof, then its
- // value is the column in weights for
- // that parameter dof, if it is any
- // other dof, then its value is -1,
- // indicating an error
+ // this is this mapping. there is one
+ // entry for each dof on the fine grid;
+ // if it is a parameter dof, then its
+ // value is the column in weights for
+ // that parameter dof, if it is any
+ // other dof, then its value is -1,
+ // indicating an error
std::vector<int> weight_mapping;
const unsigned int n_parameters_on_fine_grid
= internal::compute_intergrid_weights_1 (coarse_grid, coarse_component,
- fine_grid, fine_component,
- coarse_to_fine_grid_map,
- weights, weight_mapping);
+ fine_grid, fine_component,
+ coarse_to_fine_grid_map,
+ weights, weight_mapping);
- // global numbers of dofs
+ // global numbers of dofs
const unsigned int n_coarse_dofs = coarse_grid.n_dofs(),
- n_fine_dofs = fine_grid.n_dofs();
+ n_fine_dofs = fine_grid.n_dofs();
- // get an array in which we store
- // which dof on the coarse grid is
- // a parameter and which is not
+ // get an array in which we store
+ // which dof on the coarse grid is
+ // a parameter and which is not
std::vector<bool> coarse_dof_is_parameter (coarse_grid.n_dofs());
if (true)
{
- std::vector<bool> mask (coarse_grid.get_fe().n_components(),
- false);
- mask[coarse_component] = true;
- extract_dofs (coarse_grid, mask, coarse_dof_is_parameter);
+ std::vector<bool> mask (coarse_grid.get_fe().n_components(),
+ false);
+ mask[coarse_component] = true;
+ extract_dofs (coarse_grid, mask, coarse_dof_is_parameter);
};
- // now we know that the weights in
- // each row constitute a
- // constraint. enter this into the
- // constraints object
- //
- // first task: for each parameter
- // dof on the parameter grid, find
- // a representant on the fine,
- // global grid. this is possible
- // since we use conforming finite
- // element. we take this
- // representant to be the first
- // element in this row with weight
- // identical to one. the
- // representant will become an
- // unconstrained degree of freedom,
- // while all others will be
- // constrained to this dof (and
- // possibly others)
+ // now we know that the weights in
+ // each row constitute a
+ // constraint. enter this into the
+ // constraints object
+ //
+ // first task: for each parameter
+ // dof on the parameter grid, find
+ // a representant on the fine,
+ // global grid. this is possible
+ // since we use conforming finite
+ // element. we take this
+ // representant to be the first
+ // element in this row with weight
+ // identical to one. the
+ // representant will become an
+ // unconstrained degree of freedom,
+ // while all others will be
+ // constrained to this dof (and
+ // possibly others)
std::vector<int> representants(n_coarse_dofs, -1);
for (unsigned int parameter_dof=0; parameter_dof<n_coarse_dofs;
- ++parameter_dof)
+ ++parameter_dof)
if (coarse_dof_is_parameter[parameter_dof] == true)
- {
- // if this is the line of a
- // parameter dof on the
- // coarse grid, then it
- // should have at least one
- // dependent node on the fine
- // grid
- Assert (weights[parameter_dof].size() > 0, ExcInternalError());
-
- // find the column where the
- // representant is mentioned
- std::map<unsigned int,float>::const_iterator i = weights[parameter_dof].begin();
- for (; i!=weights[parameter_dof].end(); ++i)
- if (i->second == 1)
- break;
- Assert (i!=weights[parameter_dof].end(), ExcInternalError());
- const unsigned int column = i->first;
-
- // now we know in which column of
- // weights the representant is, but
- // we don't know its global index. get
- // it using the inverse operation of
- // the weight_mapping
- unsigned int global_dof=0;
- for (; global_dof<weight_mapping.size(); ++global_dof)
- if (weight_mapping[global_dof] == static_cast<int>(column))
- break;
- Assert (global_dof < weight_mapping.size(), ExcInternalError());
-
- // now enter the representants global
- // index into our list
- representants[parameter_dof] = global_dof;
- }
+ {
+ // if this is the line of a
+ // parameter dof on the
+ // coarse grid, then it
+ // should have at least one
+ // dependent node on the fine
+ // grid
+ Assert (weights[parameter_dof].size() > 0, ExcInternalError());
+
+ // find the column where the
+ // representant is mentioned
+ std::map<unsigned int,float>::const_iterator i = weights[parameter_dof].begin();
+ for (; i!=weights[parameter_dof].end(); ++i)
+ if (i->second == 1)
+ break;
+ Assert (i!=weights[parameter_dof].end(), ExcInternalError());
+ const unsigned int column = i->first;
+
+ // now we know in which column of
+ // weights the representant is, but
+ // we don't know its global index. get
+ // it using the inverse operation of
+ // the weight_mapping
+ unsigned int global_dof=0;
+ for (; global_dof<weight_mapping.size(); ++global_dof)
+ if (weight_mapping[global_dof] == static_cast<int>(column))
+ break;
+ Assert (global_dof < weight_mapping.size(), ExcInternalError());
+
+ // now enter the representants global
+ // index into our list
+ representants[parameter_dof] = global_dof;
+ }
else
- {
- // consistency check: if this
- // is no parameter dof on the
- // coarse grid, then the
- // respective row must be
- // empty!
- Assert (weights[parameter_dof].size() == 0, ExcInternalError());
- };
-
-
-
- // note for people that want to
- // optimize this function: the
- // largest part of the computing
- // time is spent in the following,
- // rather innocent block of
- // code. basically, it must be the
- // ConstraintMatrix::add_entry call
- // which takes the bulk of the
- // time, but it is not known to the
- // author how to make it faster...
+ {
+ // consistency check: if this
+ // is no parameter dof on the
+ // coarse grid, then the
+ // respective row must be
+ // empty!
+ Assert (weights[parameter_dof].size() == 0, ExcInternalError());
+ };
+
+
+
+ // note for people that want to
+ // optimize this function: the
+ // largest part of the computing
+ // time is spent in the following,
+ // rather innocent block of
+ // code. basically, it must be the
+ // ConstraintMatrix::add_entry call
+ // which takes the bulk of the
+ // time, but it is not known to the
+ // author how to make it faster...
std::vector<std::pair<unsigned int,double> > constraint_line;
for (unsigned int global_dof=0; global_dof<n_fine_dofs; ++global_dof)
if (weight_mapping[global_dof] != -1)
- // this global dof is a parameter
- // dof, so it may carry a constraint
- // note that for each global dof,
- // the sum of weights shall be one,
- // so we can find out whether this
- // dof is constrained in the following
- // way: if the only weight in this row
- // is a one, and the representant for
- // the parameter dof of the line in
- // which this one is is the present
- // dof, then we consider this dof
- // to be unconstrained. otherwise,
- // all other dofs are constrained
- {
- const unsigned int col = weight_mapping[global_dof];
- Assert (col < n_parameters_on_fine_grid, ExcInternalError());
-
- unsigned int first_used_row=0;
-
- {
- Assert (weights.size() > 0, ExcInternalError());
- std::map<unsigned int,float>::const_iterator
- col_entry = weights[0].end();
- for (; first_used_row<n_coarse_dofs; ++first_used_row)
- {
- col_entry = weights[first_used_row].find(col);
- if (col_entry != weights[first_used_row].end())
- break;
- }
-
- Assert (col_entry != weights[first_used_row].end(), ExcInternalError());
-
- if ((col_entry->second == 1) &&
- (representants[first_used_row] == static_cast<int>(global_dof)))
- // dof unconstrained or
- // constrained to itself
- // (in case this cell is
- // mapped to itself, rather
- // than to children of
- // itself)
- continue;
- }
-
-
- // otherwise enter all constraints
- constraints.add_line (global_dof);
-
- constraint_line.clear ();
- for (unsigned int row=first_used_row; row<n_coarse_dofs; ++row)
- {
- const std::map<unsigned int,float>::const_iterator
- j = weights[row].find(col);
- if ((j != weights[row].end()) && (j->second != 0))
- constraint_line.push_back (std::make_pair(representants[row],
- j->second));
- };
-
- constraints.add_entries (global_dof, constraint_line);
- };
+ // this global dof is a parameter
+ // dof, so it may carry a constraint
+ // note that for each global dof,
+ // the sum of weights shall be one,
+ // so we can find out whether this
+ // dof is constrained in the following
+ // way: if the only weight in this row
+ // is a one, and the representant for
+ // the parameter dof of the line in
+ // which this one is is the present
+ // dof, then we consider this dof
+ // to be unconstrained. otherwise,
+ // all other dofs are constrained
+ {
+ const unsigned int col = weight_mapping[global_dof];
+ Assert (col < n_parameters_on_fine_grid, ExcInternalError());
+
+ unsigned int first_used_row=0;
+
+ {
+ Assert (weights.size() > 0, ExcInternalError());
+ std::map<unsigned int,float>::const_iterator
+ col_entry = weights[0].end();
+ for (; first_used_row<n_coarse_dofs; ++first_used_row)
+ {
+ col_entry = weights[first_used_row].find(col);
+ if (col_entry != weights[first_used_row].end())
+ break;
+ }
+
+ Assert (col_entry != weights[first_used_row].end(), ExcInternalError());
+
+ if ((col_entry->second == 1) &&
+ (representants[first_used_row] == static_cast<int>(global_dof)))
+ // dof unconstrained or
+ // constrained to itself
+ // (in case this cell is
+ // mapped to itself, rather
+ // than to children of
+ // itself)
+ continue;
+ }
+
+
+ // otherwise enter all constraints
+ constraints.add_line (global_dof);
+
+ constraint_line.clear ();
+ for (unsigned int row=first_used_row; row<n_coarse_dofs; ++row)
+ {
+ const std::map<unsigned int,float>::const_iterator
+ j = weights[row].find(col);
+ if ((j != weights[row].end()) && (j->second != 0))
+ constraint_line.push_back (std::make_pair(representants[row],
+ j->second));
+ };
+
+ constraints.add_entries (global_dof, constraint_line);
+ };
}
const InterGridMap<DoFHandler<dim,spacedim> > &coarse_to_fine_grid_map,
std::vector<std::map<unsigned int, float> > &transfer_representation)
{
- // store the weights with which a dof
- // on the parameter grid contributes
- // to a dof on the fine grid. see the
- // long doc below for more info
- //
- // allocate as many rows as there are
- // parameter dofs on the coarse grid
- // and as many columns as there are
- // parameter dofs on the fine grid.
- //
- // weight_mapping is used to map the
- // global (fine grid) parameter dof
- // indices to the columns
- //
- // in the original implementation,
- // the weights array was actually
- // of FullMatrix<double> type. this
- // wasted huge amounts of memory,
- // but was fast. nonetheless, since
- // the memory consumption was
- // quadratic in the number of
- // degrees of freedom, this was not
- // very practical, so we now use a
- // vector of rows of the matrix,
- // and in each row a vector of
- // pairs (colnum,value). this seems
- // like the best tradeoff between
- // memory and speed, as it is now
- // linear in memory and still fast
- // enough.
- //
- // to save some memory and since
- // the weights are usually
- // (negative) powers of 2, we
- // choose the value type of the
- // matrix to be @p{float} rather
- // than @p{double}.
+ // store the weights with which a dof
+ // on the parameter grid contributes
+ // to a dof on the fine grid. see the
+ // long doc below for more info
+ //
+ // allocate as many rows as there are
+ // parameter dofs on the coarse grid
+ // and as many columns as there are
+ // parameter dofs on the fine grid.
+ //
+ // weight_mapping is used to map the
+ // global (fine grid) parameter dof
+ // indices to the columns
+ //
+ // in the original implementation,
+ // the weights array was actually
+ // of FullMatrix<double> type. this
+ // wasted huge amounts of memory,
+ // but was fast. nonetheless, since
+ // the memory consumption was
+ // quadratic in the number of
+ // degrees of freedom, this was not
+ // very practical, so we now use a
+ // vector of rows of the matrix,
+ // and in each row a vector of
+ // pairs (colnum,value). this seems
+ // like the best tradeoff between
+ // memory and speed, as it is now
+ // linear in memory and still fast
+ // enough.
+ //
+ // to save some memory and since
+ // the weights are usually
+ // (negative) powers of 2, we
+ // choose the value type of the
+ // matrix to be @p{float} rather
+ // than @p{double}.
std::vector<std::map<unsigned int, float> > weights;
- // this is this mapping. there is one
- // entry for each dof on the fine grid;
- // if it is a parameter dof, then its
- // value is the column in weights for
- // that parameter dof, if it is any
- // other dof, then its value is -1,
- // indicating an error
+ // this is this mapping. there is one
+ // entry for each dof on the fine grid;
+ // if it is a parameter dof, then its
+ // value is the column in weights for
+ // that parameter dof, if it is any
+ // other dof, then its value is -1,
+ // indicating an error
std::vector<int> weight_mapping;
internal::compute_intergrid_weights_1 (coarse_grid, coarse_component,
- fine_grid, fine_component,
- coarse_to_fine_grid_map,
- weights, weight_mapping);
+ fine_grid, fine_component,
+ coarse_to_fine_grid_map,
+ weights, weight_mapping);
- // now compute the requested
- // representation
+ // now compute the requested
+ // representation
const unsigned int n_global_parm_dofs
= std::count_if (weight_mapping.begin(), weight_mapping.end(),
- std::bind2nd (std::not_equal_to<int> (), -1));
+ std::bind2nd (std::not_equal_to<int> (), -1));
- // first construct the inverse
- // mapping of weight_mapping
+ // first construct the inverse
+ // mapping of weight_mapping
std::vector<unsigned int> inverse_weight_mapping (n_global_parm_dofs,
- DoFHandler<dim,spacedim>::invalid_dof_index);
+ DoFHandler<dim,spacedim>::invalid_dof_index);
for (unsigned int i=0; i<weight_mapping.size(); ++i)
{
- const unsigned int parameter_dof = weight_mapping[i];
- // if this global dof is a
- // parameter
- if (parameter_dof != numbers::invalid_unsigned_int)
- {
- Assert (parameter_dof < n_global_parm_dofs, ExcInternalError());
- Assert ((inverse_weight_mapping[parameter_dof] == DoFHandler<dim,spacedim>::invalid_dof_index),
- ExcInternalError());
-
- inverse_weight_mapping[parameter_dof] = i;
- };
+ const unsigned int parameter_dof = weight_mapping[i];
+ // if this global dof is a
+ // parameter
+ if (parameter_dof != numbers::invalid_unsigned_int)
+ {
+ Assert (parameter_dof < n_global_parm_dofs, ExcInternalError());
+ Assert ((inverse_weight_mapping[parameter_dof] == DoFHandler<dim,spacedim>::invalid_dof_index),
+ ExcInternalError());
+
+ inverse_weight_mapping[parameter_dof] = i;
+ };
};
- // next copy over weights array
- // and replace respective
- // numbers
+ // next copy over weights array
+ // and replace respective
+ // numbers
const unsigned int n_rows = weight_mapping.size();
transfer_representation.clear ();
const unsigned int n_coarse_dofs = coarse_grid.n_dofs();
for (unsigned int i=0; i<n_coarse_dofs; ++i)
{
- std::map<unsigned int, float>::const_iterator j = weights[i].begin();
- for (; j!=weights[i].end(); ++j)
- {
- const unsigned int p = inverse_weight_mapping[j->first];
- Assert (p<n_rows, ExcInternalError());
-
- transfer_representation[p][i] = j->second;
- };
+ std::map<unsigned int, float>::const_iterator j = weights[i].begin();
+ for (; j!=weights[i].end(); ++j)
+ {
+ const unsigned int p = inverse_weight_mapping[j->first];
+ Assert (p<n_rows, ExcInternalError());
+
+ transfer_representation[p][i] = j->second;
+ };
};
}
template <class DH>
void
map_dof_to_boundary_indices (const DH &dof_handler,
- std::vector<unsigned int> &mapping)
+ std::vector<unsigned int> &mapping)
{
Assert (&dof_handler.get_fe() != 0, ExcNoFESelected());
mapping.clear ();
mapping.insert (mapping.end(), dof_handler.n_dofs(),
- DH::invalid_dof_index);
+ DH::invalid_dof_index);
std::vector<unsigned int> dofs_on_face;
dofs_on_face.reserve (max_dofs_per_face(dof_handler));
unsigned int next_boundary_index = 0;
- // now loop over all cells and
- // check whether their faces are at
- // the boundary. note that we need
- // not take special care of single
- // lines being at the boundary
- // (using
- // @p{cell->has_boundary_lines}),
- // since we do not support
- // boundaries of dimension dim-2,
- // and so every isolated boundary
- // line is also part of a boundary
- // face which we will be visiting
- // sooner or later
+ // now loop over all cells and
+ // check whether their faces are at
+ // the boundary. note that we need
+ // not take special care of single
+ // lines being at the boundary
+ // (using
+ // @p{cell->has_boundary_lines}),
+ // since we do not support
+ // boundaries of dimension dim-2,
+ // and so every isolated boundary
+ // line is also part of a boundary
+ // face which we will be visiting
+ // sooner or later
typename DH::active_cell_iterator cell = dof_handler.begin_active(),
- endc = dof_handler.end();
+ endc = dof_handler.end();
for (; cell!=endc; ++cell)
for (unsigned int f=0; f<GeometryInfo<DH::dimension>::faces_per_cell; ++f)
- if (cell->at_boundary(f))
- {
- const unsigned int dofs_per_face = cell->get_fe().dofs_per_face;
- dofs_on_face.resize (dofs_per_face);
- cell->face(f)->get_dof_indices (dofs_on_face,
- cell->active_fe_index());
- for (unsigned int i=0; i<dofs_per_face; ++i)
- if (mapping[dofs_on_face[i]] == DH::invalid_dof_index)
- mapping[dofs_on_face[i]] = next_boundary_index++;
- }
+ if (cell->at_boundary(f))
+ {
+ const unsigned int dofs_per_face = cell->get_fe().dofs_per_face;
+ dofs_on_face.resize (dofs_per_face);
+ cell->face(f)->get_dof_indices (dofs_on_face,
+ cell->active_fe_index());
+ for (unsigned int i=0; i<dofs_per_face; ++i)
+ if (mapping[dofs_on_face[i]] == DH::invalid_dof_index)
+ mapping[dofs_on_face[i]] = next_boundary_index++;
+ }
AssertDimension (next_boundary_index, dof_handler.n_boundary_dofs());
}
{
Assert (&dof_handler.get_fe() != 0, ExcNoFESelected());
Assert (boundary_indicators.find (types::internal_face_boundary_id) == boundary_indicators.end(),
- ExcInvalidBoundaryIndicator());
+ ExcInvalidBoundaryIndicator());
mapping.clear ();
mapping.insert (mapping.end(), dof_handler.n_dofs(),
- DH::invalid_dof_index);
+ DH::invalid_dof_index);
- // return if there is nothing to do
+ // return if there is nothing to do
if (boundary_indicators.size() == 0)
return;
unsigned int next_boundary_index = 0;
typename DH::active_cell_iterator cell = dof_handler.begin_active(),
- endc = dof_handler.end();
+ endc = dof_handler.end();
for (; cell!=endc; ++cell)
for (unsigned int f=0; f<GeometryInfo<DH::dimension>::faces_per_cell; ++f)
- if (boundary_indicators.find (cell->face(f)->boundary_indicator()) !=
- boundary_indicators.end())
- {
- const unsigned int dofs_per_face = cell->get_fe().dofs_per_face;
- dofs_on_face.resize (dofs_per_face);
- cell->face(f)->get_dof_indices (dofs_on_face, cell->active_fe_index());
- for (unsigned int i=0; i<dofs_per_face; ++i)
- if (mapping[dofs_on_face[i]] == DH::invalid_dof_index)
- mapping[dofs_on_face[i]] = next_boundary_index++;
- }
+ if (boundary_indicators.find (cell->face(f)->boundary_indicator()) !=
+ boundary_indicators.end())
+ {
+ const unsigned int dofs_per_face = cell->get_fe().dofs_per_face;
+ dofs_on_face.resize (dofs_per_face);
+ cell->face(f)->get_dof_indices (dofs_on_face, cell->active_fe_index());
+ for (unsigned int i=0; i<dofs_per_face; ++i)
+ if (mapping[dofs_on_face[i]] == DH::invalid_dof_index)
+ mapping[dofs_on_face[i]] = next_boundary_index++;
+ }
AssertDimension (next_boundary_index,
- dof_handler.n_boundary_dofs (boundary_indicators));
+ dof_handler.n_boundary_dofs (boundary_indicators));
}
namespace internal
for (unsigned int i=0;i<fe.n_components();++i)
{
- const unsigned int ib = fe.component_to_block_index(i);
- for (unsigned int j=0;j<fe.n_components();++j)
- {
- const unsigned int jb = fe.component_to_block_index(j);
- tables_by_block[0](ib,jb) |= table(i,j);
- }
+ const unsigned int ib = fe.component_to_block_index(i);
+ for (unsigned int j=0;j<fe.n_components();++j)
+ {
+ const unsigned int jb = fe.component_to_block_index(j);
+ tables_by_block[0](ib,jb) |= table(i,j);
+ }
}
}
for (unsigned int f=0;f<fe_collection.size();++f)
{
- const FiniteElement<dim,spacedim>& fe = fe_collection[f];
-
- const unsigned int nb = fe.n_blocks();
- tables_by_block[f].reinit(nb, nb);
- tables_by_block[f].fill(none);
- for (unsigned int i=0;i<fe.n_components();++i)
- {
- const unsigned int ib = fe.component_to_block_index(i);
- for (unsigned int j=0;j<fe.n_components();++j)
- {
- const unsigned int jb = fe.component_to_block_index(j);
- tables_by_block[f](ib,jb) |= table(i,j);
- }
- }
+ const FiniteElement<dim,spacedim>& fe = fe_collection[f];
+
+ const unsigned int nb = fe.n_blocks();
+ tables_by_block[f].reinit(nb, nb);
+ tables_by_block[f].fill(none);
+ for (unsigned int i=0;i<fe.n_components();++i)
+ {
+ const unsigned int ib = fe.component_to_block_index(i);
+ for (unsigned int j=0;j<fe.n_components();++j)
+ {
+ const unsigned int jb = fe.component_to_block_index(j);
+ tables_by_block[f](ib,jb) |= table(i,j);
+ }
+ }
}
}
template <int dim, int spacedim, template <int,int> class DH>
void
make_zero_boundary_constraints (const DH<dim, spacedim> &dof,
- ConstraintMatrix &zero_boundary_constraints,
- const std::vector<bool> &component_mask_)
+ ConstraintMatrix &zero_boundary_constraints,
+ const std::vector<bool> &component_mask_)
{
Assert ((component_mask_.size() == 0) ||
- (component_mask_.size() == dof.get_fe().n_components()),
- ExcMessage ("The number of components in the mask has to be either "
- "zero or equal to the number of components in the finite "
- "element."));
+ (component_mask_.size() == dof.get_fe().n_components()),
+ ExcMessage ("The number of components in the mask has to be either "
+ "zero or equal to the number of components in the finite "
+ "element."));
const unsigned int n_components = DoFTools::n_components (dof);
- // set the component mask to either
- // the original value or a vector
- // of trues
+ // set the component mask to either
+ // the original value or a vector
+ // of trues
const std::vector<bool> component_mask ((component_mask_.size() == 0) ?
- std::vector<bool> (n_components, true) :
- component_mask_);
+ std::vector<bool> (n_components, true) :
+ component_mask_);
Assert (std::count(component_mask.begin(), component_mask.end(), true) > 0,
- VectorTools::ExcNoComponentSelected());
+ VectorTools::ExcNoComponentSelected());
- // a field to store the indices
+ // a field to store the indices
std::vector<unsigned int> face_dofs;
face_dofs.reserve (max_dofs_per_face(dof));
endc = dof.end();
for (; cell!=endc; ++cell)
for (unsigned int face_no = 0; face_no < GeometryInfo<dim>::faces_per_cell;
- ++face_no)
- {
- const FiniteElement<dim,spacedim> &fe = cell->get_fe();
-
- typename DH<dim,spacedim>::face_iterator face = cell->face(face_no);
-
- // if face is on the boundary
- if (face->at_boundary ())
- {
- // get indices and physical
- // location on this face
- face_dofs.resize (fe.dofs_per_face);
- face->get_dof_indices (face_dofs, cell->active_fe_index());
-
- // enter those dofs into the list
- // that match the component
- // signature.
- for (unsigned int i=0; i<face_dofs.size(); ++i)
- {
- // Find out if a dof
- // has a contribution
- // in this component,
- // and if so, add it
- // to the list
- const std::vector<bool> &nonzero_component_array
- = cell->get_fe().get_nonzero_components (i);
- bool nonzero = false;
- for (unsigned int c=0; c<n_components; ++c)
- if (nonzero_component_array[c] && component_mask[c])
- {
- nonzero = true;
- break;
- }
-
- if (nonzero)
- zero_boundary_constraints.add_line (face_dofs[i]);
- }
- }
- }
+ ++face_no)
+ {
+ const FiniteElement<dim,spacedim> &fe = cell->get_fe();
+
+ typename DH<dim,spacedim>::face_iterator face = cell->face(face_no);
+
+ // if face is on the boundary
+ if (face->at_boundary ())
+ {
+ // get indices and physical
+ // location on this face
+ face_dofs.resize (fe.dofs_per_face);
+ face->get_dof_indices (face_dofs, cell->active_fe_index());
+
+ // enter those dofs into the list
+ // that match the component
+ // signature.
+ for (unsigned int i=0; i<face_dofs.size(); ++i)
+ {
+ // Find out if a dof
+ // has a contribution
+ // in this component,
+ // and if so, add it
+ // to the list
+ const std::vector<bool> &nonzero_component_array
+ = cell->get_fe().get_nonzero_components (i);
+ bool nonzero = false;
+ for (unsigned int c=0; c<n_components; ++c)
+ if (nonzero_component_array[c] && component_mask[c])
+ {
+ nonzero = true;
+ break;
+ }
+
+ if (nonzero)
+ zero_boundary_constraints.add_line (face_dofs[i]);
+ }
+ }
+ }
}
template <class DH, class Sparsity>
void make_cell_patches(
- Sparsity& block_list,
- const DH& dof_handler,
- const unsigned int level,
- const std::vector<bool>& selected_dofs,
+ Sparsity& block_list,
+ const DH& dof_handler,
+ const unsigned int level,
+ const std::vector<bool>& selected_dofs,
unsigned int offset)
{
typename DH::cell_iterator cell;
unsigned int i=0;
for (cell=dof_handler.begin(level); cell != endc; ++i, ++cell)
{
- indices.resize(cell->get_fe().dofs_per_cell);
- cell->get_mg_dof_indices(indices);
+ indices.resize(cell->get_fe().dofs_per_cell);
+ cell->get_mg_dof_indices(indices);
if(selected_dofs.size()!=0)
AssertDimension(indices.size(), selected_dofs.size());
-
+
for (unsigned int j=0;j<indices.size();++j)
{
if(selected_dofs.size() == 0)
for (cell=dof_handler.begin(level); cell != endc;++cell)
{
- indices.resize(cell->get_fe().dofs_per_cell);
- cell->get_mg_dof_indices(indices);
-
- if (interior_only)
- {
- // Exclude degrees of
- // freedom on faces
- // opposite to the vertex
- exclude.resize(fe.dofs_per_cell);
- std::fill(exclude.begin(), exclude.end(), false);
- const unsigned int dpf = fe.dofs_per_face;
-
- for (unsigned int face=0;face<GeometryInfo<DH::dimension>::faces_per_cell;++face)
- if (cell->at_boundary(face) || cell->neighbor(face)->level() != cell->level())
- for (unsigned int i=0;i<dpf;++i)
- exclude[fe.face_to_cell_index(i,face)] = true;
- for (unsigned int j=0;j<indices.size();++j)
- if (!exclude[j])
- block_list.add(0, indices[j]);
- }
- else
- {
- for (unsigned int j=0;j<indices.size();++j)
- block_list.add(0, indices[j]);
- }
+ indices.resize(cell->get_fe().dofs_per_cell);
+ cell->get_mg_dof_indices(indices);
+
+ if (interior_only)
+ {
+ // Exclude degrees of
+ // freedom on faces
+ // opposite to the vertex
+ exclude.resize(fe.dofs_per_cell);
+ std::fill(exclude.begin(), exclude.end(), false);
+ const unsigned int dpf = fe.dofs_per_face;
+
+ for (unsigned int face=0;face<GeometryInfo<DH::dimension>::faces_per_cell;++face)
+ if (cell->at_boundary(face) || cell->neighbor(face)->level() != cell->level())
+ for (unsigned int i=0;i<dpf;++i)
+ exclude[fe.face_to_cell_index(i,face)] = true;
+ for (unsigned int j=0;j<indices.size();++j)
+ if (!exclude[j])
+ block_list.add(0, indices[j]);
+ }
+ else
+ {
+ for (unsigned int j=0;j<indices.size();++j)
+ block_list.add(0, indices[j]);
+ }
}
}
const bool boundary_dofs)
{
Assert(level > 0 && level < dof_handler.get_tria().n_levels(),
- ExcIndexRange(level, 1, dof_handler.get_tria().n_levels()));
+ ExcIndexRange(level, 1, dof_handler.get_tria().n_levels()));
typename DH::cell_iterator cell;
typename DH::cell_iterator pcell = dof_handler.begin(level-1);
for (unsigned int block = 0;pcell != endc;++pcell)
{
- if (!pcell->has_children()) continue;
- for (unsigned int child=0;child<pcell->n_children();++child)
- {
- cell = pcell->child(child);
- // For hp, only this line
- // here would have to be
- // replaced.
- const FiniteElement<DH::dimension>& fe = dof_handler.get_fe();
- const unsigned int n_dofs = fe.dofs_per_cell;
- indices.resize(n_dofs);
- exclude.resize(n_dofs);
- std::fill(exclude.begin(), exclude.end(), false);
- cell->get_mg_dof_indices(indices);
-
- if (interior_dofs_only)
- {
- // Eliminate dofs on
- // faces of the child
- // which are on faces
- // of the parent
- const unsigned int dpf = fe.dofs_per_face;
-
- for (unsigned int d=0;d<DH::dimension;++d)
- {
- const unsigned int face = GeometryInfo<DH::dimension>::vertex_to_face[child][d];
- for (unsigned int i=0;i<dpf;++i)
- exclude[fe.face_to_cell_index(i,face)] = true;
- }
- // Now remove all
- // degrees of freedom
- // on the domain
- // boundary from the
- // exclusion list
- if (boundary_dofs)
- for (unsigned int face=0;face< GeometryInfo<DH::dimension>::faces_per_cell;++face)
- if (cell->at_boundary(face))
- for (unsigned int i=0;i<dpf;++i)
- exclude[fe.face_to_cell_index(i,face)] = false;
- }
-
- for (unsigned int i=0;i<n_dofs;++i)
- if (!exclude[i])
- block_list.add(block, indices[i]);
- }
- ++block;
+ if (!pcell->has_children()) continue;
+ for (unsigned int child=0;child<pcell->n_children();++child)
+ {
+ cell = pcell->child(child);
+ // For hp, only this line
+ // here would have to be
+ // replaced.
+ const FiniteElement<DH::dimension>& fe = dof_handler.get_fe();
+ const unsigned int n_dofs = fe.dofs_per_cell;
+ indices.resize(n_dofs);
+ exclude.resize(n_dofs);
+ std::fill(exclude.begin(), exclude.end(), false);
+ cell->get_mg_dof_indices(indices);
+
+ if (interior_dofs_only)
+ {
+ // Eliminate dofs on
+ // faces of the child
+ // which are on faces
+ // of the parent
+ const unsigned int dpf = fe.dofs_per_face;
+
+ for (unsigned int d=0;d<DH::dimension;++d)
+ {
+ const unsigned int face = GeometryInfo<DH::dimension>::vertex_to_face[child][d];
+ for (unsigned int i=0;i<dpf;++i)
+ exclude[fe.face_to_cell_index(i,face)] = true;
+ }
+ // Now remove all
+ // degrees of freedom
+ // on the domain
+ // boundary from the
+ // exclusion list
+ if (boundary_dofs)
+ for (unsigned int face=0;face< GeometryInfo<DH::dimension>::faces_per_cell;++face)
+ if (cell->at_boundary(face))
+ for (unsigned int i=0;i<dpf;++i)
+ exclude[fe.face_to_cell_index(i,face)] = false;
+ }
+
+ for (unsigned int i=0;i<n_dofs;++i)
+ if (!exclude[i])
+ block_list.add(block, indices[i]);
+ }
+ ++block;
}
}
typename DH::cell_iterator cell;
typename DH::cell_iterator endc = dof_handler.end(level);
- // Vector mapping from vertex
- // index in the triangulation to
- // consecutive block indices on
- // this level
- // The number of cells at a vertex
+ // Vector mapping from vertex
+ // index in the triangulation to
+ // consecutive block indices on
+ // this level
+ // The number of cells at a vertex
std::vector<unsigned int> vertex_cell_count(dof_handler.get_tria().n_vertices(), 0);
- // Is a vertex at the boundary?
+ // Is a vertex at the boundary?
std::vector<bool> vertex_boundary(dof_handler.get_tria().n_vertices(), false);
std::vector<unsigned int> vertex_mapping(dof_handler.get_tria().n_vertices(),
- numbers::invalid_unsigned_int);
- // Estimate for the number of
- // dofs at this point
+ numbers::invalid_unsigned_int);
+ // Estimate for the number of
+ // dofs at this point
std::vector<unsigned int> vertex_dof_count(dof_handler.get_tria().n_vertices(), 0);
- // Identify all vertices active
- // on this level and remember
- // some data about them
+ // Identify all vertices active
+ // on this level and remember
+ // some data about them
for (cell=dof_handler.begin(level); cell != endc; ++cell)
for (unsigned int v=0;v<GeometryInfo<DH::dimension>::vertices_per_cell;++v)
- {
- const unsigned int vg = cell->vertex_index(v);
- vertex_dof_count[vg] += cell->get_fe().dofs_per_cell;
- ++vertex_cell_count[vg];
- for (unsigned int d=0;d<DH::dimension;++d)
- {
- const unsigned int face = GeometryInfo<DH::dimension>::vertex_to_face[v][d];
- if (cell->at_boundary(face))
- vertex_boundary[vg] = true;
- else
- if ((!level_boundary_patches)
- && (cell->neighbor(face)->level() != (int) level))
- vertex_boundary[vg] = true;
- }
- }
- // From now on, only vertices
- // with positive dof count are
- // "in".
-
- // Remove vertices at boundaries
- // or in corners
+ {
+ const unsigned int vg = cell->vertex_index(v);
+ vertex_dof_count[vg] += cell->get_fe().dofs_per_cell;
+ ++vertex_cell_count[vg];
+ for (unsigned int d=0;d<DH::dimension;++d)
+ {
+ const unsigned int face = GeometryInfo<DH::dimension>::vertex_to_face[v][d];
+ if (cell->at_boundary(face))
+ vertex_boundary[vg] = true;
+ else
+ if ((!level_boundary_patches)
+ && (cell->neighbor(face)->level() != (int) level))
+ vertex_boundary[vg] = true;
+ }
+ }
+ // From now on, only vertices
+ // with positive dof count are
+ // "in".
+
+ // Remove vertices at boundaries
+ // or in corners
for (unsigned int vg=0;vg<vertex_dof_count.size();++vg)
if ((!single_cell_patches && vertex_cell_count[vg] < 2)
- ||
- (!boundary_patches && vertex_boundary[vg]))
- vertex_dof_count[vg] = 0;
+ ||
+ (!boundary_patches && vertex_boundary[vg]))
+ vertex_dof_count[vg] = 0;
- // Create a mapping from all
- // vertices to the ones used here
+ // Create a mapping from all
+ // vertices to the ones used here
unsigned int i=0;
for (unsigned int vg=0;vg<vertex_mapping.size();++vg)
if (vertex_dof_count[vg] != 0)
- vertex_mapping[vg] = i++;
+ vertex_mapping[vg] = i++;
- // Compactify dof count
+ // Compactify dof count
for (unsigned int vg=0;vg<vertex_mapping.size();++vg)
if (vertex_dof_count[vg] != 0)
- vertex_dof_count[vertex_mapping[vg]] = vertex_dof_count[vg];
+ vertex_dof_count[vertex_mapping[vg]] = vertex_dof_count[vg];
- // Now that we have all the data,
- // we reduce it to the part we
- // actually want
+ // Now that we have all the data,
+ // we reduce it to the part we
+ // actually want
vertex_dof_count.resize(i);
- // At this point, the list of
- // patches is ready. Now we enter
- // the dofs into the sparsity
- // pattern.
+ // At this point, the list of
+ // patches is ready. Now we enter
+ // the dofs into the sparsity
+ // pattern.
block_list.reinit(vertex_dof_count.size(), dof_handler.n_dofs(level), vertex_dof_count);
-
+
std::vector<unsigned int> indices;
std::vector<bool> exclude;
for (cell=dof_handler.begin(level); cell != endc; ++cell)
{
- const FiniteElement<DH::dimension>& fe = cell->get_fe();
- indices.resize(fe.dofs_per_cell);
- cell->get_mg_dof_indices(indices);
-
- for (unsigned int v=0;v<GeometryInfo<DH::dimension>::vertices_per_cell;++v)
- {
- const unsigned int vg = cell->vertex_index(v);
- const unsigned int block = vertex_mapping[vg];
- if (block == numbers::invalid_unsigned_int)
- continue;
-
- if (interior_only)
- {
- // Exclude degrees of
- // freedom on faces
- // opposite to the vertex
- exclude.resize(fe.dofs_per_cell);
- std::fill(exclude.begin(), exclude.end(), false);
- const unsigned int dpf = fe.dofs_per_face;
-
- for (unsigned int d=0;d<DH::dimension;++d)
- {
- const unsigned int a_face = GeometryInfo<DH::dimension>::vertex_to_face[v][d];
- const unsigned int face = GeometryInfo<DH::dimension>::opposite_face[a_face];
- for (unsigned int i=0;i<dpf;++i)
- exclude[fe.face_to_cell_index(i,face)] = true;
- }
- for (unsigned int j=0;j<indices.size();++j)
- if (!exclude[j])
- block_list.add(block, indices[j]);
- }
- else
- {
- for (unsigned int j=0;j<indices.size();++j)
- block_list.add(block, indices[j]);
- }
- }
+ const FiniteElement<DH::dimension>& fe = cell->get_fe();
+ indices.resize(fe.dofs_per_cell);
+ cell->get_mg_dof_indices(indices);
+
+ for (unsigned int v=0;v<GeometryInfo<DH::dimension>::vertices_per_cell;++v)
+ {
+ const unsigned int vg = cell->vertex_index(v);
+ const unsigned int block = vertex_mapping[vg];
+ if (block == numbers::invalid_unsigned_int)
+ continue;
+
+ if (interior_only)
+ {
+ // Exclude degrees of
+ // freedom on faces
+ // opposite to the vertex
+ exclude.resize(fe.dofs_per_cell);
+ std::fill(exclude.begin(), exclude.end(), false);
+ const unsigned int dpf = fe.dofs_per_face;
+
+ for (unsigned int d=0;d<DH::dimension;++d)
+ {
+ const unsigned int a_face = GeometryInfo<DH::dimension>::vertex_to_face[v][d];
+ const unsigned int face = GeometryInfo<DH::dimension>::opposite_face[a_face];
+ for (unsigned int i=0;i<dpf;++i)
+ exclude[fe.face_to_cell_index(i,face)] = true;
+ }
+ for (unsigned int j=0;j<indices.size();++j)
+ if (!exclude[j])
+ block_list.add(block, indices[j]);
+ }
+ else
+ {
+ for (unsigned int j=0;j<indices.size();++j)
+ block_list.add(block, indices[j]);
+ }
+ }
}
}
}
// $Id$
// Version: $Name$
//
-// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 by the deal.II authors
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
namespace DoFHandler
{
NumberCache::NumberCache ()
- :
- n_global_dofs (0),
- n_locally_owned_dofs (0)
+ :
+ n_global_dofs (0),
+ n_locally_owned_dofs (0)
{}
NumberCache::memory_consumption () const
{
return
- MemoryConsumption::memory_consumption (n_global_dofs) +
- MemoryConsumption::memory_consumption (n_locally_owned_dofs) +
- MemoryConsumption::memory_consumption (locally_owned_dofs) +
- MemoryConsumption::memory_consumption (n_locally_owned_dofs_per_processor) +
- MemoryConsumption::memory_consumption (locally_owned_dofs_per_processor);
+ MemoryConsumption::memory_consumption (n_global_dofs) +
+ MemoryConsumption::memory_consumption (n_locally_owned_dofs) +
+ MemoryConsumption::memory_consumption (locally_owned_dofs) +
+ MemoryConsumption::memory_consumption (n_locally_owned_dofs_per_processor) +
+ MemoryConsumption::memory_consumption (locally_owned_dofs_per_processor);
}
}
}
// $Id$
// Version: $Name$
//
-// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 by the deal.II authors
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
void
FiniteElement<dim,spacedim>::
InternalDataBase::initialize_2nd (const FiniteElement<dim,spacedim> *element,
- const Mapping<dim,spacedim> &mapping,
- const Quadrature<dim> &quadrature)
+ const Mapping<dim,spacedim> &mapping,
+ const Quadrature<dim> &quadrature)
{
- // if we shall compute second
- // derivatives, then we do so by
- // finite differencing the
- // gradients. that we do by
- // evaluating the gradients of
- // shape values at points shifted
- // star-like a little in each
- // coordinate direction around each
- // quadrature point.
- //
- // therefore generate 2*dim (the
- // number of evaluation points)
- // FEValues objects with slightly
- // shifted positions
+ // if we shall compute second
+ // derivatives, then we do so by
+ // finite differencing the
+ // gradients. that we do by
+ // evaluating the gradients of
+ // shape values at points shifted
+ // star-like a little in each
+ // coordinate direction around each
+ // quadrature point.
+ //
+ // therefore generate 2*dim (the
+ // number of evaluation points)
+ // FEValues objects with slightly
+ // shifted positions
std::vector<Point<dim> > diff_points (quadrature.size());
differences.resize(2*dim);
Point<dim> shift;
shift (d) = fd_step_length;
- // generate points and FEValues
- // objects shifted in
- // plus-direction. note that
- // they only need to compute
- // gradients, not more
+ // generate points and FEValues
+ // objects shifted in
+ // plus-direction. note that
+ // they only need to compute
+ // gradients, not more
for (unsigned int i=0; i<diff_points.size(); ++i)
- diff_points[i] = quadrature.point(i) + shift;
+ diff_points[i] = quadrature.point(i) + shift;
const Quadrature<dim> plus_quad (diff_points, quadrature.get_weights());
differences[d] = new FEValues<dim,spacedim> (mapping, *element,
- plus_quad, update_gradients);
+ plus_quad, update_gradients);
- // now same in minus-direction
+ // now same in minus-direction
for (unsigned int i=0; i<diff_points.size(); ++i)
- diff_points[i] = quadrature.point(i) - shift;
+ diff_points[i] = quadrature.point(i) - shift;
const Quadrature<dim> minus_quad (diff_points, quadrature.get_weights());
differences[d+dim] = new FEValues<dim,spacedim> (mapping, *element,
- minus_quad, update_gradients);
+ minus_quad, update_gradients);
}
}
for (unsigned int i=0; i<differences.size (); ++i)
if (differences[i] != 0)
{
- // delete pointer and set it
- // to zero to avoid
- // inadvertant use
- delete differences[i];
- differences[i] = 0;
+ // delete pointer and set it
+ // to zero to avoid
+ // inadvertant use
+ delete differences[i];
+ differences[i] = 0;
};
}
const FiniteElementData<dim> &fe_data,
const std::vector<bool> &r_i_a_f,
const std::vector<std::vector<bool> > &nonzero_c)
- :
- FiniteElementData<dim> (fe_data),
- adjust_quad_dof_index_for_face_orientation_table (dim == 3 ?
- this->dofs_per_quad : 0 ,
- dim==3 ? 8 : 0),
- adjust_line_dof_index_for_line_orientation_table (dim == 3 ?
- this->dofs_per_line : 0),
+ :
+ FiniteElementData<dim> (fe_data),
+ adjust_quad_dof_index_for_face_orientation_table (dim == 3 ?
+ this->dofs_per_quad : 0 ,
+ dim==3 ? 8 : 0),
+ adjust_line_dof_index_for_line_orientation_table (dim == 3 ?
+ this->dofs_per_line : 0),
system_to_base_table(this->dofs_per_cell),
face_system_to_base_table(this->dofs_per_face),
component_to_base_table (this->components,
std::make_pair(std::make_pair(0U, 0U), 0U)),
restriction_is_additive_flags(r_i_a_f),
- nonzero_components (nonzero_c)
+ nonzero_components (nonzero_c)
{
- // Special handling of vectors of
- // length one: in this case, we
- // assume that all entries were
- // supposed to be equal.
-
- // Normally, we should be careful
- // with const_cast, but since this
- // is the constructor and we do it
- // here only, we are fine.
+ // Special handling of vectors of
+ // length one: in this case, we
+ // assume that all entries were
+ // supposed to be equal.
+
+ // Normally, we should be careful
+ // with const_cast, but since this
+ // is the constructor and we do it
+ // here only, we are fine.
unsigned int ndofs = this->dofs_per_cell;
if (restriction_is_additive_flags.size() == 1 && ndofs > 1)
{
std::vector<bool>& aux
- = const_cast<std::vector<bool>&> (restriction_is_additive_flags);
+ = const_cast<std::vector<bool>&> (restriction_is_additive_flags);
aux.resize(ndofs, restriction_is_additive_flags[0]);
}
if (nonzero_components.size() == 1 && ndofs > 1)
{
std::vector<std::vector<bool> >& aux
- = const_cast<std::vector<std::vector<bool> >&> (nonzero_components);
+ = const_cast<std::vector<std::vector<bool> >&> (nonzero_components);
aux.resize(ndofs, nonzero_components[0]);
}
- // These used to be initialized in
- // the constructor, but here we
- // have the possibly corrected
- // nonzero_components vector.
+ // These used to be initialized in
+ // the constructor, but here we
+ // have the possibly corrected
+ // nonzero_components vector.
const_cast<std::vector<unsigned int>&>
(n_nonzero_components_table) = compute_n_nonzero_components(nonzero_components);
this->set_primitivity(std::find_if (n_nonzero_components_table.begin(),
- n_nonzero_components_table.end(),
- std::bind2nd(std::not_equal_to<unsigned int>(),
- 1U))
- == n_nonzero_components_table.end());
+ n_nonzero_components_table.end(),
+ std::bind2nd(std::not_equal_to<unsigned int>(),
+ 1U))
+ == n_nonzero_components_table.end());
Assert (restriction_is_additive_flags.size() == this->dofs_per_cell,
- ExcDimensionMismatch(restriction_is_additive_flags.size(),
- this->dofs_per_cell));
+ ExcDimensionMismatch(restriction_is_additive_flags.size(),
+ this->dofs_per_cell));
AssertDimension (nonzero_components.size(), this->dofs_per_cell);
for (unsigned int i=0; i<nonzero_components.size(); ++i)
{
Assert (nonzero_components[i].size() == this->n_components(),
- ExcInternalError());
+ ExcInternalError());
Assert (std::count (nonzero_components[i].begin(),
- nonzero_components[i].end(),
- true)
- >= 1,
- ExcInternalError());
+ nonzero_components[i].end(),
+ true)
+ >= 1,
+ ExcInternalError());
Assert (n_nonzero_components_table[i] >= 1,
- ExcInternalError());
+ ExcInternalError());
Assert (n_nonzero_components_table[i] <= this->n_components(),
- ExcInternalError());
+ ExcInternalError());
};
// initialize some tables in the
- // default way, i.e. if there is
- // only one (vector-)component; if
- // the element is not primitive,
- // leave these tables empty.
+ // default way, i.e. if there is
+ // only one (vector-)component; if
+ // the element is not primitive,
+ // leave these tables empty.
if (this->is_primitive())
{
system_to_component_table.resize(this->dofs_per_cell);
face_system_to_component_table.resize(this->dofs_per_face);
for (unsigned int j=0 ; j<this->dofs_per_cell ; ++j)
- {
- system_to_component_table[j] = std::pair<unsigned,unsigned>(0,j);
- system_to_base_table[j] = std::make_pair(std::make_pair(0U,0U),j);
- }
+ {
+ system_to_component_table[j] = std::pair<unsigned,unsigned>(0,j);
+ system_to_base_table[j] = std::make_pair(std::make_pair(0U,0U),j);
+ }
for (unsigned int j=0 ; j<this->dofs_per_face ; ++j)
- {
- face_system_to_component_table[j] = std::pair<unsigned,unsigned>(0,j);
- face_system_to_base_table[j] = std::make_pair(std::make_pair(0U,0U),j);
- }
+ {
+ face_system_to_component_table[j] = std::pair<unsigned,unsigned>(0,j);
+ face_system_to_base_table[j] = std::make_pair(std::make_pair(0U,0U),j);
+ }
}
- // Fill with default value; may be
- // changed by constructor of
- // derived class.
+ // Fill with default value; may be
+ // changed by constructor of
+ // derived class.
base_to_block_indices.reinit(1,1);
- // initialize the restriction and
- // prolongation matrices. the default
- // contructur of FullMatrix<dim> initializes
- // them with size zero
+ // initialize the restriction and
+ // prolongation matrices. the default
+ // contructur of FullMatrix<dim> initializes
+ // them with size zero
prolongation.resize(RefinementCase<dim>::isotropic_refinement);
restriction.resize(RefinementCase<dim>::isotropic_refinement);
for (unsigned int ref=RefinementCase<dim>::cut_x;
ref<RefinementCase<dim>::isotropic_refinement+1; ++ref)
{
prolongation[ref-1].resize (GeometryInfo<dim>::
- n_children(RefinementCase<dim>(ref)),
- FullMatrix<double>());
+ n_children(RefinementCase<dim>(ref)),
+ FullMatrix<double>());
restriction[ref-1].resize (GeometryInfo<dim>::
- n_children(RefinementCase<dim>(ref)),
- FullMatrix<double>());
+ n_children(RefinementCase<dim>(ref)),
+ FullMatrix<double>());
}
adjust_quad_dof_index_for_face_orientation_table.fill(0);
template <int dim, int spacedim>
double
FiniteElement<dim,spacedim>::shape_value (const unsigned int,
- const Point<dim> &) const
+ const Point<dim> &) const
{
AssertThrow(false, ExcUnitShapeValuesDoNotExist());
return 0.;
template <int dim, int spacedim>
double
FiniteElement<dim,spacedim>::shape_value_component (const unsigned int,
- const Point<dim> &,
- const unsigned int) const
+ const Point<dim> &,
+ const unsigned int) const
{
AssertThrow(false, ExcUnitShapeValuesDoNotExist());
return 0.;
template <int dim, int spacedim>
Tensor<1,dim>
FiniteElement<dim,spacedim>::shape_grad (const unsigned int,
- const Point<dim> &) const
+ const Point<dim> &) const
{
AssertThrow(false, ExcUnitShapeValuesDoNotExist());
return Tensor<1,dim> ();
template <int dim, int spacedim>
Tensor<1,dim>
FiniteElement<dim,spacedim>::shape_grad_component (const unsigned int,
- const Point<dim> &,
- const unsigned int) const
+ const Point<dim> &,
+ const unsigned int) const
{
AssertThrow(false, ExcUnitShapeValuesDoNotExist());
return Tensor<1,dim> ();
template <int dim, int spacedim>
Tensor<2,dim>
FiniteElement<dim,spacedim>::shape_grad_grad (const unsigned int,
- const Point<dim> &) const
+ const Point<dim> &) const
{
AssertThrow(false, ExcUnitShapeValuesDoNotExist());
return Tensor<2,dim> ();
template <int dim, int spacedim>
Tensor<2,dim>
FiniteElement<dim,spacedim>::shape_grad_grad_component (const unsigned int,
- const Point<dim> &,
- const unsigned int) const
+ const Point<dim> &,
+ const unsigned int) const
{
AssertThrow(false, ExcUnitShapeValuesDoNotExist());
return Tensor<2,dim> ();
const unsigned int nc = GeometryInfo<dim>::n_children(RefinementCase<dim>(ref_case));
for (unsigned int i=0; i<nc; ++i)
- {
- if (!isotropic_restriction_only || ref_case==RefinementCase<dim>::isotropic_refinement)
- this->restriction[ref_case-1][i].reinit (this->dofs_per_cell,
- this->dofs_per_cell);
- if (!isotropic_prolongation_only || ref_case==RefinementCase<dim>::isotropic_refinement)
- this->prolongation[ref_case-1][i].reinit (this->dofs_per_cell,
- this->dofs_per_cell);
- }
+ {
+ if (!isotropic_restriction_only || ref_case==RefinementCase<dim>::isotropic_refinement)
+ this->restriction[ref_case-1][i].reinit (this->dofs_per_cell,
+ this->dofs_per_cell);
+ if (!isotropic_prolongation_only || ref_case==RefinementCase<dim>::isotropic_refinement)
+ this->prolongation[ref_case-1][i].reinit (this->dofs_per_cell,
+ this->dofs_per_cell);
+ }
}
}
template <int dim, int spacedim>
const FullMatrix<double> &
FiniteElement<dim,spacedim>::get_restriction_matrix (const unsigned int child,
- const RefinementCase<dim> &refinement_case) const
+ const RefinementCase<dim> &refinement_case) const
{
Assert (refinement_case<RefinementCase<dim>::isotropic_refinement+1,
- ExcIndexRange(refinement_case,0,RefinementCase<dim>::isotropic_refinement+1));
+ ExcIndexRange(refinement_case,0,RefinementCase<dim>::isotropic_refinement+1));
Assert (refinement_case!=RefinementCase<dim>::no_refinement,
- ExcMessage("Restriction matrices are only available for refined cells!"));
+ ExcMessage("Restriction matrices are only available for refined cells!"));
Assert (child<GeometryInfo<dim>::n_children(RefinementCase<dim>(refinement_case)),
- ExcIndexRange(child,0,GeometryInfo<dim>::n_children(RefinementCase<dim>(refinement_case))));
- // we use refinement_case-1 here. the -1 takes care
- // of the origin of the vector, as for
- // RefinementCase<dim>::no_refinement (=0) there is no
- // data available and so the vector indices
- // are shifted
+ ExcIndexRange(child,0,GeometryInfo<dim>::n_children(RefinementCase<dim>(refinement_case))));
+ // we use refinement_case-1 here. the -1 takes care
+ // of the origin of the vector, as for
+ // RefinementCase<dim>::no_refinement (=0) there is no
+ // data available and so the vector indices
+ // are shifted
Assert (restriction[refinement_case-1][child].n() == this->dofs_per_cell, ExcProjectionVoid());
return restriction[refinement_case-1][child];
}
template <int dim, int spacedim>
const FullMatrix<double> &
FiniteElement<dim,spacedim>::get_prolongation_matrix (const unsigned int child,
- const RefinementCase<dim> &refinement_case) const
+ const RefinementCase<dim> &refinement_case) const
{
Assert (refinement_case<RefinementCase<dim>::isotropic_refinement+1,
- ExcIndexRange(refinement_case,0,RefinementCase<dim>::isotropic_refinement+1));
+ ExcIndexRange(refinement_case,0,RefinementCase<dim>::isotropic_refinement+1));
Assert (refinement_case!=RefinementCase<dim>::no_refinement,
- ExcMessage("Prolongation matrices are only available for refined cells!"));
+ ExcMessage("Prolongation matrices are only available for refined cells!"));
Assert (child<GeometryInfo<dim>::n_children(RefinementCase<dim>(refinement_case)),
- ExcIndexRange(child,0,GeometryInfo<dim>::n_children(RefinementCase<dim>(refinement_case))));
- // we use refinement_case-1 here. the -1 takes care
- // of the origin of the vector, as for
- // RefinementCase::no_refinement (=0) there is no
- // data available and so the vector indices
- // are shifted
+ ExcIndexRange(child,0,GeometryInfo<dim>::n_children(RefinementCase<dim>(refinement_case))));
+ // we use refinement_case-1 here. the -1 takes care
+ // of the origin of the vector, as for
+ // RefinementCase::no_refinement (=0) there is no
+ // data available and so the vector indices
+ // are shifted
Assert (prolongation[refinement_case-1][child].n() == this->dofs_per_cell, ExcEmbeddingVoid());
return prolongation[refinement_case-1][child];
}
FiniteElement<dim,spacedim>::component_to_block_index (const unsigned int index) const
{
Assert (index < this->n_components(),
- ExcIndexRange(index, 0, this->n_components()));
+ ExcIndexRange(index, 0, this->n_components()));
return first_block_of_base(component_to_base_table[index].first.first)
+ component_to_base_table[index].second;
template <int dim, int spacedim>
unsigned int
FiniteElement<dim,spacedim>::adjust_quad_dof_index_for_face_orientation (const unsigned int index,
- const bool face_orientation,
- const bool face_flip,
- const bool face_rotation) const
+ const bool face_orientation,
+ const bool face_flip,
+ const bool face_rotation) const
{
- // general template for 1D and 2D: not
- // implemented. in fact, the function
- // shouldn't even be called unless we are
- // in 3d, so throw an internal error
+ // general template for 1D and 2D: not
+ // implemented. in fact, the function
+ // shouldn't even be called unless we are
+ // in 3d, so throw an internal error
Assert (dim==3, ExcInternalError());
if (dim < 3)
return index;
- // adjust dofs on 3d faces if the face is
- // flipped. note that we query a table that
- // derived elements need to have set up
- // front. the exception are discontinuous
- // elements for which there should be no
- // face dofs anyway (i.e. dofs_per_quad==0
- // in 3d), so we don't need the table, but
- // the function should also not have been
- // called
+ // adjust dofs on 3d faces if the face is
+ // flipped. note that we query a table that
+ // derived elements need to have set up
+ // front. the exception are discontinuous
+ // elements for which there should be no
+ // face dofs anyway (i.e. dofs_per_quad==0
+ // in 3d), so we don't need the table, but
+ // the function should also not have been
+ // called
Assert (index<this->dofs_per_quad, ExcIndexRange(index,0,this->dofs_per_quad));
Assert (adjust_quad_dof_index_for_face_orientation_table.n_elements()==8*this->dofs_per_quad,
- ExcInternalError());
+ ExcInternalError());
return index+adjust_quad_dof_index_for_face_orientation_table(index,4*face_orientation+2*face_flip+face_rotation);
}
template <int dim, int spacedim>
unsigned int
FiniteElement<dim,spacedim>::adjust_line_dof_index_for_line_orientation (const unsigned int index,
- const bool line_orientation) const
+ const bool line_orientation) const
{
- // general template for 1D and 2D: do
- // nothing. Do not throw an Assertion,
- // however, in order to allow to call this
- // function in 2D as well
+ // general template for 1D and 2D: do
+ // nothing. Do not throw an Assertion,
+ // however, in order to allow to call this
+ // function in 2D as well
if (dim<3)
return index;
Assert (index<this->dofs_per_line, ExcIndexRange(index,0,this->dofs_per_line));
Assert (adjust_line_dof_index_for_line_orientation_table.size()==this->dofs_per_line,
- ExcInternalError());
+ ExcInternalError());
if (line_orientation)
return index;
else
for (unsigned int ref_case=RefinementCase<dim>::cut_x;
ref_case<RefinementCase<dim>::isotropic_refinement+1; ++ref_case)
for (unsigned int c=0;
- c<GeometryInfo<dim>::n_children(RefinementCase<dim>(ref_case)); ++c)
+ c<GeometryInfo<dim>::n_children(RefinementCase<dim>(ref_case)); ++c)
{
- Assert ((prolongation[ref_case-1][c].m() == this->dofs_per_cell) ||
- (prolongation[ref_case-1][c].m() == 0),
- ExcInternalError());
- Assert ((prolongation[ref_case-1][c].n() == this->dofs_per_cell) ||
- (prolongation[ref_case-1][c].n() == 0),
- ExcInternalError());
- if ((prolongation[ref_case-1][c].m() == 0) ||
- (prolongation[ref_case-1][c].n() == 0))
- return false;
+ Assert ((prolongation[ref_case-1][c].m() == this->dofs_per_cell) ||
+ (prolongation[ref_case-1][c].m() == 0),
+ ExcInternalError());
+ Assert ((prolongation[ref_case-1][c].n() == this->dofs_per_cell) ||
+ (prolongation[ref_case-1][c].n() == 0),
+ ExcInternalError());
+ if ((prolongation[ref_case-1][c].m() == 0) ||
+ (prolongation[ref_case-1][c].n() == 0))
+ return false;
}
return true;
}
for (unsigned int ref_case=RefinementCase<dim>::cut_x;
ref_case<RefinementCase<dim>::isotropic_refinement+1; ++ref_case)
for (unsigned int c=0;
- c<GeometryInfo<dim>::n_children(RefinementCase<dim>(ref_case)); ++c)
+ c<GeometryInfo<dim>::n_children(RefinementCase<dim>(ref_case)); ++c)
{
- Assert ((restriction[ref_case-1][c].m() == this->dofs_per_cell) ||
- (restriction[ref_case-1][c].m() == 0),
- ExcInternalError());
- Assert ((restriction[ref_case-1][c].n() == this->dofs_per_cell) ||
- (restriction[ref_case-1][c].n() == 0),
- ExcInternalError());
- if ((restriction[ref_case-1][c].m() == 0) ||
- (restriction[ref_case-1][c].n() == 0))
- return false;
+ Assert ((restriction[ref_case-1][c].m() == this->dofs_per_cell) ||
+ (restriction[ref_case-1][c].m() == 0),
+ ExcInternalError());
+ Assert ((restriction[ref_case-1][c].n() == this->dofs_per_cell) ||
+ (restriction[ref_case-1][c].n() == 0),
+ ExcInternalError());
+ if ((restriction[ref_case-1][c].m() == 0) ||
+ (restriction[ref_case-1][c].n() == 0))
+ return false;
}
return true;
}
c<GeometryInfo<dim>::n_children(RefinementCase<dim>(ref_case)); ++c)
{
Assert ((prolongation[ref_case-1][c].m() == this->dofs_per_cell) ||
- (prolongation[ref_case-1][c].m() == 0),
- ExcInternalError());
+ (prolongation[ref_case-1][c].m() == 0),
+ ExcInternalError());
Assert ((prolongation[ref_case-1][c].n() == this->dofs_per_cell) ||
- (prolongation[ref_case-1][c].n() == 0),
- ExcInternalError());
+ (prolongation[ref_case-1][c].n() == 0),
+ ExcInternalError());
if ((prolongation[ref_case-1][c].m() == 0) ||
- (prolongation[ref_case-1][c].n() == 0))
- return false;
+ (prolongation[ref_case-1][c].n() == 0))
+ return false;
}
return true;
}
c<GeometryInfo<dim>::n_children(RefinementCase<dim>(ref_case)); ++c)
{
Assert ((restriction[ref_case-1][c].m() == this->dofs_per_cell) ||
- (restriction[ref_case-1][c].m() == 0),
- ExcInternalError());
+ (restriction[ref_case-1][c].m() == 0),
+ ExcInternalError());
Assert ((restriction[ref_case-1][c].n() == this->dofs_per_cell) ||
- (restriction[ref_case-1][c].n() == 0),
- ExcInternalError());
+ (restriction[ref_case-1][c].n() == 0),
+ ExcInternalError());
if ((restriction[ref_case-1][c].m() == 0) ||
- (restriction[ref_case-1][c].n() == 0))
- return false;
+ (restriction[ref_case-1][c].n() == 0))
+ return false;
}
return true;
}
if (dim==1)
Assert ((interface_constraints.m()==0) && (interface_constraints.n()==0),
- ExcWrongInterfaceMatrixSize(interface_constraints.m(),
- interface_constraints.n()));
+ ExcWrongInterfaceMatrixSize(interface_constraints.m(),
+ interface_constraints.n()));
return interface_constraints;
}
void
FiniteElement<dim,spacedim>::
get_interpolation_matrix (const FiniteElement<dim,spacedim> &,
- FullMatrix<double> &) const
+ FullMatrix<double> &) const
{
- // by default, no interpolation
- // implemented. so throw exception,
- // as documentation says
+ // by default, no interpolation
+ // implemented. so throw exception,
+ // as documentation says
typedef FiniteElement<dim,spacedim> FEE;
AssertThrow (false,
typename FEE::
- ExcInterpolationNotImplemented());
+ ExcInterpolationNotImplemented());
}
void
FiniteElement<dim,spacedim>::
get_face_interpolation_matrix (const FiniteElement<dim,spacedim> &,
- FullMatrix<double> &) const
+ FullMatrix<double> &) const
{
- // by default, no interpolation
- // implemented. so throw exception,
- // as documentation says
+ // by default, no interpolation
+ // implemented. so throw exception,
+ // as documentation says
typedef FiniteElement<dim,spacedim> FEE;
AssertThrow (false,
typename FEE::
void
FiniteElement<dim,spacedim>::
get_subface_interpolation_matrix (const FiniteElement<dim,spacedim> &,
- const unsigned int,
- FullMatrix<double> &) const
+ const unsigned int,
+ FullMatrix<double> &) const
{
- // by default, no interpolation
- // implemented. so throw exception,
- // as documentation says
+ // by default, no interpolation
+ // implemented. so throw exception,
+ // as documentation says
typedef FiniteElement<dim,spacedim> FEE;
AssertThrow (false,
typename FEE::ExcInterpolationNotImplemented());
FiniteElement<dim,spacedim>::operator == (const FiniteElement<dim,spacedim> &f) const
{
return ((static_cast<const FiniteElementData<dim>&>(*this) ==
- static_cast<const FiniteElementData<dim>&>(f)) &&
- (interface_constraints == f.interface_constraints));
+ static_cast<const FiniteElementData<dim>&>(f)) &&
+ (interface_constraints == f.interface_constraints));
}
const std::vector<Point<dim> > &
FiniteElement<dim,spacedim>::get_unit_support_points () const
{
- // a finite element may define
- // support points, but only if
- // there are as many as there are
- // degrees of freedom
+ // a finite element may define
+ // support points, but only if
+ // there are as many as there are
+ // degrees of freedom
Assert ((unit_support_points.size() == 0) ||
- (unit_support_points.size() == this->dofs_per_cell),
- ExcInternalError());
+ (unit_support_points.size() == this->dofs_per_cell),
+ ExcInternalError());
return unit_support_points;
}
const std::vector<Point<dim> > &
FiniteElement<dim,spacedim>::get_generalized_support_points () const
{
- // a finite element may define
- // support points, but only if
- // there are as many as there are
- // degrees of freedom
+ // a finite element may define
+ // support points, but only if
+ // there are as many as there are
+ // degrees of freedom
return ((generalized_support_points.size() == 0)
- ? unit_support_points
- : generalized_support_points);
+ ? unit_support_points
+ : generalized_support_points);
}
const std::vector<Point<dim-1> > &
FiniteElement<dim,spacedim>::get_unit_face_support_points () const
{
- // a finite element may define
- // support points, but only if
- // there are as many as there are
- // degrees of freedom on a face
+ // a finite element may define
+ // support points, but only if
+ // there are as many as there are
+ // degrees of freedom on a face
Assert ((unit_face_support_points.size() == 0) ||
- (unit_face_support_points.size() == this->dofs_per_face),
- ExcInternalError());
+ (unit_face_support_points.size() == this->dofs_per_face),
+ ExcInternalError());
return unit_face_support_points;
}
const std::vector<Point<dim-1> > &
FiniteElement<dim,spacedim>::get_generalized_face_support_points () const
{
- // a finite element may define
- // support points, but only if
- // there are as many as there are
- // degrees of freedom on a face
+ // a finite element may define
+ // support points, but only if
+ // there are as many as there are
+ // degrees of freedom on a face
return ((generalized_face_support_points.size() == 0)
- ? unit_face_support_points
- : generalized_face_support_points);
+ ? unit_face_support_points
+ : generalized_face_support_points);
}
{
Assert (has_support_points(), ExcFEHasNoSupportPoints());
Assert (values.size() == unit_support_points.size(),
- ExcDimensionMismatch(values.size(), unit_support_points.size()));
+ ExcDimensionMismatch(values.size(), unit_support_points.size()));
Assert (local_dofs.size() == this->dofs_per_cell,
- ExcDimensionMismatch(local_dofs.size(),this->dofs_per_cell));
+ ExcDimensionMismatch(local_dofs.size(),this->dofs_per_cell));
Assert (this->n_components() == 1,
- ExcDimensionMismatch(this->n_components(), 1));
+ ExcDimensionMismatch(this->n_components(), 1));
std::copy(values.begin(), values.end(), local_dofs.begin());
}
{
Assert (has_support_points(), ExcFEHasNoSupportPoints());
Assert (values.size() == unit_support_points.size(),
- ExcDimensionMismatch(values.size(), unit_support_points.size()));
+ ExcDimensionMismatch(values.size(), unit_support_points.size()));
Assert (local_dofs.size() == this->dofs_per_cell,
- ExcDimensionMismatch(local_dofs.size(),this->dofs_per_cell));
+ ExcDimensionMismatch(local_dofs.size(),this->dofs_per_cell));
Assert (values[0].size() >= offset+this->n_components(),
- ExcDimensionMismatch(values[0].size(),offset+this->n_components()));
+ ExcDimensionMismatch(values[0].size(),offset+this->n_components()));
for (unsigned int i=0;i<this->dofs_per_cell;++i)
{
const std::pair<unsigned int, unsigned int> index
- = this->system_to_component_index(i);
+ = this->system_to_component_index(i);
local_dofs[i] = values[i](offset+index.first);
}
}
{
Assert (has_support_points(), ExcFEHasNoSupportPoints());
Assert (values[0].size() == unit_support_points.size(),
- ExcDimensionMismatch(values.size(), unit_support_points.size()));
+ ExcDimensionMismatch(values.size(), unit_support_points.size()));
Assert (local_dofs.size() == this->dofs_per_cell,
- ExcDimensionMismatch(local_dofs.size(),this->dofs_per_cell));
+ ExcDimensionMismatch(local_dofs.size(),this->dofs_per_cell));
Assert (values.size() == this->n_components(),
- ExcDimensionMismatch(values.size(), this->n_components()));
+ ExcDimensionMismatch(values.size(), this->n_components()));
for (unsigned int i=0;i<this->dofs_per_cell;++i)
{
const std::pair<unsigned int, unsigned int> index
- = this->system_to_component_index(i);
+ = this->system_to_component_index(i);
local_dofs[i] = values[index.first][i];
}
}
FiniteElement<dim,spacedim>::memory_consumption () const
{
return (sizeof(FiniteElementData<dim>) +
- MemoryConsumption::memory_consumption (restriction)+
- MemoryConsumption::memory_consumption (prolongation) +
- MemoryConsumption::memory_consumption (interface_constraints) +
- MemoryConsumption::memory_consumption (system_to_component_table) +
- MemoryConsumption::memory_consumption (face_system_to_component_table) +
- MemoryConsumption::memory_consumption (system_to_base_table) +
- MemoryConsumption::memory_consumption (face_system_to_base_table) +
- MemoryConsumption::memory_consumption (component_to_base_table) +
- MemoryConsumption::memory_consumption (restriction_is_additive_flags) +
- MemoryConsumption::memory_consumption (nonzero_components) +
- MemoryConsumption::memory_consumption (n_nonzero_components_table));
+ MemoryConsumption::memory_consumption (restriction)+
+ MemoryConsumption::memory_consumption (prolongation) +
+ MemoryConsumption::memory_consumption (interface_constraints) +
+ MemoryConsumption::memory_consumption (system_to_component_table) +
+ MemoryConsumption::memory_consumption (face_system_to_component_table) +
+ MemoryConsumption::memory_consumption (system_to_base_table) +
+ MemoryConsumption::memory_consumption (face_system_to_base_table) +
+ MemoryConsumption::memory_consumption (component_to_base_table) +
+ MemoryConsumption::memory_consumption (restriction_is_additive_flags) +
+ MemoryConsumption::memory_consumption (nonzero_components) +
+ MemoryConsumption::memory_consumption (n_nonzero_components_table));
}
FEValuesData<1,2> &) const
{
- Assert(false, ExcNotImplemented());
+ Assert(false, ExcNotImplemented());
}
FEValuesData<1,3> &) const
{
- Assert(false, ExcNotImplemented());
+ Assert(false, ExcNotImplemented());
}
FEValuesData<2,3> &) const
{
- Assert(false, ExcNotImplemented());
+ Assert(false, ExcNotImplemented());
}
FEValuesData<dim,spacedim> &data) const
{
Assert ((fe_internal.update_each | fe_internal.update_once)
- & update_hessians,
- ExcInternalError());
+ & update_hessians,
+ ExcInternalError());
// make sure we have as many entries as there are nonzero components
// Assert (data.shape_hessians.size() ==
-// std::accumulate (n_nonzero_components_table.begin(),
+// std::accumulate (n_nonzero_components_table.begin(),
// n_nonzero_components_table.end(),
// 0U),
-// ExcInternalError());
- // Number of quadrature points
+// ExcInternalError());
+ // Number of quadrature points
const unsigned int n_q_points = data.shape_hessians[0].size();
- // first reinit the fe_values
- // objects used for the finite
- // differencing stuff
+ // first reinit the fe_values
+ // objects used for the finite
+ // differencing stuff
for (unsigned int d=0; d<dim; ++d)
{
fe_internal.differences[d]->reinit(cell);
fe_internal.differences[d+dim]->reinit(cell);
Assert(offset <= fe_internal.differences[d]->n_quadrature_points - n_q_points,
- ExcIndexRange(offset, 0, fe_internal.differences[d]->n_quadrature_points
- - n_q_points));
+ ExcIndexRange(offset, 0, fe_internal.differences[d]->n_quadrature_points
+ - n_q_points));
}
- // collection of difference
- // quotients of gradients in each
- // direction (first index) and at
- // all q-points (second index)
+ // collection of difference
+ // quotients of gradients in each
+ // direction (first index) and at
+ // all q-points (second index)
std::vector<std::vector<Tensor<1,dim> > >
diff_quot (spacedim, std::vector<Tensor<1,dim> > (n_q_points));
std::vector<Tensor<1,spacedim> > diff_quot2 (n_q_points);
- // for all nonzero components of
- // all shape functions at all
- // quadrature points and difference
- // quotients in all directions:
+ // for all nonzero components of
+ // all shape functions at all
+ // quadrature points and difference
+ // quotients in all directions:
unsigned int total_index = 0;
for (unsigned int shape_index=0; shape_index<this->dofs_per_cell; ++shape_index)
for (unsigned int n=0; n<n_nonzero_components(shape_index); ++n, ++total_index)
std::vector<unsigned int> retval (nonzero_components.size());
for (unsigned int i=0; i<nonzero_components.size(); ++i)
retval[i] = std::count (nonzero_components[i].begin(),
- nonzero_components[i].end(),
- true);
+ nonzero_components[i].end(),
+ true);
return retval;
}
template <int dim, int spacedim>
typename Mapping<dim,spacedim>::InternalDataBase *
FiniteElement<dim,spacedim>::get_face_data (const UpdateFlags flags,
- const Mapping<dim,spacedim> &mapping,
- const Quadrature<dim-1> &quadrature) const
+ const Mapping<dim,spacedim> &mapping,
+ const Quadrature<dim-1> &quadrature) const
{
return get_data (flags, mapping,
- QProjector<dim>::project_to_all_faces(quadrature));
+ QProjector<dim>::project_to_all_faces(quadrature));
}
template <int dim, int spacedim>
typename Mapping<dim,spacedim>::InternalDataBase *
FiniteElement<dim,spacedim>::get_subface_data (const UpdateFlags flags,
- const Mapping<dim,spacedim> &mapping,
- const Quadrature<dim-1> &quadrature) const
+ const Mapping<dim,spacedim> &mapping,
+ const Quadrature<dim-1> &quadrature) const
{
return get_data (flags, mapping,
- QProjector<dim>::project_to_all_subfaces(quadrature));
+ QProjector<dim>::project_to_all_subfaces(quadrature));
}
FiniteElement<dim,spacedim>::base_element(const unsigned index) const
{
Assert (index==0, ExcIndexRange(index,0,1));
- // This function should not be
- // called for a system element
+ // This function should not be
+ // called for a system element
Assert (base_to_block_indices.size() == 1, ExcInternalError());
return *this;
}
// $Id$
// Version: $Name$
//
-// Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2011 by the deal.II authors
+// Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
template <int dim>
FE_ABF<dim>::FE_ABF (const unsigned int deg)
- :
- FE_PolyTensor<PolynomialsABF<dim>, dim> (
- deg,
- FiniteElementData<dim>(get_dpo_vector(deg),
- dim, deg+1, FiniteElementData<dim>::Hdiv, 1),
- std::vector<bool>(PolynomialsABF<dim>::compute_n_pols(deg), true),
- std::vector<std::vector<bool> >(PolynomialsABF<dim>::compute_n_pols(deg),
- std::vector<bool>(dim,true))),
- rt_order(deg)
+ :
+ FE_PolyTensor<PolynomialsABF<dim>, dim> (
+ deg,
+ FiniteElementData<dim>(get_dpo_vector(deg),
+ dim, deg+1, FiniteElementData<dim>::Hdiv, 1),
+ std::vector<bool>(PolynomialsABF<dim>::compute_n_pols(deg), true),
+ std::vector<std::vector<bool> >(PolynomialsABF<dim>::compute_n_pols(deg),
+ std::vector<bool>(dim,true))),
+ rt_order(deg)
{
Assert (dim >= 2, ExcImpossibleInDim(dim));
const unsigned int n_dofs = this->dofs_per_cell;
this->mapping_type = mapping_raviart_thomas;
- // First, initialize the
- // generalized support points and
- // quadrature weights, since they
- // are required for interpolation.
+ // First, initialize the
+ // generalized support points and
+ // quadrature weights, since they
+ // are required for interpolation.
initialize_support_points(deg);
- // Now compute the inverse node
- //matrix, generating the correct
- //basis functions from the raw
- //ones.
+ // Now compute the inverse node
+ //matrix, generating the correct
+ //basis functions from the raw
+ //ones.
FullMatrix<double> M(n_dofs, n_dofs);
FETools::compute_node_matrix(M, *this);
this->inverse_node_matrix.reinit(n_dofs, n_dofs);
this->inverse_node_matrix.invert(M);
- // From now on, the shape functions
- // will be the correct ones, not
- // the raw shape functions anymore.
-
- // Reinit the vectors of
- // restriction and prolongation
- // matrices to the right sizes.
- // Restriction only for isotropic
- // refinement
+ // From now on, the shape functions
+ // will be the correct ones, not
+ // the raw shape functions anymore.
+
+ // Reinit the vectors of
+ // restriction and prolongation
+ // matrices to the right sizes.
+ // Restriction only for isotropic
+ // refinement
this->reinit_restriction_and_prolongation_matrices(true);
- // Fill prolongation matrices with embedding operators
+ // Fill prolongation matrices with embedding operators
FETools::compute_embedding_matrices (*this, this->prolongation);
initialize_restriction ();
- // TODO[TL]: for anisotropic refinement we will probably need a table of submatrices with an array for each refine case
+ // TODO[TL]: for anisotropic refinement we will probably need a table of submatrices with an array for each refine case
std::vector<FullMatrix<double> >
face_embeddings(1<<(dim-1), FullMatrix<double>(this->dofs_per_face,
- this->dofs_per_face));
+ this->dofs_per_face));
// TODO: Something goes wrong there. The error of the least squares fit
// is to large ...
// FETools::compute_face_embedding_matrices(*this, &face_embeddings[0], 0, 0);
this->interface_constraints.reinit((1<<(dim-1)) * this->dofs_per_face,
- this->dofs_per_face);
+ this->dofs_per_face);
unsigned int target_row=0;
for (unsigned int d=0;d<face_embeddings.size();++d)
for (unsigned int i=0;i<face_embeddings[d].m();++i)
{
- for (unsigned int j=0;j<face_embeddings[d].n();++j)
- this->interface_constraints(target_row,j) = face_embeddings[d](i,j);
- ++target_row;
+ for (unsigned int j=0;j<face_embeddings[d].n();++j)
+ this->interface_constraints(target_row,j) = face_embeddings[d](i,j);
+ ++target_row;
}
}
std::string
FE_ABF<dim>::get_name () const
{
- // note that the
- // FETools::get_fe_from_name
- // function depends on the
- // particular format of the string
- // this function returns, so they
- // have to be kept in synch
+ // note that the
+ // FETools::get_fe_from_name
+ // function depends on the
+ // particular format of the string
+ // this function returns, so they
+ // have to be kept in synch
#ifdef HAVE_STD_STRINGSTREAM
std::ostringstream namebuf;
const unsigned int n_interior_points = cell_quadrature.size();
unsigned int n_face_points = (dim>1) ? 1 : 0;
- // compute (deg+1)^(dim-1)
+ // compute (deg+1)^(dim-1)
for (unsigned int d=1;d<dim;++d)
n_face_points *= deg+1;
this->generalized_support_points.resize (GeometryInfo<dim>::faces_per_cell*n_face_points
- + n_interior_points);
+ + n_interior_points);
this->generalized_face_support_points.resize (n_face_points);
{
std::vector<std::vector<Polynomials::Polynomial<double> > > poly(dim);
for (unsigned int d=0;d<dim;++d)
- poly[d].push_back (Polynomials::Monomial<double> (deg+1));
+ poly[d].push_back (Polynomials::Monomial<double> (deg+1));
poly[dd] = Polynomials::Monomial<double>::generate_complete_basis(deg);
polynomials_abf[dd] = new AnisotropicPolynomials<dim>(poly);
}
- // Number of the point being entered
+ // Number of the point being entered
unsigned int current = 0;
if (dim>1)
{
QGauss<dim-1> face_points (deg+1);
TensorProductPolynomials<dim-1> legendre =
- Polynomials::Legendre::generate_complete_basis(deg);
+ Polynomials::Legendre::generate_complete_basis(deg);
boundary_weights.reinit(n_face_points, legendre.n());
// Assert (face_points.size() == this->dofs_per_face,
-// ExcInternalError());
+// ExcInternalError());
for (unsigned int k=0;k<n_face_points;++k)
- {
- this->generalized_face_support_points[k] = face_points.point(k);
- // Compute its quadrature
- // contribution for each
- // moment.
- for (unsigned int i=0;i<legendre.n();++i)
- {
- boundary_weights(k, i)
- = face_points.weight(k)
- * legendre.compute_value(i, face_points.point(k));
- }
- }
+ {
+ this->generalized_face_support_points[k] = face_points.point(k);
+ // Compute its quadrature
+ // contribution for each
+ // moment.
+ for (unsigned int i=0;i<legendre.n();++i)
+ {
+ boundary_weights(k, i)
+ = face_points.weight(k)
+ * legendre.compute_value(i, face_points.point(k));
+ }
+ }
Quadrature<dim> faces = QProjector<dim>::project_to_all_faces(face_points);
for (;current<GeometryInfo<dim>::faces_per_cell*n_face_points;
- ++current)
- {
- // Enter the support point
- // into the vector
- this->generalized_support_points[current] = faces.point(current);
- }
+ ++current)
+ {
+ // Enter the support point
+ // into the vector
+ this->generalized_support_points[current] = faces.point(current);
+ }
// Now initialise edge interior weights for the ABF elements.
// for vector valued elements.
boundary_weights_abf.reinit(faces.size(), polynomials_abf[0]->n() * dim);
for (unsigned int k=0;k < faces.size();++k)
- {
- for (unsigned int i=0;i<polynomials_abf[0]->n() * dim;++i)
- {
- boundary_weights_abf(k,i) = polynomials_abf[i%dim]->
- compute_value(i / dim, faces.point(k)) * faces.weight(k);
- }
- }
+ {
+ for (unsigned int i=0;i<polynomials_abf[0]->n() * dim;++i)
+ {
+ boundary_weights_abf(k,i) = polynomials_abf[i%dim]->
+ compute_value(i / dim, faces.point(k)) * faces.weight(k);
+ }
+ }
}
// Create Legendre basis for the
std::vector<AnisotropicPolynomials<dim>* > polynomials(dim);
for (unsigned int dd=0;dd<dim;++dd)
- {
- std::vector<std::vector<Polynomials::Polynomial<double> > > poly(dim);
- for (unsigned int d=0;d<dim;++d)
- poly[d] = Polynomials::Legendre::generate_complete_basis(deg);
- poly[dd] = Polynomials::Legendre::generate_complete_basis(deg-1);
+ {
+ std::vector<std::vector<Polynomials::Polynomial<double> > > poly(dim);
+ for (unsigned int d=0;d<dim;++d)
+ poly[d] = Polynomials::Legendre::generate_complete_basis(deg);
+ poly[dd] = Polynomials::Legendre::generate_complete_basis(deg-1);
- polynomials[dd] = new AnisotropicPolynomials<dim>(poly);
- }
+ polynomials[dd] = new AnisotropicPolynomials<dim>(poly);
+ }
interior_weights.reinit(TableIndices<3>(n_interior_points, polynomials[0]->n(), dim));
for (unsigned int k=0;k<cell_quadrature.size();++k)
- {
- for (unsigned int i=0;i<polynomials[0]->n();++i)
- for (unsigned int d=0;d<dim;++d)
- interior_weights(k,i,d) = cell_quadrature.weight(k)
- * polynomials[d]->compute_value(i,cell_quadrature.point(k));
- }
+ {
+ for (unsigned int i=0;i<polynomials[0]->n();++i)
+ for (unsigned int d=0;d<dim;++d)
+ interior_weights(k,i,d) = cell_quadrature.weight(k)
+ * polynomials[d]->compute_value(i,cell_quadrature.point(k));
+ }
for (unsigned int d=0;d<dim;++d)
- delete polynomials[d];
+ delete polynomials[d];
}
// behind the ABF elements is implemented. It is unclear,
// if this really leads to the ABF spaces in 3D!
interior_weights_abf.reinit(TableIndices<3>(cell_quadrature.size(),
- polynomials_abf[0]->n() * dim, dim));
+ polynomials_abf[0]->n() * dim, dim));
Tensor<1, dim> poly_grad;
for (unsigned int k=0;k<cell_quadrature.size();++k)
{
for (unsigned int i=0;i<polynomials_abf[0]->n() * dim;++i)
- {
- poly_grad = polynomials_abf[i%dim]->compute_grad(i / dim,cell_quadrature.point(k))
- * cell_quadrature.weight(k);
- // The minus sign comes from the use of the Gauss theorem to replace the divergence.
- for (unsigned int d=0;d<dim;++d)
- interior_weights_abf(k,i,d) = -poly_grad[d];
- }
+ {
+ poly_grad = polynomials_abf[i%dim]->compute_grad(i / dim,cell_quadrature.point(k))
+ * cell_quadrature.weight(k);
+ // The minus sign comes from the use of the Gauss theorem to replace the divergence.
+ for (unsigned int d=0;d<dim;++d)
+ interior_weights_abf(k,i,d) = -poly_grad[d];
+ }
}
for (unsigned int d=0;d<dim;++d)
delete polynomials_abf[d];
Assert (current == this->generalized_support_points.size(),
- ExcInternalError());
+ ExcInternalError());
}
{
unsigned int iso=RefinementCase<dim>::isotropic_refinement-1;
for (unsigned int i=0;i<GeometryInfo<dim>::max_children_per_cell;++i)
- this->restriction[iso][i].reinit(0,0);
+ this->restriction[iso][i].reinit(0,0);
return;
}
unsigned int iso=RefinementCase<dim>::isotropic_refinement-1;
QGauss<dim-1> q_base (rt_order+1);
const unsigned int n_face_points = q_base.size();
- // First, compute interpolation on
- // subfaces
+ // First, compute interpolation on
+ // subfaces
for (unsigned int face=0;face<GeometryInfo<dim>::faces_per_cell;++face)
{
- // The shape functions of the
- // child cell are evaluated
- // in the quadrature points
- // of a full face.
+ // The shape functions of the
+ // child cell are evaluated
+ // in the quadrature points
+ // of a full face.
Quadrature<dim> q_face
- = QProjector<dim>::project_to_face(q_base, face);
- // Store shape values, since the
- // evaluation suffers if not
- // ordered by point
+ = QProjector<dim>::project_to_face(q_base, face);
+ // Store shape values, since the
+ // evaluation suffers if not
+ // ordered by point
Table<2,double> cached_values(this->dofs_per_cell, q_face.size());
for (unsigned int k=0;k<q_face.size();++k)
- for (unsigned int i = 0; i < this->dofs_per_cell; ++i)
- cached_values(i,k)
- = this->shape_value_component(i, q_face.point(k),
- GeometryInfo<dim>::unit_normal_direction[face]);
+ for (unsigned int i = 0; i < this->dofs_per_cell; ++i)
+ cached_values(i,k)
+ = this->shape_value_component(i, q_face.point(k),
+ GeometryInfo<dim>::unit_normal_direction[face]);
for (unsigned int sub=0;sub<GeometryInfo<dim>::max_children_per_face;++sub)
- {
- // The weight fuctions for
- // the coarse face are
- // evaluated on the subface
- // only.
- Quadrature<dim> q_sub
- = QProjector<dim>::project_to_subface(q_base, face, sub);
- const unsigned int child
- = GeometryInfo<dim>::child_cell_on_face(
- RefinementCase<dim>::isotropic_refinement, face, sub);
-
- // On a certain face, we must
- // compute the moments of ALL
- // fine level functions with
- // the coarse level weight
- // functions belonging to
- // that face. Due to the
- // orthogonalization process
- // when building the shape
- // functions, these weights
- // are equal to the
- // corresponding shpe
- // functions.
- for (unsigned int k=0;k<n_face_points;++k)
- for (unsigned int i_child = 0; i_child < this->dofs_per_cell; ++i_child)
- for (unsigned int i_face = 0; i_face < this->dofs_per_face; ++i_face)
- {
- // The quadrature
- // weights on the
- // subcell are NOT
- // transformed, so we
- // have to do it here.
- this->restriction[iso][child](face*this->dofs_per_face+i_face,
- i_child)
- += Utilities::fixed_power<dim-1>(.5) * q_sub.weight(k)
- * cached_values(i_child, k)
- * this->shape_value_component(face*this->dofs_per_face+i_face,
- q_sub.point(k),
- GeometryInfo<dim>::unit_normal_direction[face]);
- }
- }
+ {
+ // The weight fuctions for
+ // the coarse face are
+ // evaluated on the subface
+ // only.
+ Quadrature<dim> q_sub
+ = QProjector<dim>::project_to_subface(q_base, face, sub);
+ const unsigned int child
+ = GeometryInfo<dim>::child_cell_on_face(
+ RefinementCase<dim>::isotropic_refinement, face, sub);
+
+ // On a certain face, we must
+ // compute the moments of ALL
+ // fine level functions with
+ // the coarse level weight
+ // functions belonging to
+ // that face. Due to the
+ // orthogonalization process
+ // when building the shape
+ // functions, these weights
+ // are equal to the
+ // corresponding shpe
+ // functions.
+ for (unsigned int k=0;k<n_face_points;++k)
+ for (unsigned int i_child = 0; i_child < this->dofs_per_cell; ++i_child)
+ for (unsigned int i_face = 0; i_face < this->dofs_per_face; ++i_face)
+ {
+ // The quadrature
+ // weights on the
+ // subcell are NOT
+ // transformed, so we
+ // have to do it here.
+ this->restriction[iso][child](face*this->dofs_per_face+i_face,
+ i_child)
+ += Utilities::fixed_power<dim-1>(.5) * q_sub.weight(k)
+ * cached_values(i_child, k)
+ * this->shape_value_component(face*this->dofs_per_face+i_face,
+ q_sub.point(k),
+ GeometryInfo<dim>::unit_normal_direction[face]);
+ }
+ }
}
if (rt_order==0) return;
- // Create Legendre basis for the
- // space D_xi Q_k. Here, we cannot
- // use the shape functions
+ // Create Legendre basis for the
+ // space D_xi Q_k. Here, we cannot
+ // use the shape functions
std::vector<AnisotropicPolynomials<dim>* > polynomials(dim);
for (unsigned int dd=0;dd<dim;++dd)
{
std::vector<std::vector<Polynomials::Polynomial<double> > > poly(dim);
for (unsigned int d=0;d<dim;++d)
- poly[d] = Polynomials::Legendre::generate_complete_basis(rt_order);
+ poly[d] = Polynomials::Legendre::generate_complete_basis(rt_order);
poly[dd] = Polynomials::Legendre::generate_complete_basis(rt_order-1);
polynomials[dd] = new AnisotropicPolynomials<dim>(poly);
const unsigned int start_cell_dofs
= GeometryInfo<dim>::faces_per_cell*this->dofs_per_face;
- // Store shape values, since the
- // evaluation suffers if not
- // ordered by point
+ // Store shape values, since the
+ // evaluation suffers if not
+ // ordered by point
Table<3,double> cached_values(this->dofs_per_cell, q_cell.size(), dim);
for (unsigned int k=0;k<q_cell.size();++k)
for (unsigned int i = 0; i < this->dofs_per_cell; ++i)
for (unsigned int d=0;d<dim;++d)
- cached_values(i,k,d) = this->shape_value_component(i, q_cell.point(k), d);
+ cached_values(i,k,d) = this->shape_value_component(i, q_cell.point(k), d);
for (unsigned int child=0;child<GeometryInfo<dim>::max_children_per_cell;++child)
{
Quadrature<dim> q_sub = QProjector<dim>::project_to_child(q_cell, child);
for (unsigned int k=0;k<q_sub.size();++k)
- for (unsigned int i_child = 0; i_child < this->dofs_per_cell; ++i_child)
- for (unsigned int d=0;d<dim;++d)
- for (unsigned int i_weight=0;i_weight<polynomials[d]->n();++i_weight)
- {
- this->restriction[iso][child](start_cell_dofs+i_weight*dim+d,
- i_child)
- += q_sub.weight(k)
- * cached_values(i_child, k, d)
- * polynomials[d]->compute_value(i_weight, q_sub.point(k));
- }
+ for (unsigned int i_child = 0; i_child < this->dofs_per_cell; ++i_child)
+ for (unsigned int d=0;d<dim;++d)
+ for (unsigned int i_weight=0;i_weight<polynomials[d]->n();++i_weight)
+ {
+ this->restriction[iso][child](start_cell_dofs+i_weight*dim+d,
+ i_child)
+ += q_sub.weight(k)
+ * cached_values(i_child, k, d)
+ * polynomials[d]->compute_value(i_weight, q_sub.point(k));
+ }
}
for (unsigned int d=0;d<dim;++d)
UpdateFlags
FE_ABF<dim>::update_once (const UpdateFlags) const
{
- // even the values have to be
- // computed on the real cell, so
- // nothing can be done in advance
+ // even the values have to be
+ // computed on the real cell, so
+ // nothing can be done in advance
return update_default;
}
const unsigned int face_index) const
{
Assert (shape_index < this->dofs_per_cell,
- ExcIndexRange (shape_index, 0, this->dofs_per_cell));
+ ExcIndexRange (shape_index, 0, this->dofs_per_cell));
Assert (face_index < GeometryInfo<dim>::faces_per_cell,
- ExcIndexRange (face_index, 0, GeometryInfo<dim>::faces_per_cell));
+ ExcIndexRange (face_index, 0, GeometryInfo<dim>::faces_per_cell));
- // Return computed values if we
- // know them easily. Otherwise, it
- // is always safe to return true.
+ // Return computed values if we
+ // know them easily. Otherwise, it
+ // is always safe to return true.
switch (rt_order)
{
case 0:
}
default:
- return true;
+ return true;
};
};
default: // other rt_order
- return true;
+ return true;
};
return true;
unsigned int offset) const
{
Assert (values.size() == this->generalized_support_points.size(),
- ExcDimensionMismatch(values.size(), this->generalized_support_points.size()));
+ ExcDimensionMismatch(values.size(), this->generalized_support_points.size()));
Assert (local_dofs.size() == this->dofs_per_cell,
- ExcDimensionMismatch(local_dofs.size(),this->dofs_per_cell));
+ ExcDimensionMismatch(local_dofs.size(),this->dofs_per_cell));
Assert (values[0].size() >= offset+this->n_components(),
- ExcDimensionMismatch(values[0].size(),offset+this->n_components()));
+ ExcDimensionMismatch(values[0].size(),offset+this->n_components()));
std::fill(local_dofs.begin(), local_dofs.end(), 0.);
for (unsigned int k=0;k<n_face_points;++k)
for (unsigned int i=0;i<boundary_weights.size(1);++i)
{
- local_dofs[i+face*this->dofs_per_face] += boundary_weights(k,i)
- * values[face*n_face_points+k](GeometryInfo<dim>::unit_normal_direction[face]+offset);
+ local_dofs[i+face*this->dofs_per_face] += boundary_weights(k,i)
+ * values[face*n_face_points+k](GeometryInfo<dim>::unit_normal_direction[face]+offset);
}
const unsigned start_cell_dofs = GeometryInfo<dim>::faces_per_cell*this->dofs_per_face;
for (unsigned int k=0;k<interior_weights.size(0);++k)
for (unsigned int i=0;i<interior_weights.size(1);++i)
for (unsigned int d=0;d<dim;++d)
- local_dofs[start_cell_dofs+i*dim+d] += interior_weights(k,i,d) * values[k+start_cell_points](d+offset);
+ local_dofs[start_cell_dofs+i*dim+d] += interior_weights(k,i,d) * values[k+start_cell_points](d+offset);
const unsigned start_abf_dofs = start_cell_dofs + interior_weights.size(1) * dim;
for (unsigned int k=0;k<interior_weights_abf.size(0);++k)
for (unsigned int i=0;i<interior_weights_abf.size(1);++i)
for (unsigned int d=0;d<dim;++d)
- local_dofs[start_abf_dofs+i] += interior_weights_abf(k,i,d) * values[k+start_cell_points](d+offset);
+ local_dofs[start_abf_dofs+i] += interior_weights_abf(k,i,d) * values[k+start_cell_points](d+offset);
// Face integral of ABF terms
for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
{
double n_orient = (double) GeometryInfo<dim>::unit_normal_orientation[face];
for (unsigned int fp=0; fp < n_face_points; ++fp)
- {
- // TODO: Check what the face_orientation, face_flip and face_rotation have to be in 3D
- unsigned int k = QProjector<dim>::DataSetDescriptor::face (face, false, false, false, n_face_points);
- for (unsigned int i=0; i<boundary_weights_abf.size(1); ++i)
- local_dofs[start_abf_dofs+i] += n_orient * boundary_weights_abf(k + fp, i)
- * values[k + fp](GeometryInfo<dim>::unit_normal_direction[face]+offset);
- }
+ {
+ // TODO: Check what the face_orientation, face_flip and face_rotation have to be in 3D
+ unsigned int k = QProjector<dim>::DataSetDescriptor::face (face, false, false, false, n_face_points);
+ for (unsigned int i=0; i<boundary_weights_abf.size(1); ++i)
+ local_dofs[start_abf_dofs+i] += n_orient * boundary_weights_abf(k + fp, i)
+ * values[k + fp](GeometryInfo<dim>::unit_normal_direction[face]+offset);
+ }
}
// TODO: Check if this "correction" can be removed.
const VectorSlice<const std::vector<std::vector<double> > >& values) const
{
Assert (values.size() == this->n_components(),
- ExcDimensionMismatch(values.size(), this->n_components()));
+ ExcDimensionMismatch(values.size(), this->n_components()));
Assert (values[0].size() == this->generalized_support_points.size(),
- ExcDimensionMismatch(values[0].size(), this->generalized_support_points.size()));
+ ExcDimensionMismatch(values[0].size(), this->generalized_support_points.size()));
Assert (local_dofs.size() == this->dofs_per_cell,
- ExcDimensionMismatch(local_dofs.size(),this->dofs_per_cell));
+ ExcDimensionMismatch(local_dofs.size(),this->dofs_per_cell));
std::fill(local_dofs.begin(), local_dofs.end(), 0.);
for (unsigned int k=0;k<n_face_points;++k)
for (unsigned int i=0;i<boundary_weights.size(1);++i)
{
- local_dofs[i+face*this->dofs_per_face] += boundary_weights(k,i)
- * values[GeometryInfo<dim>::unit_normal_direction[face]][face*n_face_points+k];
+ local_dofs[i+face*this->dofs_per_face] += boundary_weights(k,i)
+ * values[GeometryInfo<dim>::unit_normal_direction[face]][face*n_face_points+k];
}
const unsigned start_cell_dofs = GeometryInfo<dim>::faces_per_cell*this->dofs_per_face;
for (unsigned int k=0;k<interior_weights.size(0);++k)
for (unsigned int i=0;i<interior_weights.size(1);++i)
for (unsigned int d=0;d<dim;++d)
- local_dofs[start_cell_dofs+i*dim+d] += interior_weights(k,i,d) * values[d][k+start_cell_points];
+ local_dofs[start_cell_dofs+i*dim+d] += interior_weights(k,i,d) * values[d][k+start_cell_points];
const unsigned start_abf_dofs = start_cell_dofs + interior_weights.size(1) * dim;
for (unsigned int k=0;k<interior_weights_abf.size(0);++k)
for (unsigned int i=0;i<interior_weights_abf.size(1);++i)
for (unsigned int d=0;d<dim;++d)
- local_dofs[start_abf_dofs+i] += interior_weights_abf(k,i,d) * values[d][k+start_cell_points];
+ local_dofs[start_abf_dofs+i] += interior_weights_abf(k,i,d) * values[d][k+start_cell_points];
// Face integral of ABF terms
for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
{
double n_orient = (double) GeometryInfo<dim>::unit_normal_orientation[face];
for (unsigned int fp=0; fp < n_face_points; ++fp)
- {
- // TODO: Check what the face_orientation, face_flip and face_rotation have to be in 3D
- unsigned int k = QProjector<dim>::DataSetDescriptor::face (face, false, false, false, n_face_points);
- for (unsigned int i=0; i<boundary_weights_abf.size(1); ++i)
- local_dofs[start_abf_dofs+i] += n_orient * boundary_weights_abf(k + fp, i)
- * values[GeometryInfo<dim>::unit_normal_direction[face]][k + fp];
- }
+ {
+ // TODO: Check what the face_orientation, face_flip and face_rotation have to be in 3D
+ unsigned int k = QProjector<dim>::DataSetDescriptor::face (face, false, false, false, n_face_points);
+ for (unsigned int i=0; i<boundary_weights_abf.size(1); ++i)
+ local_dofs[start_abf_dofs+i] += n_orient * boundary_weights_abf(k + fp, i)
+ * values[GeometryInfo<dim>::unit_normal_direction[face]][k + fp];
+ }
}
// TODO: Check if this "correction" can be removed.
// $Id$
// Version: $Name$
//
-// Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 by the deal.II authors
+// Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
template <int dim>
FE_BDM<dim>::FE_BDM (const unsigned int deg)
- :
- FE_PolyTensor<PolynomialsBDM<dim>, dim> (
- deg,
- FiniteElementData<dim>(get_dpo_vector(deg),
- dim, deg+1, FiniteElementData<dim>::Hdiv, 1),
- get_ria_vector (deg),
- std::vector<std::vector<bool> >(PolynomialsBDM<dim>::compute_n_pols(deg),
- std::vector<bool>(dim,true)))
+ :
+ FE_PolyTensor<PolynomialsBDM<dim>, dim> (
+ deg,
+ FiniteElementData<dim>(get_dpo_vector(deg),
+ dim, deg+1, FiniteElementData<dim>::Hdiv, 1),
+ get_ria_vector (deg),
+ std::vector<std::vector<bool> >(PolynomialsBDM<dim>::compute_n_pols(deg),
+ std::vector<bool>(dim,true)))
{
Assert (dim >= 2, ExcImpossibleInDim(dim));
Assert (dim<3, ExcNotImplemented());
Assert (deg > 0, ExcMessage("Lowest order BDM element are degree 1, but you asked for degree 0"));
-
+
const unsigned int n_dofs = this->dofs_per_cell;
-
+
this->mapping_type = mapping_piola;
- // These must be done first, since
- // they change the evaluation of
- // basis functions
+ // These must be done first, since
+ // they change the evaluation of
+ // basis functions
- // Set up the generalized support
- // points
+ // Set up the generalized support
+ // points
initialize_support_points (deg);
- //Now compute the inverse node
- //matrix, generating the correct
- //basis functions from the raw
- //ones.
-
- // We use an auxiliary matrix in
- // this function. Therefore,
- // inverse_node_matrix is still
- // empty and shape_value_component
- // returns the 'raw' shape values.
+ //Now compute the inverse node
+ //matrix, generating the correct
+ //basis functions from the raw
+ //ones.
+
+ // We use an auxiliary matrix in
+ // this function. Therefore,
+ // inverse_node_matrix is still
+ // empty and shape_value_component
+ // returns the 'raw' shape values.
FullMatrix<double> M(n_dofs, n_dofs);
FETools::compute_node_matrix(M, *this);
// std::cout << std::endl;
// M.print_formatted(std::cout, 2, true);
-
+
this->inverse_node_matrix.reinit(n_dofs, n_dofs);
this->inverse_node_matrix.invert(M);
- // From now on, the shape functions
- // will be the correct ones, not
- // the raw shape functions anymore.
-
+ // From now on, the shape functions
+ // will be the correct ones, not
+ // the raw shape functions anymore.
+
this->reinit_restriction_and_prolongation_matrices(true, true);
FETools::compute_embedding_matrices (*this, this->prolongation, true);
-
+
FullMatrix<double> face_embeddings[GeometryInfo<dim>::max_children_per_face];
for (unsigned int i=0; i<GeometryInfo<dim>::max_children_per_face; ++i)
face_embeddings[i].reinit (this->dofs_per_face, this->dofs_per_face);
FETools::compute_face_embedding_matrices(*this, face_embeddings, 0, 0);
this->interface_constraints.reinit((1<<(dim-1)) * this->dofs_per_face,
- this->dofs_per_face);
+ this->dofs_per_face);
unsigned int target_row=0;
for (unsigned int d=0;d<GeometryInfo<dim>::max_children_per_face;++d)
for (unsigned int i=0;i<face_embeddings[d].m();++i)
{
- for (unsigned int j=0;j<face_embeddings[d].n();++j)
- this->interface_constraints(target_row,j) = face_embeddings[d](i,j);
- ++target_row;
+ for (unsigned int j=0;j<face_embeddings[d].n();++j)
+ this->interface_constraints(target_row,j) = face_embeddings[d](i,j);
+ ++target_row;
}
}
std::string
FE_BDM<dim>::get_name () const
{
- // note that the
- // FETools::get_fe_from_name
- // function depends on the
- // particular format of the string
- // this function returns, so they
- // have to be kept in synch
-
- // note that this->degree is the maximal
- // polynomial degree and is thus one higher
- // than the argument given to the
- // constructor
- std::ostringstream namebuf;
+ // note that the
+ // FETools::get_fe_from_name
+ // function depends on the
+ // particular format of the string
+ // this function returns, so they
+ // have to be kept in synch
+
+ // note that this->degree is the maximal
+ // polynomial degree and is thus one higher
+ // than the argument given to the
+ // constructor
+ std::ostringstream namebuf;
namebuf << "FE_BDM<" << dim << ">(" << this->degree-1 << ")";
return namebuf.str();
{
AssertDimension (values.size(), dim);
Assert (values[0].size() == this->generalized_support_points.size(),
- ExcDimensionMismatch(values.size(), this->generalized_support_points.size()));
+ ExcDimensionMismatch(values.size(), this->generalized_support_points.size()));
Assert (local_dofs.size() == this->dofs_per_cell,
- ExcDimensionMismatch(local_dofs.size(),this->dofs_per_cell));
- // First do interpolation on
- // faces. There, the component
- // evaluated depends on the face
- // direction and orientation.
+ ExcDimensionMismatch(local_dofs.size(),this->dofs_per_cell));
+ // First do interpolation on
+ // faces. There, the component
+ // evaluated depends on the face
+ // direction and orientation.
unsigned int fbase = 0;
unsigned int f=0;
for (;f<GeometryInfo<dim>::faces_per_cell;
++f, fbase+=this->dofs_per_face)
{
for (unsigned int i=0;i<this->dofs_per_face;++i)
- {
- local_dofs[fbase+i] = values[GeometryInfo<dim>::unit_normal_direction[f]][fbase+i];
- }
+ {
+ local_dofs[fbase+i] = values[GeometryInfo<dim>::unit_normal_direction[f]][fbase+i];
+ }
}
- // Done for BDM1
+ // Done for BDM1
if (fbase == this->dofs_per_cell) return;
-
- // What's missing are the interior
- // degrees of freedom. In each
- // point, we take all components of
- // the solution.
+
+ // What's missing are the interior
+ // degrees of freedom. In each
+ // point, we take all components of
+ // the solution.
Assert ((this->dofs_per_cell - fbase) % dim == 0, ExcInternalError());
- // Here, the number of the point
- // and of the shape function
- // coincides. This will change
- // below, since we have more
- // support points than test
- // functions in the interior.
+ // Here, the number of the point
+ // and of the shape function
+ // coincides. This will change
+ // below, since we have more
+ // support points than test
+ // functions in the interior.
const unsigned int pbase = fbase;
for (unsigned int d=0;d<dim;++d, fbase += test_values[0].size())
{
for (unsigned int i=0;i<test_values[0].size();++i)
- {
- local_dofs[fbase+i] = 0.;
- for (unsigned int k=0;k<test_values.size();++k)
- local_dofs[fbase+i] += values[d][pbase+k] * test_values[k][i];
- }
+ {
+ local_dofs[fbase+i] = 0.;
+ for (unsigned int k=0;k<test_values.size();++k)
+ local_dofs[fbase+i] += values[d][pbase+k] * test_values[k][i];
+ }
}
-
+
Assert (fbase == this->dofs_per_cell, ExcInternalError());
}
interior_dofs *= deg-2;
interior_dofs /= 3;
}
-
+
std::vector<unsigned int> dpo(dim+1);
dpo[dim-1] = dofs_per_face;
dpo[dim] = interior_dofs;
-
+
return dpo;
}
Assert(dim==2, ExcNotImplemented());
const unsigned int dofs_per_cell = PolynomialsBDM<dim>::compute_n_pols(deg);
const unsigned int dofs_per_face = deg+1;
- // all dofs need to be
- // non-additive, since they have
- // continuity requirements.
- // however, the interior dofs are
- // made additive
+ // all dofs need to be
+ // non-additive, since they have
+ // continuity requirements.
+ // however, the interior dofs are
+ // made additive
std::vector<bool> ret_val(dofs_per_cell,false);
for (unsigned int i=GeometryInfo<dim>::faces_per_cell*dofs_per_face;
i < dofs_per_cell; ++i)
void
FE_BDM<dim>::initialize_support_points (const unsigned int deg)
{
- // interior point in 1d
+ // interior point in 1d
unsigned int npoints = deg;
- // interior point in 2d
+ // interior point in 2d
if (dim >= 2)
{
npoints *= deg;
// npoints /= 2;
}
- // interior point in 2d
+ // interior point in 2d
if (dim >= 3)
{
npoints *= deg;
// npoints /= 3;
}
npoints += GeometryInfo<dim>::faces_per_cell * this->dofs_per_face;
-
+
this->generalized_support_points.resize (npoints);
this->generalized_face_support_points.resize (this->dofs_per_face);
- // Number of the point being entered
+ // Number of the point being entered
unsigned int current = 0;
- // On the faces, we choose as many
- // Gauss points as necessary to
- // determine the normal component
- // uniquely. This is the deg of
- // the BDM element plus
- // one.
+ // On the faces, we choose as many
+ // Gauss points as necessary to
+ // determine the normal component
+ // uniquely. This is the deg of
+ // the BDM element plus
+ // one.
if (dim>1)
{
QGauss<dim-1> face_points (deg+1);
Assert (face_points.size() == this->dofs_per_face,
- ExcInternalError());
+ ExcInternalError());
for (unsigned int k=0;k<this->dofs_per_face;++k)
- this->generalized_face_support_points[k] = face_points.point(k);
+ this->generalized_face_support_points[k] = face_points.point(k);
Quadrature<dim> faces = QProjector<dim>::project_to_all_faces(face_points);
for (unsigned int k=0;
- k<this->dofs_per_face*GeometryInfo<dim>::faces_per_cell;
- ++k)
- this->generalized_support_points[k] = faces.point(k+QProjector<dim>
- ::DataSetDescriptor::face(0,
- true,
- false,
- false,
- this->dofs_per_face));
+ k<this->dofs_per_face*GeometryInfo<dim>::faces_per_cell;
+ ++k)
+ this->generalized_support_points[k] = faces.point(k+QProjector<dim>
+ ::DataSetDescriptor::face(0,
+ true,
+ false,
+ false,
+ this->dofs_per_face));
current = this->dofs_per_face*GeometryInfo<dim>::faces_per_cell;
}
-
+
if (deg<=1) return;
- // Although the polynomial space is
- // only P_{k-2}, we use the tensor
- // product points for Q_{k-2}
+ // Although the polynomial space is
+ // only P_{k-2}, we use the tensor
+ // product points for Q_{k-2}
QGauss<dim> quadrature(deg);
-
- // Remember where interior points start
+
+ // Remember where interior points start
const unsigned int ibase=current;
// for (unsigned int k=0;k<deg-1;++k)
for (unsigned int j=0;j<deg;++j)
for (unsigned int i=0;i<deg;++i)
{
- this->generalized_support_points[current] = quadrature.point(current-ibase);
- ++current;
+ this->generalized_support_points[current] = quadrature.point(current-ibase);
+ ++current;
}
Assert(current == npoints, ExcInternalError());
- // Finaly, compute the values of
- // the test functios in the
- // interior quadrature points
+ // Finaly, compute the values of
+ // the test functios in the
+ // interior quadrature points
PolynomialsP<dim> poly(deg-2);
-
+
test_values.resize(quadrature.size());
std::vector<Tensor<1,dim> > dummy1;
std::vector<Tensor<2,dim> > dummy2;
-
+
for (unsigned int k=0;k<quadrature.size();++k)
{
test_values[k].resize(poly.n());
poly.compute(quadrature.point(k), test_values[k], dummy1, dummy2);
for (unsigned int i=0; i < poly.n(); ++i)
- {
- test_values[k][i] *= quadrature.weight(k);
- }
+ {
+ test_values[k][i] *= quadrature.weight(k);
+ }
}
}
// $Id$
// Version: $Name$
//
-// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2010, 2011 by the deal.II authors
+// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2010, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
template<int dim>
FiniteElementData<dim>::FiniteElementData ()
:
- dofs_per_vertex(0),
- dofs_per_line(0),
- dofs_per_quad(0),
- dofs_per_hex(0),
- first_line_index(0),
- first_quad_index(0),
- first_hex_index(0),
- first_face_line_index(0),
- first_face_quad_index(0),
- dofs_per_face(0),
- dofs_per_cell (0),
- components(0),
- degree(0),
- conforming_space(unknown),
- cached_primitivity(false)
+ dofs_per_vertex(0),
+ dofs_per_line(0),
+ dofs_per_quad(0),
+ dofs_per_hex(0),
+ first_line_index(0),
+ first_quad_index(0),
+ first_hex_index(0),
+ first_face_line_index(0),
+ first_face_quad_index(0),
+ dofs_per_face(0),
+ dofs_per_cell (0),
+ components(0),
+ degree(0),
+ conforming_space(unknown),
+ cached_primitivity(false)
{}
FiniteElementData (const std::vector<unsigned int> &dofs_per_object,
const unsigned int n_components,
const unsigned int degree,
- const Conformity conformity,
- const unsigned int)
+ const Conformity conformity,
+ const unsigned int)
:
- dofs_per_vertex(dofs_per_object[0]),
- dofs_per_line(dofs_per_object[1]),
- dofs_per_quad(dim>1? dofs_per_object[2]:0),
- dofs_per_hex(dim>2? dofs_per_object[3]:0),
- first_line_index(GeometryInfo<dim>::vertices_per_cell
- * dofs_per_vertex),
- first_quad_index(first_line_index+
- GeometryInfo<dim>::lines_per_cell
- * dofs_per_line),
- first_hex_index(first_quad_index+
- GeometryInfo<dim>::quads_per_cell
- * dofs_per_quad),
- first_face_line_index(GeometryInfo<dim-1>::vertices_per_cell
- * dofs_per_vertex),
- first_face_quad_index((dim==3 ?
- GeometryInfo<dim-1>::vertices_per_cell
- * dofs_per_vertex :
- GeometryInfo<dim>::vertices_per_cell
- * dofs_per_vertex) +
- GeometryInfo<dim-1>::lines_per_cell
- * dofs_per_line),
- dofs_per_face(GeometryInfo<dim>::vertices_per_face * dofs_per_vertex +
- GeometryInfo<dim>::lines_per_face * dofs_per_line +
- GeometryInfo<dim>::quads_per_face * dofs_per_quad),
- dofs_per_cell (GeometryInfo<dim>::vertices_per_cell * dofs_per_vertex +
- GeometryInfo<dim>::lines_per_cell * dofs_per_line +
- GeometryInfo<dim>::quads_per_cell * dofs_per_quad +
- GeometryInfo<dim>::hexes_per_cell * dofs_per_hex),
- components(n_components),
- degree(degree),
- conforming_space(conformity),
- block_indices_data(1, dofs_per_cell)
+ dofs_per_vertex(dofs_per_object[0]),
+ dofs_per_line(dofs_per_object[1]),
+ dofs_per_quad(dim>1? dofs_per_object[2]:0),
+ dofs_per_hex(dim>2? dofs_per_object[3]:0),
+ first_line_index(GeometryInfo<dim>::vertices_per_cell
+ * dofs_per_vertex),
+ first_quad_index(first_line_index+
+ GeometryInfo<dim>::lines_per_cell
+ * dofs_per_line),
+ first_hex_index(first_quad_index+
+ GeometryInfo<dim>::quads_per_cell
+ * dofs_per_quad),
+ first_face_line_index(GeometryInfo<dim-1>::vertices_per_cell
+ * dofs_per_vertex),
+ first_face_quad_index((dim==3 ?
+ GeometryInfo<dim-1>::vertices_per_cell
+ * dofs_per_vertex :
+ GeometryInfo<dim>::vertices_per_cell
+ * dofs_per_vertex) +
+ GeometryInfo<dim-1>::lines_per_cell
+ * dofs_per_line),
+ dofs_per_face(GeometryInfo<dim>::vertices_per_face * dofs_per_vertex +
+ GeometryInfo<dim>::lines_per_face * dofs_per_line +
+ GeometryInfo<dim>::quads_per_face * dofs_per_quad),
+ dofs_per_cell (GeometryInfo<dim>::vertices_per_cell * dofs_per_vertex +
+ GeometryInfo<dim>::lines_per_cell * dofs_per_line +
+ GeometryInfo<dim>::quads_per_cell * dofs_per_quad +
+ GeometryInfo<dim>::hexes_per_cell * dofs_per_hex),
+ components(n_components),
+ degree(degree),
+ conforming_space(conformity),
+ block_indices_data(1, dofs_per_cell)
{
Assert(dofs_per_object.size()==dim+1, ExcDimensionMismatch(dofs_per_object.size()-1,dim));
}
bool FiniteElementData<dim>::operator== (const FiniteElementData<dim> &f) const
{
return ((dofs_per_vertex == f.dofs_per_vertex) &&
- (dofs_per_line == f.dofs_per_line) &&
- (dofs_per_quad == f.dofs_per_quad) &&
- (dofs_per_hex == f.dofs_per_hex) &&
- (components == f.components) &&
- (degree == f.degree) &&
- (conforming_space == f.conforming_space));
+ (dofs_per_line == f.dofs_per_line) &&
+ (dofs_per_quad == f.dofs_per_quad) &&
+ (dofs_per_hex == f.dofs_per_hex) &&
+ (components == f.components) &&
+ (degree == f.degree) &&
+ (conforming_space == f.conforming_space));
}
template<int dim>
unsigned int
FiniteElementData<dim>::
face_to_cell_index (const unsigned int face_index,
- const unsigned int face,
- const bool face_orientation,
- const bool face_flip,
- const bool face_rotation) const
+ const unsigned int face,
+ const bool face_orientation,
+ const bool face_flip,
+ const bool face_rotation) const
{
Assert (face_index < this->dofs_per_face,
- ExcIndexRange(face_index, 0, this->dofs_per_face));
+ ExcIndexRange(face_index, 0, this->dofs_per_face));
Assert (face < GeometryInfo<dim>::faces_per_cell,
- ExcIndexRange(face, 0, GeometryInfo<dim>::faces_per_cell));
-
- // DoF on a vertex
+ ExcIndexRange(face, 0, GeometryInfo<dim>::faces_per_cell));
+
+ // DoF on a vertex
if (face_index < this->first_face_line_index)
{
- // Vertex number on the face
+ // Vertex number on the face
const unsigned int face_vertex = face_index / this->dofs_per_vertex;
return face_index % this->dofs_per_vertex
- + GeometryInfo<dim>::face_to_cell_vertices(face, face_vertex,
- face_orientation,
- face_flip,
- face_rotation)
- * this->dofs_per_vertex;
+ + GeometryInfo<dim>::face_to_cell_vertices(face, face_vertex,
+ face_orientation,
+ face_flip,
+ face_rotation)
+ * this->dofs_per_vertex;
}
- // Else, DoF on a line?
+ // Else, DoF on a line?
if (face_index < this->first_face_quad_index)
{
- // Ignore vertex dofs
+ // Ignore vertex dofs
const unsigned int index = face_index - this->first_face_line_index;
- // Line number on the face
+ // Line number on the face
const unsigned int face_line = index / this->dofs_per_line;
return this->first_line_index + index % this->dofs_per_line
- + GeometryInfo<dim>::face_to_cell_lines(face, face_line,
- face_orientation,
- face_flip,
- face_rotation)
- * this->dofs_per_line;
+ + GeometryInfo<dim>::face_to_cell_lines(face, face_line,
+ face_orientation,
+ face_flip,
+ face_rotation)
+ * this->dofs_per_line;
}
- // Else, DoF is on a quad
+ // Else, DoF is on a quad
- // Ignore vertex and line dofs
+ // Ignore vertex and line dofs
const unsigned int index = face_index - this->first_face_quad_index;
return this->first_quad_index + index
+ face * this->dofs_per_quad;
//---------------------------------------------------------------------------
// $Id$
//
-// Copyright (C) 2010 by the deal.II authors
+// Copyright (C) 2010, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
std::string
FE_DGNedelec<dim, spacedim>::get_name () const
{
- // note that the
- // FETools::get_fe_from_name
- // function depends on the
- // particular format of the string
- // this function returns, so they
- // have to be kept in synch
+ // note that the
+ // FETools::get_fe_from_name
+ // function depends on the
+ // particular format of the string
+ // this function returns, so they
+ // have to be kept in synch
std::ostringstream namebuf;
namebuf << "FE_DGNedelec<" << dim << ',' << spacedim << ">(" << this->degree-1 << ")";
std::string
FE_DGRaviartThomas<dim, spacedim>::get_name () const
{
- // note that the
- // FETools::get_fe_from_name
- // function depends on the
- // particular format of the string
- // this function returns, so they
- // have to be kept in synch
+ // note that the
+ // FETools::get_fe_from_name
+ // function depends on the
+ // particular format of the string
+ // this function returns, so they
+ // have to be kept in synch
std::ostringstream namebuf;
namebuf << "FE_DGRaviartThomas<" << dim << ',' << spacedim << ">(" << this->degree-1 << ")";
std::string
FE_DGBDM<dim, spacedim>::get_name () const
{
- // note that the
- // FETools::get_fe_from_name
- // function depends on the
- // particular format of the string
- // this function returns, so they
- // have to be kept in synch
+ // note that the
+ // FETools::get_fe_from_name
+ // function depends on the
+ // particular format of the string
+ // this function returns, so they
+ // have to be kept in synch
std::ostringstream namebuf;
namebuf << "FE_DGBDM<" << dim << ',' << spacedim << ">(" << this->degree-1 << ")";
// $Id$
// Version: $Name$
//
-// Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2011 by the deal.II authors
+// Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
template <int dim, int spacedim>
FE_DGP<dim,spacedim>::FE_DGP (const unsigned int degree)
- :
+ :
FE_Poly<PolynomialSpace<dim>, dim, spacedim> (
- PolynomialSpace<dim>(Polynomials::Legendre::generate_complete_basis(degree)),
- FiniteElementData<dim>(get_dpo_vector(degree), 1, degree, FiniteElementData<dim>::L2),
- std::vector<bool>(FiniteElementData<dim>(get_dpo_vector(degree), 1, degree).dofs_per_cell,true),
- std::vector<std::vector<bool> >(FiniteElementData<dim>(
- get_dpo_vector(degree), 1, degree).dofs_per_cell, std::vector<bool>(1,true)))
+ PolynomialSpace<dim>(Polynomials::Legendre::generate_complete_basis(degree)),
+ FiniteElementData<dim>(get_dpo_vector(degree), 1, degree, FiniteElementData<dim>::L2),
+ std::vector<bool>(FiniteElementData<dim>(get_dpo_vector(degree), 1, degree).dofs_per_cell,true),
+ std::vector<std::vector<bool> >(FiniteElementData<dim>(
+ get_dpo_vector(degree), 1, degree).dofs_per_cell, std::vector<bool>(1,true)))
{
- // Reinit the vectors of
- // restriction and prolongation
- // matrices to the right sizes
+ // Reinit the vectors of
+ // restriction and prolongation
+ // matrices to the right sizes
this->reinit_restriction_and_prolongation_matrices();
- // Fill prolongation matrices with embedding operators
+ // Fill prolongation matrices with embedding operators
if (dim == spacedim)
{
FETools::compute_embedding_matrices (*this, this->prolongation);
- // Fill restriction matrices with L2-projection
+ // Fill restriction matrices with L2-projection
FETools::compute_projection_matrices (*this, this->restriction);
}
}
std::string
FE_DGP<dim,spacedim>::get_name () const
{
- // note that the
- // FETools::get_fe_from_name
- // function depends on the
- // particular format of the string
- // this function returns, so they
- // have to be kept in synch
+ // note that the
+ // FETools::get_fe_from_name
+ // function depends on the
+ // particular format of the string
+ // this function returns, so they
+ // have to be kept in synch
std::ostringstream namebuf;
namebuf << "FE_DGP<" << dim << ">(" << this->degree << ")";
void
FE_DGP<dim,spacedim>::
get_face_interpolation_matrix (const FiniteElement<dim,spacedim> &x_source_fe,
- FullMatrix<double> &interpolation_matrix) const
+ FullMatrix<double> &interpolation_matrix) const
{
- // this is only implemented, if the source
- // FE is also a DGP element. in that case,
- // both elements have no dofs on their
- // faces and the face interpolation matrix
- // is necessarily empty -- i.e. there isn't
- // much we need to do here.
+ // this is only implemented, if the source
+ // FE is also a DGP element. in that case,
+ // both elements have no dofs on their
+ // faces and the face interpolation matrix
+ // is necessarily empty -- i.e. there isn't
+ // much we need to do here.
typedef FiniteElement<dim,spacedim> FE;
typedef FE_DGP<dim,spacedim> FEDGP;
AssertThrow ((x_source_fe.get_name().find ("FE_DGP<") == 0)
ExcInterpolationNotImplemented());
Assert (interpolation_matrix.m() == 0,
- ExcDimensionMismatch (interpolation_matrix.m(),
- 0));
+ ExcDimensionMismatch (interpolation_matrix.m(),
+ 0));
Assert (interpolation_matrix.n() == 0,
- ExcDimensionMismatch (interpolation_matrix.n(),
- 0));
+ ExcDimensionMismatch (interpolation_matrix.n(),
+ 0));
}
void
FE_DGP<dim,spacedim>::
get_subface_interpolation_matrix (const FiniteElement<dim,spacedim> &x_source_fe,
- const unsigned int ,
- FullMatrix<double> &interpolation_matrix) const
+ const unsigned int ,
+ FullMatrix<double> &interpolation_matrix) const
{
- // this is only implemented, if the source
- // FE is also a DGP element. in that case,
- // both elements have no dofs on their
- // faces and the face interpolation matrix
- // is necessarily empty -- i.e. there isn't
- // much we need to do here.
+ // this is only implemented, if the source
+ // FE is also a DGP element. in that case,
+ // both elements have no dofs on their
+ // faces and the face interpolation matrix
+ // is necessarily empty -- i.e. there isn't
+ // much we need to do here.
typedef FiniteElement<dim,spacedim> FE;
typedef FE_DGP<dim,spacedim> FEDGP;
AssertThrow ((x_source_fe.get_name().find ("FE_DGP<") == 0)
ExcInterpolationNotImplemented());
Assert (interpolation_matrix.m() == 0,
- ExcDimensionMismatch (interpolation_matrix.m(),
- 0));
+ ExcDimensionMismatch (interpolation_matrix.m(),
+ 0));
Assert (interpolation_matrix.n() == 0,
- ExcDimensionMismatch (interpolation_matrix.n(),
- 0));
+ ExcDimensionMismatch (interpolation_matrix.n(),
+ 0));
}
FE_DGP<dim,spacedim>::
hp_vertex_dof_identities (const FiniteElement<dim,spacedim> &fe_other) const
{
- // there are no such constraints for DGP
- // elements at all
+ // there are no such constraints for DGP
+ // elements at all
if (dynamic_cast<const FE_DGP<dim,spacedim>*>(&fe_other) != 0)
return
std::vector<std::pair<unsigned int, unsigned int> > ();
FE_DGP<dim,spacedim>::
hp_line_dof_identities (const FiniteElement<dim,spacedim> &fe_other) const
{
- // there are no such constraints for DGP
- // elements at all
+ // there are no such constraints for DGP
+ // elements at all
if (dynamic_cast<const FE_DGP<dim,spacedim>*>(&fe_other) != 0)
return
std::vector<std::pair<unsigned int, unsigned int> > ();
FE_DGP<dim,spacedim>::
hp_quad_dof_identities (const FiniteElement<dim,spacedim> &fe_other) const
{
- // there are no such constraints for DGP
- // elements at all
+ // there are no such constraints for DGP
+ // elements at all
if (dynamic_cast<const FE_DGP<dim,spacedim>*>(&fe_other) != 0)
return
std::vector<std::pair<unsigned int, unsigned int> > ();
FiniteElementDomination::Domination
FE_DGP<dim,spacedim>::compare_for_face_domination (const FiniteElement<dim,spacedim> &fe_other) const
{
- // check whether both are discontinuous
- // elements, see the description of
- // FiniteElementDomination::Domination
+ // check whether both are discontinuous
+ // elements, see the description of
+ // FiniteElementDomination::Domination
if (dynamic_cast<const FE_DGP<dim,spacedim>*>(&fe_other) != 0)
return FiniteElementDomination::no_requirements;
template <int dim, int spacedim>
bool
FE_DGP<dim,spacedim>::has_support_on_face (const unsigned int,
- const unsigned int) const
+ const unsigned int) const
{
// all shape functions have support on all
// faces
// $Id$
// Version: $Name$
//
-// Copyright (C) 2004, 2005, 2006, 2007, 2008, 2011 by the deal.II authors
+// Copyright (C) 2004, 2005, 2006, 2007, 2008, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
// namespace for some functions that are used in this file.
namespace
{
- // storage of hand-chosen support
- // points
- //
- // For dim=2, dofs_per_cell of
- // FE_DGPMonomial(k) is given by
- // 0.5(k+1)(k+2), i.e.
- //
- // k 0 1 2 3 4 5 6 7
- // dofs 1 3 6 10 15 21 28 36
- //
- // indirect access of unit points:
- // the points for degree k are
- // located at
- //
- // points[start_index[k]..start_index[k+1]-1]
+ // storage of hand-chosen support
+ // points
+ //
+ // For dim=2, dofs_per_cell of
+ // FE_DGPMonomial(k) is given by
+ // 0.5(k+1)(k+2), i.e.
+ //
+ // k 0 1 2 3 4 5 6 7
+ // dofs 1 3 6 10 15 21 28 36
+ //
+ // indirect access of unit points:
+ // the points for degree k are
+ // located at
+ //
+ // points[start_index[k]..start_index[k+1]-1]
const unsigned int start_index2d[6]={0,1,4,10,20,35};
const double points2d[35][2]=
{{0,0},
{0,0},{1,0},{0,1},{1,1},{0.25,0},{0.5,0},{0.75,0},{0,0.25},{0,0.5},{0,0.75},{1./3.,1},{2./3.,1},{1,1./3.},{1,2./3.},{0.5,0.5}
};
- // For dim=3, dofs_per_cell of
- // FE_DGPMonomial(k) is given by
- // 1./6.(k+1)(k+2)(k+3), i.e.
- //
- // k 0 1 2 3 4 5 6 7
- // dofs 1 4 10 20 35 56 84 120
+ // For dim=3, dofs_per_cell of
+ // FE_DGPMonomial(k) is given by
+ // 1./6.(k+1)(k+2)(k+3), i.e.
+ //
+ // k 0 1 2 3 4 5 6 7
+ // dofs 1 4 10 20 35 56 84 120
const unsigned int start_index3d[6]={0,1,5,15/*,35*/};
const double points3d[35][3]=
{{0,0,0},
template<int dim>
void generate_unit_points (const unsigned int,
- std::vector<Point<dim> > &);
+ std::vector<Point<dim> > &);
template <>
void generate_unit_points (const unsigned int k,
- std::vector<Point<1> > &p)
+ std::vector<Point<1> > &p)
{
Assert(p.size()==k+1, ExcDimensionMismatch(p.size(), k+1));
const double h = 1./k;
template <>
void generate_unit_points (const unsigned int k,
- std::vector<Point<2> > &p)
+ std::vector<Point<2> > &p)
{
Assert(k<=4, ExcNotImplemented());
Assert(p.size()==start_index2d[k+1]-start_index2d[k], ExcInternalError());
for (unsigned int i=0; i<p.size(); ++i)
{
- p[i](0)=points2d[start_index2d[k]+i][0];
- p[i](1)=points2d[start_index2d[k]+i][1];
+ p[i](0)=points2d[start_index2d[k]+i][0];
+ p[i](1)=points2d[start_index2d[k]+i][1];
}
}
template <>
void generate_unit_points (const unsigned int k,
- std::vector<Point<3> > &p)
+ std::vector<Point<3> > &p)
{
Assert(k<=2, ExcNotImplemented());
Assert(p.size()==start_index3d[k+1]-start_index3d[k], ExcInternalError());
for (unsigned int i=0; i<p.size(); ++i)
{
- p[i](0)=points3d[start_index3d[k]+i][0];
- p[i](1)=points3d[start_index3d[k]+i][1];
- p[i](2)=points3d[start_index3d[k]+i][2];
+ p[i](0)=points3d[start_index3d[k]+i][0];
+ p[i](1)=points3d[start_index3d[k]+i][1];
+ p[i](2)=points3d[start_index3d[k]+i][2];
}
}
}
template <int dim>
FE_DGPMonomial<dim>::FE_DGPMonomial (const unsigned int degree)
- :
- FE_Poly<PolynomialsP<dim>, dim> (
- PolynomialsP<dim>(degree),
- FiniteElementData<dim>(get_dpo_vector(degree), 1, degree, FiniteElementData<dim>::L2),
- std::vector<bool>(FiniteElementData<dim>(get_dpo_vector(degree), 1, degree).dofs_per_cell,true),
- std::vector<std::vector<bool> >(FiniteElementData<dim>(
- get_dpo_vector(degree), 1, degree).dofs_per_cell, std::vector<bool>(1,true)))
+ :
+ FE_Poly<PolynomialsP<dim>, dim> (
+ PolynomialsP<dim>(degree),
+ FiniteElementData<dim>(get_dpo_vector(degree), 1, degree, FiniteElementData<dim>::L2),
+ std::vector<bool>(FiniteElementData<dim>(get_dpo_vector(degree), 1, degree).dofs_per_cell,true),
+ std::vector<std::vector<bool> >(FiniteElementData<dim>(
+ get_dpo_vector(degree), 1, degree).dofs_per_cell, std::vector<bool>(1,true)))
{
Assert(this->poly_space.n()==this->dofs_per_cell, ExcInternalError());
Assert(this->poly_space.degree()==this->degree, ExcInternalError());
- // DG doesn't have constraints, so
- // leave them empty
+ // DG doesn't have constraints, so
+ // leave them empty
- // Reinit the vectors of
- // restriction and prolongation
- // matrices to the right sizes
+ // Reinit the vectors of
+ // restriction and prolongation
+ // matrices to the right sizes
this->reinit_restriction_and_prolongation_matrices();
- // Fill prolongation matrices with embedding operators
+ // Fill prolongation matrices with embedding operators
FETools::compute_embedding_matrices (*this, this->prolongation);
- // Fill restriction matrices with L2-projection
+ // Fill restriction matrices with L2-projection
FETools::compute_projection_matrices (*this, this->restriction);
}
std::string
FE_DGPMonomial<dim>::get_name () const
{
- // note that the
- // FETools::get_fe_from_name
- // function depends on the
- // particular format of the string
- // this function returns, so they
- // have to be kept in synch
+ // note that the
+ // FETools::get_fe_from_name
+ // function depends on the
+ // particular format of the string
+ // this function returns, so they
+ // have to be kept in synch
std::ostringstream namebuf;
namebuf << "FE_DGPMonomial<" << dim << ">(" << this->degree << ")";
void
FE_DGPMonomial<dim>::
get_interpolation_matrix (const FiniteElement<dim> &source_fe,
- FullMatrix<double> &interpolation_matrix) const
+ FullMatrix<double> &interpolation_matrix) const
{
const FE_DGPMonomial<dim> *source_dgp_monomial
= dynamic_cast<const FE_DGPMonomial<dim> *>(&source_fe);
if (source_dgp_monomial)
{
- // ok, source_fe is a DGP_Monomial
- // element. Then, the interpolation
- // matrix is simple
+ // ok, source_fe is a DGP_Monomial
+ // element. Then, the interpolation
+ // matrix is simple
const unsigned int m=interpolation_matrix.m();
const unsigned int n=interpolation_matrix.n();
Assert (m == this->dofs_per_cell, ExcDimensionMismatch (m, this->dofs_per_cell));
Assert (n == source_dgp_monomial->dofs_per_cell,
- ExcDimensionMismatch (n, source_dgp_monomial->dofs_per_cell));
+ ExcDimensionMismatch (n, source_dgp_monomial->dofs_per_cell));
const unsigned int min_mn=
- interpolation_matrix.m()<interpolation_matrix.n() ?
- interpolation_matrix.m() : interpolation_matrix.n();
+ interpolation_matrix.m()<interpolation_matrix.n() ?
+ interpolation_matrix.m() : interpolation_matrix.n();
for (unsigned int i=0; i<min_mn; ++i)
- interpolation_matrix(i,i)=1.;
+ interpolation_matrix(i,i)=1.;
}
else
{
FullMatrix<double> source_fe_matrix(unit_points.size(), source_fe.dofs_per_cell);
for (unsigned int j=0; j<source_fe.dofs_per_cell; ++j)
- for (unsigned int k=0; k<unit_points.size(); ++k)
- source_fe_matrix(k,j)=source_fe.shape_value(j, unit_points[k]);
+ for (unsigned int k=0; k<unit_points.size(); ++k)
+ source_fe_matrix(k,j)=source_fe.shape_value(j, unit_points[k]);
FullMatrix<double> this_matrix(this->dofs_per_cell, this->dofs_per_cell);
for (unsigned int j=0; j<this->dofs_per_cell; ++j)
- for (unsigned int k=0; k<unit_points.size(); ++k)
- this_matrix(k,j)=this->poly_space.compute_value (j, unit_points[k]);
+ for (unsigned int k=0; k<unit_points.size(); ++k)
+ this_matrix(k,j)=this->poly_space.compute_value (j, unit_points[k]);
this_matrix.gauss_jordan();
void
FE_DGPMonomial<dim>::
get_face_interpolation_matrix (const FiniteElement<dim> &x_source_fe,
- FullMatrix<double> &interpolation_matrix) const
+ FullMatrix<double> &interpolation_matrix) const
{
- // this is only implemented, if the source
- // FE is also a DGPMonomial element. in that case,
- // both elements have no dofs on their
- // faces and the face interpolation matrix
- // is necessarily empty -- i.e. there isn't
- // much we need to do here.
+ // this is only implemented, if the source
+ // FE is also a DGPMonomial element. in that case,
+ // both elements have no dofs on their
+ // faces and the face interpolation matrix
+ // is necessarily empty -- i.e. there isn't
+ // much we need to do here.
AssertThrow ((x_source_fe.get_name().find ("FE_DGPMonomial<") == 0)
||
(dynamic_cast<const FE_DGPMonomial<dim>*>(&x_source_fe) != 0),
ExcInterpolationNotImplemented());
Assert (interpolation_matrix.m() == 0,
- ExcDimensionMismatch (interpolation_matrix.m(),
- 0));
+ ExcDimensionMismatch (interpolation_matrix.m(),
+ 0));
Assert (interpolation_matrix.n() == 0,
- ExcDimensionMismatch (interpolation_matrix.n(),
- 0));
+ ExcDimensionMismatch (interpolation_matrix.n(),
+ 0));
}
void
FE_DGPMonomial<dim>::
get_subface_interpolation_matrix (const FiniteElement<dim> &x_source_fe,
- const unsigned int ,
- FullMatrix<double> &interpolation_matrix) const
+ const unsigned int ,
+ FullMatrix<double> &interpolation_matrix) const
{
- // this is only implemented, if the source
- // FE is also a DGPMonomial element. in that case,
- // both elements have no dofs on their
- // faces and the face interpolation matrix
- // is necessarily empty -- i.e. there isn't
- // much we need to do here.
+ // this is only implemented, if the source
+ // FE is also a DGPMonomial element. in that case,
+ // both elements have no dofs on their
+ // faces and the face interpolation matrix
+ // is necessarily empty -- i.e. there isn't
+ // much we need to do here.
AssertThrow ((x_source_fe.get_name().find ("FE_DGPMonomial<") == 0)
||
(dynamic_cast<const FE_DGPMonomial<dim>*>(&x_source_fe) != 0),
ExcInterpolationNotImplemented());
Assert (interpolation_matrix.m() == 0,
- ExcDimensionMismatch (interpolation_matrix.m(),
- 0));
+ ExcDimensionMismatch (interpolation_matrix.m(),
+ 0));
Assert (interpolation_matrix.n() == 0,
- ExcDimensionMismatch (interpolation_matrix.n(),
- 0));
+ ExcDimensionMismatch (interpolation_matrix.n(),
+ 0));
}
FE_DGPMonomial<dim>::
hp_vertex_dof_identities (const FiniteElement<dim> &fe_other) const
{
- // there are no such constraints for DGPMonomial
- // elements at all
+ // there are no such constraints for DGPMonomial
+ // elements at all
if (dynamic_cast<const FE_DGPMonomial<dim>*>(&fe_other) != 0)
return
std::vector<std::pair<unsigned int, unsigned int> > ();
FE_DGPMonomial<dim>::
hp_line_dof_identities (const FiniteElement<dim> &fe_other) const
{
- // there are no such constraints for DGPMonomial
- // elements at all
+ // there are no such constraints for DGPMonomial
+ // elements at all
if (dynamic_cast<const FE_DGPMonomial<dim>*>(&fe_other) != 0)
return
std::vector<std::pair<unsigned int, unsigned int> > ();
FE_DGPMonomial<dim>::
hp_quad_dof_identities (const FiniteElement<dim> &fe_other) const
{
- // there are no such constraints for DGPMonomial
- // elements at all
+ // there are no such constraints for DGPMonomial
+ // elements at all
if (dynamic_cast<const FE_DGPMonomial<dim>*>(&fe_other) != 0)
return
std::vector<std::pair<unsigned int, unsigned int> > ();
FE_DGPMonomial<dim>::
compare_for_face_domination (const FiniteElement<dim> &fe_other) const
{
- // check whether both are discontinuous
- // elements, see
- // the description of
- // FiniteElementDomination::Domination
+ // check whether both are discontinuous
+ // elements, see
+ // the description of
+ // FiniteElementDomination::Domination
if (dynamic_cast<const FE_DGPMonomial<dim>*>(&fe_other) != 0)
return FiniteElementDomination::no_requirements;
template <>
bool
FE_DGPMonomial<1>::has_support_on_face (const unsigned int,
- const unsigned int face_index) const
+ const unsigned int face_index) const
{
return face_index==1 || (face_index==0 && this->degree==0);
}
template <>
bool
FE_DGPMonomial<2>::has_support_on_face (const unsigned int shape_index,
- const unsigned int face_index) const
+ const unsigned int face_index) const
{
bool support_on_face=false;
if (face_index==1 || face_index==2)
unsigned int degrees[2];
this->poly_space.directional_degrees(shape_index, degrees);
if ((face_index==0 && degrees[1]==0) ||
- (face_index==3 && degrees[0]==0))
- support_on_face=true;
+ (face_index==3 && degrees[0]==0))
+ support_on_face=true;
}
return support_on_face;
}
template <>
bool
FE_DGPMonomial<3>::has_support_on_face (const unsigned int shape_index,
- const unsigned int face_index) const
+ const unsigned int face_index) const
{
bool support_on_face=false;
if (face_index==1 || face_index==3 || face_index==4)
unsigned int degrees[3];
this->poly_space.directional_degrees(shape_index, degrees);
if ((face_index==0 && degrees[1]==0) ||
- (face_index==2 && degrees[2]==0) ||
- (face_index==5 && degrees[0]==0))
- support_on_face=true;
+ (face_index==2 && degrees[2]==0) ||
+ (face_index==5 && degrees[0]==0))
+ support_on_face=true;
}
return support_on_face;
}
// $Id$
// Version: $Name$
//
-// Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2011 by the deal.II authors
+// Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
template <int dim, int spacedim>
FE_DGPNonparametric<dim,spacedim>::FE_DGPNonparametric (const unsigned int degree)
- :
- FiniteElement<dim,spacedim> (
- FiniteElementData<dim>(get_dpo_vector(degree), 1, degree,
- FiniteElementData<dim>::L2),
- std::vector<bool>(
- FiniteElementData<dim>(get_dpo_vector(degree), 1, degree).dofs_per_cell,true),
- std::vector<std::vector<bool> >(
- FiniteElementData<dim>(get_dpo_vector(degree),1, degree).dofs_per_cell,
- std::vector<bool>(1,true))),
+ :
+ FiniteElement<dim,spacedim> (
+ FiniteElementData<dim>(get_dpo_vector(degree), 1, degree,
+ FiniteElementData<dim>::L2),
+ std::vector<bool>(
+ FiniteElementData<dim>(get_dpo_vector(degree), 1, degree).dofs_per_cell,true),
+ std::vector<std::vector<bool> >(
+ FiniteElementData<dim>(get_dpo_vector(degree),1, degree).dofs_per_cell,
+ std::vector<bool>(1,true))),
degree(degree),
polynomial_space (Polynomials::Legendre::generate_complete_basis(degree))
{
ref_case<RefinementCase<dim>::isotropic_refinement+1; ++ref_case)
{
if (dim!=2 && ref_case!=RefinementCase<dim>::isotropic_refinement)
- // do nothing, as anisotropic
- // refinement is not
- // implemented so far
- continue;
+ // do nothing, as anisotropic
+ // refinement is not
+ // implemented so far
+ continue;
const unsigned int nc = GeometryInfo<dim>::n_children(RefinementCase<dim>(ref_case));
for (unsigned int i=0;i<nc;++i)
- {
- this->prolongation[ref_case-1][i].reinit (n_dofs, n_dofs);
- // Fill prolongation matrices with
- // embedding operators
- for (unsigned int j=0;j<n_dofs;++j)
- this->prolongation[ref_case-1][i](j,j) = 1.;
- }
+ {
+ this->prolongation[ref_case-1][i].reinit (n_dofs, n_dofs);
+ // Fill prolongation matrices with
+ // embedding operators
+ for (unsigned int j=0;j<n_dofs;++j)
+ this->prolongation[ref_case-1][i](j,j) = 1.;
+ }
}
// restriction can be defined
// restriction[0].fill (Matrices::projection_matrices[degree]);
// }
// else
-// // matrix undefined, set size to zero
+// // matrix undefined, set size to zero
// for (unsigned int i=0;i<GeometryInfo<dim>::max_children_per_cell;++i)
// restriction[i].reinit(0, 0);
// since not implemented, set to
std::string
FE_DGPNonparametric<dim,spacedim>::get_name () const
{
- // note that the
- // FETools::get_fe_from_name
- // function depends on the
- // particular format of the string
- // this function returns, so they
- // have to be kept in synch
+ // note that the
+ // FETools::get_fe_from_name
+ // function depends on the
+ // particular format of the string
+ // this function returns, so they
+ // have to be kept in synch
std::ostringstream namebuf;
namebuf << "FE_DGPNonparametric<" << dim << ">(" << degree << ")";
template <int dim, int spacedim>
double
FE_DGPNonparametric<dim,spacedim>::shape_value (const unsigned int i,
- const Point<dim> &p) const
+ const Point<dim> &p) const
{
Assert (i<this->dofs_per_cell, ExcIndexRange(i, 0, this->dofs_per_cell));
return polynomial_space.compute_value(i, p);
template <int dim, int spacedim>
double
FE_DGPNonparametric<dim,spacedim>::shape_value_component (const unsigned int i,
- const Point<dim> &p,
- const unsigned int component) const
+ const Point<dim> &p,
+ const unsigned int component) const
{
Assert (i<this->dofs_per_cell, ExcIndexRange(i, 0, this->dofs_per_cell));
Assert (component == 0, ExcIndexRange (component, 0, 1));
template <int dim, int spacedim>
Tensor<1,dim>
FE_DGPNonparametric<dim,spacedim>::shape_grad (const unsigned int i,
- const Point<dim> &p) const
+ const Point<dim> &p) const
{
Assert (i<this->dofs_per_cell, ExcIndexRange(i, 0, this->dofs_per_cell));
return polynomial_space.compute_grad(i, p);
template <int dim, int spacedim>
Tensor<1,dim>
FE_DGPNonparametric<dim,spacedim>::shape_grad_component (const unsigned int i,
- const Point<dim> &p,
- const unsigned int component) const
+ const Point<dim> &p,
+ const unsigned int component) const
{
Assert (i<this->dofs_per_cell, ExcIndexRange(i, 0, this->dofs_per_cell));
Assert (component == 0, ExcIndexRange (component, 0, 1));
template <int dim, int spacedim>
Tensor<2,dim>
FE_DGPNonparametric<dim,spacedim>::shape_grad_grad (const unsigned int i,
- const Point<dim> &p) const
+ const Point<dim> &p) const
{
Assert (i<this->dofs_per_cell, ExcIndexRange(i, 0, this->dofs_per_cell));
return polynomial_space.compute_grad_grad(i, p);
template <int dim, int spacedim>
Tensor<2,dim>
FE_DGPNonparametric<dim,spacedim>::shape_grad_grad_component (const unsigned int i,
- const Point<dim> &p,
- const unsigned int component) const
+ const Point<dim> &p,
+ const unsigned int component) const
{
Assert (i<this->dofs_per_cell, ExcIndexRange(i, 0, this->dofs_per_cell));
Assert (component == 0, ExcIndexRange (component, 0, 1));
UpdateFlags
FE_DGPNonparametric<dim,spacedim>::update_once (const UpdateFlags) const
{
- // for this kind of elements, only
- // the values can be precomputed
- // once and for all. set this flag
- // if the values are requested at
- // all
+ // for this kind of elements, only
+ // the values can be precomputed
+ // once and for all. set this flag
+ // if the values are requested at
+ // all
return update_default;
}
const Mapping<dim,spacedim>&,
const Quadrature<dim>&) const
{
- // generate a new data object
+ // generate a new data object
InternalData* data = new InternalData;
- // check what needs to be
- // initialized only once and what
- // on every cell/face/subface we
- // visit
+ // check what needs to be
+ // initialized only once and what
+ // on every cell/face/subface we
+ // visit
data->update_once = update_once(update_flags);
data->update_each = update_each(update_flags);
data->update_flags = data->update_once | data->update_each;
const UpdateFlags flags(data->update_flags);
- // initialize fields only if really
- // necessary. otherwise, don't
- // allocate memory
+ // initialize fields only if really
+ // necessary. otherwise, don't
+ // allocate memory
if (flags & update_values)
{
data->values.resize (this->dofs_per_cell);
FEValuesData<dim,spacedim>&data,
CellSimilarity::Similarity &/*cell_similarity*/) const
{
- // convert data object to internal
- // data for this class. fails with
- // an exception if that is not
- // possible
+ // convert data object to internal
+ // data for this class. fails with
+ // an exception if that is not
+ // possible
Assert (dynamic_cast<InternalData *> (&fedata) != 0,
- ExcInternalError());
+ ExcInternalError());
InternalData &fe_data = static_cast<InternalData &> (fedata);
const UpdateFlags flags(fe_data.current_update_flags());
if (flags & (update_values | update_gradients))
for (unsigned int i=0; i<n_q_points; ++i)
{
- polynomial_space.compute(data.quadrature_points[i],
- fe_data.values, fe_data.grads, fe_data.grad_grads);
- for (unsigned int k=0; k<this->dofs_per_cell; ++k)
- {
- if (flags & update_values)
- data.shape_values[k][i] = fe_data.values[k];
- if (flags & update_gradients)
- data.shape_gradients[k][i] = fe_data.grads[k];
- if (flags & update_hessians)
- data.shape_hessians[k][i] = fe_data.grad_grads[k];
- }
+ polynomial_space.compute(data.quadrature_points[i],
+ fe_data.values, fe_data.grads, fe_data.grad_grads);
+ for (unsigned int k=0; k<this->dofs_per_cell; ++k)
+ {
+ if (flags & update_values)
+ data.shape_values[k][i] = fe_data.values[k];
+ if (flags & update_gradients)
+ data.shape_gradients[k][i] = fe_data.grads[k];
+ if (flags & update_hessians)
+ data.shape_hessians[k][i] = fe_data.grad_grads[k];
+ }
}
}
typename Mapping<dim,spacedim>::InternalDataBase& fedata,
FEValuesData<dim,spacedim>& data) const
{
- // convert data object to internal
- // data for this class. fails with
- // an exception if that is not
- // possible
+ // convert data object to internal
+ // data for this class. fails with
+ // an exception if that is not
+ // possible
Assert (dynamic_cast<InternalData *> (&fedata) != 0,
- ExcInternalError());
+ ExcInternalError());
InternalData &fe_data = static_cast<InternalData &> (fedata);
const UpdateFlags flags(fe_data.update_once | fe_data.update_each);
if (flags & (update_values | update_gradients))
for (unsigned int i=0; i<n_q_points; ++i)
{
- polynomial_space.compute(data.quadrature_points[i],
- fe_data.values, fe_data.grads, fe_data.grad_grads);
- for (unsigned int k=0; k<this->dofs_per_cell; ++k)
- {
- if (flags & update_values)
- data.shape_values[k][i] = fe_data.values[k];
- if (flags & update_gradients)
- data.shape_gradients[k][i] = fe_data.grads[k];
- if (flags & update_hessians)
- data.shape_hessians[k][i] = fe_data.grad_grads[k];
- }
+ polynomial_space.compute(data.quadrature_points[i],
+ fe_data.values, fe_data.grads, fe_data.grad_grads);
+ for (unsigned int k=0; k<this->dofs_per_cell; ++k)
+ {
+ if (flags & update_values)
+ data.shape_values[k][i] = fe_data.values[k];
+ if (flags & update_gradients)
+ data.shape_gradients[k][i] = fe_data.grads[k];
+ if (flags & update_hessians)
+ data.shape_hessians[k][i] = fe_data.grad_grads[k];
+ }
}
}
typename Mapping<dim,spacedim>::InternalDataBase& fedata,
FEValuesData<dim,spacedim>& data) const
{
- // convert data object to internal
- // data for this class. fails with
- // an exception if that is not
- // possible
+ // convert data object to internal
+ // data for this class. fails with
+ // an exception if that is not
+ // possible
Assert (dynamic_cast<InternalData *> (&fedata) != 0,
- ExcInternalError());
+ ExcInternalError());
InternalData &fe_data = static_cast<InternalData &> (fedata);
const UpdateFlags flags(fe_data.update_once | fe_data.update_each);
if (flags & (update_values | update_gradients))
for (unsigned int i=0; i<n_q_points; ++i)
{
- polynomial_space.compute(data.quadrature_points[i],
- fe_data.values, fe_data.grads, fe_data.grad_grads);
- for (unsigned int k=0; k<this->dofs_per_cell; ++k)
- {
- if (flags & update_values)
- data.shape_values[k][i] = fe_data.values[k];
- if (flags & update_gradients)
- data.shape_gradients[k][i] = fe_data.grads[k];
- if (flags & update_hessians)
- data.shape_hessians[k][i] = fe_data.grad_grads[k];
- }
+ polynomial_space.compute(data.quadrature_points[i],
+ fe_data.values, fe_data.grads, fe_data.grad_grads);
+ for (unsigned int k=0; k<this->dofs_per_cell; ++k)
+ {
+ if (flags & update_values)
+ data.shape_values[k][i] = fe_data.values[k];
+ if (flags & update_gradients)
+ data.shape_gradients[k][i] = fe_data.grads[k];
+ if (flags & update_hessians)
+ data.shape_hessians[k][i] = fe_data.grad_grads[k];
+ }
}
}
void
FE_DGPNonparametric<dim,spacedim>::
get_face_interpolation_matrix (const FiniteElement<dim,spacedim> &x_source_fe,
- FullMatrix<double> &interpolation_matrix) const
+ FullMatrix<double> &interpolation_matrix) const
{
- // this is only implemented, if the source
- // FE is also a DGPNonparametric element. in that case,
- // both elements have no dofs on their
- // faces and the face interpolation matrix
- // is necessarily empty -- i.e. there isn't
- // much we need to do here.
- typedef FiniteElement<dim,spacedim> FEE;
+ // this is only implemented, if the source
+ // FE is also a DGPNonparametric element. in that case,
+ // both elements have no dofs on their
+ // faces and the face interpolation matrix
+ // is necessarily empty -- i.e. there isn't
+ // much we need to do here.
+ typedef FiniteElement<dim,spacedim> FEE;
AssertThrow ((x_source_fe.get_name().find ("FE_DGPNonparametric<") == 0)
||
(dynamic_cast<const FE_DGPNonparametric<dim,spacedim>*>(&x_source_fe) != 0),
ExcInterpolationNotImplemented());
Assert (interpolation_matrix.m() == 0,
- ExcDimensionMismatch (interpolation_matrix.m(),
- 0));
+ ExcDimensionMismatch (interpolation_matrix.m(),
+ 0));
Assert (interpolation_matrix.n() == 0,
- ExcDimensionMismatch (interpolation_matrix.n(),
- 0));
+ ExcDimensionMismatch (interpolation_matrix.n(),
+ 0));
}
void
FE_DGPNonparametric<dim,spacedim>::
get_subface_interpolation_matrix (const FiniteElement<dim,spacedim> &x_source_fe,
- const unsigned int ,
- FullMatrix<double> &interpolation_matrix) const
+ const unsigned int ,
+ FullMatrix<double> &interpolation_matrix) const
{
- // this is only implemented, if the source
- // FE is also a DGPNonparametric element. in that case,
- // both elements have no dofs on their
- // faces and the face interpolation matrix
- // is necessarily empty -- i.e. there isn't
- // much we need to do here.
- typedef FiniteElement<dim,spacedim> FEE;
+ // this is only implemented, if the source
+ // FE is also a DGPNonparametric element. in that case,
+ // both elements have no dofs on their
+ // faces and the face interpolation matrix
+ // is necessarily empty -- i.e. there isn't
+ // much we need to do here.
+ typedef FiniteElement<dim,spacedim> FEE;
AssertThrow ((x_source_fe.get_name().find ("FE_DGPNonparametric<") == 0)
||
(dynamic_cast<const FE_DGPNonparametric<dim,spacedim>*>(&x_source_fe) != 0),
typename FEE::
- ExcInterpolationNotImplemented());
+ ExcInterpolationNotImplemented());
Assert (interpolation_matrix.m() == 0,
- ExcDimensionMismatch (interpolation_matrix.m(),
- 0));
+ ExcDimensionMismatch (interpolation_matrix.m(),
+ 0));
Assert (interpolation_matrix.n() == 0,
- ExcDimensionMismatch (interpolation_matrix.n(),
- 0));
+ ExcDimensionMismatch (interpolation_matrix.n(),
+ 0));
}
FE_DGPNonparametric<dim,spacedim>::
hp_vertex_dof_identities (const FiniteElement<dim,spacedim> &fe_other) const
{
- // there are no such constraints for DGPNonparametric
- // elements at all
+ // there are no such constraints for DGPNonparametric
+ // elements at all
if (dynamic_cast<const FE_DGPNonparametric<dim,spacedim>*>(&fe_other) != 0)
return
std::vector<std::pair<unsigned int, unsigned int> > ();
FE_DGPNonparametric<dim,spacedim>::
hp_line_dof_identities (const FiniteElement<dim,spacedim> &fe_other) const
{
- // there are no such constraints for DGPNonparametric
- // elements at all
+ // there are no such constraints for DGPNonparametric
+ // elements at all
if (dynamic_cast<const FE_DGPNonparametric<dim,spacedim>*>(&fe_other) != 0)
return
std::vector<std::pair<unsigned int, unsigned int> > ();
FE_DGPNonparametric<dim,spacedim>::
hp_quad_dof_identities (const FiniteElement<dim,spacedim> &fe_other) const
{
- // there are no such constraints for DGPNonparametric
- // elements at all
+ // there are no such constraints for DGPNonparametric
+ // elements at all
if (dynamic_cast<const FE_DGPNonparametric<dim,spacedim>*>(&fe_other) != 0)
return
std::vector<std::pair<unsigned int, unsigned int> > ();
FE_DGPNonparametric<dim,spacedim>::
compare_for_face_domination (const FiniteElement<dim,spacedim> &fe_other) const
{
- // check whether both are discontinuous
- // elements, see the description of
- // FiniteElementDomination::Domination
+ // check whether both are discontinuous
+ // elements, see the description of
+ // FiniteElementDomination::Domination
if (dynamic_cast<const FE_DGPNonparametric<dim,spacedim>*>(&fe_other) != 0)
return FiniteElementDomination::no_requirements;
template <int dim, int spacedim>
bool
FE_DGPNonparametric<dim,spacedim>::has_support_on_face (const unsigned int,
- const unsigned int) const
+ const unsigned int) const
{
return true;
}
// $Id$
// Version: $Name$
//
-// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2010, 2011 by the deal.II authors
+// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2010, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
// are thus not very interesting to the outside world
namespace
{
- // given an integer N, compute its
- // integer square root (if it
- // exists, otherwise give up)
+ // given an integer N, compute its
+ // integer square root (if it
+ // exists, otherwise give up)
inline unsigned int int_sqrt (const unsigned int N)
{
for (unsigned int i=0; i<=N; ++i)
if (i*i == N)
- return i;
+ return i;
Assert (false, ExcInternalError());
return numbers::invalid_unsigned_int;
}
- // given an integer N, compute its
- // integer cube root (if it
- // exists, otherwise give up)
+ // given an integer N, compute its
+ // integer cube root (if it
+ // exists, otherwise give up)
inline unsigned int int_cuberoot (const unsigned int N)
{
for (unsigned int i=0; i<=N; ++i)
if (i*i*i == N)
- return i;
+ return i;
Assert (false, ExcInternalError());
return numbers::invalid_unsigned_int;
}
- // given N, generate i=0...N-1
- // equidistant points in the
- // interior of the interval [0,1]
+ // given N, generate i=0...N-1
+ // equidistant points in the
+ // interior of the interval [0,1]
inline Point<1>
generate_unit_point (const unsigned int i,
- const unsigned int N,
- const dealii::internal::int2type<1> )
+ const unsigned int N,
+ const dealii::internal::int2type<1> )
{
Assert (i<N, ExcInternalError());
if (N==1)
}
- // given N, generate i=0...N-1
- // equidistant points in the domain
- // [0,1]^2
+ // given N, generate i=0...N-1
+ // equidistant points in the domain
+ // [0,1]^2
inline Point<2>
generate_unit_point (const unsigned int i,
- const unsigned int N,
- const dealii::internal::int2type<2> )
+ const unsigned int N,
+ const dealii::internal::int2type<2> )
{
Assert (i<N, ExcInternalError());
- // given N, generate i=0...N-1
- // equidistant points in the domain
- // [0,1]^3
+ // given N, generate i=0...N-1
+ // equidistant points in the domain
+ // [0,1]^3
inline Point<3>
generate_unit_point (const unsigned int i,
- const unsigned int N,
- const dealii::internal::int2type<3> )
+ const unsigned int N,
+ const dealii::internal::int2type<3> )
{
Assert (i<N, ExcInternalError());
if (N==1)
template <int dim, int spacedim>
FE_DGQ<dim, spacedim>::FE_DGQ (const unsigned int degree)
- :
- FE_Poly<TensorProductPolynomials<dim>, dim, spacedim> (
- TensorProductPolynomials<dim>(Polynomials::LagrangeEquidistant::generate_complete_basis(degree)),
- FiniteElementData<dim>(get_dpo_vector(degree), 1, degree, FiniteElementData<dim>::L2),
- std::vector<bool>(FiniteElementData<dim>(get_dpo_vector(degree),1, degree).dofs_per_cell, true),
- std::vector<std::vector<bool> >(FiniteElementData<dim>(
- get_dpo_vector(degree),1, degree).dofs_per_cell, std::vector<bool>(1,true)))
+ :
+ FE_Poly<TensorProductPolynomials<dim>, dim, spacedim> (
+ TensorProductPolynomials<dim>(Polynomials::LagrangeEquidistant::generate_complete_basis(degree)),
+ FiniteElementData<dim>(get_dpo_vector(degree), 1, degree, FiniteElementData<dim>::L2),
+ std::vector<bool>(FiniteElementData<dim>(get_dpo_vector(degree),1, degree).dofs_per_cell, true),
+ std::vector<std::vector<bool> >(FiniteElementData<dim>(
+ get_dpo_vector(degree),1, degree).dofs_per_cell, std::vector<bool>(1,true)))
{
- // Reinit the vectors of
- // restriction and prolongation
- // matrices to the right sizes
+ // Reinit the vectors of
+ // restriction and prolongation
+ // matrices to the right sizes
this->reinit_restriction_and_prolongation_matrices();
- // Fill prolongation matrices with
- // embedding operators and
- // restriction with L2 projection
- //
- // we can call the respective
- // functions in the case
- // dim==spacedim, but they are not
- // currently implemented for the
- // codim-1 case. there's no harm
- // here, though, since these
- // matrices are independent of the
- // space dimension and so we can
- // copy them from the respective
- // elements (not cheap, but works)
+ // Fill prolongation matrices with
+ // embedding operators and
+ // restriction with L2 projection
+ //
+ // we can call the respective
+ // functions in the case
+ // dim==spacedim, but they are not
+ // currently implemented for the
+ // codim-1 case. there's no harm
+ // here, though, since these
+ // matrices are independent of the
+ // space dimension and so we can
+ // copy them from the respective
+ // elements (not cheap, but works)
if (dim == spacedim)
{
FETools::compute_embedding_matrices (*this, this->prolongation);
}
- // finally fill in support points
+ // finally fill in support points
if (degree == 0)
{
- // constant elements, take
- // midpoint
+ // constant elements, take
+ // midpoint
this->unit_support_points.resize(1);
for (unsigned int i=0; i<dim; ++i)
- this->unit_support_points[0](i) = 0.5;
+ this->unit_support_points[0](i) = 0.5;
}
else
{
- // number of points: (degree+1)^dim
+ // number of points: (degree+1)^dim
unsigned int n = degree+1;
for (unsigned int i=1; i<dim; ++i)
- n *= degree+1;
+ n *= degree+1;
this->unit_support_points.resize(n);
unsigned int k=0;
for (unsigned int iz=0; iz <= ((dim>2) ? degree : 0) ; ++iz)
- for (unsigned int iy=0; iy <= ((dim>1) ? degree : 0) ; ++iy)
- for (unsigned int ix=0; ix<=degree; ++ix)
- {
- p(0) = ix * step;
- if (dim>1)
- p(1) = iy * step;
- if (dim>2)
- p(2) = iz * step;
-
- this->unit_support_points[k++] = p;
- };
+ for (unsigned int iy=0; iy <= ((dim>1) ? degree : 0) ; ++iy)
+ for (unsigned int ix=0; ix<=degree; ++ix)
+ {
+ p(0) = ix * step;
+ if (dim>1)
+ p(1) = iy * step;
+ if (dim>2)
+ p(2) = iz * step;
+
+ this->unit_support_points[k++] = p;
+ };
};
- // note: no face support points for
- // DG elements
+ // note: no face support points for
+ // DG elements
}
template <int dim, int spacedim>
FE_DGQ<dim, spacedim>::FE_DGQ (const Quadrature<1>& points)
- :
- FE_Poly<TensorProductPolynomials<dim>, dim, spacedim> (
- TensorProductPolynomials<dim>(Polynomials::generate_complete_Lagrange_basis(points.get_points())),
- FiniteElementData<dim>(get_dpo_vector(points.size()-1), 1, points.size()-1, FiniteElementData<dim>::L2),
- std::vector<bool>(FiniteElementData<dim>(get_dpo_vector(points.size()-1),1, points.size()-1).dofs_per_cell, true),
- std::vector<std::vector<bool> >(FiniteElementData<dim>(
- get_dpo_vector(points.size()-1),1, points.size()-1).dofs_per_cell, std::vector<bool>(1,true)))
+ :
+ FE_Poly<TensorProductPolynomials<dim>, dim, spacedim> (
+ TensorProductPolynomials<dim>(Polynomials::generate_complete_Lagrange_basis(points.get_points())),
+ FiniteElementData<dim>(get_dpo_vector(points.size()-1), 1, points.size()-1, FiniteElementData<dim>::L2),
+ std::vector<bool>(FiniteElementData<dim>(get_dpo_vector(points.size()-1),1, points.size()-1).dofs_per_cell, true),
+ std::vector<std::vector<bool> >(FiniteElementData<dim>(
+ get_dpo_vector(points.size()-1),1, points.size()-1).dofs_per_cell, std::vector<bool>(1,true)))
{
- // Reinit the vectors of
- // restriction and prolongation
- // matrices to the right sizes
+ // Reinit the vectors of
+ // restriction and prolongation
+ // matrices to the right sizes
this->reinit_restriction_and_prolongation_matrices();
- // Fill prolongation matrices with embedding operators
+ // Fill prolongation matrices with embedding operators
FETools::compute_embedding_matrices (*this, this->prolongation);
- // Fill restriction matrices with L2-projection
+ // Fill restriction matrices with L2-projection
FETools::compute_projection_matrices (*this, this->restriction);
- // Compute support points, which
- // are the tensor product of the
- // Lagrange interpolation points in
- // the constructor.
+ // Compute support points, which
+ // are the tensor product of the
+ // Lagrange interpolation points in
+ // the constructor.
Quadrature<dim> support_quadrature(points);
this->unit_support_points = support_quadrature.get_points();
}
std::string
FE_DGQ<dim, spacedim>::get_name () const
{
- // note that the
- // FETools::get_fe_from_name
- // function depends on the
- // particular format of the string
- // this function returns, so they
- // have to be kept in synch
+ // note that the
+ // FETools::get_fe_from_name
+ // function depends on the
+ // particular format of the string
+ // this function returns, so they
+ // have to be kept in synch
std::ostringstream namebuf;
namebuf << "FE_DGQ<" << dim << ">(" << this->degree << ")";
template <int dim, int spacedim>
void
FE_DGQ<dim, spacedim>::rotate_indices (std::vector<unsigned int> &numbers,
- const char direction) const
+ const char direction) const
{
const unsigned int n = this->degree+1;
unsigned int s = n;
if (dim==1)
{
- // Mirror around midpoint
+ // Mirror around midpoint
for (unsigned int i=n;i>0;)
- numbers[l++]=--i;
+ numbers[l++]=--i;
}
else
{
switch (direction)
- {
- // Rotate xy-plane
- // counter-clockwise
- case 'z':
- for (unsigned int iz=0;iz<((dim>2) ? n:1);++iz)
- for (unsigned int j=0;j<n;++j)
- for (unsigned int i=0;i<n;++i)
- {
- unsigned int k = n*i-j+n-1 + n*n*iz;
- numbers[l++] = k;
- }
- break;
- // Rotate xy-plane
- // clockwise
- case 'Z':
- for (unsigned int iz=0;iz<((dim>2) ? n:1);++iz)
- for (unsigned int iy=0;iy<n;++iy)
- for (unsigned int ix=0;ix<n;++ix)
- {
- unsigned int k = n*ix-iy+n-1 + n*n*iz;
- numbers[k] = l++;
- }
- break;
- // Rotate yz-plane
- // counter-clockwise
- case 'x':
- Assert (dim>2, ExcDimensionMismatch (dim,3));
- for (unsigned int iz=0;iz<n;++iz)
- for (unsigned int iy=0;iy<n;++iy)
- for (unsigned int ix=0;ix<n;++ix)
- {
- unsigned int k = n*(n*iy-iz+n-1) + ix;
- numbers[l++] = k;
- }
- break;
- // Rotate yz-plane
- // clockwise
- case 'X':
- Assert (dim>2, ExcDimensionMismatch (dim,3));
- for (unsigned int iz=0;iz<n;++iz)
- for (unsigned int iy=0;iy<n;++iy)
- for (unsigned int ix=0;ix<n;++ix)
- {
- unsigned int k = n*(n*iy-iz+n-1) + ix;
- numbers[k] = l++;
- }
- break;
- default:
- Assert (false, ExcNotImplemented ());
- }
+ {
+ // Rotate xy-plane
+ // counter-clockwise
+ case 'z':
+ for (unsigned int iz=0;iz<((dim>2) ? n:1);++iz)
+ for (unsigned int j=0;j<n;++j)
+ for (unsigned int i=0;i<n;++i)
+ {
+ unsigned int k = n*i-j+n-1 + n*n*iz;
+ numbers[l++] = k;
+ }
+ break;
+ // Rotate xy-plane
+ // clockwise
+ case 'Z':
+ for (unsigned int iz=0;iz<((dim>2) ? n:1);++iz)
+ for (unsigned int iy=0;iy<n;++iy)
+ for (unsigned int ix=0;ix<n;++ix)
+ {
+ unsigned int k = n*ix-iy+n-1 + n*n*iz;
+ numbers[k] = l++;
+ }
+ break;
+ // Rotate yz-plane
+ // counter-clockwise
+ case 'x':
+ Assert (dim>2, ExcDimensionMismatch (dim,3));
+ for (unsigned int iz=0;iz<n;++iz)
+ for (unsigned int iy=0;iy<n;++iy)
+ for (unsigned int ix=0;ix<n;++ix)
+ {
+ unsigned int k = n*(n*iy-iz+n-1) + ix;
+ numbers[l++] = k;
+ }
+ break;
+ // Rotate yz-plane
+ // clockwise
+ case 'X':
+ Assert (dim>2, ExcDimensionMismatch (dim,3));
+ for (unsigned int iz=0;iz<n;++iz)
+ for (unsigned int iy=0;iy<n;++iy)
+ for (unsigned int ix=0;ix<n;++ix)
+ {
+ unsigned int k = n*(n*iy-iz+n-1) + ix;
+ numbers[k] = l++;
+ }
+ break;
+ default:
+ Assert (false, ExcNotImplemented ());
+ }
}
}
void
FE_DGQ<dim, spacedim>::
get_interpolation_matrix (const FiniteElement<dim, spacedim> &x_source_fe,
- FullMatrix<double> &interpolation_matrix) const
+ FullMatrix<double> &interpolation_matrix) const
{
- // this is only implemented, if the
- // source FE is also a
- // DGQ element
+ // this is only implemented, if the
+ // source FE is also a
+ // DGQ element
typedef FiniteElement<dim, spacedim> FE;
AssertThrow ((x_source_fe.get_name().find ("FE_DGQ<") == 0)
||
(dynamic_cast<const FE_DGQ<dim, spacedim>*>(&x_source_fe) != 0),
typename FE::ExcInterpolationNotImplemented() );
- // ok, source is a Q element, so
- // we will be able to do the work
+ // ok, source is a Q element, so
+ // we will be able to do the work
const FE_DGQ<dim, spacedim> &source_fe
= dynamic_cast<const FE_DGQ<dim, spacedim>&>(x_source_fe);
Assert (interpolation_matrix.m() == this->dofs_per_cell,
- ExcDimensionMismatch (interpolation_matrix.m(),
- this->dofs_per_cell));
+ ExcDimensionMismatch (interpolation_matrix.m(),
+ this->dofs_per_cell));
Assert (interpolation_matrix.n() == source_fe.dofs_per_cell,
- ExcDimensionMismatch (interpolation_matrix.n(),
- source_fe.dofs_per_cell));
+ ExcDimensionMismatch (interpolation_matrix.n(),
+ source_fe.dofs_per_cell));
- // compute the interpolation
- // matrices in much the same way as
- // we do for the embedding matrices
- // from mother to child.
+ // compute the interpolation
+ // matrices in much the same way as
+ // we do for the embedding matrices
+ // from mother to child.
FullMatrix<double> cell_interpolation (this->dofs_per_cell,
- this->dofs_per_cell);
+ this->dofs_per_cell);
FullMatrix<double> source_interpolation (this->dofs_per_cell,
- source_fe.dofs_per_cell);
+ source_fe.dofs_per_cell);
FullMatrix<double> tmp (this->dofs_per_cell,
- source_fe.dofs_per_cell);
+ source_fe.dofs_per_cell);
for (unsigned int j=0; j<this->dofs_per_cell; ++j)
{
// generate a point on this
if (std::fabs(interpolation_matrix(i,j)) < 1e-15)
interpolation_matrix(i,j) = 0.;
- // make sure that the row sum of
- // each of the matrices is 1 at
- // this point. this must be so
- // since the shape functions sum up
- // to 1
+ // make sure that the row sum of
+ // each of the matrices is 1 at
+ // this point. this must be so
+ // since the shape functions sum up
+ // to 1
for (unsigned int i=0; i<this->dofs_per_cell; ++i)
{
double sum = 0.;
void
FE_DGQ<dim, spacedim>::
get_face_interpolation_matrix (const FiniteElement<dim, spacedim> &x_source_fe,
- FullMatrix<double> &interpolation_matrix) const
+ FullMatrix<double> &interpolation_matrix) const
{
- // this is only implemented, if the source
- // FE is also a DGQ element. in that case,
- // both elements have no dofs on their
- // faces and the face interpolation matrix
- // is necessarily empty -- i.e. there isn't
- // much we need to do here.
+ // this is only implemented, if the source
+ // FE is also a DGQ element. in that case,
+ // both elements have no dofs on their
+ // faces and the face interpolation matrix
+ // is necessarily empty -- i.e. there isn't
+ // much we need to do here.
typedef FiniteElement<dim,spacedim> FE;
AssertThrow ((x_source_fe.get_name().find ("FE_DGQ<") == 0)
||
typename FE::ExcInterpolationNotImplemented());
Assert (interpolation_matrix.m() == 0,
- ExcDimensionMismatch (interpolation_matrix.m(),
- 0));
+ ExcDimensionMismatch (interpolation_matrix.m(),
+ 0));
Assert (interpolation_matrix.n() == 0,
- ExcDimensionMismatch (interpolation_matrix.m(),
- 0));
+ ExcDimensionMismatch (interpolation_matrix.m(),
+ 0));
}
void
FE_DGQ<dim, spacedim>::
get_subface_interpolation_matrix (const FiniteElement<dim, spacedim> &x_source_fe,
- const unsigned int ,
- FullMatrix<double> &interpolation_matrix) const
+ const unsigned int ,
+ FullMatrix<double> &interpolation_matrix) const
{
- // this is only implemented, if the source
- // FE is also a DGQ element. in that case,
- // both elements have no dofs on their
- // faces and the face interpolation matrix
- // is necessarily empty -- i.e. there isn't
- // much we need to do here.
+ // this is only implemented, if the source
+ // FE is also a DGQ element. in that case,
+ // both elements have no dofs on their
+ // faces and the face interpolation matrix
+ // is necessarily empty -- i.e. there isn't
+ // much we need to do here.
typedef FiniteElement<dim, spacedim> FE;
AssertThrow ((x_source_fe.get_name().find ("FE_DGQ<") == 0)
||
typename FE::ExcInterpolationNotImplemented());
Assert (interpolation_matrix.m() == 0,
- ExcDimensionMismatch (interpolation_matrix.m(),
- 0));
+ ExcDimensionMismatch (interpolation_matrix.m(),
+ 0));
Assert (interpolation_matrix.n() == 0,
- ExcDimensionMismatch (interpolation_matrix.m(),
- 0));
+ ExcDimensionMismatch (interpolation_matrix.m(),
+ 0));
}
FE_DGQ<dim, spacedim>::
hp_vertex_dof_identities (const FiniteElement<dim, spacedim> &fe_other) const
{
- // there are no such constraints for DGQ
- // elements at all
+ // there are no such constraints for DGQ
+ // elements at all
if (dynamic_cast<const FE_DGQ<dim, spacedim>*>(&fe_other) != 0)
return
std::vector<std::pair<unsigned int, unsigned int> > ();
FE_DGQ<dim, spacedim>::
hp_line_dof_identities (const FiniteElement<dim, spacedim> &fe_other) const
{
- // there are no such constraints for DGQ
- // elements at all
+ // there are no such constraints for DGQ
+ // elements at all
if (dynamic_cast<const FE_DGQ<dim, spacedim>*>(&fe_other) != 0)
return
std::vector<std::pair<unsigned int, unsigned int> > ();
FE_DGQ<dim, spacedim>::
hp_quad_dof_identities (const FiniteElement<dim, spacedim> &fe_other) const
{
- // there are no such constraints for DGQ
- // elements at all
+ // there are no such constraints for DGQ
+ // elements at all
if (dynamic_cast<const FE_DGQ<dim, spacedim>*>(&fe_other) != 0)
return
std::vector<std::pair<unsigned int, unsigned int> > ();
FiniteElementDomination::Domination
FE_DGQ<dim, spacedim>::compare_for_face_domination (const FiniteElement<dim, spacedim> &fe_other) const
{
- // check whether both are discontinuous
- // elements, see the description of
- // FiniteElementDomination::Domination
+ // check whether both are discontinuous
+ // elements, see the description of
+ // FiniteElementDomination::Domination
if (dynamic_cast<const FE_DGQ<dim, spacedim>*>(&fe_other) != 0)
return FiniteElementDomination::no_requirements;
template <int dim, int spacedim>
bool
FE_DGQ<dim, spacedim>::has_support_on_face (const unsigned int shape_index,
- const unsigned int face_index) const
+ const unsigned int face_index) const
{
Assert (shape_index < this->dofs_per_cell,
- ExcIndexRange (shape_index, 0, this->dofs_per_cell));
+ ExcIndexRange (shape_index, 0, this->dofs_per_cell));
Assert (face_index < GeometryInfo<dim>::faces_per_cell,
- ExcIndexRange (face_index, 0, GeometryInfo<dim>::faces_per_cell));
+ ExcIndexRange (face_index, 0, GeometryInfo<dim>::faces_per_cell));
unsigned int n = this->degree+1;
- // for DGQ(0) elements, the single
- // shape functions is constant and
- // therefore lives on the boundary
+ // for DGQ(0) elements, the single
+ // shape functions is constant and
+ // therefore lives on the boundary
if (this->degree == 0)
return true;
{
case 1:
{
- // in 1d, things are simple. since
- // there is only one degree of
- // freedom per vertex in this
- // class, the first is on vertex 0
- // (==face 0 in some sense), the
- // second on face 1:
- return (((shape_index == 0) && (face_index == 0)) ||
- ((shape_index == 1) && (face_index == 1)));
+ // in 1d, things are simple. since
+ // there is only one degree of
+ // freedom per vertex in this
+ // class, the first is on vertex 0
+ // (==face 0 in some sense), the
+ // second on face 1:
+ return (((shape_index == 0) && (face_index == 0)) ||
+ ((shape_index == 1) && (face_index == 1)));
};
case 2:
{
- if (face_index==0 && (shape_index % n) == 0)
- return true;
- if (face_index==1 && (shape_index % n) == this->degree)
- return true;
- if (face_index==2 && shape_index < n)
- return true;
- if (face_index==3 && shape_index >= this->dofs_per_cell-n)
- return true;
- return false;
+ if (face_index==0 && (shape_index % n) == 0)
+ return true;
+ if (face_index==1 && (shape_index % n) == this->degree)
+ return true;
+ if (face_index==2 && shape_index < n)
+ return true;
+ if (face_index==3 && shape_index >= this->dofs_per_cell-n)
+ return true;
+ return false;
};
case 3:
{
- const unsigned int in2 = shape_index % n2;
-
- // x=0
- if (face_index==0 && (shape_index % n) == 0)
- return true;
- // x=1
- if (face_index==1 && (shape_index % n) == n-1)
- return true;
- // y=0
- if (face_index==2 && in2 < n )
- return true;
- // y=1
- if (face_index==3 && in2 >= n2-n)
- return true;
- // z=0
- if (face_index==4 && shape_index < n2)
- return true;
- // z=1
- if (face_index==5 && shape_index >= this->dofs_per_cell - n2)
- return true;
- return false;
+ const unsigned int in2 = shape_index % n2;
+
+ // x=0
+ if (face_index==0 && (shape_index % n) == 0)
+ return true;
+ // x=1
+ if (face_index==1 && (shape_index % n) == n-1)
+ return true;
+ // y=0
+ if (face_index==2 && in2 < n )
+ return true;
+ // y=1
+ if (face_index==3 && in2 >= n2-n)
+ return true;
+ // z=0
+ if (face_index==4 && shape_index < n2)
+ return true;
+ // z=1
+ if (face_index==5 && shape_index >= this->dofs_per_cell - n2)
+ return true;
+ return false;
};
default:
- Assert (false, ExcNotImplemented());
+ Assert (false, ExcNotImplemented());
}
return true;
}
template <int dim>
FE_DGQArbitraryNodes<dim>::FE_DGQArbitraryNodes (const Quadrature<1>& points)
- : FE_DGQ<dim>(points)
+ : FE_DGQ<dim>(points)
{}
std::string
FE_DGQArbitraryNodes<dim>::get_name () const
{
- // note that the
- // FETools::get_fe_from_name
- // function does not work for
- // FE_DGQArbitraryNodes since
- // there is no initialization by
- // a degree value.
+ // note that the
+ // FETools::get_fe_from_name
+ // function does not work for
+ // FE_DGQArbitraryNodes since
+ // there is no initialization by
+ // a degree value.
std::ostringstream namebuf;
bool type = true;
const std::vector<Point<dim> > &unit_support_points = this->unit_support_points;
unsigned int index = 0;
- // Decode the support points
- // in one coordinate direction.
+ // Decode the support points
+ // in one coordinate direction.
for (unsigned int j=0;j<dofs_per_cell;j++)
{
if ((dim>1) ? (unit_support_points[j](1)==0 &&
- ((dim>2) ? unit_support_points[j](2)==0: true)) : true)
- {
- points[index++] = unit_support_points[j](0);
- }
+ ((dim>2) ? unit_support_points[j](2)==0: true)) : true)
+ {
+ points[index++] = unit_support_points[j](0);
+ }
}
Assert (index == n_points,
- ExcMessage ("Could not decode support points in one coordinate direction."));
+ ExcMessage ("Could not decode support points in one coordinate direction."));
- // Check whether the support
- // points are equidistant.
+ // Check whether the support
+ // points are equidistant.
for(unsigned int j=0;j<n_points;j++)
if (std::fabs(points[j] - (double)j/this->degree) > 1e-15)
{
- type = false;
- break;
+ type = false;
+ break;
}
if (type == true)
else
{
- // Check whether the support
- // points come from QGaussLobatto.
+ // Check whether the support
+ // points come from QGaussLobatto.
const QGaussLobatto<1> points_gl(n_points);
type = true;
for(unsigned int j=0;j<n_points;j++)
- if (points[j] != points_gl.point(j)(0))
- {
- type = false;
- break;
- }
+ if (points[j] != points_gl.point(j)(0))
+ {
+ type = false;
+ break;
+ }
if(type == true)
- namebuf << "FE_DGQArbitraryNodes<" << dim << ">(QGaussLobatto(" << this->degree+1 << "))";
+ namebuf << "FE_DGQArbitraryNodes<" << dim << ">(QGaussLobatto(" << this->degree+1 << "))";
else
- namebuf << "FE_DGQArbitraryNodes<" << dim << ">(QUnknownNodes(" << this->degree << "))";
+ namebuf << "FE_DGQArbitraryNodes<" << dim << ">(QUnknownNodes(" << this->degree << "))";
}
return namebuf.str();
FiniteElement<dim> *
FE_DGQArbitraryNodes<dim>::clone() const
{
- // TODO[Prill] : There must be a better way
- // to extract 1D quadrature points from the
- // tensor product FE.
+ // TODO[Prill] : There must be a better way
+ // to extract 1D quadrature points from the
+ // tensor product FE.
- // Construct a dummy quadrature formula
- // containing the FE's nodes:
+ // Construct a dummy quadrature formula
+ // containing the FE's nodes:
std::vector<Point<1> > qpoints(this->degree+1);
for (unsigned int i=0; i<=this->degree; ++i)
qpoints[i] = Point<1>(this->unit_support_points[i][0]);
// $Id$
// Version: $Name$
//
-// Copyright (C) 2009, 2011 by the deal.II authors
+// Copyright (C) 2009, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
template <int dim, int spacedim>
FE_FaceQ<dim,spacedim>::FE_FaceQ (const unsigned int degree)
- :
+ :
FE_PolyFace<TensorProductPolynomials<dim-1>, dim, spacedim> (
- TensorProductPolynomials<dim-1>(Polynomials::LagrangeEquidistant::generate_complete_basis(degree)),
- FiniteElementData<dim>(get_dpo_vector(degree), 1, degree, FiniteElementData<dim>::L2),
- std::vector<bool>(1,true))
+ TensorProductPolynomials<dim-1>(Polynomials::LagrangeEquidistant::generate_complete_basis(degree)),
+ FiniteElementData<dim>(get_dpo_vector(degree), 1, degree, FiniteElementData<dim>::L2),
+ std::vector<bool>(1,true))
{}
std::string
FE_FaceQ<dim,spacedim>::get_name () const
{
- // note that the
- // FETools::get_fe_from_name
- // function depends on the
- // particular format of the string
- // this function returns, so they
- // have to be kept in synch
+ // note that the
+ // FETools::get_fe_from_name
+ // function depends on the
+ // particular format of the string
+ // this function returns, so they
+ // have to be kept in synch
std::ostringstream namebuf;
namebuf << "FE_FaceQ<" << dim << ">(" << this->degree << ")";
#ifdef DEBUG_NEDELEC
deallog << get_name() << std::endl;
#endif
-
+
Assert (dim >= 2, ExcImpossibleInDim(dim));
const unsigned int n_dofs = this->dofs_per_cell;
this->mapping_type = mapping_nedelec;
- // First, initialize the
- // generalized support points and
- // quadrature weights, since they
- // are required for interpolation.
+ // First, initialize the
+ // generalized support points and
+ // quadrature weights, since they
+ // are required for interpolation.
initialize_support_points (p);
this->inverse_node_matrix.reinit (n_dofs, n_dofs);
this->inverse_node_matrix.fill
(FullMatrix<double> (IdentityMatrix (n_dofs)));
- // From now on, the shape functions
- // will be the correct ones, not
- // the raw shape functions anymore.
-
- // Reinit the vectors of
- // restriction and prolongation
- // matrices to the right sizes.
- // Restriction only for isotropic
- // refinement
+ // From now on, the shape functions
+ // will be the correct ones, not
+ // the raw shape functions anymore.
+
+ // Reinit the vectors of
+ // restriction and prolongation
+ // matrices to the right sizes.
+ // Restriction only for isotropic
+ // refinement
#ifdef DEBUG_NEDELEC
deallog << "Embedding" << std::endl;
#endif
this->reinit_restriction_and_prolongation_matrices ();
- // Fill prolongation matrices with embedding operators
+ // Fill prolongation matrices with embedding operators
FETools::compute_embedding_matrices (*this, this->prolongation, true);
#ifdef DEBUG_NEDELEC
deallog << "Restriction" << std::endl;
#endif
initialize_restriction ();
-
+
#ifdef DEBUG_NEDELEC
deallog << "Face Embedding" << std::endl;
#endif
FETools::compute_face_embedding_matrices<dim,double>
(*this, face_embeddings, 0, 0);
-
+
switch (dim)
{
case 1:
- {
+ {
this->interface_constraints.reinit (0, 0);
break;
}
-
+
case 2:
- {
+ {
this->interface_constraints.reinit (2 * this->dofs_per_face,
this->dofs_per_face);
-
+
for (unsigned int i = 0; i < GeometryInfo<2>::max_children_per_face;
++i)
for (unsigned int j = 0; j < this->dofs_per_face; ++j)
for (unsigned int k = 0; k < this->dofs_per_face; ++k)
this->interface_constraints (i * this->dofs_per_face + j, k)
= face_embeddings[i] (j, k);
-
+
break;
}
-
+
case 3:
{
this->interface_constraints.reinit
(4 * (this->dofs_per_face - this->degree), this->dofs_per_face);
-
+
unsigned int target_row = 0;
-
+
for (unsigned int i = 0; i < 2; ++i)
for (unsigned int j = this->degree; j < 2 * this->degree;
++j, ++target_row)
for (unsigned int k = 0; k < this->dofs_per_face; ++k)
this->interface_constraints (target_row, k)
= face_embeddings[2 * i] (j, k);
-
+
for (unsigned int i = 0; i < 2; ++i)
for (unsigned int j = 3 * this->degree;
j < GeometryInfo<3>::lines_per_face * this->degree;
for (unsigned int k = 0; k < this->dofs_per_face; ++k)
this->interface_constraints (target_row, k)
= face_embeddings[i] (j, k);
-
+
for (unsigned int i = 0; i < 2; ++i)
for (unsigned int j = 0; j < 2; ++j)
for (unsigned int k = i * this->degree;
for (unsigned int l = 0; l < this->dofs_per_face; ++l)
this->interface_constraints (target_row, l)
= face_embeddings[i + 2 * j] (k, l);
-
+
for (unsigned int i = 0; i < 2; ++i)
for (unsigned int j = 0; j < 2; ++j)
for (unsigned int k = (i + 2) * this->degree;
for (unsigned int l = 0; l < this->dofs_per_face; ++l)
this->interface_constraints (target_row, l)
= face_embeddings[2 * i + j] (k, l);
-
+
for (unsigned int i = 0; i < GeometryInfo<3>::max_children_per_face;
++i)
for (unsigned int
for (unsigned int k = 0; k < this->dofs_per_face; ++k)
this->interface_constraints (target_row, k)
= face_embeddings[i] (j, k);
-
+
break;
}
-
+
default:
Assert (false, ExcNotImplemented ());
}
std::string
FE_Nedelec<dim>::get_name () const
{
- // note that the
- // FETools::get_fe_from_name
- // function depends on the
- // particular format of the string
- // this function returns, so they
- // have to be kept in synch
+ // note that the
+ // FETools::get_fe_from_name
+ // function depends on the
+ // particular format of the string
+ // this function returns, so they
+ // have to be kept in synch
std::ostringstream namebuf;
namebuf << "FE_Nedelec<" << dim << ">(" << this->degree-1 << ")";
{
const int dim = 2;
- // Create polynomial basis.
+ // Create polynomial basis.
const std::vector<Polynomials::Polynomial<double> >& lobatto_polynomials
= Polynomials::Lobatto::generate_complete_basis (degree + 1);
std::vector<Polynomials::Polynomial<double> >
for (unsigned int i = 0; i < lobatto_polynomials_grad.size (); ++i)
lobatto_polynomials_grad[i] = lobatto_polynomials[i + 1].derivative ();
- // Initialize quadratures to obtain
- // quadrature points later on.
+ // Initialize quadratures to obtain
+ // quadrature points later on.
const QGauss<dim - 1> reference_edge_quadrature (degree + 1);
const unsigned int&
n_edge_points = reference_edge_quadrature.size ();
this->generalized_face_support_points.resize (n_edge_points);
- // Create face support points.
+ // Create face support points.
for (unsigned int q_point = 0; q_point < n_edge_points; ++q_point)
this->generalized_face_support_points[q_point]
= reference_edge_quadrature.point (q_point);
if (degree > 0)
{
- // If the polynomial degree is positive
- // we have support points on the faces
- // and in the interior of a cell.
+ // If the polynomial degree is positive
+ // we have support points on the faces
+ // and in the interior of a cell.
const QGauss<dim> quadrature (degree + 1);
const unsigned int& n_interior_points = quadrature.size ();
this->generalized_support_points.resize
- (n_boundary_points + n_interior_points);
+ (n_boundary_points + n_interior_points);
boundary_weights.reinit (n_edge_points, degree);
for (unsigned int q_point = 0; q_point < n_edge_points;
- ++q_point)
- {
- for (unsigned int line = 0;
- line < GeometryInfo<dim>::lines_per_cell; ++line)
- this->generalized_support_points[line * n_edge_points
- + q_point]
- = edge_quadrature.point
- (QProjector<dim>::DataSetDescriptor::face
- (line, true, false, false, n_edge_points) + q_point);
-
- for (unsigned int i = 0; i < degree; ++i)
- boundary_weights (q_point, i)
- = reference_edge_quadrature.weight (q_point)
- * lobatto_polynomials_grad[i + 1].value
- (this->generalized_face_support_points[q_point] (0));
- }
+ ++q_point)
+ {
+ for (unsigned int line = 0;
+ line < GeometryInfo<dim>::lines_per_cell; ++line)
+ this->generalized_support_points[line * n_edge_points
+ + q_point]
+ = edge_quadrature.point
+ (QProjector<dim>::DataSetDescriptor::face
+ (line, true, false, false, n_edge_points) + q_point);
+
+ for (unsigned int i = 0; i < degree; ++i)
+ boundary_weights (q_point, i)
+ = reference_edge_quadrature.weight (q_point)
+ * lobatto_polynomials_grad[i + 1].value
+ (this->generalized_face_support_points[q_point] (0));
+ }
for (unsigned int q_point = 0; q_point < n_interior_points;
- ++q_point)
- this->generalized_support_points[q_point + n_boundary_points]
- = quadrature.point (q_point);
+ ++q_point)
+ this->generalized_support_points[q_point + n_boundary_points]
+ = quadrature.point (q_point);
}
else
{
- // In this case we only need support points
- // on the faces of a cell.
+ // In this case we only need support points
+ // on the faces of a cell.
const Quadrature<dim>& edge_quadrature
- = QProjector<dim>::project_to_all_faces
- (reference_edge_quadrature);
+ = QProjector<dim>::project_to_all_faces
+ (reference_edge_quadrature);
this->generalized_support_points.resize (n_boundary_points);
for (unsigned int line = 0;
- line < GeometryInfo<dim>::lines_per_cell; ++line)
- for (unsigned int q_point = 0; q_point < n_edge_points;
- ++q_point)
- this->generalized_support_points[line * n_edge_points
- + q_point]
- = edge_quadrature.point
- (QProjector<dim>::DataSetDescriptor::face
- (line, true, false, false, n_edge_points) + q_point);
+ line < GeometryInfo<dim>::lines_per_cell; ++line)
+ for (unsigned int q_point = 0; q_point < n_edge_points;
+ ++q_point)
+ this->generalized_support_points[line * n_edge_points
+ + q_point]
+ = edge_quadrature.point
+ (QProjector<dim>::DataSetDescriptor::face
+ (line, true, false, false, n_edge_points) + q_point);
}
}
{
const int dim = 3;
- // Create polynomial basis.
+ // Create polynomial basis.
const std::vector<Polynomials::Polynomial<double> >& lobatto_polynomials
= Polynomials::Lobatto::generate_complete_basis (degree + 1);
std::vector<Polynomials::Polynomial<double> >
for (unsigned int i = 0; i < lobatto_polynomials_grad.size (); ++i)
lobatto_polynomials_grad[i] = lobatto_polynomials[i + 1].derivative ();
- // Initialize quadratures to obtain
- // quadrature points later on.
+ // Initialize quadratures to obtain
+ // quadrature points later on.
const QGauss<1> reference_edge_quadrature (degree + 1);
const unsigned int& n_edge_points = reference_edge_quadrature.size ();
const Quadrature<dim - 1>& edge_quadrature
if (degree > 0)
{
- // If the polynomial degree is positive
- // we have support points on the edges,
- // faces and in the interior of a cell.
+ // If the polynomial degree is positive
+ // we have support points on the edges,
+ // faces and in the interior of a cell.
const QGauss<dim - 1> reference_face_quadrature (degree + 1);
const unsigned int& n_face_points
- = reference_face_quadrature.size ();
+ = reference_face_quadrature.size ();
const unsigned int n_boundary_points
- = GeometryInfo<dim>::lines_per_cell * n_edge_points
- + GeometryInfo<dim>::faces_per_cell * n_face_points;
+ = GeometryInfo<dim>::lines_per_cell * n_edge_points
+ + GeometryInfo<dim>::faces_per_cell * n_face_points;
const QGauss<dim> quadrature (degree + 1);
const unsigned int& n_interior_points = quadrature.size ();
boundary_weights.reinit (n_edge_points + n_face_points,
- 2 * (degree + 1) * degree);
+ 2 * (degree + 1) * degree);
this->generalized_face_support_points.resize
- (4 * n_edge_points + n_face_points);
+ (4 * n_edge_points + n_face_points);
this->generalized_support_points.resize
- (n_boundary_points + n_interior_points);
+ (n_boundary_points + n_interior_points);
- // Create support points on edges.
+ // Create support points on edges.
for (unsigned int q_point = 0; q_point < n_edge_points; ++q_point)
- {
- for (unsigned int line = 0;
- line < GeometryInfo<dim - 1>::lines_per_cell; ++line)
- this->generalized_face_support_points[line * n_edge_points
- + q_point]
- = edge_quadrature.point
- (QProjector<dim - 1>::DataSetDescriptor::face
- (line, true, false, false, n_edge_points) + q_point);
-
- for (unsigned int i = 0; i < 2; ++i)
- for (unsigned int j = 0; j < 2; ++j)
- {
- this->generalized_support_points
- [q_point + (i + 4 * j) * n_edge_points]
- = Point<dim>
- (i, reference_edge_quadrature.point (q_point) (0),
- j);
- this->generalized_support_points
- [q_point + (i + 4 * j + 2) * n_edge_points]
- = Point<dim>
- (reference_edge_quadrature.point (q_point) (0),
- i, j);
- this->generalized_support_points
- [q_point + (i + 2 * (j + 4)) * n_edge_points]
- = Point<dim>
- (i, j,
- reference_edge_quadrature.point (q_point) (0));
- }
-
- for (unsigned int i = 0; i < degree; ++i)
- boundary_weights (q_point, i)
- = reference_edge_quadrature.weight (q_point)
- * lobatto_polynomials_grad[i + 1].value
- (this->generalized_face_support_points[q_point] (1));
- }
-
- // Create support points on faces.
+ {
+ for (unsigned int line = 0;
+ line < GeometryInfo<dim - 1>::lines_per_cell; ++line)
+ this->generalized_face_support_points[line * n_edge_points
+ + q_point]
+ = edge_quadrature.point
+ (QProjector<dim - 1>::DataSetDescriptor::face
+ (line, true, false, false, n_edge_points) + q_point);
+
+ for (unsigned int i = 0; i < 2; ++i)
+ for (unsigned int j = 0; j < 2; ++j)
+ {
+ this->generalized_support_points
+ [q_point + (i + 4 * j) * n_edge_points]
+ = Point<dim>
+ (i, reference_edge_quadrature.point (q_point) (0),
+ j);
+ this->generalized_support_points
+ [q_point + (i + 4 * j + 2) * n_edge_points]
+ = Point<dim>
+ (reference_edge_quadrature.point (q_point) (0),
+ i, j);
+ this->generalized_support_points
+ [q_point + (i + 2 * (j + 4)) * n_edge_points]
+ = Point<dim>
+ (i, j,
+ reference_edge_quadrature.point (q_point) (0));
+ }
+
+ for (unsigned int i = 0; i < degree; ++i)
+ boundary_weights (q_point, i)
+ = reference_edge_quadrature.weight (q_point)
+ * lobatto_polynomials_grad[i + 1].value
+ (this->generalized_face_support_points[q_point] (1));
+ }
+
+ // Create support points on faces.
for (unsigned int q_point = 0; q_point < n_face_points;
- ++q_point)
- {
- this->generalized_face_support_points[q_point
- + 4 * n_edge_points]
- = reference_face_quadrature.point (q_point);
-
- for (unsigned int i = 0; i <= degree; ++i)
- for (unsigned int j = 0; j < degree; ++j)
- {
- boundary_weights (q_point + n_edge_points,
- 2 * (i * degree + j))
- = reference_face_quadrature.weight (q_point)
- * lobatto_polynomials_grad[i].value
- (this->generalized_face_support_points
- [q_point + 4 * n_edge_points] (0))
- * lobatto_polynomials[j + 2].value
- (this->generalized_face_support_points
- [q_point + 4 * n_edge_points] (1));
- boundary_weights (q_point + n_edge_points,
- 2 * (i * degree + j) + 1)
- = reference_face_quadrature.weight (q_point)
- * lobatto_polynomials_grad[i].value
- (this->generalized_face_support_points
- [q_point + 4 * n_edge_points] (1))
- * lobatto_polynomials[j + 2].value
- (this->generalized_face_support_points
- [q_point + 4 * n_edge_points] (0));
- }
- }
+ ++q_point)
+ {
+ this->generalized_face_support_points[q_point
+ + 4 * n_edge_points]
+ = reference_face_quadrature.point (q_point);
+
+ for (unsigned int i = 0; i <= degree; ++i)
+ for (unsigned int j = 0; j < degree; ++j)
+ {
+ boundary_weights (q_point + n_edge_points,
+ 2 * (i * degree + j))
+ = reference_face_quadrature.weight (q_point)
+ * lobatto_polynomials_grad[i].value
+ (this->generalized_face_support_points
+ [q_point + 4 * n_edge_points] (0))
+ * lobatto_polynomials[j + 2].value
+ (this->generalized_face_support_points
+ [q_point + 4 * n_edge_points] (1));
+ boundary_weights (q_point + n_edge_points,
+ 2 * (i * degree + j) + 1)
+ = reference_face_quadrature.weight (q_point)
+ * lobatto_polynomials_grad[i].value
+ (this->generalized_face_support_points
+ [q_point + 4 * n_edge_points] (1))
+ * lobatto_polynomials[j + 2].value
+ (this->generalized_face_support_points
+ [q_point + 4 * n_edge_points] (0));
+ }
+ }
const Quadrature<dim>& face_quadrature
- = QProjector<dim>::project_to_all_faces
- (reference_face_quadrature);
+ = QProjector<dim>::project_to_all_faces
+ (reference_face_quadrature);
for (unsigned int face = 0;
- face < GeometryInfo<dim>::faces_per_cell; ++face)
- for (unsigned int q_point = 0; q_point < n_face_points;
- ++q_point)
- {
- this->generalized_support_points
- [face * n_face_points + q_point
- + GeometryInfo<dim>::lines_per_cell * n_edge_points]
- = face_quadrature.point
- (QProjector<dim>::DataSetDescriptor::face
- (face, true, false, false, n_face_points) + q_point);
- }
-
- // Create support points in the interior.
+ face < GeometryInfo<dim>::faces_per_cell; ++face)
+ for (unsigned int q_point = 0; q_point < n_face_points;
+ ++q_point)
+ {
+ this->generalized_support_points
+ [face * n_face_points + q_point
+ + GeometryInfo<dim>::lines_per_cell * n_edge_points]
+ = face_quadrature.point
+ (QProjector<dim>::DataSetDescriptor::face
+ (face, true, false, false, n_face_points) + q_point);
+ }
+
+ // Create support points in the interior.
for (unsigned int q_point = 0; q_point < n_interior_points;
- ++q_point)
- this->generalized_support_points[q_point + n_boundary_points]
- = quadrature.point (q_point);
+ ++q_point)
+ this->generalized_support_points[q_point + n_boundary_points]
+ = quadrature.point (q_point);
}
else
{
this->generalized_face_support_points.resize (4 * n_edge_points);
this->generalized_support_points.resize
- (GeometryInfo<dim>::lines_per_cell * n_edge_points);
+ (GeometryInfo<dim>::lines_per_cell * n_edge_points);
for (unsigned int q_point = 0; q_point < n_edge_points;
- ++q_point)
- {
- for (unsigned int line = 0;
- line < GeometryInfo<dim - 1>::lines_per_cell; ++line)
- this->generalized_face_support_points[line * n_edge_points
- + q_point]
- = edge_quadrature.point
- (QProjector<dim - 1>::DataSetDescriptor::face
- (line, true, false, false, n_edge_points) + q_point);
-
- for (unsigned int i = 0; i < 2; ++i)
- for (unsigned int j = 0; j < 2; ++j)
- {
- this->generalized_support_points
- [q_point + (i + 4 * j) * n_edge_points]
- = Point<dim>
- (i, reference_edge_quadrature.point (q_point) (0),
- j);
- this->generalized_support_points
- [q_point + (i + 4 * j + 2) * n_edge_points]
- = Point<dim>
- (reference_edge_quadrature.point (q_point) (0),
- i, j);
- this->generalized_support_points
- [q_point + (i + 2 * (j + 4)) * n_edge_points]
- = Point<dim>
- (i, j,
- reference_edge_quadrature.point (q_point) (0));
- }
- }
+ ++q_point)
+ {
+ for (unsigned int line = 0;
+ line < GeometryInfo<dim - 1>::lines_per_cell; ++line)
+ this->generalized_face_support_points[line * n_edge_points
+ + q_point]
+ = edge_quadrature.point
+ (QProjector<dim - 1>::DataSetDescriptor::face
+ (line, true, false, false, n_edge_points) + q_point);
+
+ for (unsigned int i = 0; i < 2; ++i)
+ for (unsigned int j = 0; j < 2; ++j)
+ {
+ this->generalized_support_points
+ [q_point + (i + 4 * j) * n_edge_points]
+ = Point<dim>
+ (i, reference_edge_quadrature.point (q_point) (0),
+ j);
+ this->generalized_support_points
+ [q_point + (i + 4 * j + 2) * n_edge_points]
+ = Point<dim>
+ (reference_edge_quadrature.point (q_point) (0),
+ i, j);
+ this->generalized_support_points
+ [q_point + (i + 2 * (j + 4)) * n_edge_points]
+ = Point<dim>
+ (i, j,
+ reference_edge_quadrature.point (q_point) (0));
+ }
+ }
}
}
void
FE_Nedelec<1>::initialize_restriction ()
{
- // there is only one refinement case in 1d,
- // which is the isotropic one
+ // there is only one refinement case in 1d,
+ // which is the isotropic one
for (unsigned int i = 0; i < GeometryInfo<1>::max_children_per_cell; ++i)
this->restriction[0][i].reinit(0, 0);
}
void
FE_Nedelec<dim>::initialize_restriction ()
{
- // This function does the same as the
- // function interpolate further below.
- // But since the functions, which we
- // interpolate here, are discontinuous
- // we have to use more quadrature
- // points as in interpolate.
+ // This function does the same as the
+ // function interpolate further below.
+ // But since the functions, which we
+ // interpolate here, are discontinuous
+ // we have to use more quadrature
+ // points as in interpolate.
const QGauss<1> edge_quadrature (2 * this->degree);
const std::vector<Point<1> >& edge_quadrature_points
= edge_quadrature.get_points ();
{
case 2:
{
- // First interpolate the shape
- // functions of the child cells
- // to the lowest order shape
- // functions of the parent cell.
+ // First interpolate the shape
+ // functions of the child cells
+ // to the lowest order shape
+ // functions of the parent cell.
for (unsigned int dof = 0; dof < this->dofs_per_cell; ++dof)
for (unsigned int q_point = 0; q_point < n_edge_quadrature_points;
++q_point)
else
{
Point<dim> quadrature_point (0.0,
- 2.0 * edge_quadrature_points[q_point] (0)
- - 1.0);
+ 2.0 * edge_quadrature_points[q_point] (0)
+ - 1.0);
this->restriction[index][2] (0, dof) += weight
* this->shape_value_component
// parent cell.
if (this->degree > 1)
{
- const unsigned int deg = this->degree-1;
+ const unsigned int deg = this->degree-1;
const std::vector<Polynomials::Polynomial<double> >&
legendre_polynomials
= Polynomials::Legendre::generate_complete_basis (deg);
for (unsigned int i = 0; i < deg; ++i)
assembling_matrix (i, q_point) = weight
* legendre_polynomials[i + 1].value
- (edge_quadrature_points[q_point] (0));
+ (edge_quadrature_points[q_point] (0));
}
FullMatrix<double> system_matrix (deg, deg);
const double weight
= edge_quadrature.weight (q_point);
const Point<dim> quadrature_point_0 (i,
- edge_quadrature_points[q_point] (0));
+ edge_quadrature_points[q_point] (0));
const Point<dim> quadrature_point_1
- (edge_quadrature_points[q_point] (0),
- i);
+ (edge_quadrature_points[q_point] (0),
+ i);
if (edge_quadrature_points[q_point] (0) < 0.5)
{
Point<dim> quadrature_point_2 (i,
- 2.0 * edge_quadrature_points[q_point] (0));
+ 2.0 * edge_quadrature_points[q_point] (0));
tmp (0) = weight
* (2.0 * this->shape_value_component
- (dof, quadrature_point_2, 1)
- - this->restriction[index][i]
- (i * this->degree, dof)
- * this->shape_value_component
- (i * this->degree,
- quadrature_point_0, 1));
+ (dof, quadrature_point_2, 1)
+ - this->restriction[index][i]
+ (i * this->degree, dof)
+ * this->shape_value_component
+ (i * this->degree,
+ quadrature_point_0, 1));
tmp (1) = -1.0 * weight
- * this->restriction[index][i + 2]
- (i * this->degree, dof)
- * this->shape_value_component
- (i * this->degree,
- quadrature_point_0, 1);
+ * this->restriction[index][i + 2]
+ (i * this->degree, dof)
+ * this->shape_value_component
+ (i * this->degree,
+ quadrature_point_0, 1);
quadrature_point_2
= Point<dim> (2.0 * edge_quadrature_points[q_point] (0),
- i);
+ i);
tmp (2) = weight
* (2.0 * this->shape_value_component
- (dof, quadrature_point_2, 0)
- - this->restriction[index][2 * i]
- ((i + 2) * this->degree, dof)
- * this->shape_value_component
- ((i + 2) * this->degree,
- quadrature_point_1, 0));
+ (dof, quadrature_point_2, 0)
+ - this->restriction[index][2 * i]
+ ((i + 2) * this->degree, dof)
+ * this->shape_value_component
+ ((i + 2) * this->degree,
+ quadrature_point_1, 0));
tmp (3) = -1.0 * weight
- * this->restriction[index][2 * i + 1]
- ((i + 2) * this->degree, dof)
- * this->shape_value_component
- ((i + 2) * this->degree,
- quadrature_point_1, 0);
+ * this->restriction[index][2 * i + 1]
+ ((i + 2) * this->degree, dof)
+ * this->shape_value_component
+ ((i + 2) * this->degree,
+ quadrature_point_1, 0);
}
else
{
tmp (0) = -1.0 * weight
* this->restriction[index][i]
- (i * this->degree, dof)
- * this->shape_value_component
- (i * this->degree,
- quadrature_point_0, 1);
+ (i * this->degree, dof)
+ * this->shape_value_component
+ (i * this->degree,
+ quadrature_point_0, 1);
Point<dim> quadrature_point_2 (i,
- 2.0 * edge_quadrature_points[q_point] (0)
- - 1.0);
+ 2.0 * edge_quadrature_points[q_point] (0)
+ - 1.0);
tmp (1) = weight
- * (2.0 * this->shape_value_component
- (dof, quadrature_point_2, 1)
- - this->restriction[index][i + 2]
- (i * this->degree, dof)
- * this->shape_value_component
- (i * this->degree,
- quadrature_point_0, 1));
+ * (2.0 * this->shape_value_component
+ (dof, quadrature_point_2, 1)
+ - this->restriction[index][i + 2]
+ (i * this->degree, dof)
+ * this->shape_value_component
+ (i * this->degree,
+ quadrature_point_0, 1));
tmp (2) = -1.0 * weight
- * this->restriction[index][2 * i]
- ((i + 2) * this->degree, dof)
- * this->shape_value_component
- ((i + 2) * this->degree,
- quadrature_point_1, 0);
+ * this->restriction[index][2 * i]
+ ((i + 2) * this->degree, dof)
+ * this->shape_value_component
+ ((i + 2) * this->degree,
+ quadrature_point_1, 0);
quadrature_point_2
= Point<dim> (2.0 * edge_quadrature_points[q_point] (0)
- - 1.0, i);
+ - 1.0, i);
tmp (3) = weight
- * (2.0 * this->shape_value_component
- (dof, quadrature_point_2, 0)
- - this->restriction[index][2 * i + 1]
- ((i + 2) * this->degree, dof)
- * this->shape_value_component
- ((i + 2) * this->degree,
- quadrature_point_1, 0));
+ * (2.0 * this->shape_value_component
+ (dof, quadrature_point_2, 0)
+ - this->restriction[index][2 * i + 1]
+ ((i + 2) * this->degree, dof)
+ * this->shape_value_component
+ ((i + 2) * this->degree,
+ quadrature_point_1, 0));
}
for (unsigned int j = 0; j < this->degree-1; ++j)
if (std::abs (solution (i * (this->degree-1) + j, 2 * k))
> 1e-14)
this->restriction[index][k]
- (i * (this->degree-1) + j + n_boundary_dofs, dof)
+ (i * (this->degree-1) + j + n_boundary_dofs, dof)
= solution (i * (this->degree-1) + j, 2 * k);
if (std::abs (solution (i * (this->degree-1) + j, 2 * k + 1))
this->restriction[index][k]
(i + (this->degree-1 + j) * this->degree + n_boundary_dofs,
dof)
- = solution (i * (this->degree-1) + j, 2 * k + 1);
+ = solution (i * (this->degree-1) + j, 2 * k + 1);
}
}
}
case 3:
{
- // First interpolate the shape
- // functions of the child cells
- // to the lowest order shape
- // functions of the parent cell.
+ // First interpolate the shape
+ // functions of the child cells
+ // to the lowest order shape
+ // functions of the parent cell.
for (unsigned int dof = 0; dof < this->dofs_per_cell; ++dof)
for (unsigned int q_point = 0; q_point < n_edge_quadrature_points;
++q_point)
// parent cell.
if (this->degree > 1)
{
- const unsigned int deg = this->degree-1;
+ const unsigned int deg = this->degree-1;
const std::vector<Polynomials::Polynomial<double> >&
legendre_polynomials
= Polynomials::Legendre::generate_complete_basis (deg);
for (unsigned int i = 0; i < deg; ++i)
assembling_matrix (i, q_point) = weight
- * legendre_polynomials[i + 1].value
- (edge_quadrature_points[q_point] (0));
+ * legendre_polynomials[i + 1].value
+ (edge_quadrature_points[q_point] (0));
}
FullMatrix<double> system_matrix (deg, deg);
if (face_quadrature_points[q_point] (1) < 0.5)
{
Point<dim> quadrature_point_0 (i,
- 2.0 * face_quadrature_points[q_point] (0),
- 2.0 * face_quadrature_points[q_point] (1));
+ 2.0 * face_quadrature_points[q_point] (0),
+ 2.0 * face_quadrature_points[q_point] (1));
tmp (0) += 2.0 * this->shape_value_component
(dof, quadrature_point_0, 1);
else
{
Point<dim> quadrature_point_0 (i,
- 2.0 * face_quadrature_points[q_point] (0),
- 2.0 * face_quadrature_points[q_point] (1)
- - 1.0);
+ 2.0 * face_quadrature_points[q_point] (0),
+ 2.0 * face_quadrature_points[q_point] (1)
+ - 1.0);
tmp (2) += 2.0 * this->shape_value_component
(dof, quadrature_point_0, 1);
{
if (std::abs (solution
((l * deg + m) * deg + n,
- 3 * (i + 2 * (j + 2 * k))))
+ 3 * (i + 2 * (j + 2 * k))))
> 1e-14)
this->restriction[index][2 * (2 * i + j) + k]
((l * deg + m) * deg + n + n_boundary_dofs,
dof) = solution ((l * deg + m) * deg + n,
- 3 * (i + 2 * (j + 2 * k)));
+ 3 * (i + 2 * (j + 2 * k)));
if (std::abs (solution
((l * deg + m) * deg + n,
- 3 * (i + 2 * (j + 2 * k)) + 1))
+ 3 * (i + 2 * (j + 2 * k)) + 1))
> 1e-14)
this->restriction[index][2 * (2 * i + j) + k]
((l + (m + deg) * this->degree) * deg + n
+ n_boundary_dofs,
dof) = solution ((l * deg + m) * deg + n,
- 3 * (i + 2 * (j + 2 * k)) + 1);
+ 3 * (i + 2 * (j + 2 * k)) + 1);
if (std::abs (solution
((l * deg + m) * deg + n,
- 3 * (i + 2 * (j + 2 * k)) + 2))
+ 3 * (i + 2 * (j + 2 * k)) + 2))
> 1e-14)
this->restriction[index][2 * (2 * i + j) + k]
(l + ((m + 2 * deg) * deg + n) * this->degree
+ n_boundary_dofs, dof)
= solution ((l * deg + m) * deg + n,
- 3 * (i + 2 * (j + 2 * k)) + 2);
+ 3 * (i + 2 * (j + 2 * k)) + 2);
}
}
}
FE_Nedelec<dim>::get_dpo_vector (const unsigned int degree, bool dg)
{
std::vector<unsigned int> dpo (dim + 1);
-
+
if (dg)
{
dpo[dim] = PolynomialsNedelec<dim>::compute_n_pols(degree);
dpo[0] = 0;
dpo[1] = degree + 1;
dpo[2] = 2 * degree * (degree + 1);
-
+
if (dim == 3)
- dpo[3] = 3 * degree * degree * (degree + 1);
+ dpo[3] = 3 * degree * degree * (degree + 1);
}
-
+
return dpo;
}
= dynamic_cast<const FE_Nedelec<dim>*>(&fe_other))
{
if (this->degree < fe_nedelec_other->degree)
- return FiniteElementDomination::this_element_dominates;
+ return FiniteElementDomination::this_element_dominates;
else if (this->degree == fe_nedelec_other->degree)
- return FiniteElementDomination::either_element_can_dominate;
+ return FiniteElementDomination::either_element_can_dominate;
else
- return FiniteElementDomination::other_element_dominates;
+ return FiniteElementDomination::other_element_dominates;
}
else if (dynamic_cast<const FE_Nothing<dim>*>(&fe_other) != 0)
{
- // the FE_Nothing has no
- // degrees of
- // freedom. nevertheless, we
- // say that the FE_Q element
- // dominates so that we don't
- // have to force the FE_Q side
- // to become a zero function
- // and rather allow the
- // function to be discontinuous
- // along the interface
+ // the FE_Nothing has no
+ // degrees of
+ // freedom. nevertheless, we
+ // say that the FE_Q element
+ // dominates so that we don't
+ // have to force the FE_Q side
+ // to become a zero function
+ // and rather allow the
+ // function to be discontinuous
+ // along the interface
return FiniteElementDomination::other_element_dominates;
}
FE_Nedelec<dim>::hp_line_dof_identities (const FiniteElement<dim>& fe_other)
const
{
- // we can presently only compute these
- // identities if both FEs are
- // FE_Nedelec or if the other one is an
- // FE_Nothing
+ // we can presently only compute these
+ // identities if both FEs are
+ // FE_Nedelec or if the other one is an
+ // FE_Nothing
if (const FE_Nedelec<dim> *fe_nedelec_other
= dynamic_cast<const FE_Nedelec<dim>*> (&fe_other))
{
- // dofs are located on lines, so
- // two dofs are identical, if their
- // edge shape functions have the
- // same polynomial degree.
+ // dofs are located on lines, so
+ // two dofs are identical, if their
+ // edge shape functions have the
+ // same polynomial degree.
std::vector<std::pair<unsigned int, unsigned int> > identities;
for (unsigned int i = 0;
else
if (dynamic_cast<const FE_Nothing<dim>*> (&fe_other) != 0)
{
- // the FE_Nothing has no
- // degrees of freedom, so there
- // are no equivalencies to be
- // recorded
+ // the FE_Nothing has no
+ // degrees of freedom, so there
+ // are no equivalencies to be
+ // recorded
return std::vector<std::pair<unsigned int, unsigned int> > ();
}
FE_Nedelec<dim>::hp_quad_dof_identities (const FiniteElement<dim>& fe_other)
const
{
- // we can presently only compute
- // these identities if both FEs are
- // FE_Nedelec or if the other one is an
- // FE_Nothing
+ // we can presently only compute
+ // these identities if both FEs are
+ // FE_Nedelec or if the other one is an
+ // FE_Nothing
if (const FE_Nedelec<dim> *fe_nedelec_other
= dynamic_cast<const FE_Nedelec<dim>*> (&fe_other))
{
- // dofs are located on the interior
- // of faces, so two dofs are identical,
- // if their face shape functions have
- // the same polynomial degree.
+ // dofs are located on the interior
+ // of faces, so two dofs are identical,
+ // if their face shape functions have
+ // the same polynomial degree.
const unsigned int p = fe_nedelec_other->degree;
const unsigned int q = this->degree;
const unsigned int p_min = std::min (p, q);
else
if (dynamic_cast<const FE_Nothing<dim>*> (&fe_other) != 0)
{
- // the FE_Nothing has no
- // degrees of freedom, so there
- // are no equivalencies to be
- // recorded
+ // the FE_Nothing has no
+ // degrees of freedom, so there
+ // are no equivalencies to be
+ // recorded
return std::vector<std::pair<unsigned int, unsigned int> > ();
}
(const FiniteElement<dim>& source, FullMatrix<double>& interpolation_matrix)
const
{
- // this is only implemented, if the
- // source FE is also a
- // Nedelec element
+ // this is only implemented, if the
+ // source FE is also a
+ // Nedelec element
typedef FE_Nedelec<dim> FEN;
typedef FiniteElement<dim> FEL;
ExcDimensionMismatch (interpolation_matrix.n (),
this->dofs_per_face));
- // ok, source is a Nedelec element, so
- // we will be able to do the work
+ // ok, source is a Nedelec element, so
+ // we will be able to do the work
const FE_Nedelec<dim> &source_fe
= dynamic_cast<const FE_Nedelec<dim>&> (source);
- // Make sure, that the element,
+ // Make sure, that the element,
// for which the DoFs should be
// constrained is the one with
// the higher polynomial degree.
// also if this assertion is not
// satisfied. But the matrices
// produced in that case might
- // lead to problems in the
+ // lead to problems in the
// hp procedures, which use this
- // method.
+ // method.
Assert (this->dofs_per_face <= source_fe.dofs_per_face,
typename FEL::ExcInterpolationNotImplemented ());
interpolation_matrix = 0;
const unsigned int subface,
FullMatrix<double>& interpolation_matrix) const
{
- // this is only implemented, if the
- // source FE is also a
- // Nedelec element
+ // this is only implemented, if the
+ // source FE is also a
+ // Nedelec element
typedef FE_Nedelec<dim> FEN;
typedef FiniteElement<dim> FEL;
ExcDimensionMismatch (interpolation_matrix.n (),
this->dofs_per_face));
- // ok, source is a Nedelec element, so
- // we will be able to do the work
+ // ok, source is a Nedelec element, so
+ // we will be able to do the work
const FE_Nedelec<dim> &source_fe
= dynamic_cast<const FE_Nedelec<dim>&> (source);
- // Make sure, that the element,
+ // Make sure, that the element,
// for which the DoFs should be
// constrained is the one with
// the higher polynomial degree.
// also if this assertion is not
// satisfied. But the matrices
// produced in that case might
- // lead to problems in the
+ // lead to problems in the
// hp procedures, which use this
- // method.
+ // method.
Assert (this->dofs_per_face <= source_fe.dofs_per_face,
typename FEL::ExcInterpolationNotImplemented ());
interpolation_matrix = 0.0;
- // Perform projection-based interpolation
- // as usual.
+ // Perform projection-based interpolation
+ // as usual.
const QGauss<1> edge_quadrature (source_fe.degree);
const std::vector<Point<1> >&
edge_quadrature_points = edge_quadrature.get_points ();
for (unsigned int q_point = 0; q_point < n_edge_quadrature_points;
++q_point)
{
- const Point<dim> quadrature_point (0.0,
- 0.5 * (edge_quadrature_points[q_point] (0)
- + subface));
+ const Point<dim> quadrature_point (0.0,
+ 0.5 * (edge_quadrature_points[q_point] (0)
+ + subface));
interpolation_matrix (0, dof) += 0.5
* edge_quadrature.weight (q_point)
Point<dim>
quadrature_point (0.5 * (i + shifts[subface][0]),
0.5 * (edge_quadrature_points[q_point] (0)
- + shifts[subface][1]),
- 0.0);
+ + shifts[subface][1]),
+ 0.0);
interpolation_matrix (i * source_fe.degree, dof) += weight
* this->shape_value_component
unsigned int offset) const
{
const unsigned int deg = this->degree-1;
-
+
Assert (values.size () == this->generalized_support_points.size (),
ExcDimensionMismatch (values.size (),
this->generalized_support_points.size ()));
// equations.
if (this->degree > 1)
{
- // We start with projection
- // on the higher order edge
- // shape function.
+ // We start with projection
+ // on the higher order edge
+ // shape function.
const std::vector<Polynomials::Polynomial<double> >&
lobatto_polynomials
= Polynomials::Lobatto::generate_complete_basis
const QGauss<dim> reference_quadrature (this->degree);
const std::vector<Polynomials::Polynomial<double> >&
legendre_polynomials
- = Polynomials::Legendre::generate_complete_basis (this->degree-1);
+ = Polynomials::Legendre::generate_complete_basis (this->degree-1);
const unsigned int& n_interior_points
= reference_quadrature.size ();
system_matrix.reinit ((this->degree-1) * this->degree,
- (this->degree-1) * this->degree);
+ (this->degree-1) * this->degree);
system_matrix = 0;
for (unsigned int i = 0; i < this->degree; ++i)
// equations.
if (this->degree > 1)
{
- // We start with projection
- // on the higher order edge
- // shape function.
+ // We start with projection
+ // on the higher order edge
+ // shape function.
const std::vector<Polynomials::Polynomial<double> >&
lobatto_polynomials
= Polynomials::Lobatto::generate_complete_basis
n_face_points = n_edge_points * n_edge_points;
system_matrix.reinit ((this->degree-1) * this->degree,
- (this->degree-1) * this->degree);
+ (this->degree-1) * this->degree);
system_matrix = 0;
for (unsigned int i = 0; i < this->degree; ++i)
// Set up the right hand side
// for the horizontal shape
// functions.
- system_rhs = 0;
+ system_rhs = 0;
for (unsigned int q_point = 0;
q_point < n_face_points; ++q_point)
// Set up the right hand side
// for the horizontal shape
// functions.
- system_rhs = 0;
+ system_rhs = 0;
for (unsigned int q_point = 0;
q_point < n_face_points; ++q_point)
// Set up the right hand side
// for the horizontal shape
// functions.
- system_rhs = 0;
+ system_rhs = 0;
for (unsigned int q_point = 0;
q_point < n_face_points; ++q_point)
// equations.
if (this->degree-1 > 1)
{
- // We start with projection
- // on the higher order edge
- // shape function.
+ // We start with projection
+ // on the higher order edge
+ // shape function.
const std::vector<Polynomials::Polynomial<double> >&
lobatto_polynomials
= Polynomials::Lobatto::generate_complete_basis
* lobatto_polynomials_grad[i + 1].value
(this->generalized_face_support_points[q_point]
(1));
-
+
FullMatrix<double> system_matrix_inv (this->degree-1, this->degree-1);
system_matrix_inv.invert (system_matrix);
n_interior_points = reference_quadrature.size ();
const std::vector<Polynomials::Polynomial<double> >&
legendre_polynomials
- = Polynomials::Legendre::generate_complete_basis (this->degree-1);
+ = Polynomials::Legendre::generate_complete_basis (this->degree-1);
system_matrix.reinit ((this->degree-1) * this->degree,
- (this->degree-1) * this->degree);
+ (this->degree-1) * this->degree);
system_matrix = 0;
for (unsigned int i = 0; i < this->degree; ++i)
// equations.
if (this->degree > 1)
{
- // We start with projection
- // on the higher order edge
- // shape function.
+ // We start with projection
+ // on the higher order edge
+ // shape function.
const std::vector<Polynomials::Polynomial<double> >&
lobatto_polynomials
= Polynomials::Lobatto::generate_complete_basis
for (unsigned int line = 0;
line < GeometryInfo<dim>::lines_per_cell; ++line)
{
- // Set up the right hand side.
+ // Set up the right hand side.
system_rhs = 0;
for (unsigned int q_point = 0; q_point < this->degree; ++q_point)
const unsigned int n_face_points = n_edge_points * n_edge_points;
system_matrix.reinit ((this->degree-1) * this->degree,
- (this->degree-1) * this->degree);
+ (this->degree-1) * this->degree);
system_matrix = 0;
for (unsigned int i = 0; i < this->degree; ++i)
// $Id$
// Version: $Name$
//
-// Copyright (C) 2009, 2011 by the deal.II authors
+// Copyright (C) 2009, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
FE_Nothing<dim>::FE_Nothing (const unsigned n_components)
:
FiniteElement<dim>
- (FiniteElementData<dim>(std::vector<unsigned>(dim+1,0),
- n_components, 0,
- FiniteElementData<dim>::unknown),
- std::vector<bool>(),
- std::vector<std::vector<bool> >() )
+ (FiniteElementData<dim>(std::vector<unsigned>(dim+1,0),
+ n_components, 0,
+ FiniteElementData<dim>::unknown),
+ std::vector<bool>(),
+ std::vector<std::vector<bool> >() )
{
// in most other elements we have to set up all sorts of stuff
// here. there isn't much that we have to do here; in particular,
template <int dim>
double
FE_Nothing<dim>::shape_value (const unsigned int /*i*/,
- const Point<dim> & /*p*/) const
+ const Point<dim> & /*p*/) const
{
Assert(false,ExcMessage(zero_dof_message));
return 0;
template <int dim>
typename Mapping<dim>::InternalDataBase *
FE_Nothing<dim>::get_data (const UpdateFlags /*flags*/,
- const Mapping<dim> & /*mapping*/,
- const Quadrature<dim> & /*quadrature*/) const
+ const Mapping<dim> & /*mapping*/,
+ const Quadrature<dim> & /*quadrature*/) const
{
// Create a default data object. Normally we would then
// need to resize things to hold the appropriate numbers
void
FE_Nothing<dim>::
fill_fe_values (const Mapping<dim> & /*mapping*/,
- const typename Triangulation<dim>::cell_iterator & /*cell*/,
- const Quadrature<dim> & /*quadrature*/,
- typename Mapping<dim>::InternalDataBase & /*mapping_data*/,
- typename Mapping<dim>::InternalDataBase & /*fedata*/,
- FEValuesData<dim,dim> & /*data*/,
- CellSimilarity::Similarity & /*cell_similarity*/) const
+ const typename Triangulation<dim>::cell_iterator & /*cell*/,
+ const Quadrature<dim> & /*quadrature*/,
+ typename Mapping<dim>::InternalDataBase & /*mapping_data*/,
+ typename Mapping<dim>::InternalDataBase & /*fedata*/,
+ FEValuesData<dim,dim> & /*data*/,
+ CellSimilarity::Similarity & /*cell_similarity*/) const
{
// leave data fields empty
}
void
FE_Nothing<dim>::
fill_fe_face_values (const Mapping<dim> & /*mapping*/,
- const typename Triangulation<dim>::cell_iterator & /*cell*/,
- const unsigned int /*face*/,
- const Quadrature<dim-1> & /*quadrature*/,
- typename Mapping<dim>::InternalDataBase & /*mapping_data*/,
- typename Mapping<dim>::InternalDataBase & /*fedata*/,
- FEValuesData<dim,dim> & /*data*/) const
+ const typename Triangulation<dim>::cell_iterator & /*cell*/,
+ const unsigned int /*face*/,
+ const Quadrature<dim-1> & /*quadrature*/,
+ typename Mapping<dim>::InternalDataBase & /*mapping_data*/,
+ typename Mapping<dim>::InternalDataBase & /*fedata*/,
+ FEValuesData<dim,dim> & /*data*/) const
{
// leave data fields empty
}
void
FE_Nothing<dim>::
fill_fe_subface_values (const Mapping<dim> & /*mapping*/,
- const typename Triangulation<dim>::cell_iterator & /*cell*/,
- const unsigned int /*face*/,
- const unsigned int /*subface*/,
- const Quadrature<dim-1> & /*quadrature*/,
- typename Mapping<dim>::InternalDataBase & /*mapping_data*/,
- typename Mapping<dim>::InternalDataBase & /*fedata*/,
- FEValuesData<dim,dim> & /*data*/) const
+ const typename Triangulation<dim>::cell_iterator & /*cell*/,
+ const unsigned int /*face*/,
+ const unsigned int /*subface*/,
+ const Quadrature<dim-1> & /*quadrature*/,
+ typename Mapping<dim>::InternalDataBase & /*mapping_data*/,
+ typename Mapping<dim>::InternalDataBase & /*fedata*/,
+ FEValuesData<dim,dim> & /*data*/) const
{
// leave data fields empty
}
hp_vertex_dof_identities (const FiniteElement<dim> &/*fe_other*/) const
{
// the FE_Nothing has no
- // degrees of freedom, so there
- // are no equivalencies to be
- // recorded
+ // degrees of freedom, so there
+ // are no equivalencies to be
+ // recorded
return std::vector<std::pair<unsigned int, unsigned int> > ();
}
hp_line_dof_identities (const FiniteElement<dim> &/*fe_other*/) const
{
// the FE_Nothing has no
- // degrees of freedom, so there
- // are no equivalencies to be
- // recorded
+ // degrees of freedom, so there
+ // are no equivalencies to be
+ // recorded
return std::vector<std::pair<unsigned int, unsigned int> > ();
}
hp_quad_dof_identities (const FiniteElement<dim> &/*fe_other*/) const
{
// the FE_Nothing has no
- // degrees of freedom, so there
- // are no equivalencies to be
- // recorded
+ // degrees of freedom, so there
+ // are no equivalencies to be
+ // recorded
return std::vector<std::pair<unsigned int, unsigned int> > ();
}
FEValuesData<1,2> &data,
CellSimilarity::Similarity &cell_similarity) const
{
- // convert data object to internal
- // data for this class. fails with
- // an exception if that is not
- // possible
+ // convert data object to internal
+ // data for this class. fails with
+ // an exception if that is not
+ // possible
Assert (dynamic_cast<InternalData *> (&fedata) != 0, ExcInternalError());
InternalData &fe_data = static_cast<InternalData &> (fedata);
for (unsigned int k=0; k<this->dofs_per_cell; ++k)
{
if (flags & update_values)
- for (unsigned int i=0; i<quadrature.size(); ++i)
- data.shape_values(k,i) = fe_data.shape_values[k][i];
+ for (unsigned int i=0; i<quadrature.size(); ++i)
+ data.shape_values(k,i) = fe_data.shape_values[k][i];
if (flags & update_gradients && cell_similarity != CellSimilarity::translation)
- mapping.transform(fe_data.shape_gradients[k], data.shape_gradients[k],
- mapping_data, mapping_covariant);
+ mapping.transform(fe_data.shape_gradients[k], data.shape_gradients[k],
+ mapping_data, mapping_covariant);
}
if (flags & update_hessians && cell_similarity != CellSimilarity::translation)
this->compute_2nd (mapping, cell, QProjector<1>::DataSetDescriptor::cell(),
- mapping_data, fe_data, data);
+ mapping_data, fe_data, data);
}
CellSimilarity::Similarity &cell_similarity) const
{
- // assert that the following dynamics
- // cast is really well-defined.
+ // assert that the following dynamics
+ // cast is really well-defined.
Assert (dynamic_cast<InternalData *> (&fedata) != 0, ExcInternalError());
InternalData &fe_data = static_cast<InternalData &> (fedata);
for (unsigned int k=0; k<this->dofs_per_cell; ++k)
{
if (flags & update_values)
- for (unsigned int i=0; i<quadrature.size(); ++i)
- data.shape_values(k,i) = fe_data.shape_values[k][i];
+ for (unsigned int i=0; i<quadrature.size(); ++i)
+ data.shape_values(k,i) = fe_data.shape_values[k][i];
if (flags & update_gradients && cell_similarity != CellSimilarity::translation)
- mapping.transform(fe_data.shape_gradients[k], data.shape_gradients[k],
- mapping_data, mapping_covariant);
+ mapping.transform(fe_data.shape_gradients[k], data.shape_gradients[k],
+ mapping_data, mapping_covariant);
}
if (flags & update_hessians && cell_similarity != CellSimilarity::translation)
this->compute_2nd (mapping, cell, QProjector<2>::DataSetDescriptor::cell(),
- mapping_data, fe_data, data);
+ mapping_data, fe_data, data);
}
FEValuesData<1,2> &data,
CellSimilarity::Similarity &cell_similarity) const
{
- // convert data object to internal
- // data for this class. fails with
- // an exception if that is not
- // possible
+ // convert data object to internal
+ // data for this class. fails with
+ // an exception if that is not
+ // possible
Assert (dynamic_cast<InternalData *> (&fedata) != 0, ExcInternalError());
InternalData &fe_data = static_cast<InternalData &> (fedata);
for (unsigned int k=0; k<this->dofs_per_cell; ++k)
{
if (flags & update_values)
- for (unsigned int i=0; i<quadrature.size(); ++i)
- data.shape_values(k,i) = fe_data.shape_values[k][i];
+ for (unsigned int i=0; i<quadrature.size(); ++i)
+ data.shape_values(k,i) = fe_data.shape_values[k][i];
if (flags & update_gradients && cell_similarity != CellSimilarity::translation)
- mapping.transform(fe_data.shape_gradients[k], data.shape_gradients[k],
- mapping_data, mapping_covariant);
+ mapping.transform(fe_data.shape_gradients[k], data.shape_gradients[k],
+ mapping_data, mapping_covariant);
}
if (flags & update_hessians && cell_similarity != CellSimilarity::translation)
this->compute_2nd (mapping, cell, QProjector<1>::DataSetDescriptor::cell(),
- mapping_data, fe_data, data);
+ mapping_data, fe_data, data);
}
for (unsigned int k=0; k<this->dofs_per_cell; ++k)
{
if (flags & update_values)
- for (unsigned int i=0; i<quadrature.size(); ++i)
- data.shape_values(k,i) = fe_data.shape_values[k][i];
+ for (unsigned int i=0; i<quadrature.size(); ++i)
+ data.shape_values(k,i) = fe_data.shape_values[k][i];
if (flags & update_gradients && cell_similarity != CellSimilarity::translation)
- mapping.transform(fe_data.shape_gradients[k], data.shape_gradients[k],
- mapping_data, mapping_covariant);
+ mapping.transform(fe_data.shape_gradients[k], data.shape_gradients[k],
+ mapping_data, mapping_covariant);
}
if (flags & update_hessians && cell_similarity != CellSimilarity::translation)
this->compute_2nd (mapping, cell, QProjector<2>::DataSetDescriptor::cell(),
- mapping_data, fe_data, data);
+ mapping_data, fe_data, data);
}
// $Id$
// Version: $Name$
//
-// Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011 by the deal.II authors
+// Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
*/
void
get_face_sign_change (const Triangulation<1>::cell_iterator &,
- const unsigned int ,
- std::vector<double> &face_sign)
+ const unsigned int ,
+ std::vector<double> &face_sign)
{
- // nothing to do in 1d
+ // nothing to do in 1d
std::fill (face_sign.begin (), face_sign.end (), 1.0);
}
void
get_face_sign_change (const Triangulation<2>::cell_iterator &cell,
- const unsigned int dofs_per_face,
- std::vector<double> &face_sign)
+ const unsigned int dofs_per_face,
+ std::vector<double> &face_sign)
{
const unsigned int dim = 2;
const unsigned int spacedim = 2;
- // Default is no sign
- // change. I.e. multiply by one.
+ // Default is no sign
+ // change. I.e. multiply by one.
std::fill (face_sign.begin (), face_sign.end (), 1.0);
for (unsigned int f = GeometryInfo<dim>::faces_per_cell / 2;
- f < GeometryInfo<dim>::faces_per_cell; ++f)
+ f < GeometryInfo<dim>::faces_per_cell; ++f)
{
- Triangulation<dim,spacedim>::face_iterator face = cell->face (f);
- if (!face->at_boundary ())
- {
- const unsigned int nn = cell->neighbor_face_no(f);
+ Triangulation<dim,spacedim>::face_iterator face = cell->face (f);
+ if (!face->at_boundary ())
+ {
+ const unsigned int nn = cell->neighbor_face_no(f);
- if (nn < GeometryInfo<dim>::faces_per_cell / 2)
- for (unsigned int j = 0; j < dofs_per_face; ++j)
- {
- Assert (f * dofs_per_face + j < face_sign.size(),
- ExcInternalError());
+ if (nn < GeometryInfo<dim>::faces_per_cell / 2)
+ for (unsigned int j = 0; j < dofs_per_face; ++j)
+ {
+ Assert (f * dofs_per_face + j < face_sign.size(),
+ ExcInternalError());
//TODO: This is probably only going to work for those elements for which all dofs are face dofs
- face_sign[f * dofs_per_face + j] = -1.0;
- }
- }
+ face_sign[f * dofs_per_face + j] = -1.0;
+ }
+ }
}
}
void
get_face_sign_change (const Triangulation<3>::cell_iterator &/*cell*/,
- const unsigned int /*dofs_per_face*/,
- std::vector<double> &face_sign)
+ const unsigned int /*dofs_per_face*/,
+ std::vector<double> &face_sign)
{
std::fill (face_sign.begin (), face_sign.end (), 1.0);
//TODO: think about what it would take here
template <class POLY, int dim, int spacedim>
FE_PolyTensor<POLY,dim,spacedim>::FE_PolyTensor (const unsigned int degree,
- const FiniteElementData<dim> &fe_data,
- const std::vector<bool> &restriction_is_additive_flags,
- const std::vector<std::vector<bool> > &nonzero_components)
- :
- FiniteElement<dim,spacedim> (fe_data,
- restriction_is_additive_flags,
- nonzero_components),
+ const FiniteElementData<dim> &fe_data,
+ const std::vector<bool> &restriction_is_additive_flags,
+ const std::vector<std::vector<bool> > &nonzero_components)
+ :
+ FiniteElement<dim,spacedim> (fe_data,
+ restriction_is_additive_flags,
+ nonzero_components),
poly_space(POLY(degree))
{
cached_point(0) = -1;
- // Set up the table converting
- // components to base
- // components. Since we have only
- // one base element, everything
- // remains zero except the
- // component in the base, which is
- // the component itself
+ // Set up the table converting
+ // components to base
+ // components. Since we have only
+ // one base element, everything
+ // remains zero except the
+ // component in the base, which is
+ // the component itself
for (unsigned int comp=0;comp<this->n_components() ;++comp)
this->component_to_base_table[comp].first.second = comp;
}
template <class POLY, int dim, int spacedim>
double
FE_PolyTensor<POLY,dim,spacedim>::shape_value_component (const unsigned int i,
- const Point<dim> &p,
- const unsigned int component) const
+ const Point<dim> &p,
+ const unsigned int component) const
{
Assert (i<this->dofs_per_cell, ExcIndexRange(i,0,this->dofs_per_cell));
Assert (component < dim, ExcIndexRange (component, 0, dim));
template <class POLY, int dim, int spacedim>
Tensor<1,dim>
FE_PolyTensor<POLY,dim,spacedim>::shape_grad (const unsigned int,
- const Point<dim> &) const
+ const Point<dim> &) const
{
typedef FiniteElement<dim,spacedim> FEE;
Assert(false, typename FEE::ExcFENotPrimitive());
template <class POLY, int dim, int spacedim>
Tensor<1,dim>
FE_PolyTensor<POLY,dim,spacedim>::shape_grad_component (const unsigned int i,
- const Point<dim> &p,
- const unsigned int component) const
+ const Point<dim> &p,
+ const unsigned int component) const
{
Assert (i<this->dofs_per_cell, ExcIndexRange(i,0,this->dofs_per_cell));
Assert (component < dim, ExcIndexRange (component, 0, dim));
template <class POLY, int dim, int spacedim>
Tensor<2,dim>
FE_PolyTensor<POLY,dim,spacedim>::shape_grad_grad_component (const unsigned int i,
- const Point<dim> &p,
- const unsigned int component) const
+ const Point<dim> &p,
+ const unsigned int component) const
{
Assert (i<this->dofs_per_cell, ExcIndexRange(i,0,this->dofs_per_cell));
Assert (component < dim, ExcIndexRange (component, 0, dim));
const Mapping<dim,spacedim> &mapping,
const Quadrature<dim> &quadrature) const
{
- // generate a new data object and
- // initialize some fields
+ // generate a new data object and
+ // initialize some fields
InternalData* data = new InternalData;
- // check what needs to be
- // initialized only once and what
- // on every cell/face/subface we
- // visit
+ // check what needs to be
+ // initialized only once and what
+ // on every cell/face/subface we
+ // visit
data->update_once = update_once(update_flags);
data->update_each = update_each(update_flags);
data->update_flags = data->update_once | data->update_each;
const UpdateFlags flags(data->update_flags);
const unsigned int n_q_points = quadrature.size();
- // some scratch arrays
+ // some scratch arrays
std::vector<Tensor<1,dim> > values(0);
std::vector<Tensor<2,dim> > grads(0);
std::vector<Tensor<3,dim> > grad_grads(0);
- // initialize fields only if really
- // necessary. otherwise, don't
- // allocate memory
+ // initialize fields only if really
+ // necessary. otherwise, don't
+ // allocate memory
if (flags & update_values)
{
values.resize (this->dofs_per_cell);
data->shape_values.resize (this->dofs_per_cell);
for (unsigned int i=0;i<this->dofs_per_cell;++i)
- data->shape_values[i].resize (n_q_points);
+ data->shape_values[i].resize (n_q_points);
}
if (flags & update_gradients)
grads.resize (this->dofs_per_cell);
data->shape_grads.resize (this->dofs_per_cell);
for (unsigned int i=0;i<this->dofs_per_cell;++i)
- data->shape_grads[i].resize (n_q_points);
+ data->shape_grads[i].resize (n_q_points);
}
- // if second derivatives through
- // finite differencing is required,
- // then initialize some objects for
- // that
+ // if second derivatives through
+ // finite differencing is required,
+ // then initialize some objects for
+ // that
if (flags & update_hessians)
{
// grad_grads.resize (this->dofs_per_cell);
data->initialize_2nd (this, mapping, quadrature);
}
- // Compute shape function values
- // and derivatives on the reference
- // cell. Make sure, that for the
- // node values N_i holds
- // N_i(v_j)=\delta_ij for all basis
- // functions v_j
+ // Compute shape function values
+ // and derivatives on the reference
+ // cell. Make sure, that for the
+ // node values N_i holds
+ // N_i(v_j)=\delta_ij for all basis
+ // functions v_j
if (flags & (update_values | update_gradients))
for (unsigned int k=0; k<n_q_points; ++k)
{
- poly_space.compute(quadrature.point(k),
- values, grads, grad_grads);
-
- if (flags & update_values)
- {
- if (inverse_node_matrix.n_cols() == 0)
- for (unsigned int i=0; i<this->dofs_per_cell; ++i)
- data->shape_values[i][k] = values[i];
- else
- for (unsigned int i=0; i<this->dofs_per_cell; ++i)
- {
- Tensor<1,dim> add_values;
- for (unsigned int j=0; j<this->dofs_per_cell; ++j)
- add_values += inverse_node_matrix(j,i) * values[j];
- data->shape_values[i][k] = add_values;
- }
- }
-
- if (flags & update_gradients)
- {
- if (inverse_node_matrix.n_cols() == 0)
- for (unsigned int i=0; i<this->dofs_per_cell; ++i)
- data->shape_grads[i][k] = grads[i];
- else
- for (unsigned int i=0; i<this->dofs_per_cell; ++i)
- {
- Tensor<2,dim> add_grads;
- for (unsigned int j=0; j<this->dofs_per_cell; ++j)
- add_grads += inverse_node_matrix(j,i) * grads[j];
- data->shape_grads[i][k] = add_grads;
- }
- }
+ poly_space.compute(quadrature.point(k),
+ values, grads, grad_grads);
+
+ if (flags & update_values)
+ {
+ if (inverse_node_matrix.n_cols() == 0)
+ for (unsigned int i=0; i<this->dofs_per_cell; ++i)
+ data->shape_values[i][k] = values[i];
+ else
+ for (unsigned int i=0; i<this->dofs_per_cell; ++i)
+ {
+ Tensor<1,dim> add_values;
+ for (unsigned int j=0; j<this->dofs_per_cell; ++j)
+ add_values += inverse_node_matrix(j,i) * values[j];
+ data->shape_values[i][k] = add_values;
+ }
+ }
+
+ if (flags & update_gradients)
+ {
+ if (inverse_node_matrix.n_cols() == 0)
+ for (unsigned int i=0; i<this->dofs_per_cell; ++i)
+ data->shape_grads[i][k] = grads[i];
+ else
+ for (unsigned int i=0; i<this->dofs_per_cell; ++i)
+ {
+ Tensor<2,dim> add_grads;
+ for (unsigned int j=0; j<this->dofs_per_cell; ++j)
+ add_grads += inverse_node_matrix(j,i) * grads[j];
+ data->shape_grads[i][k] = add_grads;
+ }
+ }
}
return data;
FEValuesData<dim,spacedim> &data,
CellSimilarity::Similarity &cell_similarity) const
{
- // convert data object to internal
- // data for this class. fails with
- // an exception if that is not
- // possible
+ // convert data object to internal
+ // data for this class. fails with
+ // an exception if that is not
+ // possible
Assert (dynamic_cast<InternalData *> (&fedata) != 0,
- ExcInternalError());
+ ExcInternalError());
InternalData &fe_data = static_cast<InternalData &> (fedata);
const unsigned int n_q_points = quadrature.size();
const UpdateFlags flags(fe_data.current_update_flags());
Assert(!(flags & update_values) || fe_data.shape_values.size() == this->dofs_per_cell,
- ExcDimensionMismatch(fe_data.shape_values.size(), this->dofs_per_cell));
+ ExcDimensionMismatch(fe_data.shape_values.size(), this->dofs_per_cell));
Assert(!(flags & update_values) || fe_data.shape_values[0].size() == n_q_points,
- ExcDimensionMismatch(fe_data.shape_values[0].size(), n_q_points));
+ ExcDimensionMismatch(fe_data.shape_values[0].size(), n_q_points));
// Create table with sign changes, due to the special structure of the RT elements.
// TODO: Preliminary hack to demonstrate the overall prinicple!
std::vector<double> sign_change (this->dofs_per_cell, 1.0);
get_face_sign_change (cell, this->dofs_per_face, sign_change);
- // for Piola mapping, the similarity
- // concept cannot be used because of
- // possible sign changes from one cell to
- // the next.
+ // for Piola mapping, the similarity
+ // concept cannot be used because of
+ // possible sign changes from one cell to
+ // the next.
if ( (mapping_type == mapping_piola) || (mapping_type == mapping_raviart_thomas) )
if (cell_similarity == CellSimilarity::translation)
cell_similarity = CellSimilarity::none;
const unsigned int first = data.shape_function_to_row_table[i];
if (flags & update_values && cell_similarity != CellSimilarity::translation)
- switch (mapping_type)
- {
- case mapping_none:
- {
- for (unsigned int k=0; k<n_q_points; ++k)
- for (unsigned int d=0; d<dim; ++d)
- data.shape_values(first+d,k) = fe_data.shape_values[i][k][d];
- break;
- }
-
- case mapping_covariant:
- case mapping_contravariant:
- {
- std::vector<Tensor<1,dim> > shape_values (n_q_points);
- mapping.transform(fe_data.shape_values[i],
- shape_values, mapping_data, mapping_type);
-
- for (unsigned int k=0; k<n_q_points; ++k)
- for (unsigned int d=0; d<dim; ++d)
- data.shape_values(first+d,k) = shape_values[k][d];
-
- break;
- }
-
- case mapping_raviart_thomas:
- case mapping_piola:
- {
- std::vector<Tensor<1,dim> > shape_values (n_q_points);
- mapping.transform(fe_data.shape_values[i], shape_values,
- mapping_data, mapping_piola);
- for (unsigned int k=0; k<n_q_points; ++k)
- for (unsigned int d=0; d<dim; ++d)
- data.shape_values(first+d,k)
- = sign_change[i] * shape_values[k][d];
- break;
- }
-
- case mapping_nedelec:
- {
- std::vector<Tensor<1,dim> > shape_values (n_q_points);
- mapping.transform (fe_data.shape_values[i], shape_values,
- mapping_data, mapping_covariant);
-
- for (unsigned int k = 0; k < n_q_points; ++k)
- for (unsigned int d = 0; d < dim; ++d)
- data.shape_values(first+d,k) = shape_values[k][d];
-
- break;
- }
-
- default:
- Assert(false, ExcNotImplemented());
- }
+ switch (mapping_type)
+ {
+ case mapping_none:
+ {
+ for (unsigned int k=0; k<n_q_points; ++k)
+ for (unsigned int d=0; d<dim; ++d)
+ data.shape_values(first+d,k) = fe_data.shape_values[i][k][d];
+ break;
+ }
+
+ case mapping_covariant:
+ case mapping_contravariant:
+ {
+ std::vector<Tensor<1,dim> > shape_values (n_q_points);
+ mapping.transform(fe_data.shape_values[i],
+ shape_values, mapping_data, mapping_type);
+
+ for (unsigned int k=0; k<n_q_points; ++k)
+ for (unsigned int d=0; d<dim; ++d)
+ data.shape_values(first+d,k) = shape_values[k][d];
+
+ break;
+ }
+
+ case mapping_raviart_thomas:
+ case mapping_piola:
+ {
+ std::vector<Tensor<1,dim> > shape_values (n_q_points);
+ mapping.transform(fe_data.shape_values[i], shape_values,
+ mapping_data, mapping_piola);
+ for (unsigned int k=0; k<n_q_points; ++k)
+ for (unsigned int d=0; d<dim; ++d)
+ data.shape_values(first+d,k)
+ = sign_change[i] * shape_values[k][d];
+ break;
+ }
+
+ case mapping_nedelec:
+ {
+ std::vector<Tensor<1,dim> > shape_values (n_q_points);
+ mapping.transform (fe_data.shape_values[i], shape_values,
+ mapping_data, mapping_covariant);
+
+ for (unsigned int k = 0; k < n_q_points; ++k)
+ for (unsigned int d = 0; d < dim; ++d)
+ data.shape_values(first+d,k) = shape_values[k][d];
+
+ break;
+ }
+
+ default:
+ Assert(false, ExcNotImplemented());
+ }
if (flags & update_gradients && cell_similarity != CellSimilarity::translation)
- {
- std::vector<Tensor<2, spacedim > > shape_grads1 (n_q_points);
- //std::vector<DerivativeForm<1,dim,spacedim> > shape_grads2 (n_q_points);
-
- switch (mapping_type)
- {
- case mapping_none:
- {
- mapping.transform(fe_data.shape_grads[i], shape_grads1,
- mapping_data, mapping_covariant);
- for (unsigned int k=0; k<n_q_points; ++k)
- for (unsigned int d=0; d<dim; ++d)
- data.shape_gradients[first+d][k] = shape_grads1[k][d];
- break;
- }
- case mapping_covariant:
- {
- mapping.transform(fe_data.shape_grads[i], shape_grads1,
- mapping_data, mapping_covariant_gradient);
-
- for (unsigned int k=0; k<n_q_points; ++k)
- for (unsigned int d=0; d<dim; ++d)
- data.shape_gradients[first+d][k] = shape_grads1[k][d];
-
- break;
- }
- case mapping_contravariant:
- {
- mapping.transform(fe_data.shape_grads[i], shape_grads1,
- mapping_data, mapping_contravariant_gradient);
-
- for (unsigned int k=0; k<n_q_points; ++k)
- for (unsigned int d=0; d<dim; ++d)
- data.shape_gradients[first+d][k] = shape_grads1[k][d];
-
- break;
- }
- case mapping_raviart_thomas:
- case mapping_piola_gradient:
- {
-
-
- std::vector <Tensor<2,spacedim> > input(fe_data.shape_grads[i].size());
- for (unsigned int k=0; k<input.size(); ++k)
- input[k] = fe_data.shape_grads[i][k];
-
- mapping.transform(input, shape_grads1,
- mapping_data, mapping_piola_gradient);
-
- for (unsigned int k=0; k<n_q_points; ++k)
- for (unsigned int d=0; d<dim; ++d)
- data.shape_gradients[first+d][k] = sign_change[i] * shape_grads1[k][d];
-
- break;
- }
-
- case mapping_nedelec: {
+ {
+ std::vector<Tensor<2, spacedim > > shape_grads1 (n_q_points);
+ //std::vector<DerivativeForm<1,dim,spacedim> > shape_grads2 (n_q_points);
+
+ switch (mapping_type)
+ {
+ case mapping_none:
+ {
+ mapping.transform(fe_data.shape_grads[i], shape_grads1,
+ mapping_data, mapping_covariant);
+ for (unsigned int k=0; k<n_q_points; ++k)
+ for (unsigned int d=0; d<dim; ++d)
+ data.shape_gradients[first+d][k] = shape_grads1[k][d];
+ break;
+ }
+ case mapping_covariant:
+ {
+ mapping.transform(fe_data.shape_grads[i], shape_grads1,
+ mapping_data, mapping_covariant_gradient);
+
+ for (unsigned int k=0; k<n_q_points; ++k)
+ for (unsigned int d=0; d<dim; ++d)
+ data.shape_gradients[first+d][k] = shape_grads1[k][d];
+
+ break;
+ }
+ case mapping_contravariant:
+ {
+ mapping.transform(fe_data.shape_grads[i], shape_grads1,
+ mapping_data, mapping_contravariant_gradient);
+
+ for (unsigned int k=0; k<n_q_points; ++k)
+ for (unsigned int d=0; d<dim; ++d)
+ data.shape_gradients[first+d][k] = shape_grads1[k][d];
+
+ break;
+ }
+ case mapping_raviart_thomas:
+ case mapping_piola_gradient:
+ {
+
+
+ std::vector <Tensor<2,spacedim> > input(fe_data.shape_grads[i].size());
+ for (unsigned int k=0; k<input.size(); ++k)
+ input[k] = fe_data.shape_grads[i][k];
+
+ mapping.transform(input, shape_grads1,
+ mapping_data, mapping_piola_gradient);
+
+ for (unsigned int k=0; k<n_q_points; ++k)
+ for (unsigned int d=0; d<dim; ++d)
+ data.shape_gradients[first+d][k] = sign_change[i] * shape_grads1[k][d];
+
+ break;
+ }
+
+ case mapping_nedelec: {
// treat the gradients of
// this particular shape
// function at all
// (J^-T)Dv(J^-1) is the
// value we want to have on
// the real cell.
- std::vector <Tensor<2,spacedim> > input(fe_data.shape_grads[i].size());
- for (unsigned int k=0; k<input.size(); ++k)
- input[k] = fe_data.shape_grads[i][k];
- mapping.transform (input,shape_grads1,
- mapping_data, mapping_covariant_gradient);
-
- for (unsigned int k = 0; k < n_q_points; ++k)
- for (unsigned int d = 0; d < dim; ++d)
- data.shape_gradients[first + d][k] = shape_grads1[k][d];
- // then copy over to target:
-
- break;
- }
-
- default:
- Assert(false, ExcNotImplemented());
- }
- }
+ std::vector <Tensor<2,spacedim> > input(fe_data.shape_grads[i].size());
+ for (unsigned int k=0; k<input.size(); ++k)
+ input[k] = fe_data.shape_grads[i][k];
+ mapping.transform (input,shape_grads1,
+ mapping_data, mapping_covariant_gradient);
+
+ for (unsigned int k = 0; k < n_q_points; ++k)
+ for (unsigned int d = 0; d < dim; ++d)
+ data.shape_gradients[first + d][k] = shape_grads1[k][d];
+ // then copy over to target:
+
+ break;
+ }
+
+ default:
+ Assert(false, ExcNotImplemented());
+ }
+ }
}
if (flags & update_hessians && cell_similarity != CellSimilarity::translation)
this->compute_2nd (mapping, cell,
- typename QProjector<dim>::DataSetDescriptor().cell(),
- mapping_data, fe_data, data);
+ typename QProjector<dim>::DataSetDescriptor().cell(),
+ mapping_data, fe_data, data);
}
typename Mapping<dim,spacedim>::InternalDataBase &fedata,
FEValuesData<dim,spacedim> &data) const
{
- // convert data object to internal
- // data for this class. fails with
- // an exception if that is not
- // possible
+ // convert data object to internal
+ // data for this class. fails with
+ // an exception if that is not
+ // possible
Assert (dynamic_cast<InternalData *> (&fedata) != 0,
- ExcInternalError());
+ ExcInternalError());
InternalData &fe_data = static_cast<InternalData &> (fedata);
const unsigned int n_q_points = quadrature.size();
- // offset determines which data set
- // to take (all data sets for all
- // faces are stored contiguously)
+ // offset determines which data set
+ // to take (all data sets for all
+ // faces are stored contiguously)
const typename QProjector<dim>::DataSetDescriptor offset
= QProjector<dim>::DataSetDescriptor::face (face,
- cell->face_orientation(face),
- cell->face_flip(face),
- cell->face_rotation(face),
- n_q_points);
+ cell->face_orientation(face),
+ cell->face_flip(face),
+ cell->face_rotation(face),
+ n_q_points);
const UpdateFlags flags(fe_data.update_once | fe_data.update_each);
// Create table with sign changes, due to the special structure of the RT elements.
// TODO: Preliminary hack to demonstrate the overall prinicple!
- // Compute eventual sign changes depending
- // on the neighborhood between two faces.
+ // Compute eventual sign changes depending
+ // on the neighborhood between two faces.
std::vector<double> sign_change (this->dofs_per_cell, 1.0);
get_face_sign_change (cell, this->dofs_per_face, sign_change);
const unsigned int first = data.shape_function_to_row_table[i];
if (flags & update_values)
- {
- switch (mapping_type)
- {
- case mapping_none:
- {
- for (unsigned int k=0; k<n_q_points; ++k)
- for (unsigned int d=0; d<dim; ++d)
- data.shape_values(first+d,k) = fe_data.shape_values[i][k+offset][d];
- break;
- }
-
- case mapping_covariant:
- case mapping_contravariant:
- {
- // Use auxiliary vector
- // for transformation
- std::vector<Tensor<1,dim> > shape_values (n_q_points);
- mapping.transform(make_slice(fe_data.shape_values[i], offset, n_q_points),
- shape_values, mapping_data, mapping_type);
-
- for (unsigned int k=0; k<n_q_points; ++k)
- for (unsigned int d=0; d<dim; ++d)
- data.shape_values(first+d,k) = shape_values[k][d];
-
- break;
- }
- case mapping_raviart_thomas:
- case mapping_piola:
- {
- std::vector<Tensor<1,dim> > shape_values (n_q_points);
- mapping.transform(make_slice(fe_data.shape_values[i], offset, n_q_points),
- shape_values, mapping_data, mapping_piola);
- for (unsigned int k=0; k<n_q_points; ++k)
- for (unsigned int d=0; d<dim; ++d)
- data.shape_values(first+d,k)
- = sign_change[i] * shape_values[k][d];
- break;
- }
-
- case mapping_nedelec: {
- std::vector<Tensor<1,dim> > shape_values (n_q_points);
- mapping.transform (make_slice (fe_data.shape_values[i], offset, n_q_points),
- shape_values, mapping_data, mapping_covariant);
-
- for (unsigned int k = 0; k < n_q_points; ++k)
- for (unsigned int d = 0; d < dim; ++d)
- data.shape_values(first+d,k) = shape_values[k][d];
-
- break;
- }
-
- default:
- Assert(false, ExcNotImplemented());
- }
- }
+ {
+ switch (mapping_type)
+ {
+ case mapping_none:
+ {
+ for (unsigned int k=0; k<n_q_points; ++k)
+ for (unsigned int d=0; d<dim; ++d)
+ data.shape_values(first+d,k) = fe_data.shape_values[i][k+offset][d];
+ break;
+ }
+
+ case mapping_covariant:
+ case mapping_contravariant:
+ {
+ // Use auxiliary vector
+ // for transformation
+ std::vector<Tensor<1,dim> > shape_values (n_q_points);
+ mapping.transform(make_slice(fe_data.shape_values[i], offset, n_q_points),
+ shape_values, mapping_data, mapping_type);
+
+ for (unsigned int k=0; k<n_q_points; ++k)
+ for (unsigned int d=0; d<dim; ++d)
+ data.shape_values(first+d,k) = shape_values[k][d];
+
+ break;
+ }
+ case mapping_raviart_thomas:
+ case mapping_piola:
+ {
+ std::vector<Tensor<1,dim> > shape_values (n_q_points);
+ mapping.transform(make_slice(fe_data.shape_values[i], offset, n_q_points),
+ shape_values, mapping_data, mapping_piola);
+ for (unsigned int k=0; k<n_q_points; ++k)
+ for (unsigned int d=0; d<dim; ++d)
+ data.shape_values(first+d,k)
+ = sign_change[i] * shape_values[k][d];
+ break;
+ }
+
+ case mapping_nedelec: {
+ std::vector<Tensor<1,dim> > shape_values (n_q_points);
+ mapping.transform (make_slice (fe_data.shape_values[i], offset, n_q_points),
+ shape_values, mapping_data, mapping_covariant);
+
+ for (unsigned int k = 0; k < n_q_points; ++k)
+ for (unsigned int d = 0; d < dim; ++d)
+ data.shape_values(first+d,k) = shape_values[k][d];
+
+ break;
+ }
+
+ default:
+ Assert(false, ExcNotImplemented());
+ }
+ }
if (flags & update_gradients)
- {
- std::vector<Tensor<2,dim> > shape_grads1 (n_q_points);
- // std::vector<DerivativeForm<1,dim,spacedim> > shape_grads2 (n_q_points);
-
-
- switch (mapping_type)
- {
- case mapping_none:
- {
- mapping.transform(make_slice(fe_data.shape_grads[i], offset, n_q_points),
- shape_grads1, mapping_data, mapping_covariant);
- for (unsigned int k=0; k<n_q_points; ++k)
- for (unsigned int d=0; d<dim; ++d)
- data.shape_gradients[first+d][k] = shape_grads1[k][d];
- break;
- }
-
- case mapping_covariant:
- {
- mapping.transform(make_slice(fe_data.shape_grads[i], offset, n_q_points),
- shape_grads1, mapping_data, mapping_covariant_gradient);
-
- for (unsigned int k=0; k<n_q_points; ++k)
- for (unsigned int d=0; d<dim; ++d)
- data.shape_gradients[first+d][k] = shape_grads1[k][d];
- break;
- }
- case mapping_contravariant:
- {
- mapping.transform(make_slice(fe_data.shape_grads[i], offset, n_q_points),
- shape_grads1, mapping_data, mapping_contravariant_gradient);
-
- for (unsigned int k=0; k<n_q_points; ++k)
- for (unsigned int d=0; d<dim; ++d)
- data.shape_gradients[first+d][k] = shape_grads1[k][d];
-
- break;
- }
- case mapping_raviart_thomas:
- case mapping_piola_gradient:
- {
- std::vector <Tensor<2,spacedim> > input(fe_data.shape_grads[i].size());
- for (unsigned int k=0; k<input.size(); ++k)
- input[k] = fe_data.shape_grads[i][k];
-
- mapping.transform(make_slice(input, offset, n_q_points), shape_grads1,
- mapping_data, mapping_piola_gradient);
-
- for (unsigned int k=0; k<n_q_points; ++k)
- for (unsigned int d=0; d<dim; ++d)
- data.shape_gradients[first+d][k] = sign_change[i] * shape_grads1[k][d];
-
- break;
- }
-
- case mapping_nedelec:
- {
- // treat the gradients of
- // this particular shape
- // function at all
- // q-points. if Dv is the
- // gradient of the shape
- // function on the unit
- // cell, then
- // (J^-T)Dv(J^-1) is the
- // value we want to have on
- // the real cell.
- std::vector <Tensor<2,spacedim> > input(fe_data.shape_grads[i].size());
- for (unsigned int k=0; k<input.size(); ++k)
- input[k] = fe_data.shape_grads[i][k];
- mapping.transform (make_slice (input, offset, n_q_points),
- shape_grads1, mapping_data, mapping_covariant_gradient);
-
- for (unsigned int k = 0; k < n_q_points; ++k)
- for (unsigned int d = 0; d < dim; ++d)
- data.shape_gradients[first + d][k] = shape_grads1[k][d];
- // then copy over to target:
- break;
- }
-
- default:
- Assert(false, ExcNotImplemented());
- }
- }
+ {
+ std::vector<Tensor<2,dim> > shape_grads1 (n_q_points);
+ // std::vector<DerivativeForm<1,dim,spacedim> > shape_grads2 (n_q_points);
+
+
+ switch (mapping_type)
+ {
+ case mapping_none:
+ {
+ mapping.transform(make_slice(fe_data.shape_grads[i], offset, n_q_points),
+ shape_grads1, mapping_data, mapping_covariant);
+ for (unsigned int k=0; k<n_q_points; ++k)
+ for (unsigned int d=0; d<dim; ++d)
+ data.shape_gradients[first+d][k] = shape_grads1[k][d];
+ break;
+ }
+
+ case mapping_covariant:
+ {
+ mapping.transform(make_slice(fe_data.shape_grads[i], offset, n_q_points),
+ shape_grads1, mapping_data, mapping_covariant_gradient);
+
+ for (unsigned int k=0; k<n_q_points; ++k)
+ for (unsigned int d=0; d<dim; ++d)
+ data.shape_gradients[first+d][k] = shape_grads1[k][d];
+ break;
+ }
+ case mapping_contravariant:
+ {
+ mapping.transform(make_slice(fe_data.shape_grads[i], offset, n_q_points),
+ shape_grads1, mapping_data, mapping_contravariant_gradient);
+
+ for (unsigned int k=0; k<n_q_points; ++k)
+ for (unsigned int d=0; d<dim; ++d)
+ data.shape_gradients[first+d][k] = shape_grads1[k][d];
+
+ break;
+ }
+ case mapping_raviart_thomas:
+ case mapping_piola_gradient:
+ {
+ std::vector <Tensor<2,spacedim> > input(fe_data.shape_grads[i].size());
+ for (unsigned int k=0; k<input.size(); ++k)
+ input[k] = fe_data.shape_grads[i][k];
+
+ mapping.transform(make_slice(input, offset, n_q_points), shape_grads1,
+ mapping_data, mapping_piola_gradient);
+
+ for (unsigned int k=0; k<n_q_points; ++k)
+ for (unsigned int d=0; d<dim; ++d)
+ data.shape_gradients[first+d][k] = sign_change[i] * shape_grads1[k][d];
+
+ break;
+ }
+
+ case mapping_nedelec:
+ {
+ // treat the gradients of
+ // this particular shape
+ // function at all
+ // q-points. if Dv is the
+ // gradient of the shape
+ // function on the unit
+ // cell, then
+ // (J^-T)Dv(J^-1) is the
+ // value we want to have on
+ // the real cell.
+ std::vector <Tensor<2,spacedim> > input(fe_data.shape_grads[i].size());
+ for (unsigned int k=0; k<input.size(); ++k)
+ input[k] = fe_data.shape_grads[i][k];
+ mapping.transform (make_slice (input, offset, n_q_points),
+ shape_grads1, mapping_data, mapping_covariant_gradient);
+
+ for (unsigned int k = 0; k < n_q_points; ++k)
+ for (unsigned int d = 0; d < dim; ++d)
+ data.shape_gradients[first + d][k] = shape_grads1[k][d];
+ // then copy over to target:
+ break;
+ }
+
+ default:
+ Assert(false, ExcNotImplemented());
+ }
+ }
}
if (flags & update_hessians)
typename Mapping<dim,spacedim>::InternalDataBase &fedata,
FEValuesData<dim,spacedim> &data) const
{
- // convert data object to internal
- // data for this class. fails with
- // an exception if that is not
- // possible
+ // convert data object to internal
+ // data for this class. fails with
+ // an exception if that is not
+ // possible
Assert (dynamic_cast<InternalData *> (&fedata) != 0,
- ExcInternalError());
+ ExcInternalError());
InternalData &fe_data = static_cast<InternalData &> (fedata);
const unsigned int n_q_points = quadrature.size();
- // offset determines which data set
- // to take (all data sets for all
- // sub-faces are stored contiguously)
+ // offset determines which data set
+ // to take (all data sets for all
+ // sub-faces are stored contiguously)
const typename QProjector<dim>::DataSetDescriptor offset
= QProjector<dim>::DataSetDescriptor::subface (face, subface,
- cell->face_orientation(face),
- cell->face_flip(face),
- cell->face_rotation(face),
- n_q_points,
- cell->subface_case(face));
+ cell->face_orientation(face),
+ cell->face_flip(face),
+ cell->face_rotation(face),
+ n_q_points,
+ cell->subface_case(face));
const UpdateFlags flags(fe_data.update_once | fe_data.update_each);
// Assert(mapping_type == independent
-// || ( mapping_type == independent_on_cartesian
-// && dynamic_cast<const MappingCartesian<dim>*>(&mapping) != 0),
-// ExcNotImplemented());
+// || ( mapping_type == independent_on_cartesian
+// && dynamic_cast<const MappingCartesian<dim>*>(&mapping) != 0),
+// ExcNotImplemented());
//TODO: Size assertions
//TODO: Sign change for the face DoFs!
- // Compute eventual sign changes depending
- // on the neighborhood between two faces.
+ // Compute eventual sign changes depending
+ // on the neighborhood between two faces.
std::vector<double> sign_change (this->dofs_per_cell, 1.0);
get_face_sign_change (cell, this->dofs_per_face, sign_change);
const unsigned int first = data.shape_function_to_row_table[i];
if (flags & update_values)
- {
- switch (mapping_type)
- {
- case mapping_none:
- {
- for (unsigned int k=0; k<n_q_points; ++k)
- for (unsigned int d=0; d<dim; ++d)
- data.shape_values(first+d,k) = fe_data.shape_values[i][k+offset][d];
- break;
- }
-
- case mapping_covariant:
- case mapping_contravariant:
- {
- // Use auxiliary vector for
- // transformation
- std::vector<Tensor<1,dim> > shape_values (n_q_points);
- mapping.transform(make_slice(fe_data.shape_values[i], offset, n_q_points),
- shape_values, mapping_data, mapping_type);
-
- for (unsigned int k=0; k<n_q_points; ++k)
- for (unsigned int d=0; d<dim; ++d)
- data.shape_values(first+d,k) = shape_values[k][d];
-
- break;
- }
- case mapping_raviart_thomas:
- case mapping_piola:
- {
- std::vector<Tensor<1,dim> > shape_values (n_q_points);
- mapping.transform(make_slice(fe_data.shape_values[i], offset, n_q_points),
- shape_values, mapping_data, mapping_piola);
- for (unsigned int k=0; k<n_q_points; ++k)
- for (unsigned int d=0; d<dim; ++d)
- data.shape_values(first+d,k)
- = sign_change[i] * shape_values[k][d];
- break;
- }
- case mapping_nedelec: {
- std::vector<Tensor<1,dim> > shape_values (n_q_points);
- mapping.transform (make_slice (fe_data.shape_values[i], offset, n_q_points),
- shape_values, mapping_data, mapping_covariant);
-
- for (unsigned int k = 0; k < n_q_points; ++k)
- for (unsigned int d = 0; d < dim; ++d)
- data.shape_values(first+d,k) = shape_values[k][d];
-
- break;
- }
- default:
- Assert(false, ExcNotImplemented());
- }
- }
+ {
+ switch (mapping_type)
+ {
+ case mapping_none:
+ {
+ for (unsigned int k=0; k<n_q_points; ++k)
+ for (unsigned int d=0; d<dim; ++d)
+ data.shape_values(first+d,k) = fe_data.shape_values[i][k+offset][d];
+ break;
+ }
+
+ case mapping_covariant:
+ case mapping_contravariant:
+ {
+ // Use auxiliary vector for
+ // transformation
+ std::vector<Tensor<1,dim> > shape_values (n_q_points);
+ mapping.transform(make_slice(fe_data.shape_values[i], offset, n_q_points),
+ shape_values, mapping_data, mapping_type);
+
+ for (unsigned int k=0; k<n_q_points; ++k)
+ for (unsigned int d=0; d<dim; ++d)
+ data.shape_values(first+d,k) = shape_values[k][d];
+
+ break;
+ }
+ case mapping_raviart_thomas:
+ case mapping_piola:
+ {
+ std::vector<Tensor<1,dim> > shape_values (n_q_points);
+ mapping.transform(make_slice(fe_data.shape_values[i], offset, n_q_points),
+ shape_values, mapping_data, mapping_piola);
+ for (unsigned int k=0; k<n_q_points; ++k)
+ for (unsigned int d=0; d<dim; ++d)
+ data.shape_values(first+d,k)
+ = sign_change[i] * shape_values[k][d];
+ break;
+ }
+ case mapping_nedelec: {
+ std::vector<Tensor<1,dim> > shape_values (n_q_points);
+ mapping.transform (make_slice (fe_data.shape_values[i], offset, n_q_points),
+ shape_values, mapping_data, mapping_covariant);
+
+ for (unsigned int k = 0; k < n_q_points; ++k)
+ for (unsigned int d = 0; d < dim; ++d)
+ data.shape_values(first+d,k) = shape_values[k][d];
+
+ break;
+ }
+ default:
+ Assert(false, ExcNotImplemented());
+ }
+ }
if (flags & update_gradients)
- {
- std::vector<Tensor<2,dim> > shape_grads1 (n_q_points);
- std::vector<Tensor<2,dim> > shape_grads2 (n_q_points);
-
- switch (mapping_type)
- {
- case mapping_none:
- {
- mapping.transform(make_slice(fe_data.shape_grads[i], offset, n_q_points),
- shape_grads1, mapping_data, mapping_covariant);
- for (unsigned int k=0; k<n_q_points; ++k)
- for (unsigned int d=0; d<dim; ++d)
- data.shape_gradients[first+d][k] = shape_grads1[k][d];
- break;
- }
-
- case mapping_covariant:
- {
- mapping.transform(make_slice(fe_data.shape_grads[i], offset, n_q_points),
- shape_grads1, mapping_data, mapping_covariant_gradient);
-
- for (unsigned int k=0; k<n_q_points; ++k)
- for (unsigned int d=0; d<dim; ++d)
- data.shape_gradients[first+d][k] = shape_grads1[k][d];
- break;
- }
-
- case mapping_contravariant:
- {
- mapping.transform(make_slice(fe_data.shape_grads[i], offset, n_q_points),
- shape_grads1, mapping_data, mapping_contravariant_gradient);
-
- for (unsigned int k=0; k<n_q_points; ++k)
- for (unsigned int d=0; d<dim; ++d)
- data.shape_gradients[first+d][k] = shape_grads1[k][d];
-
- break;
- }
-
- case mapping_raviart_thomas:
- case mapping_piola_gradient:
- {
-
- std::vector <Tensor<2,spacedim> > input(fe_data.shape_grads[i].size());
- for (unsigned int k=0; k<input.size(); ++k)
- input[k] = fe_data.shape_grads[i][k];
-
- mapping.transform(make_slice(input, offset, n_q_points), shape_grads1,
- mapping_data, mapping_piola_gradient);
-
- for (unsigned int k=0; k<n_q_points; ++k)
- for (unsigned int d=0; d<dim; ++d)
- data.shape_gradients[first+d][k] = sign_change[i] * shape_grads1[k][d];
-
- break;
- }
-
- case mapping_nedelec:
- {
- // this particular shape
- // function at all
- // q-points. if Dv is the
- // gradient of the shape
- // function on the unit
- // cell, then
- // (J^-T)Dv(J^-1) is the
- // value we want to have on
- // the real cell.
- std::vector <Tensor<2,spacedim> > input(fe_data.shape_grads[i].size());
- for (unsigned int k=0; k<input.size(); ++k)
- input[k] = fe_data.shape_grads[i][k];
-
- mapping.transform (make_slice (input, offset, n_q_points),
- shape_grads1, mapping_data, mapping_covariant_gradient);
-
-
- for (unsigned int k = 0; k < n_q_points; ++k)
- for (unsigned int d = 0; d < dim; ++d)
- data.shape_gradients[first + d][k] = shape_grads1[k][d];
-
- break;
- }
-
- default:
- Assert(false, ExcNotImplemented());
- }
- }
+ {
+ std::vector<Tensor<2,dim> > shape_grads1 (n_q_points);
+ std::vector<Tensor<2,dim> > shape_grads2 (n_q_points);
+
+ switch (mapping_type)
+ {
+ case mapping_none:
+ {
+ mapping.transform(make_slice(fe_data.shape_grads[i], offset, n_q_points),
+ shape_grads1, mapping_data, mapping_covariant);
+ for (unsigned int k=0; k<n_q_points; ++k)
+ for (unsigned int d=0; d<dim; ++d)
+ data.shape_gradients[first+d][k] = shape_grads1[k][d];
+ break;
+ }
+
+ case mapping_covariant:
+ {
+ mapping.transform(make_slice(fe_data.shape_grads[i], offset, n_q_points),
+ shape_grads1, mapping_data, mapping_covariant_gradient);
+
+ for (unsigned int k=0; k<n_q_points; ++k)
+ for (unsigned int d=0; d<dim; ++d)
+ data.shape_gradients[first+d][k] = shape_grads1[k][d];
+ break;
+ }
+
+ case mapping_contravariant:
+ {
+ mapping.transform(make_slice(fe_data.shape_grads[i], offset, n_q_points),
+ shape_grads1, mapping_data, mapping_contravariant_gradient);
+
+ for (unsigned int k=0; k<n_q_points; ++k)
+ for (unsigned int d=0; d<dim; ++d)
+ data.shape_gradients[first+d][k] = shape_grads1[k][d];
+
+ break;
+ }
+
+ case mapping_raviart_thomas:
+ case mapping_piola_gradient:
+ {
+
+ std::vector <Tensor<2,spacedim> > input(fe_data.shape_grads[i].size());
+ for (unsigned int k=0; k<input.size(); ++k)
+ input[k] = fe_data.shape_grads[i][k];
+
+ mapping.transform(make_slice(input, offset, n_q_points), shape_grads1,
+ mapping_data, mapping_piola_gradient);
+
+ for (unsigned int k=0; k<n_q_points; ++k)
+ for (unsigned int d=0; d<dim; ++d)
+ data.shape_gradients[first+d][k] = sign_change[i] * shape_grads1[k][d];
+
+ break;
+ }
+
+ case mapping_nedelec:
+ {
+ // this particular shape
+ // function at all
+ // q-points. if Dv is the
+ // gradient of the shape
+ // function on the unit
+ // cell, then
+ // (J^-T)Dv(J^-1) is the
+ // value we want to have on
+ // the real cell.
+ std::vector <Tensor<2,spacedim> > input(fe_data.shape_grads[i].size());
+ for (unsigned int k=0; k<input.size(); ++k)
+ input[k] = fe_data.shape_grads[i][k];
+
+ mapping.transform (make_slice (input, offset, n_q_points),
+ shape_grads1, mapping_data, mapping_covariant_gradient);
+
+
+ for (unsigned int k = 0; k < n_q_points; ++k)
+ for (unsigned int d = 0; d < dim; ++d)
+ data.shape_gradients[first + d][k] = shape_grads1[k][d];
+
+ break;
+ }
+
+ default:
+ Assert(false, ExcNotImplemented());
+ }
+ }
}
if (flags & update_hessians)
case mapping_raviart_thomas:
case mapping_piola:
{
- if (flags & update_values)
- out |= update_values | update_piola;
+ if (flags & update_values)
+ out |= update_values | update_piola;
- if (flags & update_gradients)
- out |= update_gradients | update_piola | update_covariant_transformation;
+ if (flags & update_gradients)
+ out |= update_gradients | update_piola | update_covariant_transformation;
- if (flags & update_hessians)
- out |= update_hessians | update_piola | update_covariant_transformation;
+ if (flags & update_hessians)
+ out |= update_hessians | update_piola | update_covariant_transformation;
- break;
+ break;
}
case mapping_piola_gradient:
{
- if (flags & update_values)
- out |= update_values | update_piola;
+ if (flags & update_values)
+ out |= update_values | update_piola;
- if (flags & update_gradients)
- out |= update_gradients | update_piola | update_covariant_transformation;
+ if (flags & update_gradients)
+ out |= update_gradients | update_piola | update_covariant_transformation;
- if (flags & update_hessians)
- out |= update_hessians | update_piola | update_covariant_transformation;
+ if (flags & update_hessians)
+ out |= update_hessians | update_piola | update_covariant_transformation;
- break;
+ break;
}
case mapping_nedelec: {
- if (flags & update_values)
- out |= update_values | update_covariant_transformation;
+ if (flags & update_values)
+ out |= update_values | update_covariant_transformation;
- if (flags & update_gradients)
- out |= update_gradients | update_covariant_transformation;
+ if (flags & update_gradients)
+ out |= update_gradients | update_covariant_transformation;
- if (flags & update_hessians)
- out |= update_hessians | update_covariant_transformation;
+ if (flags & update_hessians)
+ out |= update_hessians | update_covariant_transformation;
break;
}
default:
{
- Assert (false, ExcNotImplemented());
+ Assert (false, ExcNotImplemented());
}
}
// $Id$
// Version: $Name$
//
-// Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 by the deal.II authors
+// Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
{
namespace
{
- // given a permutation array,
- // compute and return the inverse
- // permutation
+ // given a permutation array,
+ // compute and return the inverse
+ // permutation
#ifdef DEAL_II_ANON_NAMESPACE_BUG
static
#endif
{
std::vector<unsigned int> out (in.size());
for (unsigned int i=0; i<in.size(); ++i)
- out[in[i]]=i;
+ out[in[i]]=i;
return out;
}
- // in initialize_embedding() and
- // initialize_restriction(), want to undo
- // tensorization on inner loops for
- // performance reasons. this clears a
- // dim-array
+ // in initialize_embedding() and
+ // initialize_restriction(), want to undo
+ // tensorization on inner loops for
+ // performance reasons. this clears a
+ // dim-array
template <int dim>
#ifdef DEAL_II_ANON_NAMESPACE_BUG
static
zero_indices (unsigned int indices[dim])
{
for (unsigned int d=0; d<dim; ++d)
- indices[d] = 0;
+ indices[d] = 0;
}
- // in initialize_embedding() and
- // initialize_restriction(), want to undo
- // tensorization on inner loops for
- // performance reasons. this increments tensor
- // product indices
+ // in initialize_embedding() and
+ // initialize_restriction(), want to undo
+ // tensorization on inner loops for
+ // performance reasons. this increments tensor
+ // product indices
template <int dim>
#ifdef DEAL_II_ANON_NAMESPACE_BUG
static
inline
void
increment_indices (unsigned int indices[dim],
- const unsigned int dofs1d)
+ const unsigned int dofs1d)
{
++indices[0];
for (int d=0; d<dim-1; ++d)
- if (indices[d]==dofs1d)
- {
- indices[d] = 0;
- indices[d+1]++;
- }
+ if (indices[d]==dofs1d)
+ {
+ indices[d] = 0;
+ indices[d+1]++;
+ }
}
- // in initialize_embedding() and
- // initialize_restriction(), want to undo
- // tensorization on inner loops for
- // performance reasons, and we need to again
- // access 1D polynomials. This function
- // creates them from dim-dimensional support
- // points.
+ // in initialize_embedding() and
+ // initialize_restriction(), want to undo
+ // tensorization on inner loops for
+ // performance reasons, and we need to again
+ // access 1D polynomials. This function
+ // creates them from dim-dimensional support
+ // points.
template <int dim>
#ifdef DEAL_II_ANON_NAMESPACE_BUG
static
inline
std::vector<Polynomials::Polynomial<double> >
generate_poly_space1d (const std::vector<Point<dim> > &unit_support_points,
- const std::vector<unsigned int> &index_map_inverse,
- const unsigned int dofs1d)
+ const std::vector<unsigned int> &index_map_inverse,
+ const unsigned int dofs1d)
{
AssertDimension (Utilities::fixed_power<dim> (dofs1d),
- unit_support_points.size());
+ unit_support_points.size());
std::vector<Point<1> > points1d (dofs1d);
for (unsigned int i=0; i<dofs1d; ++i)
- {
- const unsigned int j = index_map_inverse[i];
- points1d[i] = Point<1>(unit_support_points[j](0));
- for (unsigned int d=1; d<dim; ++d)
- Assert (unit_support_points[j][d] == 0.,
- ExcInternalError());
- }
+ {
+ const unsigned int j = index_map_inverse[i];
+ points1d[i] = Point<1>(unit_support_points[j](0));
+ for (unsigned int d=1; d<dim; ++d)
+ Assert (unit_support_points[j][d] == 0.,
+ ExcInternalError());
+ }
return Polynomials::generate_complete_Lagrange_basis (points1d);
}
}
template <int xdim, int xspacedim>
struct FE_Q<xdim,xspacedim>::Implementation
{
- /**
- * Initialize the hanging node
- * constraints matrices. Called from the
- * constructor in case the finite element
- * is based on quadrature points.
- */
+ /**
+ * Initialize the hanging node
+ * constraints matrices. Called from the
+ * constructor in case the finite element
+ * is based on quadrature points.
+ */
template <int spacedim>
static
void initialize_constraints (const Quadrature<1> &,
- FE_Q<1,spacedim> &)
+ FE_Q<1,spacedim> &)
{
- // no constraints in 1d
+ // no constraints in 1d
}
template <int spacedim>
static
void initialize_constraints (const Quadrature<1> &points,
- FE_Q<2,spacedim> &fe)
+ FE_Q<2,spacedim> &fe)
{
- const unsigned int dim = 2;
-
- // restricted to each face, the
- // traces of the shape functions is
- // an element of P_{k} (in 2d), or
- // Q_{k} (in 3d), where k is the
- // degree of the element. from
- // this, we interpolate between
- // mother and cell face.
-
- // the interpolation process works
- // as follows: on each subface,
- // we want that finite element
- // solutions from both sides
- // coincide. i.e. if a and b are
- // expansion coefficients for the
- // shape functions from both sides,
- // we seek a relation between a and
- // b such that
- // sum_j a_j phi^c_j(x)
- // == sum_j b_j phi_j(x)
- // for all points x on the
- // interface. here, phi^c_j are the
- // shape functions on the small
- // cell on one side of the face,
- // and phi_j those on the big cell
- // on the other side. To get this
- // relation, it suffices to look at
- // a sufficient number of points
- // for which this has to hold. if
- // there are n functions, then we
- // need n evaluation points, and we
- // choose them equidistantly.
- //
- // we obtain the matrix system
- // A a == B b
- // where
- // A_ij = phi^c_j(x_i)
- // B_ij = phi_j(x_i)
- // and the relation we are looking
- // for is
- // a = A^-1 B b
- //
- // for the special case of Lagrange
- // interpolation polynomials, A_ij
- // reduces to delta_ij, and
- // a_i = B_ij b_j
- // Hence,
- // interface_constraints(i,j)=B_ij.
- //
- // for the general case, where we
- // don't have Lagrange
- // interpolation polynomials, this
- // is a little more
- // complicated. Then we would
- // evaluate at a number of points
- // and invert the interpolation
- // matrix A.
- //
- // Note, that we build up these
- // matrices for all subfaces at
- // once, rather than considering
- // them separately. the reason is
- // that we finally will want to
- // have them in this order anyway,
- // as this is the format we need
- // inside deal.II
-
- // In the following the points x_i
- // are constructed in following
- // order (n=degree-1)
- // *----------*---------*
- // 1..n 0 n+1..2n
- // i.e. first the midpoint of the
- // line, then the support points on
- // subface 0 and on subface 1
- std::vector<Point<dim-1> > constraint_points;
- // Add midpoint
- constraint_points.push_back (Point<dim-1> (0.5));
-
- if (fe.degree>1)
- {
- const unsigned int n=fe.degree-1;
- const double step=1./fe.degree;
- // subface 0
- for (unsigned int i=1; i<=n; ++i)
- constraint_points.push_back (
- GeometryInfo<dim-1>::child_to_cell_coordinates(Point<dim-1>(i*step),0));
- // subface 1
- for (unsigned int i=1; i<=n; ++i)
- constraint_points.push_back (
- GeometryInfo<dim-1>::child_to_cell_coordinates(Point<dim-1>(i*step),1));
- }
-
- // Now construct relation between
- // destination (child) and source (mother)
- // dofs.
- const std::vector<Polynomials::Polynomial<double> > polynomials=
- Polynomials::generate_complete_Lagrange_basis(points.get_points());
-
- fe.interface_constraints
- .TableBase<2,double>::reinit (fe.interface_constraints_size());
-
- for (unsigned int i=0; i<constraint_points.size(); ++i)
- for (unsigned j=0; j<fe.degree+1; ++j)
- {
- fe.interface_constraints(i,j) =
- polynomials[fe.face_index_map[j]].value (constraint_points[i](0));
-
- // if the value is small up
- // to round-off, then
- // simply set it to zero to
- // avoid unwanted fill-in
- // of the constraint
- // matrices (which would
- // then increase the number
- // of other DoFs a
- // constrained DoF would
- // couple to)
- if (std::fabs(fe.interface_constraints(i,j)) < 1e-14)
- fe.interface_constraints(i,j) = 0;
- }
+ const unsigned int dim = 2;
+
+ // restricted to each face, the
+ // traces of the shape functions is
+ // an element of P_{k} (in 2d), or
+ // Q_{k} (in 3d), where k is the
+ // degree of the element. from
+ // this, we interpolate between
+ // mother and cell face.
+
+ // the interpolation process works
+ // as follows: on each subface,
+ // we want that finite element
+ // solutions from both sides
+ // coincide. i.e. if a and b are
+ // expansion coefficients for the
+ // shape functions from both sides,
+ // we seek a relation between a and
+ // b such that
+ // sum_j a_j phi^c_j(x)
+ // == sum_j b_j phi_j(x)
+ // for all points x on the
+ // interface. here, phi^c_j are the
+ // shape functions on the small
+ // cell on one side of the face,
+ // and phi_j those on the big cell
+ // on the other side. To get this
+ // relation, it suffices to look at
+ // a sufficient number of points
+ // for which this has to hold. if
+ // there are n functions, then we
+ // need n evaluation points, and we
+ // choose them equidistantly.
+ //
+ // we obtain the matrix system
+ // A a == B b
+ // where
+ // A_ij = phi^c_j(x_i)
+ // B_ij = phi_j(x_i)
+ // and the relation we are looking
+ // for is
+ // a = A^-1 B b
+ //
+ // for the special case of Lagrange
+ // interpolation polynomials, A_ij
+ // reduces to delta_ij, and
+ // a_i = B_ij b_j
+ // Hence,
+ // interface_constraints(i,j)=B_ij.
+ //
+ // for the general case, where we
+ // don't have Lagrange
+ // interpolation polynomials, this
+ // is a little more
+ // complicated. Then we would
+ // evaluate at a number of points
+ // and invert the interpolation
+ // matrix A.
+ //
+ // Note, that we build up these
+ // matrices for all subfaces at
+ // once, rather than considering
+ // them separately. the reason is
+ // that we finally will want to
+ // have them in this order anyway,
+ // as this is the format we need
+ // inside deal.II
+
+ // In the following the points x_i
+ // are constructed in following
+ // order (n=degree-1)
+ // *----------*---------*
+ // 1..n 0 n+1..2n
+ // i.e. first the midpoint of the
+ // line, then the support points on
+ // subface 0 and on subface 1
+ std::vector<Point<dim-1> > constraint_points;
+ // Add midpoint
+ constraint_points.push_back (Point<dim-1> (0.5));
+
+ if (fe.degree>1)
+ {
+ const unsigned int n=fe.degree-1;
+ const double step=1./fe.degree;
+ // subface 0
+ for (unsigned int i=1; i<=n; ++i)
+ constraint_points.push_back (
+ GeometryInfo<dim-1>::child_to_cell_coordinates(Point<dim-1>(i*step),0));
+ // subface 1
+ for (unsigned int i=1; i<=n; ++i)
+ constraint_points.push_back (
+ GeometryInfo<dim-1>::child_to_cell_coordinates(Point<dim-1>(i*step),1));
+ }
+
+ // Now construct relation between
+ // destination (child) and source (mother)
+ // dofs.
+ const std::vector<Polynomials::Polynomial<double> > polynomials=
+ Polynomials::generate_complete_Lagrange_basis(points.get_points());
+
+ fe.interface_constraints
+ .TableBase<2,double>::reinit (fe.interface_constraints_size());
+
+ for (unsigned int i=0; i<constraint_points.size(); ++i)
+ for (unsigned j=0; j<fe.degree+1; ++j)
+ {
+ fe.interface_constraints(i,j) =
+ polynomials[fe.face_index_map[j]].value (constraint_points[i](0));
+
+ // if the value is small up
+ // to round-off, then
+ // simply set it to zero to
+ // avoid unwanted fill-in
+ // of the constraint
+ // matrices (which would
+ // then increase the number
+ // of other DoFs a
+ // constrained DoF would
+ // couple to)
+ if (std::fabs(fe.interface_constraints(i,j)) < 1e-14)
+ fe.interface_constraints(i,j) = 0;
+ }
}
template <int spacedim>
static
void initialize_constraints (const Quadrature<1> &points,
- FE_Q<3,spacedim> &fe)
+ FE_Q<3,spacedim> &fe)
{
- const unsigned int dim = 3;
-
- // For a detailed documentation of
- // the interpolation see the
- // FE_Q<2>::initialize_constraints
- // function.
-
- // In the following the points x_i
- // are constructed in the order as
- // described in the documentation
- // of the FiniteElement class
- // (fe_base.h), i.e.
- // *--15--4--16--*
- // | | |
- // 10 19 6 20 12
- // | | |
- // 1--7---0--8---2
- // | | |
- // 9 17 5 18 11
- // | | |
- // *--13--3--14--*
- std::vector<Point<dim-1> > constraint_points;
-
- // Add midpoint
- constraint_points.push_back (Point<dim-1> (0.5, 0.5));
-
- // Add midpoints of lines of
- // "mother-face"
- constraint_points.push_back (Point<dim-1> (0, 0.5));
- constraint_points.push_back (Point<dim-1> (1, 0.5));
- constraint_points.push_back (Point<dim-1> (0.5, 0));
- constraint_points.push_back (Point<dim-1> (0.5, 1));
-
- if (fe.degree>1)
- {
- const unsigned int n=fe.degree-1;
- const double step=1./fe.degree;
- std::vector<Point<dim-2> > line_support_points(n);
- for (unsigned int i=0; i<n; ++i)
- line_support_points[i](0)=(i+1)*step;
- Quadrature<dim-2> qline(line_support_points);
-
- // auxiliary points in 2d
- std::vector<Point<dim-1> > p_line(n);
-
- // Add nodes of lines interior
- // in the "mother-face"
-
- // line 5: use line 9
- QProjector<dim-1>::project_to_subface(qline, 0, 0, p_line);
- for (unsigned int i=0; i<n; ++i)
- constraint_points.push_back (p_line[i] + Point<dim-1> (0.5, 0));
- // line 6: use line 10
- QProjector<dim-1>::project_to_subface(qline, 0, 1, p_line);
- for (unsigned int i=0; i<n; ++i)
- constraint_points.push_back (p_line[i] + Point<dim-1> (0.5, 0));
- // line 7: use line 13
- QProjector<dim-1>::project_to_subface(qline, 2, 0, p_line);
- for (unsigned int i=0; i<n; ++i)
- constraint_points.push_back (p_line[i] + Point<dim-1> (0, 0.5));
- // line 8: use line 14
- QProjector<dim-1>::project_to_subface(qline, 2, 1, p_line);
- for (unsigned int i=0; i<n; ++i)
- constraint_points.push_back (p_line[i] + Point<dim-1> (0, 0.5));
-
- // DoFs on bordering lines
- // lines 9-16
- for (unsigned int face=0; face<GeometryInfo<dim-1>::faces_per_cell; ++face)
- for (unsigned int subface=0;
- subface<GeometryInfo<dim-1>::max_children_per_face; ++subface)
- {
- QProjector<dim-1>::project_to_subface(qline, face, subface, p_line);
- constraint_points.insert(constraint_points.end(),
- p_line.begin(), p_line.end());
- }
-
- // Create constraints for
- // interior nodes
- std::vector<Point<dim-1> > inner_points(n*n);
- for (unsigned int i=0, iy=1; iy<=n; ++iy)
- for (unsigned int ix=1; ix<=n; ++ix)
- inner_points[i++] = Point<dim-1> (ix*step, iy*step);
-
- // at the moment do this for
- // isotropic face refinement only
- for (unsigned int child=0;
- child<GeometryInfo<dim-1>::max_children_per_cell; ++child)
- for (unsigned int i=0; i<inner_points.size(); ++i)
- constraint_points.push_back (
- GeometryInfo<dim-1>::child_to_cell_coordinates(inner_points[i], child));
- }
-
- // Now construct relation between
- // destination (child) and source (mother)
- // dofs.
- const unsigned int pnts=(fe.degree+1)*(fe.degree+1);
- const std::vector<Polynomials::Polynomial<double> > polynomial_basis=
- Polynomials::generate_complete_Lagrange_basis(points.get_points());
-
- const TensorProductPolynomials<dim-1> face_polynomials(polynomial_basis);
-
- fe.interface_constraints
- .TableBase<2,double>::reinit (fe.interface_constraints_size());
-
- for (unsigned int i=0; i<constraint_points.size(); ++i)
- {
- const double interval = (double) (fe.degree * 2);
- bool mirror[dim - 1];
- Point<dim-1> constraint_point;
-
- // Eliminate FP errors in constraint
- // points. Due to their origin, they
- // must all be fractions of the unit
- // interval. If we have polynomial
- // degree 4, the refined element has 8
- // intervals. Hence the coordinates
- // must be 0, 0.125, 0.25, 0.375 etc.
- // Now the coordinates of the
- // constraint points will be multiplied
- // by the inverse of the interval size
- // (in the example by 8). After that
- // the coordinates must be integral
- // numbers. Hence a normal truncation
- // is performed and the coordinates
- // will be scaled back. The equal
- // treatment of all coordinates should
- // eliminate any FP errors.
- for (unsigned int k=0; k<dim-1; ++k)
- {
- const int coord_int =
- static_cast<int> (constraint_points[i](k) * interval + 0.25);
- constraint_point(k) = 1.*coord_int / interval;
-
- // The following lines of code
- // should eliminate the problems
- // with the Constraint-Matrix,
- // which appeared for P>=4. The
- // Constraint-Matrix class
- // complained about different
- // constraints for the same entry
- // of the Constraint-Matrix.
- // Actually this difference could
- // be attributed to FP errors, as
- // it was in the range of
- // 1.0e-16. These errors originate
- // in the loss of symmetry in the
- // FP approximation of the
- // shape-functions. Considering a
- // 3rd order shape function in 1D,
- // we have N0(x)=N3(1-x) and
- // N1(x)=N2(1-x). For higher order
- // polynomials the FP
- // approximations of the shape
- // functions do not satisfy these
- // equations any more! Thus in the
- // following code everything is
- // computed in the interval x \in
- // [0..0.5], which is sufficient to
- // express all values that could
- // come out from a computation of
- // any shape function in the full
- // interval [0..1]. If x > 0.5 the
- // computation is done for 1-x with
- // the shape function N_{p-n}
- // instead of N_n. Hence symmetry
- // is preserved and everything
- // works fine...
- //
- // For a different explanation of
- // the problem, see the discussion
- // in the FiniteElement class
- // for constraint matrices in 3d.
- mirror[k] = (constraint_point(k) > 0.5);
- if (mirror[k])
- constraint_point(k) = 1.0 - constraint_point(k);
- }
-
- for (unsigned j=0; j<pnts; ++j)
- {
- unsigned int indices[2]
- = { fe.face_index_map[j] % (fe.degree + 1),
- fe.face_index_map[j] / (fe.degree + 1) };
-
- for (unsigned int k = 0; k<2; ++k)
- if (mirror[k])
- indices[k] = fe.degree - indices[k];
-
- const unsigned int
- new_index = indices[1] * (fe.degree + 1) + indices[0];
-
- fe.interface_constraints(i,j) =
- face_polynomials.compute_value (new_index, constraint_point);
-
- // if the value is small up
- // to round-off, then
- // simply set it to zero to
- // avoid unwanted fill-in
- // of the constraint
- // matrices (which would
- // then increase the number
- // of other DoFs a
- // constrained DoF would
- // couple to)
- if (std::fabs(fe.interface_constraints(i,j)) < 1e-14)
- fe.interface_constraints(i,j) = 0;
- }
- }
+ const unsigned int dim = 3;
+
+ // For a detailed documentation of
+ // the interpolation see the
+ // FE_Q<2>::initialize_constraints
+ // function.
+
+ // In the following the points x_i
+ // are constructed in the order as
+ // described in the documentation
+ // of the FiniteElement class
+ // (fe_base.h), i.e.
+ // *--15--4--16--*
+ // | | |
+ // 10 19 6 20 12
+ // | | |
+ // 1--7---0--8---2
+ // | | |
+ // 9 17 5 18 11
+ // | | |
+ // *--13--3--14--*
+ std::vector<Point<dim-1> > constraint_points;
+
+ // Add midpoint
+ constraint_points.push_back (Point<dim-1> (0.5, 0.5));
+
+ // Add midpoints of lines of
+ // "mother-face"
+ constraint_points.push_back (Point<dim-1> (0, 0.5));
+ constraint_points.push_back (Point<dim-1> (1, 0.5));
+ constraint_points.push_back (Point<dim-1> (0.5, 0));
+ constraint_points.push_back (Point<dim-1> (0.5, 1));
+
+ if (fe.degree>1)
+ {
+ const unsigned int n=fe.degree-1;
+ const double step=1./fe.degree;
+ std::vector<Point<dim-2> > line_support_points(n);
+ for (unsigned int i=0; i<n; ++i)
+ line_support_points[i](0)=(i+1)*step;
+ Quadrature<dim-2> qline(line_support_points);
+
+ // auxiliary points in 2d
+ std::vector<Point<dim-1> > p_line(n);
+
+ // Add nodes of lines interior
+ // in the "mother-face"
+
+ // line 5: use line 9
+ QProjector<dim-1>::project_to_subface(qline, 0, 0, p_line);
+ for (unsigned int i=0; i<n; ++i)
+ constraint_points.push_back (p_line[i] + Point<dim-1> (0.5, 0));
+ // line 6: use line 10
+ QProjector<dim-1>::project_to_subface(qline, 0, 1, p_line);
+ for (unsigned int i=0; i<n; ++i)
+ constraint_points.push_back (p_line[i] + Point<dim-1> (0.5, 0));
+ // line 7: use line 13
+ QProjector<dim-1>::project_to_subface(qline, 2, 0, p_line);
+ for (unsigned int i=0; i<n; ++i)
+ constraint_points.push_back (p_line[i] + Point<dim-1> (0, 0.5));
+ // line 8: use line 14
+ QProjector<dim-1>::project_to_subface(qline, 2, 1, p_line);
+ for (unsigned int i=0; i<n; ++i)
+ constraint_points.push_back (p_line[i] + Point<dim-1> (0, 0.5));
+
+ // DoFs on bordering lines
+ // lines 9-16
+ for (unsigned int face=0; face<GeometryInfo<dim-1>::faces_per_cell; ++face)
+ for (unsigned int subface=0;
+ subface<GeometryInfo<dim-1>::max_children_per_face; ++subface)
+ {
+ QProjector<dim-1>::project_to_subface(qline, face, subface, p_line);
+ constraint_points.insert(constraint_points.end(),
+ p_line.begin(), p_line.end());
+ }
+
+ // Create constraints for
+ // interior nodes
+ std::vector<Point<dim-1> > inner_points(n*n);
+ for (unsigned int i=0, iy=1; iy<=n; ++iy)
+ for (unsigned int ix=1; ix<=n; ++ix)
+ inner_points[i++] = Point<dim-1> (ix*step, iy*step);
+
+ // at the moment do this for
+ // isotropic face refinement only
+ for (unsigned int child=0;
+ child<GeometryInfo<dim-1>::max_children_per_cell; ++child)
+ for (unsigned int i=0; i<inner_points.size(); ++i)
+ constraint_points.push_back (
+ GeometryInfo<dim-1>::child_to_cell_coordinates(inner_points[i], child));
+ }
+
+ // Now construct relation between
+ // destination (child) and source (mother)
+ // dofs.
+ const unsigned int pnts=(fe.degree+1)*(fe.degree+1);
+ const std::vector<Polynomials::Polynomial<double> > polynomial_basis=
+ Polynomials::generate_complete_Lagrange_basis(points.get_points());
+
+ const TensorProductPolynomials<dim-1> face_polynomials(polynomial_basis);
+
+ fe.interface_constraints
+ .TableBase<2,double>::reinit (fe.interface_constraints_size());
+
+ for (unsigned int i=0; i<constraint_points.size(); ++i)
+ {
+ const double interval = (double) (fe.degree * 2);
+ bool mirror[dim - 1];
+ Point<dim-1> constraint_point;
+
+ // Eliminate FP errors in constraint
+ // points. Due to their origin, they
+ // must all be fractions of the unit
+ // interval. If we have polynomial
+ // degree 4, the refined element has 8
+ // intervals. Hence the coordinates
+ // must be 0, 0.125, 0.25, 0.375 etc.
+ // Now the coordinates of the
+ // constraint points will be multiplied
+ // by the inverse of the interval size
+ // (in the example by 8). After that
+ // the coordinates must be integral
+ // numbers. Hence a normal truncation
+ // is performed and the coordinates
+ // will be scaled back. The equal
+ // treatment of all coordinates should
+ // eliminate any FP errors.
+ for (unsigned int k=0; k<dim-1; ++k)
+ {
+ const int coord_int =
+ static_cast<int> (constraint_points[i](k) * interval + 0.25);
+ constraint_point(k) = 1.*coord_int / interval;
+
+ // The following lines of code
+ // should eliminate the problems
+ // with the Constraint-Matrix,
+ // which appeared for P>=4. The
+ // Constraint-Matrix class
+ // complained about different
+ // constraints for the same entry
+ // of the Constraint-Matrix.
+ // Actually this difference could
+ // be attributed to FP errors, as
+ // it was in the range of
+ // 1.0e-16. These errors originate
+ // in the loss of symmetry in the
+ // FP approximation of the
+ // shape-functions. Considering a
+ // 3rd order shape function in 1D,
+ // we have N0(x)=N3(1-x) and
+ // N1(x)=N2(1-x). For higher order
+ // polynomials the FP
+ // approximations of the shape
+ // functions do not satisfy these
+ // equations any more! Thus in the
+ // following code everything is
+ // computed in the interval x \in
+ // [0..0.5], which is sufficient to
+ // express all values that could
+ // come out from a computation of
+ // any shape function in the full
+ // interval [0..1]. If x > 0.5 the
+ // computation is done for 1-x with
+ // the shape function N_{p-n}
+ // instead of N_n. Hence symmetry
+ // is preserved and everything
+ // works fine...
+ //
+ // For a different explanation of
+ // the problem, see the discussion
+ // in the FiniteElement class
+ // for constraint matrices in 3d.
+ mirror[k] = (constraint_point(k) > 0.5);
+ if (mirror[k])
+ constraint_point(k) = 1.0 - constraint_point(k);
+ }
+
+ for (unsigned j=0; j<pnts; ++j)
+ {
+ unsigned int indices[2]
+ = { fe.face_index_map[j] % (fe.degree + 1),
+ fe.face_index_map[j] / (fe.degree + 1) };
+
+ for (unsigned int k = 0; k<2; ++k)
+ if (mirror[k])
+ indices[k] = fe.degree - indices[k];
+
+ const unsigned int
+ new_index = indices[1] * (fe.degree + 1) + indices[0];
+
+ fe.interface_constraints(i,j) =
+ face_polynomials.compute_value (new_index, constraint_point);
+
+ // if the value is small up
+ // to round-off, then
+ // simply set it to zero to
+ // avoid unwanted fill-in
+ // of the constraint
+ // matrices (which would
+ // then increase the number
+ // of other DoFs a
+ // constrained DoF would
+ // couple to)
+ if (std::fabs(fe.interface_constraints(i,j)) < 1e-14)
+ fe.interface_constraints(i,j) = 0;
+ }
+ }
}
};
template <int dim, int spacedim>
FE_Q<dim,spacedim>::FE_Q (const unsigned int degree)
- :
- FE_Poly<TensorProductPolynomials<dim>, dim, spacedim> (
- TensorProductPolynomials<dim>(Polynomials::LagrangeEquidistant::generate_complete_basis(degree)),
- FiniteElementData<dim>(get_dpo_vector(degree),
- 1, degree,
- FiniteElementData<dim>::H1),
- std::vector<bool> (1, false),
- std::vector<std::vector<bool> >(1, std::vector<bool>(1,true))),
- face_index_map(FE_Q_Helper::invert_numbering(face_lexicographic_to_hierarchic_numbering (degree)))
+ :
+ FE_Poly<TensorProductPolynomials<dim>, dim, spacedim> (
+ TensorProductPolynomials<dim>(Polynomials::LagrangeEquidistant::generate_complete_basis(degree)),
+ FiniteElementData<dim>(get_dpo_vector(degree),
+ 1, degree,
+ FiniteElementData<dim>::H1),
+ std::vector<bool> (1, false),
+ std::vector<std::vector<bool> >(1, std::vector<bool>(1,true))),
+ face_index_map(FE_Q_Helper::invert_numbering(face_lexicographic_to_hierarchic_numbering (degree)))
{
Assert (degree > 0,
ExcMessage ("This element can only be used for polynomial degrees "
FETools::hierarchic_to_lexicographic_numbering (*this, renumber);
this->poly_space.set_numbering(renumber);
- // finally fill in support points
- // on cell and face
+ // finally fill in support points
+ // on cell and face
initialize_unit_support_points ();
initialize_unit_face_support_points ();
- // reinit constraints
+ // reinit constraints
initialize_constraints ();
- // Reinit the vectors of restriction and
- // prolongation matrices to the right sizes
- // and compute the matrices
+ // Reinit the vectors of restriction and
+ // prolongation matrices to the right sizes
+ // and compute the matrices
this->reinit_restriction_and_prolongation_matrices();
initialize_embedding();
initialize_restriction();
template <int dim, int spacedim>
FE_Q<dim,spacedim>::FE_Q (const Quadrature<1> &points)
- :
- FE_Poly<TensorProductPolynomials<dim>, dim, spacedim> (
- TensorProductPolynomials<dim>(Polynomials::generate_complete_Lagrange_basis(points.get_points())),
- FiniteElementData<dim>(get_dpo_vector(points.size()-1),
- 1, points.size()-1,
- FiniteElementData<dim>::H1),
- std::vector<bool> (1, false),
- std::vector<std::vector<bool> >(1, std::vector<bool>(1,true))),
- face_index_map(FE_Q_Helper::invert_numbering(face_lexicographic_to_hierarchic_numbering (points.size()-1)))
+ :
+ FE_Poly<TensorProductPolynomials<dim>, dim, spacedim> (
+ TensorProductPolynomials<dim>(Polynomials::generate_complete_Lagrange_basis(points.get_points())),
+ FiniteElementData<dim>(get_dpo_vector(points.size()-1),
+ 1, points.size()-1,
+ FiniteElementData<dim>::H1),
+ std::vector<bool> (1, false),
+ std::vector<std::vector<bool> >(1, std::vector<bool>(1,true))),
+ face_index_map(FE_Q_Helper::invert_numbering(face_lexicographic_to_hierarchic_numbering (points.size()-1)))
{
const int degree = points.size()-1;
ExcMessage ("This element can only be used for polynomial degrees "
"at least zero"));
Assert (points.point(0)(0) == 0,
- ExcMessage ("The first support point has to be zero."));
+ ExcMessage ("The first support point has to be zero."));
Assert (points.point(degree)(0) == 1,
- ExcMessage ("The last support point has to be one."));
+ ExcMessage ("The last support point has to be one."));
std::vector<unsigned int> renumber (this->dofs_per_cell);
FETools::hierarchic_to_lexicographic_numbering (*this, renumber);
this->poly_space.set_numbering(renumber);
- // finally fill in support points
- // on cell and face
+ // finally fill in support points
+ // on cell and face
initialize_unit_support_points (points);
initialize_unit_face_support_points (points);
- // reinit constraints
+ // reinit constraints
Implementation::initialize_constraints (points, *this);
- // Reinit the vectors of restriction and
- // prolongation matrices to the right sizes
- // and compute the matrices
+ // Reinit the vectors of restriction and
+ // prolongation matrices to the right sizes
+ // and compute the matrices
this->reinit_restriction_and_prolongation_matrices();
initialize_embedding();
initialize_restriction();
std::string
FE_Q<dim,spacedim>::get_name () const
{
- // note that the
- // FETools::get_fe_from_name
- // function depends on the
- // particular format of the string
- // this function returns, so they
- // have to be kept in synch
+ // note that the
+ // FETools::get_fe_from_name
+ // function depends on the
+ // particular format of the string
+ // this function returns, so they
+ // have to be kept in synch
std::ostringstream namebuf;
bool type = true;
const std::vector<Point<dim> > &unit_support_points = this->unit_support_points;
unsigned int index = 0;
- // Decode the support points
- // in one coordinate direction.
+ // Decode the support points
+ // in one coordinate direction.
for (unsigned int j=0;j<dofs_per_cell;j++)
{
if ((dim>1) ? (unit_support_points[j](1)==0 &&
- ((dim>2) ? unit_support_points[j](2)==0: true)) : true)
- {
- if (index == 0)
- points[index] = unit_support_points[j](0);
+ ((dim>2) ? unit_support_points[j](2)==0: true)) : true)
+ {
+ if (index == 0)
+ points[index] = unit_support_points[j](0);
else if (index == 1)
- points[n_points-1] = unit_support_points[j](0);
+ points[n_points-1] = unit_support_points[j](0);
else
- points[index-1] = unit_support_points[j](0);
+ points[index-1] = unit_support_points[j](0);
- index++;
- }
+ index++;
+ }
}
Assert (index == n_points,
- ExcMessage ("Could not decode support points in one coordinate direction."));
+ ExcMessage ("Could not decode support points in one coordinate direction."));
- // Check whether the support
- // points are equidistant.
+ // Check whether the support
+ // points are equidistant.
for(unsigned int j=0;j<n_points;j++)
if (std::fabs(points[j] - (double)j/this->degree) > 1e-15)
{
- type = false;
- break;
+ type = false;
+ break;
}
if (type == true)
else
{
- // Check whether the support
- // points come from QGaussLobatto.
+ // Check whether the support
+ // points come from QGaussLobatto.
const QGaussLobatto<1> points_gl(n_points);
type = true;
for(unsigned int j=0;j<n_points;j++)
- if (points[j] != points_gl.point(j)(0))
- {
- type = false;
- break;
- }
+ if (points[j] != points_gl.point(j)(0))
+ {
+ type = false;
+ break;
+ }
if(type == true)
- namebuf << "FE_Q<" << dim << ">(QGaussLobatto(" << this->degree+1 << "))";
+ namebuf << "FE_Q<" << dim << ">(QGaussLobatto(" << this->degree+1 << "))";
else
- namebuf << "FE_Q<" << dim << ">(QUnknownNodes(" << this->degree << "))";
+ namebuf << "FE_Q<" << dim << ">(QUnknownNodes(" << this->degree << "))";
}
return namebuf.str();
}
void
FE_Q<dim,spacedim>::
get_interpolation_matrix (const FiniteElement<dim,spacedim> &x_source_fe,
- FullMatrix<double> &interpolation_matrix) const
+ FullMatrix<double> &interpolation_matrix) const
{
- // this is only implemented, if the
- // source FE is also a
- // Q element
+ // this is only implemented, if the
+ // source FE is also a
+ // Q element
typedef FE_Q<dim,spacedim> FEQ;
typedef FiniteElement<dim,spacedim> FEL;
ExcInterpolationNotImplemented());
Assert (interpolation_matrix.m() == this->dofs_per_cell,
- ExcDimensionMismatch (interpolation_matrix.m(),
- this->dofs_per_cell));
+ ExcDimensionMismatch (interpolation_matrix.m(),
+ this->dofs_per_cell));
Assert (interpolation_matrix.n() == x_source_fe.dofs_per_cell,
- ExcDimensionMismatch (interpolation_matrix.m(),
- x_source_fe.dofs_per_cell));
+ ExcDimensionMismatch (interpolation_matrix.m(),
+ x_source_fe.dofs_per_cell));
- // ok, source is a Q element, so
- // we will be able to do the work
+ // ok, source is a Q element, so
+ // we will be able to do the work
const FE_Q<dim,spacedim> &source_fe
= dynamic_cast<const FE_Q<dim,spacedim>&>(x_source_fe);
- // compute the interpolation
- // matrices in much the same way as
- // we do for the embedding matrices
- // from mother to child.
+ // compute the interpolation
+ // matrices in much the same way as
+ // we do for the embedding matrices
+ // from mother to child.
FullMatrix<double> cell_interpolation (this->dofs_per_cell,
- this->dofs_per_cell);
+ this->dofs_per_cell);
FullMatrix<double> source_interpolation (this->dofs_per_cell,
- source_fe.dofs_per_cell);
+ source_fe.dofs_per_cell);
FullMatrix<double> tmp (this->dofs_per_cell,
- source_fe.dofs_per_cell);
+ source_fe.dofs_per_cell);
for (unsigned int j=0; j<this->dofs_per_cell; ++j)
{
// read in a point on this
if (std::fabs(interpolation_matrix(i,j)) < eps)
interpolation_matrix(i,j) = 0.;
- // make sure that the row sum of
- // each of the matrices is 1 at
- // this point. this must be so
- // since the shape functions sum up
- // to 1
+ // make sure that the row sum of
+ // each of the matrices is 1 at
+ // this point. this must be so
+ // since the shape functions sum up
+ // to 1
for (unsigned int i=0; i<this->dofs_per_cell; ++i)
{
double sum = 0.;
void
FE_Q<1>::
get_face_interpolation_matrix (const FiniteElement<1,1> &/*x_source_fe*/,
- FullMatrix<double> &/*interpolation_matrix*/) const
+ FullMatrix<double> &/*interpolation_matrix*/) const
{
Assert (false, ExcImpossibleInDim(1));
}
void
FE_Q<1>::
get_subface_interpolation_matrix (const FiniteElement<1,1> &/*x_source_fe*/,
- const unsigned int /*subface*/,
- FullMatrix<double> &/*interpolation_matrix*/) const
+ const unsigned int /*subface*/,
+ FullMatrix<double> &/*interpolation_matrix*/) const
{
Assert (false, ExcImpossibleInDim(1));
}
void
FE_Q<1,2>::
get_face_interpolation_matrix (const FiniteElement<1,2> &/*x_source_fe*/,
- FullMatrix<double> &/*interpolation_matrix*/) const
+ FullMatrix<double> &/*interpolation_matrix*/) const
{
typedef FiniteElement<1,2> FEL;
Assert (false,
- FEL::
- ExcInterpolationNotImplemented ());
+ FEL::
+ ExcInterpolationNotImplemented ());
}
void
FE_Q<1,2>::
get_subface_interpolation_matrix (const FiniteElement<1,2> &/*x_source_fe*/,
- const unsigned int /*subface*/,
- FullMatrix<double> &/*interpolation_matrix*/) const
+ const unsigned int /*subface*/,
+ FullMatrix<double> &/*interpolation_matrix*/) const
{
typedef FiniteElement<1,2> FEL;
Assert (false,
- FEL::
- ExcInterpolationNotImplemented ());
+ FEL::
+ ExcInterpolationNotImplemented ());
}
void
FE_Q<1,3>::
get_face_interpolation_matrix (const FiniteElement<1,3> &/*x_source_fe*/,
- FullMatrix<double> &/*interpolation_matrix*/) const
+ FullMatrix<double> &/*interpolation_matrix*/) const
{
typedef FiniteElement<1,3> FEL;
Assert (false,
- FEL::
- ExcInterpolationNotImplemented ());
+ FEL::
+ ExcInterpolationNotImplemented ());
}
void
FE_Q<1,3>::
get_subface_interpolation_matrix (const FiniteElement<1,3> &/*x_source_fe*/,
- const unsigned int /*subface*/,
- FullMatrix<double> &/*interpolation_matrix*/) const
+ const unsigned int /*subface*/,
+ FullMatrix<double> &/*interpolation_matrix*/) const
{
typedef FiniteElement<1,3> FEL;
Assert (false,
- FEL::
- ExcInterpolationNotImplemented ());
+ FEL::
+ ExcInterpolationNotImplemented ());
}
void
FE_Q<dim,spacedim>::
get_face_interpolation_matrix (const FiniteElement<dim,spacedim> &x_source_fe,
- FullMatrix<double> &interpolation_matrix) const
+ FullMatrix<double> &interpolation_matrix) const
{
- // this is only implemented, if the
- // source FE is also a
- // Q element
+ // this is only implemented, if the
+ // source FE is also a
+ // Q element
typedef FE_Q<dim,spacedim> FEQ;
typedef FiniteElement<dim,spacedim> FEL;
AssertThrow ((x_source_fe.get_name().find ("FE_Q<") == 0)
ExcInterpolationNotImplemented());
Assert (interpolation_matrix.n() == this->dofs_per_face,
- ExcDimensionMismatch (interpolation_matrix.n(),
- this->dofs_per_face));
+ ExcDimensionMismatch (interpolation_matrix.n(),
+ this->dofs_per_face));
Assert (interpolation_matrix.m() == x_source_fe.dofs_per_face,
- ExcDimensionMismatch (interpolation_matrix.m(),
- x_source_fe.dofs_per_face));
+ ExcDimensionMismatch (interpolation_matrix.m(),
+ x_source_fe.dofs_per_face));
- // ok, source is a Q element, so
- // we will be able to do the work
+ // ok, source is a Q element, so
+ // we will be able to do the work
const FE_Q<dim,spacedim> &source_fe
= dynamic_cast<const FE_Q<dim,spacedim>&>(x_source_fe);
- // Make sure, that the element,
+ // Make sure, that the element,
// for which the DoFs should be
// constrained is the one with
// the higher polynomial degree.
// also if this assertion is not
// satisfied. But the matrices
// produced in that case might
- // lead to problems in the
+ // lead to problems in the
// hp procedures, which use this
- // method.
+ // method.
Assert (this->dofs_per_face <= source_fe.dofs_per_face,
- typename FEL::
- ExcInterpolationNotImplemented ());
+ typename FEL::
+ ExcInterpolationNotImplemented ());
// generate a quadrature
// with the unit support points.
// This is later based as a
- // basis for the QProjector,
- // which returns the support
+ // basis for the QProjector,
+ // which returns the support
// points on the face.
Quadrature<dim-1> quad_face_support (source_fe.get_unit_face_support_points ());
- // Rule of thumb for FP accuracy,
- // that can be expected for a
- // given polynomial degree.
- // This value is used to cut
- // off values close to zero.
+ // Rule of thumb for FP accuracy,
+ // that can be expected for a
+ // given polynomial degree.
+ // This value is used to cut
+ // off values close to zero.
const double eps = 2e-13*this->degree*(dim-1);
- // compute the interpolation
- // matrix by simply taking the
+ // compute the interpolation
+ // matrix by simply taking the
// value at the support points.
//TODO: Verify that all faces are the same with respect to
// these support points. Furthermore, check if something has to
const Point<dim> &p = face_quadrature.point (i);
for (unsigned int j=0; j<this->dofs_per_face; ++j)
- {
- double matrix_entry = this->shape_value (this->face_to_cell_index(j, 0), p);
-
- // Correct the interpolated
- // value. I.e. if it is close
- // to 1 or 0, make it exactly
- // 1 or 0. Unfortunately, this
- // is required to avoid problems
- // with higher order elements.
- if (std::fabs (matrix_entry - 1.0) < eps)
- matrix_entry = 1.0;
- if (std::fabs (matrix_entry) < eps)
- matrix_entry = 0.0;
-
- interpolation_matrix(i,j) = matrix_entry;
- }
+ {
+ double matrix_entry = this->shape_value (this->face_to_cell_index(j, 0), p);
+
+ // Correct the interpolated
+ // value. I.e. if it is close
+ // to 1 or 0, make it exactly
+ // 1 or 0. Unfortunately, this
+ // is required to avoid problems
+ // with higher order elements.
+ if (std::fabs (matrix_entry - 1.0) < eps)
+ matrix_entry = 1.0;
+ if (std::fabs (matrix_entry) < eps)
+ matrix_entry = 0.0;
+
+ interpolation_matrix(i,j) = matrix_entry;
+ }
}
- // make sure that the row sum of
- // each of the matrices is 1 at
- // this point. this must be so
- // since the shape functions sum up
- // to 1
+ // make sure that the row sum of
+ // each of the matrices is 1 at
+ // this point. this must be so
+ // since the shape functions sum up
+ // to 1
for (unsigned int j=0; j<source_fe.dofs_per_face; ++j)
{
double sum = 0.;
void
FE_Q<dim,spacedim>::
get_subface_interpolation_matrix (const FiniteElement<dim,spacedim> &x_source_fe,
- const unsigned int subface,
- FullMatrix<double> &interpolation_matrix) const
+ const unsigned int subface,
+ FullMatrix<double> &interpolation_matrix) const
{
Assert (interpolation_matrix.m() == x_source_fe.dofs_per_face,
- ExcDimensionMismatch (interpolation_matrix.m(),
- x_source_fe.dofs_per_face));
+ ExcDimensionMismatch (interpolation_matrix.m(),
+ x_source_fe.dofs_per_face));
- // see if source is a Q element
+ // see if source is a Q element
if (const FE_Q<dim,spacedim> *source_fe
= dynamic_cast<const FE_Q<dim,spacedim> *>(&x_source_fe))
{
- // have this test in here since
- // a table of size 2x0 reports
- // its size as 0x0
+ // have this test in here since
+ // a table of size 2x0 reports
+ // its size as 0x0
Assert (interpolation_matrix.n() == this->dofs_per_face,
- ExcDimensionMismatch (interpolation_matrix.n(),
- this->dofs_per_face));
-
- // Make sure, that the element,
- // for which the DoFs should be
- // constrained is the one with
- // the higher polynomial degree.
- // Actually the procedure will work
- // also if this assertion is not
- // satisfied. But the matrices
- // produced in that case might
- // lead to problems in the
- // hp procedures, which use this
- // method.
+ ExcDimensionMismatch (interpolation_matrix.n(),
+ this->dofs_per_face));
+
+ // Make sure, that the element,
+ // for which the DoFs should be
+ // constrained is the one with
+ // the higher polynomial degree.
+ // Actually the procedure will work
+ // also if this assertion is not
+ // satisfied. But the matrices
+ // produced in that case might
+ // lead to problems in the
+ // hp procedures, which use this
+ // method.
Assert (this->dofs_per_face <= source_fe->dofs_per_face,
- (typename FiniteElement<dim,spacedim>::
- ExcInterpolationNotImplemented ()));
+ (typename FiniteElement<dim,spacedim>::
+ ExcInterpolationNotImplemented ()));
- // generate a point on this
- // cell and evaluate the
- // shape functions there
+ // generate a point on this
+ // cell and evaluate the
+ // shape functions there
const Quadrature<dim-1>
- quad_face_support (source_fe->get_unit_face_support_points ());
+ quad_face_support (source_fe->get_unit_face_support_points ());
- // Rule of thumb for FP accuracy,
- // that can be expected for a
- // given polynomial degree.
- // This value is used to cut
- // off values close to zero.
+ // Rule of thumb for FP accuracy,
+ // that can be expected for a
+ // given polynomial degree.
+ // This value is used to cut
+ // off values close to zero.
double eps = 2e-13*this->degree*(dim-1);
- // compute the interpolation
- // matrix by simply taking the
- // value at the support points.
+ // compute the interpolation
+ // matrix by simply taking the
+ // value at the support points.
//TODO: Verify that all faces are the same with respect to
// these support points. Furthermore, check if something has to
// be done for the face orientation flag in 3D.
const Quadrature<dim> subface_quadrature
- = QProjector<dim>::project_to_subface (quad_face_support, 0, subface);
+ = QProjector<dim>::project_to_subface (quad_face_support, 0, subface);
for (unsigned int i=0; i<source_fe->dofs_per_face; ++i)
- {
- const Point<dim> &p = subface_quadrature.point (i);
-
- for (unsigned int j=0; j<this->dofs_per_face; ++j)
- {
- double matrix_entry = this->shape_value (this->face_to_cell_index(j, 0), p);
-
- // Correct the interpolated
- // value. I.e. if it is close
- // to 1 or 0, make it exactly
- // 1 or 0. Unfortunately, this
- // is required to avoid problems
- // with higher order elements.
- if (std::fabs (matrix_entry - 1.0) < eps)
- matrix_entry = 1.0;
- if (std::fabs (matrix_entry) < eps)
- matrix_entry = 0.0;
-
- interpolation_matrix(i,j) = matrix_entry;
- }
- }
-
- // make sure that the row sum of
- // each of the matrices is 1 at
- // this point. this must be so
- // since the shape functions sum up
- // to 1
+ {
+ const Point<dim> &p = subface_quadrature.point (i);
+
+ for (unsigned int j=0; j<this->dofs_per_face; ++j)
+ {
+ double matrix_entry = this->shape_value (this->face_to_cell_index(j, 0), p);
+
+ // Correct the interpolated
+ // value. I.e. if it is close
+ // to 1 or 0, make it exactly
+ // 1 or 0. Unfortunately, this
+ // is required to avoid problems
+ // with higher order elements.
+ if (std::fabs (matrix_entry - 1.0) < eps)
+ matrix_entry = 1.0;
+ if (std::fabs (matrix_entry) < eps)
+ matrix_entry = 0.0;
+
+ interpolation_matrix(i,j) = matrix_entry;
+ }
+ }
+
+ // make sure that the row sum of
+ // each of the matrices is 1 at
+ // this point. this must be so
+ // since the shape functions sum up
+ // to 1
for (unsigned int j=0; j<source_fe->dofs_per_face; ++j)
- {
- double sum = 0.;
+ {
+ double sum = 0.;
- for (unsigned int i=0; i<this->dofs_per_face; ++i)
- sum += interpolation_matrix(j,i);
+ for (unsigned int i=0; i<this->dofs_per_face; ++i)
+ sum += interpolation_matrix(j,i);
- Assert (std::fabs(sum-1) < 2e-13*this->degree*dim,
- ExcInternalError());
- }
+ Assert (std::fabs(sum-1) < 2e-13*this->degree*dim,
+ ExcInternalError());
+ }
}
else if (dynamic_cast<const FE_Nothing<dim> *>(&x_source_fe) != 0)
{
- // nothing to do here, the
- // FE_Nothing has no degrees of
- // freedom anyway
+ // nothing to do here, the
+ // FE_Nothing has no degrees of
+ // freedom anyway
}
else
AssertThrow (false,
- (typename FiniteElement<dim,spacedim>::
- ExcInterpolationNotImplemented()));
+ (typename FiniteElement<dim,spacedim>::
+ ExcInterpolationNotImplemented()));
}
FE_Q<dim,spacedim>::
hp_vertex_dof_identities (const FiniteElement<dim,spacedim> &fe_other) const
{
- // we can presently only compute
- // these identities if both FEs are
- // FE_Qs or if the other one is an
- // FE_Nothing. in the first case,
- // there should be exactly one
- // single DoF of each FE at a
- // vertex, and they should have
- // identical value
+ // we can presently only compute
+ // these identities if both FEs are
+ // FE_Qs or if the other one is an
+ // FE_Nothing. in the first case,
+ // there should be exactly one
+ // single DoF of each FE at a
+ // vertex, and they should have
+ // identical value
if (dynamic_cast<const FE_Q<dim,spacedim>*>(&fe_other) != 0)
{
return
- std::vector<std::pair<unsigned int, unsigned int> >
- (1, std::make_pair (0U, 0U));
+ std::vector<std::pair<unsigned int, unsigned int> >
+ (1, std::make_pair (0U, 0U));
}
else if (dynamic_cast<const FE_Nothing<dim>*>(&fe_other) != 0)
{
- // the FE_Nothing has no
- // degrees of freedom, so there
- // are no equivalencies to be
- // recorded
+ // the FE_Nothing has no
+ // degrees of freedom, so there
+ // are no equivalencies to be
+ // recorded
return std::vector<std::pair<unsigned int, unsigned int> > ();
}
else
FE_Q<dim,spacedim>::
hp_line_dof_identities (const FiniteElement<dim,spacedim> &fe_other) const
{
- // we can presently only compute
- // these identities if both FEs are
- // FE_Qs or if the other one is an
- // FE_Nothing
+ // we can presently only compute
+ // these identities if both FEs are
+ // FE_Qs or if the other one is an
+ // FE_Nothing
if (const FE_Q<dim,spacedim> *fe_q_other = dynamic_cast<const FE_Q<dim,spacedim>*>(&fe_other))
{
- // dofs are located along lines, so two
- // dofs are identical if they are
- // located at identical positions. if
- // we had only equidistant points, we
- // could simple check for similarity
- // like (i+1)*q == (j+1)*p, but we
- // might have other support points
- // (e.g. Gauss-Lobatto
- // points). Therefore, read the points
- // in unit_support_points for the first
- // coordinate direction. We take the
- // lexicographic ordering of the points
- // in the first direction (i.e.,
- // x-direction), which we access
- // between index 1 and p-1 (index 0 and
- // p are vertex dofs).
+ // dofs are located along lines, so two
+ // dofs are identical if they are
+ // located at identical positions. if
+ // we had only equidistant points, we
+ // could simple check for similarity
+ // like (i+1)*q == (j+1)*p, but we
+ // might have other support points
+ // (e.g. Gauss-Lobatto
+ // points). Therefore, read the points
+ // in unit_support_points for the first
+ // coordinate direction. We take the
+ // lexicographic ordering of the points
+ // in the first direction (i.e.,
+ // x-direction), which we access
+ // between index 1 and p-1 (index 0 and
+ // p are vertex dofs).
const unsigned int p = this->degree;
const unsigned int q = fe_q_other->degree;
std::vector<std::pair<unsigned int, unsigned int> > identities;
const std::vector<unsigned int> &index_map_inverse=
- this->poly_space.get_numbering_inverse();
+ this->poly_space.get_numbering_inverse();
const std::vector<unsigned int> &index_map_inverse_other=
- fe_q_other->poly_space.get_numbering_inverse();
+ fe_q_other->poly_space.get_numbering_inverse();
for (unsigned int i=0; i<p-1; ++i)
- for (unsigned int j=0; j<q-1; ++j)
- if (std::fabs(this->unit_support_points[index_map_inverse[i+1]][0]-
- fe_q_other->unit_support_points[index_map_inverse_other[j+1]][0])
- < 1e-14)
- identities.push_back (std::make_pair(i,j));
+ for (unsigned int j=0; j<q-1; ++j)
+ if (std::fabs(this->unit_support_points[index_map_inverse[i+1]][0]-
+ fe_q_other->unit_support_points[index_map_inverse_other[j+1]][0])
+ < 1e-14)
+ identities.push_back (std::make_pair(i,j));
return identities;
}
else if (dynamic_cast<const FE_Nothing<dim>*>(&fe_other) != 0)
{
- // the FE_Nothing has no
- // degrees of freedom, so there
- // are no equivalencies to be
- // recorded
+ // the FE_Nothing has no
+ // degrees of freedom, so there
+ // are no equivalencies to be
+ // recorded
return std::vector<std::pair<unsigned int, unsigned int> > ();
}
else
FE_Q<dim,spacedim>::
hp_quad_dof_identities (const FiniteElement<dim,spacedim> &fe_other) const
{
- // we can presently only compute
- // these identities if both FEs are
- // FE_Qs or if the other one is an
- // FE_Nothing
+ // we can presently only compute
+ // these identities if both FEs are
+ // FE_Qs or if the other one is an
+ // FE_Nothing
if (const FE_Q<dim,spacedim> *fe_q_other = dynamic_cast<const FE_Q<dim,spacedim>*>(&fe_other))
{
- // this works exactly like the line
- // case above, except that now we have
- // to have two indices i1, i2 and j1,
- // j2 to characterize the dofs on the
- // face of each of the finite
- // elements. since they are ordered
- // lexicographically along the first
- // line and we have a tensor product,
- // the rest is rather straightforward
+ // this works exactly like the line
+ // case above, except that now we have
+ // to have two indices i1, i2 and j1,
+ // j2 to characterize the dofs on the
+ // face of each of the finite
+ // elements. since they are ordered
+ // lexicographically along the first
+ // line and we have a tensor product,
+ // the rest is rather straightforward
const unsigned int p = this->degree;
const unsigned int q = fe_q_other->degree;
std::vector<std::pair<unsigned int, unsigned int> > identities;
const std::vector<unsigned int> &index_map_inverse=
- this->poly_space.get_numbering_inverse();
+ this->poly_space.get_numbering_inverse();
const std::vector<unsigned int> &index_map_inverse_other=
- fe_q_other->poly_space.get_numbering_inverse();
+ fe_q_other->poly_space.get_numbering_inverse();
for (unsigned int i1=0; i1<p-1; ++i1)
- for (unsigned int i2=0; i2<p-1; ++i2)
- for (unsigned int j1=0; j1<q-1; ++j1)
- for (unsigned int j2=0; j2<q-1; ++j2)
- if ((std::fabs(this->unit_support_points[index_map_inverse[i1+1]][0]-
- fe_q_other->unit_support_points[index_map_inverse_other[j1+1]][0])
- < 1e-14)
- &&
- (std::fabs(this->unit_support_points[index_map_inverse[i2+1]][0]-
- fe_q_other->unit_support_points[index_map_inverse_other[j2+1]][0])
- < 1e-14))
- identities.push_back (std::make_pair(i1*(p-1)+i2,
- j1*(q-1)+j2));
+ for (unsigned int i2=0; i2<p-1; ++i2)
+ for (unsigned int j1=0; j1<q-1; ++j1)
+ for (unsigned int j2=0; j2<q-1; ++j2)
+ if ((std::fabs(this->unit_support_points[index_map_inverse[i1+1]][0]-
+ fe_q_other->unit_support_points[index_map_inverse_other[j1+1]][0])
+ < 1e-14)
+ &&
+ (std::fabs(this->unit_support_points[index_map_inverse[i2+1]][0]-
+ fe_q_other->unit_support_points[index_map_inverse_other[j2+1]][0])
+ < 1e-14))
+ identities.push_back (std::make_pair(i1*(p-1)+i2,
+ j1*(q-1)+j2));
return identities;
}
else if (dynamic_cast<const FE_Nothing<dim>*>(&fe_other) != 0)
{
- // the FE_Nothing has no
- // degrees of freedom, so there
- // are no equivalencies to be
- // recorded
+ // the FE_Nothing has no
+ // degrees of freedom, so there
+ // are no equivalencies to be
+ // recorded
return std::vector<std::pair<unsigned int, unsigned int> > ();
}
else
= dynamic_cast<const FE_Q<dim,spacedim>*>(&fe_other))
{
if (this->degree < fe_q_other->degree)
- return FiniteElementDomination::this_element_dominates;
+ return FiniteElementDomination::this_element_dominates;
else if (this->degree == fe_q_other->degree)
- return FiniteElementDomination::either_element_can_dominate;
+ return FiniteElementDomination::either_element_can_dominate;
else
- return FiniteElementDomination::other_element_dominates;
+ return FiniteElementDomination::other_element_dominates;
}
else if (dynamic_cast<const FE_Nothing<dim>*>(&fe_other) != 0)
{
- // the FE_Nothing has no
- // degrees of freedom and it is
- // typically used in a context
- // where we don't require any
- // continuity along the
- // interface
+ // the FE_Nothing has no
+ // degrees of freedom and it is
+ // typically used in a context
+ // where we don't require any
+ // continuity along the
+ // interface
return FiniteElementDomination::no_requirements;
}
template <int dim, int spacedim>
void FE_Q<dim,spacedim>::initialize_unit_support_points ()
{
- // number of points: (degree+1)^dim
+ // number of points: (degree+1)^dim
unsigned int n = this->degree+1;
for (unsigned int i=1; i<dim; ++i)
n *= this->degree+1;
for (unsigned int iz=0; iz <= ((dim>2) ? this->degree : 0) ; ++iz)
for (unsigned int iy=0; iy <= ((dim>1) ? this->degree : 0) ; ++iy)
for (unsigned int ix=0; ix<=this->degree; ++ix)
- {
- p(0) = ix * step;
- if (dim>1)
- p(1) = iy * step;
- if (dim>2)
- p(2) = iz * step;
-
- this->unit_support_points[index_map_inverse[k++]] = p;
- }
+ {
+ p(0) = ix * step;
+ if (dim>1)
+ p(1) = iy * step;
+ if (dim>2)
+ p(2) = iz * step;
+
+ this->unit_support_points[index_map_inverse[k++]] = p;
+ }
}
template <int dim, int spacedim>
void FE_Q<dim,spacedim>::initialize_unit_support_points (const Quadrature<1> &points)
{
- // number of points: (degree+1)^dim
+ // number of points: (degree+1)^dim
unsigned int n = this->degree+1;
for (unsigned int i=1; i<dim; ++i)
n *= this->degree+1;
template <>
void FE_Q<1>::initialize_unit_face_support_points ()
{
- // no faces in 1d, so nothing to do
+ // no faces in 1d, so nothing to do
}
template <>
void FE_Q<1>::initialize_unit_face_support_points (const Quadrature<1> &/*points*/)
{
- // no faces in 1d, so nothing to do
+ // no faces in 1d, so nothing to do
}
template <>
void FE_Q<1,2>::initialize_unit_face_support_points ()
{
- // no faces in 1d, so nothing to do
+ // no faces in 1d, so nothing to do
}
template <>
void FE_Q<1,2>::initialize_unit_face_support_points (const Quadrature<1> &/*points*/)
{
- // no faces in 1d, so nothing to do
+ // no faces in 1d, so nothing to do
}
template <>
void FE_Q<1,3>::initialize_unit_face_support_points ()
{
- // no faces in 1d, so nothing to do
+ // no faces in 1d, so nothing to do
}
template <>
void FE_Q<1,3>::initialize_unit_face_support_points (const Quadrature<1> &/*points*/)
{
- // no faces in 1d, so nothing to do
+ // no faces in 1d, so nothing to do
}
template <int dim, int spacedim>
{
const unsigned int codim = dim-1;
- // number of points: (degree+1)^codim
+ // number of points: (degree+1)^codim
unsigned int n = this->degree+1;
for (unsigned int i=1; i<codim; ++i)
n *= this->degree+1;
for (unsigned int iz=0; iz <= ((codim>2) ? this->degree : 0) ; ++iz)
for (unsigned int iy=0; iy <= ((codim>1) ? this->degree : 0) ; ++iy)
for (unsigned int ix=0; ix<=this->degree; ++ix)
- {
- p(0) = ix * step;
- if (codim>1)
- p(1) = iy * step;
- if (codim>2)
- p(2) = iz * step;
-
- this->unit_face_support_points[face_index_map_inverse[k++]] = p;
- }
+ {
+ p(0) = ix * step;
+ if (codim>1)
+ p(1) = iy * step;
+ if (codim>2)
+ p(2) = iz * step;
+
+ this->unit_face_support_points[face_index_map_inverse[k++]] = p;
+ }
}
{
const unsigned int codim = dim-1;
- // number of points: (degree+1)^codim
+ // number of points: (degree+1)^codim
unsigned int n = this->degree+1;
for (unsigned int i=1; i<codim; ++i)
n *= this->degree+1;
for (unsigned int iz=0; iz <= ((codim>2) ? this->degree : 0) ; ++iz)
for (unsigned int iy=0; iy <= ((codim>1) ? this->degree : 0) ; ++iy)
for (unsigned int ix=0; ix<=this->degree; ++ix)
- {
- p(0) = edge[ix](0);
- if (codim>1)
- p(1) = edge[iy](0);
- if (codim>2)
- p(2) = edge[iz](0);
-
- this->unit_face_support_points[face_index_map_inverse[k++]] = p;
- }
+ {
+ p(0) = edge[ix](0);
+ if (codim>1)
+ p(1) = edge[iy](0);
+ if (codim>2)
+ p(2) = edge[iz](0);
+
+ this->unit_face_support_points[face_index_map_inverse[k++]] = p;
+ }
}
void
FE_Q<dim,spacedim>::initialize_quad_dof_index_permutation ()
{
- // general template for 1D and 2D, do nothing
+ // general template for 1D and 2D, do nothing
}
FE_Q<3>::initialize_quad_dof_index_permutation ()
{
Assert (adjust_quad_dof_index_for_face_orientation_table.n_elements()==8*this->dofs_per_quad,
- ExcInternalError());
+ ExcInternalError());
const unsigned int n=this->degree-1;
Assert(n*n==this->dofs_per_quad, ExcInternalError());
- // alias for the table to fill
+ // alias for the table to fill
Table<2,int> &data=this->adjust_quad_dof_index_for_face_orientation_table;
- // the dofs on a face are connected to a n x
- // n matrix. for example, for degree==4 we
- // have the following dofs on a quad
-
- // ___________
- // | |
- // | 6 7 8 |
- // | |
- // | 3 4 5 |
- // | |
- // | 0 1 2 |
- // |___________|
- //
- // we have dof_no=i+n*j with index i in
- // x-direction and index j in y-direction
- // running from 0 to n-1. to extract i and j
- // we can use i=dof_no%n and j=dof_no/n. i
- // and j can then be used to construct the
- // rotated and mirrored numbers.
+ // the dofs on a face are connected to a n x
+ // n matrix. for example, for degree==4 we
+ // have the following dofs on a quad
+
+ // ___________
+ // | |
+ // | 6 7 8 |
+ // | |
+ // | 3 4 5 |
+ // | |
+ // | 0 1 2 |
+ // |___________|
+ //
+ // we have dof_no=i+n*j with index i in
+ // x-direction and index j in y-direction
+ // running from 0 to n-1. to extract i and j
+ // we can use i=dof_no%n and j=dof_no/n. i
+ // and j can then be used to construct the
+ // rotated and mirrored numbers.
for (unsigned int local=0; local<this->dofs_per_quad; ++local)
- // face support points are in lexicographic
- // ordering with x running fastest. invert
- // that (y running fastest)
+ // face support points are in lexicographic
+ // ordering with x running fastest. invert
+ // that (y running fastest)
{
unsigned int i=local%n,
- j=local/n;
+ j=local/n;
- // face_orientation=false, face_flip=false, face_rotation=false
+ // face_orientation=false, face_flip=false, face_rotation=false
data(local,0)=j + i *n - local;
- // face_orientation=false, face_flip=false, face_rotation=true
+ // face_orientation=false, face_flip=false, face_rotation=true
data(local,1)=i + (n-1-j)*n - local;
- // face_orientation=false, face_flip=true, face_rotation=false
+ // face_orientation=false, face_flip=true, face_rotation=false
data(local,2)=(n-1-j) + (n-1-i)*n - local;
- // face_orientation=false, face_flip=true, face_rotation=true
+ // face_orientation=false, face_flip=true, face_rotation=true
data(local,3)=(n-1-i) + j *n - local;
- // face_orientation=true, face_flip=false, face_rotation=false
+ // face_orientation=true, face_flip=false, face_rotation=false
data(local,4)=0;
- // face_orientation=true, face_flip=false, face_rotation=true
+ // face_orientation=true, face_flip=false, face_rotation=true
data(local,5)=j + (n-1-i)*n - local;
- // face_orientation=true, face_flip=true, face_rotation=false
+ // face_orientation=true, face_flip=true, face_rotation=false
data(local,6)=(n-1-i) + (n-1-j)*n - local;
- // face_orientation=true, face_flip=true, face_rotation=true
+ // face_orientation=true, face_flip=true, face_rotation=true
data(local,7)=(n-1-j) + i *n - local;
}
- // aditionally initialize reordering of line
- // dofs
+ // aditionally initialize reordering of line
+ // dofs
for (unsigned int i=0; i<this->dofs_per_line; ++i)
this->adjust_line_dof_index_for_line_orientation_table[i]=this->dofs_per_line-1-i - i;
}
void
FE_Q<dim,spacedim>::initialize_embedding ()
{
- // compute the interpolation matrices in
- // much the same way as we do for the
- // constraints. it's actually simpler
- // here, since we don't have this weird
- // renumbering stuff going on. The trick
- // is again that we the interpolation
- // matrix is formed by a permutation of
- // the indices of the cell matrix. The
- // value eps is used a threshold to
- // decide when certain evaluations of the
- // Lagrange polynomials are zero or one.
+ // compute the interpolation matrices in
+ // much the same way as we do for the
+ // constraints. it's actually simpler
+ // here, since we don't have this weird
+ // renumbering stuff going on. The trick
+ // is again that we the interpolation
+ // matrix is formed by a permutation of
+ // the indices of the cell matrix. The
+ // value eps is used a threshold to
+ // decide when certain evaluations of the
+ // Lagrange polynomials are zero or one.
const double eps = 1e-15*this->degree*dim;
#ifdef DEBUG
- // in DEBUG mode, check that the evaluation of
- // support points in the current numbering
- // gives the identity operation
+ // in DEBUG mode, check that the evaluation of
+ // support points in the current numbering
+ // gives the identity operation
for (unsigned int i=0; i<this->dofs_per_cell; ++i)
{
Assert (std::fabs (1.-this->poly_space.compute_value
- (i, this->unit_support_points[i])) < eps,
- ExcInternalError());
+ (i, this->unit_support_points[i])) < eps,
+ ExcInternalError());
for (unsigned int j=0; j<this->dofs_per_cell; ++j)
- if (j!=i)
- Assert (std::fabs (this->poly_space.compute_value
- (i, this->unit_support_points[j])) < eps,
- ExcInternalError());
+ if (j!=i)
+ Assert (std::fabs (this->poly_space.compute_value
+ (i, this->unit_support_points[j])) < eps,
+ ExcInternalError());
}
#endif
- // to efficiently evaluate the polynomial at
- // the subcell, make use of the tensor product
- // structure of this element and only evaluate
- // 1D information from the polynomial. This
- // makes the cost of this function almost
- // negligible also for high order elements
+ // to efficiently evaluate the polynomial at
+ // the subcell, make use of the tensor product
+ // structure of this element and only evaluate
+ // 1D information from the polynomial. This
+ // makes the cost of this function almost
+ // negligible also for high order elements
const unsigned int dofs1d = this->degree+1;
std::vector<Table<2,double> >
subcell_evaluations (dim, Table<2,double>(dofs1d, dofs1d));
const std::vector<unsigned int> &index_map_inverse =
this->poly_space.get_numbering_inverse();
- // recreate 1D polynomials
+ // recreate 1D polynomials
std::vector<Polynomials::Polynomial<double> > poly_space1d =
FE_Q_Helper::generate_poly_space1d (this->unit_support_points,
index_map_inverse, dofs1d);
- // helper value: step size how to walk through
- // diagonal and how many points we have left
- // apart from the first dimension
+ // helper value: step size how to walk through
+ // diagonal and how many points we have left
+ // apart from the first dimension
unsigned int step_size_diag = 0;
{
unsigned int factor = 1;
for (unsigned int d=0; d<dim; ++d)
{
- step_size_diag += factor;
- factor *= dofs1d;
+ step_size_diag += factor;
+ factor *= dofs1d;
}
}
- // next evaluate the functions
- // for the different refinement
- // cases.
+ // next evaluate the functions
+ // for the different refinement
+ // cases.
for (unsigned int ref=0; ref<RefinementCase<dim>::isotropic_refinement; ++ref)
for (unsigned int child=0; child<GeometryInfo<dim>::n_children(RefinementCase<dim>(ref+1)); ++child)
{
- // go through the points in diagonal to
- // capture variation in all directions
- // simultaneously
- for (unsigned int j=0; j<dofs1d; ++j)
- {
- const unsigned int diag_comp = index_map_inverse[j*step_size_diag];
- const Point<dim> p_subcell = this->unit_support_points[diag_comp];
- const Point<dim> p_cell =
- GeometryInfo<dim>::child_to_cell_coordinates (p_subcell, child,
- RefinementCase<dim>(ref+1));
- for (unsigned int i=0; i<dofs1d; ++i)
- for (unsigned int d=0; d<dim; ++d)
- {
- const double cell_value = poly_space1d[i].value (p_cell[d]);
-
- // cut off values that are too
- // small. note that we have here Lagrange
- // interpolation functions, so they
- // should be zero at almost all points,
- // and one at the others, at least on the
- // subcells. so set them to their exact
- // values
- //
- // the actual cut-off value is somewhat
- // fuzzy, but it works for
- // 2e-13*degree*dim (see above), which
- // is kind of reasonable given that we
- // compute the values of the polynomials
- // via an degree-step recursion and then
- // multiply the 1d-values. this gives us
- // a linear growth in degree*dim, times a
- // small constant.
- //
- // the embedding matrix is given by
- // applying the inverse of the subcell
- // matrix on the cell_interpolation
- // matrix. since the subcell matrix is
- // actually only a permutation vector,
- // all we need to do is to switch the
- // rows we write the data into. moreover,
- // cut off very small values here
- if (std::fabs(cell_value) < eps)
- subcell_evaluations[d](j,i) = 0;
- else
- subcell_evaluations[d](j,i) = cell_value;
- }
- }
-
- // now expand from 1D info. block innermost
- // dimension (x_0) in order to avoid difficult
- // checks at innermost loop
- unsigned int j_indices[dim];
- FE_Q_Helper::zero_indices<dim> (j_indices);
- for (unsigned int j=0; j<this->dofs_per_cell; j+=dofs1d)
- {
- unsigned int i_indices[dim];
- FE_Q_Helper::zero_indices<dim> (i_indices);
- for (unsigned int i=0; i<this->dofs_per_cell; i+=dofs1d)
- {
- double val_extra_dim = 1.;
- for (unsigned int d=1; d<dim; ++d)
- val_extra_dim *= subcell_evaluations[d](j_indices[d-1],
- i_indices[d-1]);
-
- // innermost sum where we actually
- // compute. the same as
- // this->prolongation[ref][child](j,i) =
- // this->poly_space.compute_value (i, p_cell);
- for (unsigned int jj=0; jj<dofs1d; ++jj)
- {
- const unsigned int j_ind = index_map_inverse[j+jj];
- for (unsigned int ii=0; ii<dofs1d; ++ii)
- this->prolongation[ref][child](j_ind,index_map_inverse[i+ii])
- = val_extra_dim * subcell_evaluations[0](jj,ii);
- }
-
- // update indices that denote the tensor
- // product position. a bit fuzzy and therefore
- // not done for innermost x_0 direction
- FE_Q_Helper::increment_indices<dim> (i_indices, dofs1d);
- }
- Assert (i_indices[dim-1] == 1, ExcInternalError());
- FE_Q_Helper::increment_indices<dim> (j_indices, dofs1d);
- }
-
- // and make sure that the row sum is
- // 1. this must be so since for this
- // element, the shape functions add up to
- // one
+ // go through the points in diagonal to
+ // capture variation in all directions
+ // simultaneously
+ for (unsigned int j=0; j<dofs1d; ++j)
+ {
+ const unsigned int diag_comp = index_map_inverse[j*step_size_diag];
+ const Point<dim> p_subcell = this->unit_support_points[diag_comp];
+ const Point<dim> p_cell =
+ GeometryInfo<dim>::child_to_cell_coordinates (p_subcell, child,
+ RefinementCase<dim>(ref+1));
+ for (unsigned int i=0; i<dofs1d; ++i)
+ for (unsigned int d=0; d<dim; ++d)
+ {
+ const double cell_value = poly_space1d[i].value (p_cell[d]);
+
+ // cut off values that are too
+ // small. note that we have here Lagrange
+ // interpolation functions, so they
+ // should be zero at almost all points,
+ // and one at the others, at least on the
+ // subcells. so set them to their exact
+ // values
+ //
+ // the actual cut-off value is somewhat
+ // fuzzy, but it works for
+ // 2e-13*degree*dim (see above), which
+ // is kind of reasonable given that we
+ // compute the values of the polynomials
+ // via an degree-step recursion and then
+ // multiply the 1d-values. this gives us
+ // a linear growth in degree*dim, times a
+ // small constant.
+ //
+ // the embedding matrix is given by
+ // applying the inverse of the subcell
+ // matrix on the cell_interpolation
+ // matrix. since the subcell matrix is
+ // actually only a permutation vector,
+ // all we need to do is to switch the
+ // rows we write the data into. moreover,
+ // cut off very small values here
+ if (std::fabs(cell_value) < eps)
+ subcell_evaluations[d](j,i) = 0;
+ else
+ subcell_evaluations[d](j,i) = cell_value;
+ }
+ }
+
+ // now expand from 1D info. block innermost
+ // dimension (x_0) in order to avoid difficult
+ // checks at innermost loop
+ unsigned int j_indices[dim];
+ FE_Q_Helper::zero_indices<dim> (j_indices);
+ for (unsigned int j=0; j<this->dofs_per_cell; j+=dofs1d)
+ {
+ unsigned int i_indices[dim];
+ FE_Q_Helper::zero_indices<dim> (i_indices);
+ for (unsigned int i=0; i<this->dofs_per_cell; i+=dofs1d)
+ {
+ double val_extra_dim = 1.;
+ for (unsigned int d=1; d<dim; ++d)
+ val_extra_dim *= subcell_evaluations[d](j_indices[d-1],
+ i_indices[d-1]);
+
+ // innermost sum where we actually
+ // compute. the same as
+ // this->prolongation[ref][child](j,i) =
+ // this->poly_space.compute_value (i, p_cell);
+ for (unsigned int jj=0; jj<dofs1d; ++jj)
+ {
+ const unsigned int j_ind = index_map_inverse[j+jj];
+ for (unsigned int ii=0; ii<dofs1d; ++ii)
+ this->prolongation[ref][child](j_ind,index_map_inverse[i+ii])
+ = val_extra_dim * subcell_evaluations[0](jj,ii);
+ }
+
+ // update indices that denote the tensor
+ // product position. a bit fuzzy and therefore
+ // not done for innermost x_0 direction
+ FE_Q_Helper::increment_indices<dim> (i_indices, dofs1d);
+ }
+ Assert (i_indices[dim-1] == 1, ExcInternalError());
+ FE_Q_Helper::increment_indices<dim> (j_indices, dofs1d);
+ }
+
+ // and make sure that the row sum is
+ // 1. this must be so since for this
+ // element, the shape functions add up to
+ // one
#ifdef DEBUG
- for (unsigned int row=0; row<this->dofs_per_cell; ++row)
- {
- double sum = 0;
- for (unsigned int col=0; col<this->dofs_per_cell; ++col)
- sum += this->prolongation[ref][child](row,col);
- Assert (std::fabs(sum-1.) < eps, ExcInternalError());
- }
+ for (unsigned int row=0; row<this->dofs_per_cell; ++row)
+ {
+ double sum = 0;
+ for (unsigned int col=0; col<this->dofs_per_cell; ++col)
+ sum += this->prolongation[ref][child](row,col);
+ Assert (std::fabs(sum-1.) < eps, ExcInternalError());
+ }
#endif
}
}
const std::vector<unsigned int> &index_map_inverse =
this->poly_space.get_numbering_inverse();
- // recreate 1D polynomials for faster
- // evaluation of polynomial
+ // recreate 1D polynomials for faster
+ // evaluation of polynomial
const unsigned int dofs1d = this->degree+1;
std::vector<Polynomials::Polynomial<double> > poly_space1d =
FE_Q_Helper::generate_poly_space1d (this->unit_support_points,
// which the interpolation
// point is located
for (unsigned int ref=RefinementCase<dim>::cut_x; ref<=RefinementCase<dim>::isotropic_refinement; ++ref)
- for (unsigned int child=0; child<GeometryInfo<dim>::n_children(RefinementCase<dim>(ref)); ++child)
- {
- // check whether this
- // interpolation point is
- // inside this child cell
- const Point<dim> p_subcell
- = GeometryInfo<dim>::cell_to_child_coordinates (p_cell, child, RefinementCase<dim>(ref));
- if (GeometryInfo<dim>::is_inside_unit_cell (p_subcell))
- {
- // same logic as in initialize_embedding to
- // evaluate the polynomial faster than from
- // the tensor product: since we evaluate all
- // polynomials, it is much faster to just
- // compute the 1D values for all polynomials
- // before and then get the dim-data.
- for (unsigned int j=0; j<dofs1d; ++j)
- for (unsigned int d=0; d<dim; ++d)
- evaluations1d[j][d] = poly_space1d[j].value (p_subcell[d]);
- unsigned int j_indices[dim];
- FE_Q_Helper::zero_indices<dim> (j_indices);
- double sum_check = 0;
- for (unsigned int j = 0; j<this->dofs_per_cell; j += dofs1d)
- {
- double val_extra_dim = 1.;
- for (unsigned int d=1; d<dim; ++d)
- val_extra_dim *= evaluations1d[j_indices[d-1]][d];
- for (unsigned int jj=0; jj<dofs1d; ++jj)
- {
-
- // find the child shape
- // function(s) corresponding
- // to this point. Usually
- // this is just one function;
- // however, when we use FE_Q
- // on arbitrary nodes a
- // parent support point might
- // not be a child support
- // point, and then we will
- // get more than one nonzero
- // value per row. Still, the
- // values should sum up to 1
- const double val
- = val_extra_dim * evaluations1d[jj][0];
- const unsigned int child_dof =
- index_map_inverse[j+jj];
- if (std::fabs (val-1.) < eps)
- this->restriction[ref-1][child](mother_dof,child_dof)=1.;
- else if(std::fabs(val) > eps)
- this->restriction[ref-1][child](mother_dof,child_dof)=val;
- sum_check += val;
- }
- FE_Q_Helper::increment_indices<dim> (j_indices, dofs1d);
- }
- Assert (std::fabs(sum_check-1) < eps,
- ExcInternalError());
- }
- }
+ for (unsigned int child=0; child<GeometryInfo<dim>::n_children(RefinementCase<dim>(ref)); ++child)
+ {
+ // check whether this
+ // interpolation point is
+ // inside this child cell
+ const Point<dim> p_subcell
+ = GeometryInfo<dim>::cell_to_child_coordinates (p_cell, child, RefinementCase<dim>(ref));
+ if (GeometryInfo<dim>::is_inside_unit_cell (p_subcell))
+ {
+ // same logic as in initialize_embedding to
+ // evaluate the polynomial faster than from
+ // the tensor product: since we evaluate all
+ // polynomials, it is much faster to just
+ // compute the 1D values for all polynomials
+ // before and then get the dim-data.
+ for (unsigned int j=0; j<dofs1d; ++j)
+ for (unsigned int d=0; d<dim; ++d)
+ evaluations1d[j][d] = poly_space1d[j].value (p_subcell[d]);
+ unsigned int j_indices[dim];
+ FE_Q_Helper::zero_indices<dim> (j_indices);
+ double sum_check = 0;
+ for (unsigned int j = 0; j<this->dofs_per_cell; j += dofs1d)
+ {
+ double val_extra_dim = 1.;
+ for (unsigned int d=1; d<dim; ++d)
+ val_extra_dim *= evaluations1d[j_indices[d-1]][d];
+ for (unsigned int jj=0; jj<dofs1d; ++jj)
+ {
+
+ // find the child shape
+ // function(s) corresponding
+ // to this point. Usually
+ // this is just one function;
+ // however, when we use FE_Q
+ // on arbitrary nodes a
+ // parent support point might
+ // not be a child support
+ // point, and then we will
+ // get more than one nonzero
+ // value per row. Still, the
+ // values should sum up to 1
+ const double val
+ = val_extra_dim * evaluations1d[jj][0];
+ const unsigned int child_dof =
+ index_map_inverse[j+jj];
+ if (std::fabs (val-1.) < eps)
+ this->restriction[ref-1][child](mother_dof,child_dof)=1.;
+ else if(std::fabs(val) > eps)
+ this->restriction[ref-1][child](mother_dof,child_dof)=val;
+ sum_check += val;
+ }
+ FE_Q_Helper::increment_indices<dim> (j_indices, dofs1d);
+ }
+ Assert (std::fabs(sum_check-1) < eps,
+ ExcInternalError());
+ }
+ }
}
}
const unsigned int face_index) const
{
Assert (shape_index < this->dofs_per_cell,
- ExcIndexRange (shape_index, 0, this->dofs_per_cell));
+ ExcIndexRange (shape_index, 0, this->dofs_per_cell));
Assert (face_index < GeometryInfo<1>::faces_per_cell,
- ExcIndexRange (face_index, 0, GeometryInfo<1>::faces_per_cell));
+ ExcIndexRange (face_index, 0, GeometryInfo<1>::faces_per_cell));
- // in 1d, things are simple. since
- // there is only one degree of
- // freedom per vertex in this
- // class, the first is on vertex 0
- // (==face 0 in some sense), the
- // second on face 1:
+ // in 1d, things are simple. since
+ // there is only one degree of
+ // freedom per vertex in this
+ // class, the first is on vertex 0
+ // (==face 0 in some sense), the
+ // second on face 1:
return (((shape_index == 0) && (face_index == 0)) ||
((shape_index == 1) && (face_index == 1)));
}
const unsigned int face_index) const
{
Assert (shape_index < this->dofs_per_cell,
- ExcIndexRange (shape_index, 0, this->dofs_per_cell));
+ ExcIndexRange (shape_index, 0, this->dofs_per_cell));
Assert (face_index < GeometryInfo<1>::faces_per_cell,
- ExcIndexRange (face_index, 0, GeometryInfo<1>::faces_per_cell));
+ ExcIndexRange (face_index, 0, GeometryInfo<1>::faces_per_cell));
- // in 1d, things are simple. since
- // there is only one degree of
- // freedom per vertex in this
- // class, the first is on vertex 0
- // (==face 0 in some sense), the
- // second on face 1:
+ // in 1d, things are simple. since
+ // there is only one degree of
+ // freedom per vertex in this
+ // class, the first is on vertex 0
+ // (==face 0 in some sense), the
+ // second on face 1:
return (((shape_index == 0) && (face_index == 0)) ||
((shape_index == 1) && (face_index == 1)));
}
const unsigned int face_index) const
{
Assert (shape_index < this->dofs_per_cell,
- ExcIndexRange (shape_index, 0, this->dofs_per_cell));
+ ExcIndexRange (shape_index, 0, this->dofs_per_cell));
Assert (face_index < GeometryInfo<1>::faces_per_cell,
- ExcIndexRange (face_index, 0, GeometryInfo<1>::faces_per_cell));
+ ExcIndexRange (face_index, 0, GeometryInfo<1>::faces_per_cell));
- // in 1d, things are simple. since
- // there is only one degree of
- // freedom per vertex in this
- // class, the first is on vertex 0
- // (==face 0 in some sense), the
- // second on face 1:
+ // in 1d, things are simple. since
+ // there is only one degree of
+ // freedom per vertex in this
+ // class, the first is on vertex 0
+ // (==face 0 in some sense), the
+ // second on face 1:
return (((shape_index == 0) && (face_index == 0)) ||
((shape_index == 1) && (face_index == 1)));
}
template <int dim, int spacedim>
bool
FE_Q<dim,spacedim>::has_support_on_face (const unsigned int shape_index,
- const unsigned int face_index) const
+ const unsigned int face_index) const
{
Assert (shape_index < this->dofs_per_cell,
- ExcIndexRange (shape_index, 0, this->dofs_per_cell));
+ ExcIndexRange (shape_index, 0, this->dofs_per_cell));
Assert (face_index < GeometryInfo<dim>::faces_per_cell,
- ExcIndexRange (face_index, 0, GeometryInfo<dim>::faces_per_cell));
+ ExcIndexRange (face_index, 0, GeometryInfo<dim>::faces_per_cell));
// first, special-case interior
// $Id$
// Version: $Name$
//
-// Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2010, 2011 by the deal.II authors
+// Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2010, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
template <int dim>
FE_Q_Hierarchical<dim>::FE_Q_Hierarchical (const unsigned int degree)
- :
- FE_Poly<TensorProductPolynomials<dim>, dim> (
- Polynomials::Hierarchical::generate_complete_basis(degree),
- FiniteElementData<dim>(get_dpo_vector(degree),1, degree,
- FiniteElementData<dim>::H1),
- std::vector<bool> (FiniteElementData<dim>(
- get_dpo_vector(degree),1, degree).dofs_per_cell, false),
- std::vector<std::vector<bool> >(FiniteElementData<dim>(
- get_dpo_vector(degree),1, degree).dofs_per_cell, std::vector<bool>(1,true))),
- face_renumber(face_fe_q_hierarchical_to_hierarchic_numbering (degree))
+ :
+ FE_Poly<TensorProductPolynomials<dim>, dim> (
+ Polynomials::Hierarchical::generate_complete_basis(degree),
+ FiniteElementData<dim>(get_dpo_vector(degree),1, degree,
+ FiniteElementData<dim>::H1),
+ std::vector<bool> (FiniteElementData<dim>(
+ get_dpo_vector(degree),1, degree).dofs_per_cell, false),
+ std::vector<std::vector<bool> >(FiniteElementData<dim>(
+ get_dpo_vector(degree),1, degree).dofs_per_cell, std::vector<bool>(1,true))),
+ face_renumber(face_fe_q_hierarchical_to_hierarchic_numbering (degree))
{
this->poly_space.set_numbering(
hierarchic_to_fe_q_hierarchical_numbering(*this));
- // The matrix @p{dofs_cell} contains the
- // values of the linear functionals of
- // the master 1d cell applied to the
- // shape functions of the two 1d subcells.
- // The matrix @p{dofs_subcell} constains
- // the values of the linear functionals
- // on each 1d subcell applied to the
- // shape functions on the master 1d
- // subcell.
- // We use @p{dofs_cell} and
- // @p{dofs_subcell} to compute the
- // @p{prolongation}, @p{restriction} and
- // @p{interface_constraints} matrices
- // for all dimensions.
+ // The matrix @p{dofs_cell} contains the
+ // values of the linear functionals of
+ // the master 1d cell applied to the
+ // shape functions of the two 1d subcells.
+ // The matrix @p{dofs_subcell} constains
+ // the values of the linear functionals
+ // on each 1d subcell applied to the
+ // shape functions on the master 1d
+ // subcell.
+ // We use @p{dofs_cell} and
+ // @p{dofs_subcell} to compute the
+ // @p{prolongation}, @p{restriction} and
+ // @p{interface_constraints} matrices
+ // for all dimensions.
std::vector<FullMatrix<double> >
dofs_cell (GeometryInfo<1>::max_children_per_cell,
- FullMatrix<double> (2*this->dofs_per_vertex + this->dofs_per_line,
- 2*this->dofs_per_vertex + this->dofs_per_line));
+ FullMatrix<double> (2*this->dofs_per_vertex + this->dofs_per_line,
+ 2*this->dofs_per_vertex + this->dofs_per_line));
std::vector<FullMatrix<double> >
dofs_subcell (GeometryInfo<1>::max_children_per_cell,
- FullMatrix<double> (2*this->dofs_per_vertex + this->dofs_per_line,
- 2*this->dofs_per_vertex + this->dofs_per_line));
- // build these fields, as they are
- // needed as auxiliary fields later
- // on
+ FullMatrix<double> (2*this->dofs_per_vertex + this->dofs_per_line,
+ 2*this->dofs_per_vertex + this->dofs_per_line));
+ // build these fields, as they are
+ // needed as auxiliary fields later
+ // on
build_dofs_cell (dofs_cell, dofs_subcell);
- // then use them to initialize
- // other fields
+ // then use them to initialize
+ // other fields
initialize_constraints (dofs_subcell);
initialize_embedding_and_restriction (dofs_cell, dofs_subcell);
- // finally fill in support points
- // on cell and face
+ // finally fill in support points
+ // on cell and face
initialize_unit_support_points ();
initialize_unit_face_support_points ();
}
std::string
FE_Q_Hierarchical<dim>::get_name () const
{
- // note that the
- // FETools::get_fe_from_name
- // function depends on the
- // particular format of the string
- // this function returns, so they
- // have to be kept in synch
+ // note that the
+ // FETools::get_fe_from_name
+ // function depends on the
+ // particular format of the string
+ // this function returns, so they
+ // have to be kept in synch
std::ostringstream namebuf;
namebuf << "FE_Q_Hierarchical<" << dim << ">(" << this->degree << ")";
FE_Q_Hierarchical<dim>::
hp_vertex_dof_identities (const FiniteElement<dim> &fe_other) const
{
- // we can presently only compute
- // these identities if both FEs are
- // FE_Q_Hierarchicals or if the other
- // one is an FE_Nothing. in the first
- // case, there should be exactly one
- // single DoF of each FE at a
- // vertex, and they should have
- // identical value
+ // we can presently only compute
+ // these identities if both FEs are
+ // FE_Q_Hierarchicals or if the other
+ // one is an FE_Nothing. in the first
+ // case, there should be exactly one
+ // single DoF of each FE at a
+ // vertex, and they should have
+ // identical value
if (dynamic_cast<const FE_Q_Hierarchical<dim>*>(&fe_other) != 0)
{
return
- std::vector<std::pair<unsigned int, unsigned int> >
- (1, std::make_pair (0U, 0U));
+ std::vector<std::pair<unsigned int, unsigned int> >
+ (1, std::make_pair (0U, 0U));
}
else if (dynamic_cast<const FE_Nothing<dim>*>(&fe_other) != 0)
{
- // the FE_Nothing has no
- // degrees of freedom, so there
- // are no equivalencies to be
- // recorded
+ // the FE_Nothing has no
+ // degrees of freedom, so there
+ // are no equivalencies to be
+ // recorded
return std::vector<std::pair<unsigned int, unsigned int> > ();
}
else
= dynamic_cast<const FE_Q_Hierarchical<dim>*>(&fe_other))
{
if (this->degree < fe_q_other->degree)
- return FiniteElementDomination::this_element_dominates;
+ return FiniteElementDomination::this_element_dominates;
else if (this->degree == fe_q_other->degree)
- return FiniteElementDomination::either_element_can_dominate;
+ return FiniteElementDomination::either_element_can_dominate;
else
- return FiniteElementDomination::other_element_dominates;
+ return FiniteElementDomination::other_element_dominates;
}
else if (dynamic_cast<const FE_Nothing<dim>*>(&fe_other) != 0)
{
- // the FE_Nothing has no
- // degrees of freedom and it is
- // typically used in a context
- // where we don't require any
- // continuity along the
- // interface
+ // the FE_Nothing has no
+ // degrees of freedom and it is
+ // typically used in a context
+ // where we don't require any
+ // continuity along the
+ // interface
return FiniteElementDomination::no_requirements;
}
template <int dim>
void
FE_Q_Hierarchical<dim>::build_dofs_cell (std::vector<FullMatrix<double> > &dofs_cell,
- std::vector<FullMatrix<double> > &dofs_subcell) const
+ std::vector<FullMatrix<double> > &dofs_subcell) const
{
const unsigned int dofs_1d = 2*this->dofs_per_vertex + this->dofs_per_line;
for (unsigned int c=0; c<GeometryInfo<1>::max_children_per_cell; ++c)
for (unsigned int j=0; j<dofs_1d; ++j)
for (unsigned int k=0; k<dofs_1d; ++k)
- {
- // upper diagonal block
- if ((j<=1) && (k<=1))
- {
- if (((c==0) && (j==0) && (k==0)) ||
- ((c==1) && (j==1) && (k==1)))
- dofs_cell[c](j,k) = 1.;
- else
- dofs_cell[c](j,k) = 0.;
-
- if (((c==0) && (j==1)) || ((c==1) && (j==0)))
- dofs_subcell[c](j,k) = .5;
- else if (((c==0) && (k==0)) || ((c==1) && (k==1)))
- dofs_subcell[c](j,k) = 1.;
- else
- dofs_subcell[c](j,k) = 0.;
- }
- // upper right block
- else if ((j<=1) && (k>=2))
- {
- if (((c==0) && (j==1) && ((k % 2)==0)) ||
- ((c==1) && (j==0) && ((k % 2)==0)))
- dofs_subcell[c](j,k) = -1.;
- }
- // lower diagonal block
- else if ((j>=2) && (k>=2) && (j<=k))
- {
- double factor = 1.;
- for (unsigned int i=1; i<=j;++i)
- factor *= ((double) (k-i+1))/((double) i);
- if (c==0)
- {
- dofs_subcell[c](j,k) = ((k+j) % 2 == 0) ?
- std::pow(.5,static_cast<double>(k))*factor :
- -std::pow(.5,static_cast<double>(k))*factor;
- dofs_cell[c](j,k) = std::pow(2.,static_cast<double>(j))*factor;
- }
- else
- {
- dofs_subcell[c](j,k) = std::pow(.5,static_cast<double>(k))*factor;
- dofs_cell[c](j,k) = ((k+j) % 2 == 0) ?
- std::pow(2.,static_cast<double>(j))*factor :
- -std::pow(2.,static_cast<double>(j))*factor;
- }
- }
- }
+ {
+ // upper diagonal block
+ if ((j<=1) && (k<=1))
+ {
+ if (((c==0) && (j==0) && (k==0)) ||
+ ((c==1) && (j==1) && (k==1)))
+ dofs_cell[c](j,k) = 1.;
+ else
+ dofs_cell[c](j,k) = 0.;
+
+ if (((c==0) && (j==1)) || ((c==1) && (j==0)))
+ dofs_subcell[c](j,k) = .5;
+ else if (((c==0) && (k==0)) || ((c==1) && (k==1)))
+ dofs_subcell[c](j,k) = 1.;
+ else
+ dofs_subcell[c](j,k) = 0.;
+ }
+ // upper right block
+ else if ((j<=1) && (k>=2))
+ {
+ if (((c==0) && (j==1) && ((k % 2)==0)) ||
+ ((c==1) && (j==0) && ((k % 2)==0)))
+ dofs_subcell[c](j,k) = -1.;
+ }
+ // lower diagonal block
+ else if ((j>=2) && (k>=2) && (j<=k))
+ {
+ double factor = 1.;
+ for (unsigned int i=1; i<=j;++i)
+ factor *= ((double) (k-i+1))/((double) i);
+ if (c==0)
+ {
+ dofs_subcell[c](j,k) = ((k+j) % 2 == 0) ?
+ std::pow(.5,static_cast<double>(k))*factor :
+ -std::pow(.5,static_cast<double>(k))*factor;
+ dofs_cell[c](j,k) = std::pow(2.,static_cast<double>(j))*factor;
+ }
+ else
+ {
+ dofs_subcell[c](j,k) = std::pow(.5,static_cast<double>(k))*factor;
+ dofs_cell[c](j,k) = ((k+j) % 2 == 0) ?
+ std::pow(2.,static_cast<double>(j))*factor :
+ -std::pow(2.,static_cast<double>(j))*factor;
+ }
+ }
+ }
}
{
case 1:
{
- // no constraints in 1d
- break;
+ // no constraints in 1d
+ break;
}
case 2:
{
- // vertex node
- for (unsigned int i=0; i<dofs_1d; ++i)
- this->interface_constraints(0,i) = dofs_subcell[0](1,i);
- // edge nodes
- for (unsigned int c=0; c<GeometryInfo<1>::max_children_per_cell; ++c)
- for (unsigned int i=0; i<dofs_1d; ++i)
- for (unsigned int j=2; j<dofs_1d; ++j)
- this->interface_constraints(1 + c*(degree-1) + j - 2,i) =
- dofs_subcell[c](j,i);
- break;
+ // vertex node
+ for (unsigned int i=0; i<dofs_1d; ++i)
+ this->interface_constraints(0,i) = dofs_subcell[0](1,i);
+ // edge nodes
+ for (unsigned int c=0; c<GeometryInfo<1>::max_children_per_cell; ++c)
+ for (unsigned int i=0; i<dofs_1d; ++i)
+ for (unsigned int j=2; j<dofs_1d; ++j)
+ this->interface_constraints(1 + c*(degree-1) + j - 2,i) =
+ dofs_subcell[c](j,i);
+ break;
}
case 3:
{
- for (unsigned int i=0; i<dofs_1d * dofs_1d; i++)
- {
- // center vertex node
- this->interface_constraints(0,face_renumber[i]) =
- dofs_subcell[0](1,i % dofs_1d) *
- dofs_subcell[0](1,(i - (i % dofs_1d)) / dofs_1d);
-
- // boundary vertex nodes
- this->interface_constraints(1,face_renumber[i]) =
- dofs_subcell[0](0, i % dofs_1d) *
- dofs_subcell[0](1, (i - (i % dofs_1d)) / dofs_1d);
- this->interface_constraints(2,face_renumber[i]) =
- dofs_subcell[1](1, i % dofs_1d) *
- dofs_subcell[0](1, (i - (i % dofs_1d)) / dofs_1d);
- this->interface_constraints(3,face_renumber[i]) =
- dofs_subcell[0](1, i % dofs_1d) *
- dofs_subcell[0](0, (i - (i % dofs_1d)) / dofs_1d);
- this->interface_constraints(4,face_renumber[i]) =
- dofs_subcell[1](0, i % dofs_1d) *
- dofs_subcell[1](1, (i - (i % dofs_1d)) / dofs_1d);
-
- // interior edges
- for (unsigned int j=0; j<(degree-1); j++)
- {
- this->interface_constraints(5 + j,face_renumber[i]) =
- dofs_subcell[0](1, i % dofs_1d) *
- dofs_subcell[0](2 + j, (i - (i % dofs_1d)) / dofs_1d);
- this->interface_constraints(5 + (degree-1) + j,face_renumber[i]) =
- dofs_subcell[0](1,i % dofs_1d) *
- dofs_subcell[1](2 + j, (i - (i % dofs_1d)) / dofs_1d);
- this->interface_constraints(5 + 2*(degree-1) + j,face_renumber[i]) =
- dofs_subcell[0](2 + j,i % dofs_1d) *
- dofs_subcell[1](0, (i - (i % dofs_1d)) / dofs_1d);
- this->interface_constraints(5 + 3*(degree-1) + j,face_renumber[i]) =
- dofs_subcell[1](2 + j, i % dofs_1d) *
- dofs_subcell[0](1, (i - (i % dofs_1d)) / dofs_1d);
- }
-
- // boundary edges
- for (unsigned int j=0; j<(degree-1); j++)
- {
- // left edge
- this->interface_constraints(5 + 4*(degree-1) + j,face_renumber[i]) =
- dofs_subcell[0](0, i % dofs_1d) *
- dofs_subcell[0](2 + j, (i - (i % dofs_1d)) / dofs_1d);
- this->interface_constraints(5 + 4*(degree-1) + (degree-1) + j,face_renumber[i]) =
- dofs_subcell[0](0, i % dofs_1d) *
- dofs_subcell[1](2 + j, (i - (i % dofs_1d)) / dofs_1d);
- // right edge
- this->interface_constraints(5 + 4*(degree-1) + 2*(degree-1) + j,face_renumber[i]) =
- dofs_subcell[1](1, i % dofs_1d) *
- dofs_subcell[0](2 + j, (i - (i % dofs_1d)) / dofs_1d);
- this->interface_constraints(5 + 4*(degree-1) + 3*(degree-1) + j,face_renumber[i]) =
- dofs_subcell[1](1, i % dofs_1d) *
- dofs_subcell[1](2 + j, (i - (i % dofs_1d)) / dofs_1d);
- // bottom edge
- this->interface_constraints(5 + 4*(degree-1) + 4*(degree-1) + j,face_renumber[i]) =
- dofs_subcell[0](2 + j, i % dofs_1d) *
- dofs_subcell[0](0, (i - (i % dofs_1d)) / dofs_1d);
- this->interface_constraints(5 + 4*(degree-1) + 5*(degree-1) + j,face_renumber[i]) =
- dofs_subcell[1](2 + j, i % dofs_1d) *
- dofs_subcell[0](0, (i - (i % dofs_1d)) / dofs_1d);
- // top edge
- this->interface_constraints(5 + 4*(degree-1) + 6*(degree-1) + j,face_renumber[i]) =
- dofs_subcell[0](2 + j, i % dofs_1d) *
- dofs_subcell[1](1, (i - (i % dofs_1d)) / dofs_1d);
- this->interface_constraints(5 + 4*(degree-1) + 7*(degree-1) + j,face_renumber[i]) =
- dofs_subcell[1](2 + j, i % dofs_1d) *
- dofs_subcell[1](1, (i - (i % dofs_1d)) / dofs_1d);
- }
-
- // interior faces
- for (unsigned int j=0; j<(degree-1); j++)
- for (unsigned int k=0; k<(degree-1); k++)
- {
- // subcell 0
- this->interface_constraints(5 + 12*(degree-1) + j + k*(degree-1),face_renumber[i]) =
- dofs_subcell[0](2 + j, i % dofs_1d) *
- dofs_subcell[0](2 + k, (i - (i % dofs_1d)) / dofs_1d);
- // subcell 1
- this->interface_constraints(5 + 12*(degree-1) + j + k*(degree-1) + (degree-1)*(degree-1),face_renumber[i]) =
- dofs_subcell[1](2 + j, i % dofs_1d) *
- dofs_subcell[0](2 + k, (i - (i % dofs_1d)) / dofs_1d);
- // subcell 2
- this->interface_constraints(5 + 12*(degree-1) + j + k*(degree-1) + 2*(degree-1)*(degree-1),face_renumber[i]) =
- dofs_subcell[0](2 + j, i % dofs_1d) *
- dofs_subcell[1](2 + k, (i - (i % dofs_1d)) / dofs_1d);
- // subcell 3
- this->interface_constraints(5 + 12*(degree-1) + j + k*(degree-1) + 3*(degree-1)*(degree-1),face_renumber[i]) =
- dofs_subcell[1](2 + j, i % dofs_1d) *
- dofs_subcell[1](2 + k, (i - (i % dofs_1d)) / dofs_1d);
- }
- }
- break;
+ for (unsigned int i=0; i<dofs_1d * dofs_1d; i++)
+ {
+ // center vertex node
+ this->interface_constraints(0,face_renumber[i]) =
+ dofs_subcell[0](1,i % dofs_1d) *
+ dofs_subcell[0](1,(i - (i % dofs_1d)) / dofs_1d);
+
+ // boundary vertex nodes
+ this->interface_constraints(1,face_renumber[i]) =
+ dofs_subcell[0](0, i % dofs_1d) *
+ dofs_subcell[0](1, (i - (i % dofs_1d)) / dofs_1d);
+ this->interface_constraints(2,face_renumber[i]) =
+ dofs_subcell[1](1, i % dofs_1d) *
+ dofs_subcell[0](1, (i - (i % dofs_1d)) / dofs_1d);
+ this->interface_constraints(3,face_renumber[i]) =
+ dofs_subcell[0](1, i % dofs_1d) *
+ dofs_subcell[0](0, (i - (i % dofs_1d)) / dofs_1d);
+ this->interface_constraints(4,face_renumber[i]) =
+ dofs_subcell[1](0, i % dofs_1d) *
+ dofs_subcell[1](1, (i - (i % dofs_1d)) / dofs_1d);
+
+ // interior edges
+ for (unsigned int j=0; j<(degree-1); j++)
+ {
+ this->interface_constraints(5 + j,face_renumber[i]) =
+ dofs_subcell[0](1, i % dofs_1d) *
+ dofs_subcell[0](2 + j, (i - (i % dofs_1d)) / dofs_1d);
+ this->interface_constraints(5 + (degree-1) + j,face_renumber[i]) =
+ dofs_subcell[0](1,i % dofs_1d) *
+ dofs_subcell[1](2 + j, (i - (i % dofs_1d)) / dofs_1d);
+ this->interface_constraints(5 + 2*(degree-1) + j,face_renumber[i]) =
+ dofs_subcell[0](2 + j,i % dofs_1d) *
+ dofs_subcell[1](0, (i - (i % dofs_1d)) / dofs_1d);
+ this->interface_constraints(5 + 3*(degree-1) + j,face_renumber[i]) =
+ dofs_subcell[1](2 + j, i % dofs_1d) *
+ dofs_subcell[0](1, (i - (i % dofs_1d)) / dofs_1d);
+ }
+
+ // boundary edges
+ for (unsigned int j=0; j<(degree-1); j++)
+ {
+ // left edge
+ this->interface_constraints(5 + 4*(degree-1) + j,face_renumber[i]) =
+ dofs_subcell[0](0, i % dofs_1d) *
+ dofs_subcell[0](2 + j, (i - (i % dofs_1d)) / dofs_1d);
+ this->interface_constraints(5 + 4*(degree-1) + (degree-1) + j,face_renumber[i]) =
+ dofs_subcell[0](0, i % dofs_1d) *
+ dofs_subcell[1](2 + j, (i - (i % dofs_1d)) / dofs_1d);
+ // right edge
+ this->interface_constraints(5 + 4*(degree-1) + 2*(degree-1) + j,face_renumber[i]) =
+ dofs_subcell[1](1, i % dofs_1d) *
+ dofs_subcell[0](2 + j, (i - (i % dofs_1d)) / dofs_1d);
+ this->interface_constraints(5 + 4*(degree-1) + 3*(degree-1) + j,face_renumber[i]) =
+ dofs_subcell[1](1, i % dofs_1d) *
+ dofs_subcell[1](2 + j, (i - (i % dofs_1d)) / dofs_1d);
+ // bottom edge
+ this->interface_constraints(5 + 4*(degree-1) + 4*(degree-1) + j,face_renumber[i]) =
+ dofs_subcell[0](2 + j, i % dofs_1d) *
+ dofs_subcell[0](0, (i - (i % dofs_1d)) / dofs_1d);
+ this->interface_constraints(5 + 4*(degree-1) + 5*(degree-1) + j,face_renumber[i]) =
+ dofs_subcell[1](2 + j, i % dofs_1d) *
+ dofs_subcell[0](0, (i - (i % dofs_1d)) / dofs_1d);
+ // top edge
+ this->interface_constraints(5 + 4*(degree-1) + 6*(degree-1) + j,face_renumber[i]) =
+ dofs_subcell[0](2 + j, i % dofs_1d) *
+ dofs_subcell[1](1, (i - (i % dofs_1d)) / dofs_1d);
+ this->interface_constraints(5 + 4*(degree-1) + 7*(degree-1) + j,face_renumber[i]) =
+ dofs_subcell[1](2 + j, i % dofs_1d) *
+ dofs_subcell[1](1, (i - (i % dofs_1d)) / dofs_1d);
+ }
+
+ // interior faces
+ for (unsigned int j=0; j<(degree-1); j++)
+ for (unsigned int k=0; k<(degree-1); k++)
+ {
+ // subcell 0
+ this->interface_constraints(5 + 12*(degree-1) + j + k*(degree-1),face_renumber[i]) =
+ dofs_subcell[0](2 + j, i % dofs_1d) *
+ dofs_subcell[0](2 + k, (i - (i % dofs_1d)) / dofs_1d);
+ // subcell 1
+ this->interface_constraints(5 + 12*(degree-1) + j + k*(degree-1) + (degree-1)*(degree-1),face_renumber[i]) =
+ dofs_subcell[1](2 + j, i % dofs_1d) *
+ dofs_subcell[0](2 + k, (i - (i % dofs_1d)) / dofs_1d);
+ // subcell 2
+ this->interface_constraints(5 + 12*(degree-1) + j + k*(degree-1) + 2*(degree-1)*(degree-1),face_renumber[i]) =
+ dofs_subcell[0](2 + j, i % dofs_1d) *
+ dofs_subcell[1](2 + k, (i - (i % dofs_1d)) / dofs_1d);
+ // subcell 3
+ this->interface_constraints(5 + 12*(degree-1) + j + k*(degree-1) + 3*(degree-1)*(degree-1),face_renumber[i]) =
+ dofs_subcell[1](2 + j, i % dofs_1d) *
+ dofs_subcell[1](2 + k, (i - (i % dofs_1d)) / dofs_1d);
+ }
+ }
+ break;
}
default:
- Assert (false, ExcNotImplemented());
+ Assert (false, ExcNotImplemented());
}
}
void
FE_Q_Hierarchical<dim>::
initialize_embedding_and_restriction (const std::vector<FullMatrix<double> > &dofs_cell,
- const std::vector<FullMatrix<double> > &dofs_subcell)
+ const std::vector<FullMatrix<double> > &dofs_subcell)
{
unsigned int iso=RefinementCase<dim>::isotropic_refinement-1;
this->restriction[iso][c].reinit (this->dofs_per_cell, this->dofs_per_cell);
}
- // the 1d case is particularly
- // simple, so special case it:
+ // the 1d case is particularly
+ // simple, so special case it:
if (dim==1)
{
for (unsigned int c=0; c<GeometryInfo<dim>::max_children_per_cell; ++c)
- {
- this->prolongation[iso][c].fill (dofs_subcell[c]);
- this->restriction[iso][c].fill (dofs_cell[c]);
- }
+ {
+ this->prolongation[iso][c].fill (dofs_subcell[c]);
+ this->restriction[iso][c].fill (dofs_cell[c]);
+ }
return;
}
- // for higher dimensions, things
- // are a little more tricky:
+ // for higher dimensions, things
+ // are a little more tricky:
- // j loops over dofs in the
- // subcell. These are the rows in
- // the embedding matrix.
- //
- // i loops over the dofs in the
- // master cell. These are the
- // columns in the embedding matrix.
+ // j loops over dofs in the
+ // subcell. These are the rows in
+ // the embedding matrix.
+ //
+ // i loops over the dofs in the
+ // master cell. These are the
+ // columns in the embedding matrix.
for (unsigned int j=0; j<this->dofs_per_cell; ++j)
for (unsigned int i=0; i<this->dofs_per_cell; ++i)
switch (dim)
- {
- case 2:
- {
- for (unsigned int c=0; c<GeometryInfo<2>::max_children_per_cell; ++c)
- {
- // left/right line: 0/1
- const unsigned int c0 = c%2;
- // bottom/top line: 0/1
- const unsigned int c1 = c/2;
-
- this->prolongation[iso][c](j,i) =
- dofs_subcell[c0](renumber[j] % dofs_1d,
- renumber[i] % dofs_1d) *
- dofs_subcell[c1]((renumber[j] - (renumber[j] % dofs_1d)) / dofs_1d,
- (renumber[i] - (renumber[i] % dofs_1d)) / dofs_1d);
-
- this->restriction[iso][c](j,i) =
- dofs_cell[c0](renumber[j] % dofs_1d,
- renumber[i] % dofs_1d) *
- dofs_cell[c1]((renumber[j] - (renumber[j] % dofs_1d)) / dofs_1d,
- (renumber[i] - (renumber[i] % dofs_1d)) / dofs_1d);
- }
- break;
- }
-
- case 3:
- {
- for (unsigned int c=0; c<GeometryInfo<3>::max_children_per_cell; ++c)
- {
- // left/right face: 0/1
- const unsigned int c0 = c%2;
- // front/back face: 0/1
- const unsigned int c1 = (c%4)/2;
- // bottom/top face: 0/1
- const unsigned int c2 = c/4;
-
- this->prolongation[iso][c](j,i) =
- dofs_subcell[c0](renumber[j] % dofs_1d,
- renumber[i] % dofs_1d) *
- dofs_subcell[c1](((renumber[j] - (renumber[j] % dofs_1d)) / dofs_1d) % dofs_1d,
- ((renumber[i] - (renumber[i] % dofs_1d)) / dofs_1d) % dofs_1d) *
- dofs_subcell[c2](((renumber[j] - (renumber[j] % dofs_1d)) / dofs_1d - (((renumber[j] - (renumber[j] % dofs_1d)) / dofs_1d ) % dofs_1d)) / dofs_1d,
- ((renumber[i] - (renumber[i] % dofs_1d)) / dofs_1d - (((renumber[i] - (renumber[i] % dofs_1d)) / dofs_1d ) % dofs_1d)) / dofs_1d);
-
- this->restriction[iso][c](j,i) =
- dofs_cell[c0](renumber[j] % dofs_1d,
- renumber[i] % dofs_1d) *
- dofs_cell[c1](((renumber[j] - (renumber[j] % dofs_1d)) / dofs_1d) % dofs_1d,
- ((renumber[i] - (renumber[i] % dofs_1d)) / dofs_1d) % dofs_1d) *
- dofs_cell[c2](((renumber[j] - (renumber[j] % dofs_1d)) / dofs_1d - (((renumber[j] - (renumber[j] % dofs_1d)) / dofs_1d ) % dofs_1d)) / dofs_1d,
- ((renumber[i] - (renumber[i] % dofs_1d)) / dofs_1d - (((renumber[i] - (renumber[i] % dofs_1d)) / dofs_1d ) % dofs_1d)) / dofs_1d);
- }
- break;
- }
-
- default:
- Assert (false, ExcNotImplemented());
- }
+ {
+ case 2:
+ {
+ for (unsigned int c=0; c<GeometryInfo<2>::max_children_per_cell; ++c)
+ {
+ // left/right line: 0/1
+ const unsigned int c0 = c%2;
+ // bottom/top line: 0/1
+ const unsigned int c1 = c/2;
+
+ this->prolongation[iso][c](j,i) =
+ dofs_subcell[c0](renumber[j] % dofs_1d,
+ renumber[i] % dofs_1d) *
+ dofs_subcell[c1]((renumber[j] - (renumber[j] % dofs_1d)) / dofs_1d,
+ (renumber[i] - (renumber[i] % dofs_1d)) / dofs_1d);
+
+ this->restriction[iso][c](j,i) =
+ dofs_cell[c0](renumber[j] % dofs_1d,
+ renumber[i] % dofs_1d) *
+ dofs_cell[c1]((renumber[j] - (renumber[j] % dofs_1d)) / dofs_1d,
+ (renumber[i] - (renumber[i] % dofs_1d)) / dofs_1d);
+ }
+ break;
+ }
+
+ case 3:
+ {
+ for (unsigned int c=0; c<GeometryInfo<3>::max_children_per_cell; ++c)
+ {
+ // left/right face: 0/1
+ const unsigned int c0 = c%2;
+ // front/back face: 0/1
+ const unsigned int c1 = (c%4)/2;
+ // bottom/top face: 0/1
+ const unsigned int c2 = c/4;
+
+ this->prolongation[iso][c](j,i) =
+ dofs_subcell[c0](renumber[j] % dofs_1d,
+ renumber[i] % dofs_1d) *
+ dofs_subcell[c1](((renumber[j] - (renumber[j] % dofs_1d)) / dofs_1d) % dofs_1d,
+ ((renumber[i] - (renumber[i] % dofs_1d)) / dofs_1d) % dofs_1d) *
+ dofs_subcell[c2](((renumber[j] - (renumber[j] % dofs_1d)) / dofs_1d - (((renumber[j] - (renumber[j] % dofs_1d)) / dofs_1d ) % dofs_1d)) / dofs_1d,
+ ((renumber[i] - (renumber[i] % dofs_1d)) / dofs_1d - (((renumber[i] - (renumber[i] % dofs_1d)) / dofs_1d ) % dofs_1d)) / dofs_1d);
+
+ this->restriction[iso][c](j,i) =
+ dofs_cell[c0](renumber[j] % dofs_1d,
+ renumber[i] % dofs_1d) *
+ dofs_cell[c1](((renumber[j] - (renumber[j] % dofs_1d)) / dofs_1d) % dofs_1d,
+ ((renumber[i] - (renumber[i] % dofs_1d)) / dofs_1d) % dofs_1d) *
+ dofs_cell[c2](((renumber[j] - (renumber[j] % dofs_1d)) / dofs_1d - (((renumber[j] - (renumber[j] % dofs_1d)) / dofs_1d ) % dofs_1d)) / dofs_1d,
+ ((renumber[i] - (renumber[i] % dofs_1d)) / dofs_1d - (((renumber[i] - (renumber[i] % dofs_1d)) / dofs_1d ) % dofs_1d)) / dofs_1d);
+ }
+ break;
+ }
+
+ default:
+ Assert (false, ExcNotImplemented());
+ }
}
template <int dim>
void FE_Q_Hierarchical<dim>::initialize_unit_support_points ()
{
- // number of points: (degree+1)^dim
+ // number of points: (degree+1)^dim
unsigned int n = this->degree+1;
for (unsigned int i=1; i<dim; ++i)
n *= this->degree+1;
for (unsigned int iz=0; iz <= ((dim>2) ? this->degree : 0) ; ++iz)
for (unsigned int iy=0; iy <= ((dim>1) ? this->degree : 0) ; ++iy)
for (unsigned int ix=0; ix<=this->degree; ++ix)
- {
- if (ix==0)
- p(0) = 0.;
- else if (ix==1)
- p(0) = 1.;
- else
- p(0) = .5;
- if (dim>1)
- {
- if (iy==0)
- p(1) = 0.;
- else if (iy==1)
- p(1) = 1.;
- else
- p(1) = .5;
- }
- if (dim>2)
- {
- if (iz==0)
- p(2) = 0.;
- else if (iz==1)
- p(2) = 1.;
- else
- p(2) = .5;
- }
- this->unit_support_points[index_map_inverse[k++]] = p;
- };
+ {
+ if (ix==0)
+ p(0) = 0.;
+ else if (ix==1)
+ p(0) = 1.;
+ else
+ p(0) = .5;
+ if (dim>1)
+ {
+ if (iy==0)
+ p(1) = 0.;
+ else if (iy==1)
+ p(1) = 1.;
+ else
+ p(1) = .5;
+ }
+ if (dim>2)
+ {
+ if (iz==0)
+ p(2) = 0.;
+ else if (iz==1)
+ p(2) = 1.;
+ else
+ p(2) = .5;
+ }
+ this->unit_support_points[index_map_inverse[k++]] = p;
+ };
}
template <>
void FE_Q_Hierarchical<1>::initialize_unit_face_support_points ()
{
- // no faces in 1d, so nothing to do
+ // no faces in 1d, so nothing to do
}
template <>
void FE_Q_Hierarchical<1>::
get_face_interpolation_matrix (const FiniteElement<1,1> &/*x_source_fe*/,
- FullMatrix<double> &/*interpolation_matrix*/) const
+ FullMatrix<double> &/*interpolation_matrix*/) const
{
Assert (false, ExcImpossibleInDim(1));
}
void
FE_Q_Hierarchical<1>::
get_subface_interpolation_matrix (const FiniteElement<1,1> &/*x_source_fe*/,
- const unsigned int /*subface*/,
- FullMatrix<double> &/*interpolation_matrix*/) const
+ const unsigned int /*subface*/,
+ FullMatrix<double> &/*interpolation_matrix*/) const
{
Assert (false, ExcImpossibleInDim(1));
}
void
FE_Q_Hierarchical<dim>::
get_face_interpolation_matrix (const FiniteElement<dim> &x_source_fe,
- FullMatrix<double> &interpolation_matrix) const
+ FullMatrix<double> &interpolation_matrix) const
{
- // this is only implemented, if the
- // source FE is also a
- // Q_Hierarchical element
+ // this is only implemented, if the
+ // source FE is also a
+ // Q_Hierarchical element
typedef FE_Q_Hierarchical<dim> FEQHierarchical;
typedef FiniteElement<dim> FEL;
AssertThrow ((x_source_fe.get_name().find ("FE_Q_Hierarchical<") == 0)
ExcInterpolationNotImplemented());
Assert (interpolation_matrix.n() == this->dofs_per_face,
- ExcDimensionMismatch (interpolation_matrix.n(),
- this->dofs_per_face));
+ ExcDimensionMismatch (interpolation_matrix.n(),
+ this->dofs_per_face));
Assert (interpolation_matrix.m() == x_source_fe.dofs_per_face,
- ExcDimensionMismatch (interpolation_matrix.m(),
- x_source_fe.dofs_per_face));
+ ExcDimensionMismatch (interpolation_matrix.m(),
+ x_source_fe.dofs_per_face));
- // ok, source is a Q_Hierarchical element, so
- // we will be able to do the work
+ // ok, source is a Q_Hierarchical element, so
+ // we will be able to do the work
const FE_Q_Hierarchical<dim> &source_fe
= dynamic_cast<const FE_Q_Hierarchical<dim>&>(x_source_fe);
- // Make sure, that the element,
+ // Make sure, that the element,
// for which the DoFs should be
// constrained is the one with
// the higher polynomial degree.
// also if this assertion is not
// satisfied. But the matrices
// produced in that case might
- // lead to problems in the
+ // lead to problems in the
// hp procedures, which use this
- // method.
+ // method.
Assert (this->dofs_per_face <= source_fe.dofs_per_face,
- typename FEL::
- ExcInterpolationNotImplemented ());
+ typename FEL::
+ ExcInterpolationNotImplemented ());
interpolation_matrix = 0;
switch (dim) {
case 2: {
for (unsigned int i = 0; i < this->dofs_per_face; ++i)
- interpolation_matrix (i, i) = 1;
+ interpolation_matrix (i, i) = 1;
break;
}
case 3: {
for (unsigned int i = 0; i < GeometryInfo<3>::vertices_per_face; ++i)
- interpolation_matrix (i, i) = 1;
+ interpolation_matrix (i, i) = 1;
for (unsigned int i = 0; i < this->degree - 1; ++i) {
- for (unsigned int j = 0; j < GeometryInfo<3>::lines_per_face; ++j)
- interpolation_matrix (
- i + j * (x_source_fe.degree - 1) + GeometryInfo<3>::vertices_per_face,
- i + j * (this->degree - 1) + GeometryInfo<3>::vertices_per_face) = 1;
-
- for (unsigned int j = 0; j < this->degree - 1; ++j)
- interpolation_matrix (
- (i + GeometryInfo<3>::lines_per_face) * (x_source_fe.degree - 1) + j
- + GeometryInfo<3>::vertices_per_face,
- (i + GeometryInfo<3>::lines_per_face) * (this->degree - 1) + j
- + GeometryInfo<3>::vertices_per_face) = 1;
+ for (unsigned int j = 0; j < GeometryInfo<3>::lines_per_face; ++j)
+ interpolation_matrix (
+ i + j * (x_source_fe.degree - 1) + GeometryInfo<3>::vertices_per_face,
+ i + j * (this->degree - 1) + GeometryInfo<3>::vertices_per_face) = 1;
+
+ for (unsigned int j = 0; j < this->degree - 1; ++j)
+ interpolation_matrix (
+ (i + GeometryInfo<3>::lines_per_face) * (x_source_fe.degree - 1) + j
+ + GeometryInfo<3>::vertices_per_face,
+ (i + GeometryInfo<3>::lines_per_face) * (this->degree - 1) + j
+ + GeometryInfo<3>::vertices_per_face) = 1;
}
}
}
void
FE_Q_Hierarchical<dim>::
get_subface_interpolation_matrix (const FiniteElement<dim> &x_source_fe,
- const unsigned int subface,
- FullMatrix<double> &interpolation_matrix) const
+ const unsigned int subface,
+ FullMatrix<double> &interpolation_matrix) const
{
- // this is only implemented, if the
- // source FE is also a
- // Q_Hierarchical element
+ // this is only implemented, if the
+ // source FE is also a
+ // Q_Hierarchical element
typedef FE_Q_Hierarchical<dim> FEQHierarchical;
typedef FiniteElement<dim> FEL;
AssertThrow ((x_source_fe.get_name().find ("FE_Q_Hierarchical<") == 0)
ExcInterpolationNotImplemented());
Assert (interpolation_matrix.n() == this->dofs_per_face,
- ExcDimensionMismatch (interpolation_matrix.n(),
- this->dofs_per_face));
+ ExcDimensionMismatch (interpolation_matrix.n(),
+ this->dofs_per_face));
Assert (interpolation_matrix.m() == x_source_fe.dofs_per_face,
- ExcDimensionMismatch (interpolation_matrix.m(),
- x_source_fe.dofs_per_face));
+ ExcDimensionMismatch (interpolation_matrix.m(),
+ x_source_fe.dofs_per_face));
- // ok, source is a Q_Hierarchical element, so
- // we will be able to do the work
+ // ok, source is a Q_Hierarchical element, so
+ // we will be able to do the work
const FE_Q_Hierarchical<dim> &source_fe
= dynamic_cast<const FE_Q_Hierarchical<dim>&>(x_source_fe);
- // Make sure, that the element,
+ // Make sure, that the element,
// for which the DoFs should be
// constrained is the one with
// the higher polynomial degree.
// also if this assertion is not
// satisfied. But the matrices
// produced in that case might
- // lead to problems in the
+ // lead to problems in the
// hp procedures, which use this
- // method.
+ // method.
Assert (this->dofs_per_face <= source_fe.dofs_per_face,
- typename FEL::
- ExcInterpolationNotImplemented ());
+ typename FEL::
+ ExcInterpolationNotImplemented ());
switch (dim)
{
case 2:
{
- switch (subface)
- {
- case 0:
- {
- interpolation_matrix (0, 0) = 1.0;
- interpolation_matrix (1, 0) = 0.5;
- interpolation_matrix (1, 1) = 0.5;
-
- for (unsigned int dof = 2; dof < this->dofs_per_face;)
- {
- interpolation_matrix (1, dof) = -1.0;
- dof = dof + 2;
- }
-
- int factorial_i = 1;
- int factorial_ij;
- int factorial_j;
-
- for (int i = 2; i < (int) this->dofs_per_face; ++i)
- {
- interpolation_matrix (i, i) = std::pow (0.5, i);
- factorial_i *= i;
- factorial_j = factorial_i;
- factorial_ij = 1;
-
- for (int j = i + 1; j < (int) this->dofs_per_face; ++j)
- {
- factorial_ij *= j - i;
- factorial_j *= j;
-
- if ((i + j) & 1)
- interpolation_matrix (i, j)
- = -1.0 * std::pow (0.5, j) *
- factorial_j / (factorial_i * factorial_ij);
-
- else
- interpolation_matrix (i, j)
- = std::pow (0.5, j) *
- factorial_j / (factorial_i * factorial_ij);
- }
- }
-
- break;
- }
-
- case 1:
- {
- interpolation_matrix (0, 0) = 0.5;
- interpolation_matrix (0, 1) = 0.5;
-
- for (unsigned int dof = 2; dof < this->dofs_per_face;)
- {
- interpolation_matrix (0, dof) = -1.0;
- dof = dof + 2;
- }
-
- interpolation_matrix (1, 1) = 1.0;
-
- int factorial_i = 1;
- int factorial_ij;
- int factorial_j;
-
- for (int i = 2; i < (int) this->dofs_per_face; ++i)
- {
- interpolation_matrix (i, i) = std::pow (0.5, i);
- factorial_i *= i;
- factorial_j = factorial_i;
- factorial_ij = 1;
-
- for (int j = i + 1; j < (int) this->dofs_per_face; ++j)
- {
- factorial_ij *= j - i;
- factorial_j *= j;
- interpolation_matrix (i, j)
- = std::pow (0.5, j) * factorial_j / (factorial_i * factorial_ij);
- }
- }
- }
- }
+ switch (subface)
+ {
+ case 0:
+ {
+ interpolation_matrix (0, 0) = 1.0;
+ interpolation_matrix (1, 0) = 0.5;
+ interpolation_matrix (1, 1) = 0.5;
+
+ for (unsigned int dof = 2; dof < this->dofs_per_face;)
+ {
+ interpolation_matrix (1, dof) = -1.0;
+ dof = dof + 2;
+ }
+
+ int factorial_i = 1;
+ int factorial_ij;
+ int factorial_j;
+
+ for (int i = 2; i < (int) this->dofs_per_face; ++i)
+ {
+ interpolation_matrix (i, i) = std::pow (0.5, i);
+ factorial_i *= i;
+ factorial_j = factorial_i;
+ factorial_ij = 1;
+
+ for (int j = i + 1; j < (int) this->dofs_per_face; ++j)
+ {
+ factorial_ij *= j - i;
+ factorial_j *= j;
+
+ if ((i + j) & 1)
+ interpolation_matrix (i, j)
+ = -1.0 * std::pow (0.5, j) *
+ factorial_j / (factorial_i * factorial_ij);
+
+ else
+ interpolation_matrix (i, j)
+ = std::pow (0.5, j) *
+ factorial_j / (factorial_i * factorial_ij);
+ }
+ }
+
+ break;
+ }
+
+ case 1:
+ {
+ interpolation_matrix (0, 0) = 0.5;
+ interpolation_matrix (0, 1) = 0.5;
+
+ for (unsigned int dof = 2; dof < this->dofs_per_face;)
+ {
+ interpolation_matrix (0, dof) = -1.0;
+ dof = dof + 2;
+ }
+
+ interpolation_matrix (1, 1) = 1.0;
+
+ int factorial_i = 1;
+ int factorial_ij;
+ int factorial_j;
+
+ for (int i = 2; i < (int) this->dofs_per_face; ++i)
+ {
+ interpolation_matrix (i, i) = std::pow (0.5, i);
+ factorial_i *= i;
+ factorial_j = factorial_i;
+ factorial_ij = 1;
+
+ for (int j = i + 1; j < (int) this->dofs_per_face; ++j)
+ {
+ factorial_ij *= j - i;
+ factorial_j *= j;
+ interpolation_matrix (i, j)
+ = std::pow (0.5, j) * factorial_j / (factorial_i * factorial_ij);
+ }
+ }
+ }
+ }
break;
}
case 3:
{
switch (subface)
- {
- case 0:
- {
+ {
+ case 0:
+ {
interpolation_matrix (0, 0) = 1.0;
interpolation_matrix (1, 0) = 0.5;
interpolation_matrix (1, 1) = 0.5;
interpolation_matrix (2, 0) = 0.5;
interpolation_matrix (2, 2) = 0.5;
- for (unsigned int i = 0; i < this->degree - 1;)
- {
- for (unsigned int line = 0; line < GeometryInfo<3>::lines_per_face; ++line)
- interpolation_matrix (3, i + line * (this->degree - 1) + 4) = -0.5;
-
- for (unsigned int j = 0; j < this->degree - 1;)
- {
- interpolation_matrix (3, i + (j + 4) * this->degree - j) = 1.0;
- j = j + 2;
- }
-
- interpolation_matrix (1, i + 2 * (this->degree + 1)) = -1.0;
- interpolation_matrix (2, i + 4) = -1.0;
- i = i + 2;
- }
-
- for (unsigned int vertex = 0; vertex < GeometryInfo<3>::vertices_per_face; ++vertex)
- interpolation_matrix (3, vertex) = 0.25;
-
- int factorial_i = 1;
- int factorial_ij;
- int factorial_j;
- int factorial_k;
- int factorial_kl;
- int factorial_l;
-
- for (int i = 2; i <= (int) this->degree; ++i)
- {
- double tmp = std::pow (0.5, i);
- interpolation_matrix (i + 2, i + 2) = tmp;
- interpolation_matrix (i + 2 * source_fe.degree, i + 2 * this->degree) = tmp;
- tmp *= 0.5;
- interpolation_matrix (i + source_fe.degree + 1, i + 2) = tmp;
- interpolation_matrix (i + source_fe.degree + 1, i + this->degree + 1) = tmp;
- interpolation_matrix (i + 3 * source_fe.degree - 1, i + 2 * this->degree) = tmp;
- interpolation_matrix (i + 3 * source_fe.degree - 1, i + 3 * this->degree - 1) = tmp;
- tmp *= -2.0;
-
- for (unsigned int j = 0; j < this->degree - 1;)
- {
- interpolation_matrix (i + source_fe.degree + 1, (i + 2) * this->degree + j + 2 - i) = tmp;
- interpolation_matrix (i + 3 * source_fe.degree - 1, i + (j + 4) * this->degree - j - 2) = tmp;
- j = j + 2;
- }
-
- factorial_k = 1;
-
- for (int j = 2; j <= (int) this->degree; ++j)
- {
- interpolation_matrix (i + (j + 2) * source_fe.degree - j, i + (j + 2) * this->degree - j) = std::pow (0.5, i + j);
- factorial_k *= j;
- factorial_kl = 1;
- factorial_l = factorial_k;
-
- for (int k = j + 1; k < (int) this->degree; ++k)
- {
- factorial_kl *= k - j;
- factorial_l *= k;
-
- if ((j + k) & 1)
- interpolation_matrix (i + (j + 2) * source_fe.degree - j, i + (k + 2) * this->degree - k) = -1.0 * std::pow (0.5, i + k) * factorial_l / (factorial_k * factorial_kl);
-
- else
- interpolation_matrix (i + (j + 2) * source_fe.degree - j, i + (k + 2) * this->degree - k) = std::pow (0.5, i + k) * factorial_l / (factorial_k * factorial_kl);
- }
- }
-
- factorial_i *= i;
- factorial_j = factorial_i;
- factorial_ij = 1;
-
- for (int j = i + 1; j <= (int) this->degree; ++j)
- {
- factorial_ij *= j - i;
- factorial_j *= j;
-
- if ((i + j) & 1)
- {
- tmp = -1.0 * std::pow (0.5, j) * factorial_j / (factorial_i * factorial_ij);
- interpolation_matrix (i + 2, j + 2) = tmp;
- interpolation_matrix (i + 2 * source_fe.degree, j + 2 * this->degree) = tmp;
- factorial_k = 1;
-
- for (int k = 2; k <= (int) this->degree; ++k)
- {
- interpolation_matrix (i + (k + 2) * source_fe.degree - k, j + (k + 2) * this->degree - k) = tmp * std::pow (0.5, k);
- factorial_k *= k;
- factorial_l = factorial_k;
- factorial_kl = 1;
-
- for (int l = k + 1; l <= (int) this->degree; ++l) {
- factorial_kl *= l - k;
- factorial_l *= l;
-
- if ((k + l) & 1)
- interpolation_matrix (i + (k + 2) * source_fe.degree - k, j + (l + 2) * this->degree - l) = -1.0 * tmp * std::pow (0.5, l) * factorial_l / (factorial_k * factorial_kl);
-
- else
- interpolation_matrix (i + (k + 2) * source_fe.degree - k, j + (l + 2) * this->degree - l) = tmp * std::pow (0.5, l) * factorial_l / (factorial_k * factorial_kl);
- }
- }
-
- tmp *= 0.5;
- interpolation_matrix (i + source_fe.degree + 1, j + 2) = tmp;
- interpolation_matrix (i + source_fe.degree + 1, j + this->degree + 1) = tmp;
- interpolation_matrix (i + 3 * source_fe.degree - 1, j + 2 * this->degree) = tmp;
- interpolation_matrix (i + 3 * source_fe.degree - 1, j + 3 * this->degree - 1) = tmp;
- tmp *= -2.0;
-
- for (unsigned int k = 0; k < this->degree - 1;)
- {
- interpolation_matrix (i + source_fe.degree + 1, (j + 2) * this->degree + k + 2 - j) = tmp;
- interpolation_matrix (i + 3 * source_fe.degree - 1, j + (k + 4) * this->degree - k - 2) = tmp;
- k = k + 2;
- }
- }
- else
- {
- tmp = std::pow (0.5, j) * factorial_j / (factorial_i * factorial_ij);
- interpolation_matrix (i + 2, j + 2) = tmp;
- interpolation_matrix (i + 2 * source_fe.degree, j + 2 * this->degree) = tmp;
- factorial_k = 1;
-
- for (int k = 2; k <= (int) this->degree; ++k)
- {
- interpolation_matrix (i + (k + 2) * source_fe.degree - k, j + (k + 2) * this->degree - k) = tmp * std::pow (0.5, k);
- factorial_k *= k;
- factorial_l = factorial_k;
- factorial_kl = 1;
-
- for (int l = k + 1; l <= (int) this->degree; ++l)
- {
- factorial_kl *= l - k;
- factorial_l *= l;
-
- if ((k + l) & 1)
- interpolation_matrix (i + (k + 2) * source_fe.degree - k, j + (l + 2) * this->degree - l) = -1.0 * tmp * std::pow (0.5, l) * factorial_l / (factorial_k * factorial_kl);
-
- else
- interpolation_matrix (i + (k + 2) * source_fe.degree - k, j + (l + 2) * this->degree - l) = tmp * std::pow (0.5, l) * factorial_l / (factorial_k * factorial_kl);
- }
- }
-
- tmp *= 0.5;
- interpolation_matrix (i + source_fe.degree + 1, j + 2) = tmp;
- interpolation_matrix (i + source_fe.degree + 1, j + this->degree + 1) = tmp;
- interpolation_matrix (i + 3 * source_fe.degree - 1, j + 2 * this->degree) = tmp;
- interpolation_matrix (i + 3 * source_fe.degree - 1, j + 3 * this->degree - 1) = tmp;
- tmp *= -2.0;
-
- for (unsigned int k = 0; k < this->degree - 1;)
- {
- interpolation_matrix (i + source_fe.degree + 1, (j + 2) * this->degree + k + 2 - j) = tmp;
- interpolation_matrix (i + 3 * source_fe.degree - 1, j + (k + 4) * this->degree - k - 2) = tmp;
- k = k + 2;
- }
- }
- }
- }
+ for (unsigned int i = 0; i < this->degree - 1;)
+ {
+ for (unsigned int line = 0; line < GeometryInfo<3>::lines_per_face; ++line)
+ interpolation_matrix (3, i + line * (this->degree - 1) + 4) = -0.5;
+
+ for (unsigned int j = 0; j < this->degree - 1;)
+ {
+ interpolation_matrix (3, i + (j + 4) * this->degree - j) = 1.0;
+ j = j + 2;
+ }
+
+ interpolation_matrix (1, i + 2 * (this->degree + 1)) = -1.0;
+ interpolation_matrix (2, i + 4) = -1.0;
+ i = i + 2;
+ }
+
+ for (unsigned int vertex = 0; vertex < GeometryInfo<3>::vertices_per_face; ++vertex)
+ interpolation_matrix (3, vertex) = 0.25;
+
+ int factorial_i = 1;
+ int factorial_ij;
+ int factorial_j;
+ int factorial_k;
+ int factorial_kl;
+ int factorial_l;
+
+ for (int i = 2; i <= (int) this->degree; ++i)
+ {
+ double tmp = std::pow (0.5, i);
+ interpolation_matrix (i + 2, i + 2) = tmp;
+ interpolation_matrix (i + 2 * source_fe.degree, i + 2 * this->degree) = tmp;
+ tmp *= 0.5;
+ interpolation_matrix (i + source_fe.degree + 1, i + 2) = tmp;
+ interpolation_matrix (i + source_fe.degree + 1, i + this->degree + 1) = tmp;
+ interpolation_matrix (i + 3 * source_fe.degree - 1, i + 2 * this->degree) = tmp;
+ interpolation_matrix (i + 3 * source_fe.degree - 1, i + 3 * this->degree - 1) = tmp;
+ tmp *= -2.0;
+
+ for (unsigned int j = 0; j < this->degree - 1;)
+ {
+ interpolation_matrix (i + source_fe.degree + 1, (i + 2) * this->degree + j + 2 - i) = tmp;
+ interpolation_matrix (i + 3 * source_fe.degree - 1, i + (j + 4) * this->degree - j - 2) = tmp;
+ j = j + 2;
+ }
+
+ factorial_k = 1;
+
+ for (int j = 2; j <= (int) this->degree; ++j)
+ {
+ interpolation_matrix (i + (j + 2) * source_fe.degree - j, i + (j + 2) * this->degree - j) = std::pow (0.5, i + j);
+ factorial_k *= j;
+ factorial_kl = 1;
+ factorial_l = factorial_k;
+
+ for (int k = j + 1; k < (int) this->degree; ++k)
+ {
+ factorial_kl *= k - j;
+ factorial_l *= k;
+
+ if ((j + k) & 1)
+ interpolation_matrix (i + (j + 2) * source_fe.degree - j, i + (k + 2) * this->degree - k) = -1.0 * std::pow (0.5, i + k) * factorial_l / (factorial_k * factorial_kl);
+
+ else
+ interpolation_matrix (i + (j + 2) * source_fe.degree - j, i + (k + 2) * this->degree - k) = std::pow (0.5, i + k) * factorial_l / (factorial_k * factorial_kl);
+ }
+ }
+
+ factorial_i *= i;
+ factorial_j = factorial_i;
+ factorial_ij = 1;
+
+ for (int j = i + 1; j <= (int) this->degree; ++j)
+ {
+ factorial_ij *= j - i;
+ factorial_j *= j;
+
+ if ((i + j) & 1)
+ {
+ tmp = -1.0 * std::pow (0.5, j) * factorial_j / (factorial_i * factorial_ij);
+ interpolation_matrix (i + 2, j + 2) = tmp;
+ interpolation_matrix (i + 2 * source_fe.degree, j + 2 * this->degree) = tmp;
+ factorial_k = 1;
+
+ for (int k = 2; k <= (int) this->degree; ++k)
+ {
+ interpolation_matrix (i + (k + 2) * source_fe.degree - k, j + (k + 2) * this->degree - k) = tmp * std::pow (0.5, k);
+ factorial_k *= k;
+ factorial_l = factorial_k;
+ factorial_kl = 1;
+
+ for (int l = k + 1; l <= (int) this->degree; ++l) {
+ factorial_kl *= l - k;
+ factorial_l *= l;
+
+ if ((k + l) & 1)
+ interpolation_matrix (i + (k + 2) * source_fe.degree - k, j + (l + 2) * this->degree - l) = -1.0 * tmp * std::pow (0.5, l) * factorial_l / (factorial_k * factorial_kl);
+
+ else
+ interpolation_matrix (i + (k + 2) * source_fe.degree - k, j + (l + 2) * this->degree - l) = tmp * std::pow (0.5, l) * factorial_l / (factorial_k * factorial_kl);
+ }
+ }
+
+ tmp *= 0.5;
+ interpolation_matrix (i + source_fe.degree + 1, j + 2) = tmp;
+ interpolation_matrix (i + source_fe.degree + 1, j + this->degree + 1) = tmp;
+ interpolation_matrix (i + 3 * source_fe.degree - 1, j + 2 * this->degree) = tmp;
+ interpolation_matrix (i + 3 * source_fe.degree - 1, j + 3 * this->degree - 1) = tmp;
+ tmp *= -2.0;
+
+ for (unsigned int k = 0; k < this->degree - 1;)
+ {
+ interpolation_matrix (i + source_fe.degree + 1, (j + 2) * this->degree + k + 2 - j) = tmp;
+ interpolation_matrix (i + 3 * source_fe.degree - 1, j + (k + 4) * this->degree - k - 2) = tmp;
+ k = k + 2;
+ }
+ }
+ else
+ {
+ tmp = std::pow (0.5, j) * factorial_j / (factorial_i * factorial_ij);
+ interpolation_matrix (i + 2, j + 2) = tmp;
+ interpolation_matrix (i + 2 * source_fe.degree, j + 2 * this->degree) = tmp;
+ factorial_k = 1;
+
+ for (int k = 2; k <= (int) this->degree; ++k)
+ {
+ interpolation_matrix (i + (k + 2) * source_fe.degree - k, j + (k + 2) * this->degree - k) = tmp * std::pow (0.5, k);
+ factorial_k *= k;
+ factorial_l = factorial_k;
+ factorial_kl = 1;
+
+ for (int l = k + 1; l <= (int) this->degree; ++l)
+ {
+ factorial_kl *= l - k;
+ factorial_l *= l;
+
+ if ((k + l) & 1)
+ interpolation_matrix (i + (k + 2) * source_fe.degree - k, j + (l + 2) * this->degree - l) = -1.0 * tmp * std::pow (0.5, l) * factorial_l / (factorial_k * factorial_kl);
+
+ else
+ interpolation_matrix (i + (k + 2) * source_fe.degree - k, j + (l + 2) * this->degree - l) = tmp * std::pow (0.5, l) * factorial_l / (factorial_k * factorial_kl);
+ }
+ }
+
+ tmp *= 0.5;
+ interpolation_matrix (i + source_fe.degree + 1, j + 2) = tmp;
+ interpolation_matrix (i + source_fe.degree + 1, j + this->degree + 1) = tmp;
+ interpolation_matrix (i + 3 * source_fe.degree - 1, j + 2 * this->degree) = tmp;
+ interpolation_matrix (i + 3 * source_fe.degree - 1, j + 3 * this->degree - 1) = tmp;
+ tmp *= -2.0;
+
+ for (unsigned int k = 0; k < this->degree - 1;)
+ {
+ interpolation_matrix (i + source_fe.degree + 1, (j + 2) * this->degree + k + 2 - j) = tmp;
+ interpolation_matrix (i + 3 * source_fe.degree - 1, j + (k + 4) * this->degree - k - 2) = tmp;
+ k = k + 2;
+ }
+ }
+ }
+ }
break;
- }
-
- case 1:
- {
- interpolation_matrix (0, 0) = 0.5;
- interpolation_matrix (0, 1) = 0.5;
- interpolation_matrix (1, 1) = 1.0;
- interpolation_matrix (3, 1) = 0.5;
- interpolation_matrix (3, 3) = 0.5;
-
- for (unsigned int i = 0; i < this->degree - 1;)
- {
- for (unsigned int line = 0; line < GeometryInfo<3>::lines_per_face; ++line)
- interpolation_matrix (2, i + line * (this->degree - 1) + 4) = -0.5;
-
- for (unsigned int j = 0; j < this->degree - 1;)
- {
- interpolation_matrix (2, i + (j + 4) * this->degree - j) = 1.0;
- j = j + 2;
- }
-
- interpolation_matrix (0, i + 2 * (this->degree + 1)) = -1.0;
- interpolation_matrix (3, i + this->degree + 3) = -1.0;
- i = i + 2;
- }
-
- for (unsigned int vertex = 0; vertex < GeometryInfo<3>::vertices_per_face; ++vertex)
- interpolation_matrix (2, vertex) = 0.25;
-
- int factorial_i = 1;
- int factorial_ij;
- int factorial_j;
- int factorial_k;
- int factorial_kl;
- int factorial_l;
-
- for (int i = 2; i <= (int) this->degree; ++i)
- {
- double tmp = std::pow (0.5, i + 1);
- interpolation_matrix (i + 2, i + 2) = tmp;
- interpolation_matrix (i + 2, i + this->degree + 1) = tmp;
- interpolation_matrix (i + 3 * source_fe.degree - 1, i + 2 * this->degree) = tmp;
- interpolation_matrix (i + 3 * source_fe.degree - 1, i + 3 * this->degree - 1) = tmp;
- tmp *= -2.0;
-
- for (unsigned int j = 0; j < this->degree - 1;)
- {
- interpolation_matrix (i + 2, j + (i + 2) * this->degree + 2 - i) = tmp;
- interpolation_matrix (i + 3 * source_fe.degree - 1, i + (j + 4) * this->degree - j - 2) = tmp;
- j = j + 2;
- }
-
- tmp *= - 1.0;
- interpolation_matrix (i + source_fe.degree + 1, i + this->degree + 1) = tmp;
- interpolation_matrix (i + 2 * source_fe.degree, i + 2 * this->degree) = tmp;
- factorial_i *= i;
- factorial_j = factorial_i;
- factorial_ij = 1;
-
- for (int j = i + 1; j <= (int) this->degree; ++j)
- {
- factorial_ij *= j - i;
- factorial_j *= j;
- tmp = std::pow (0.5, j) * factorial_j / (factorial_i * factorial_ij);
- interpolation_matrix (i + 2 * source_fe.degree, j + 2 * this->degree) = tmp;
- factorial_k = 1;
-
- for (int k = 2; k <= (int) this->degree; ++k)
- {
- interpolation_matrix (i + (k + 2) * source_fe.degree - k, j + (k + 2) * this->degree - k) = tmp * std::pow (0.5, k);
- factorial_k *= k;
- factorial_l = factorial_k;
- factorial_kl = 1;
-
- for (int l = k + 1; l <= (int) this->degree; ++l)
- {
- factorial_kl *= l - k;
- factorial_l *= l;
-
- if ((k + l) & 1)
- interpolation_matrix (i + (k + 2) * source_fe.degree - k, j + (l + 2) * this->degree - l) = -1.0 * tmp * std::pow (0.5, l) * factorial_l / (factorial_k * factorial_kl);
-
- else
- interpolation_matrix (i + (k + 2) * source_fe.degree - k, j + (l + 2) * this->degree - l) = tmp * std::pow (0.5, l) * factorial_l / (factorial_k * factorial_kl);
- }
- }
-
- tmp *= -1.0;
-
- for (unsigned int k = 0; k < this->degree - 1;)
- {
- interpolation_matrix (i + 3 * source_fe.degree - 1, j + (k + 4) * this->degree - k - 2) = tmp;
- k = k + 2;
- }
-
- tmp *= -0.5;
- interpolation_matrix (i + 3 * source_fe.degree - 1, j + 2 * this->degree) = tmp;
- interpolation_matrix (i + 3 * source_fe.degree - 1, j + 3 * this->degree - 1) = tmp;
-
- if ((i + j) & 1)
- tmp *= -1.0;
-
- interpolation_matrix (i + 2, j + 2) = tmp;
- interpolation_matrix (i + 2, j + this->degree + 1) = tmp;
- interpolation_matrix (i + source_fe.degree + 1, j + this->degree + 1) = 2.0 * tmp;
- tmp *= -2.0;
-
- for (unsigned int k = 0; k < this->degree - 1;)
- {
- interpolation_matrix (i + 2, k + (j + 2) * this->degree + 2 - j) = tmp;
- k = k + 2;
- }
- }
-
- factorial_k = 1;
-
- for (int j = 2; j <= (int) this->degree; ++j)
- {
- interpolation_matrix (i + (j + 2) * source_fe.degree - j, i + (j + 2) * this->degree - j) = std::pow (0.5, i + j);
- factorial_k *= j;
- factorial_l = factorial_k;
- factorial_kl = 1;
-
- for (int k = j + 1; k <= (int) this->degree; ++k)
- {
- factorial_kl *= k - j;
- factorial_l *= k;
-
- if ((j + k) & 1)
- interpolation_matrix (i + (j + 2) * source_fe.degree - j, i + (k + 2) * this->degree - k) = -1.0 * std::pow (0.5, i + k) * factorial_l / (factorial_k * factorial_kl);
-
- else
- interpolation_matrix (i + (j + 2) * source_fe.degree - j, i + (k + 2) * this->degree - k) = std::pow (0.5, i + k) * factorial_l / (factorial_k * factorial_kl);
- }
- }
- }
+ }
+
+ case 1:
+ {
+ interpolation_matrix (0, 0) = 0.5;
+ interpolation_matrix (0, 1) = 0.5;
+ interpolation_matrix (1, 1) = 1.0;
+ interpolation_matrix (3, 1) = 0.5;
+ interpolation_matrix (3, 3) = 0.5;
+
+ for (unsigned int i = 0; i < this->degree - 1;)
+ {
+ for (unsigned int line = 0; line < GeometryInfo<3>::lines_per_face; ++line)
+ interpolation_matrix (2, i + line * (this->degree - 1) + 4) = -0.5;
+
+ for (unsigned int j = 0; j < this->degree - 1;)
+ {
+ interpolation_matrix (2, i + (j + 4) * this->degree - j) = 1.0;
+ j = j + 2;
+ }
+
+ interpolation_matrix (0, i + 2 * (this->degree + 1)) = -1.0;
+ interpolation_matrix (3, i + this->degree + 3) = -1.0;
+ i = i + 2;
+ }
+
+ for (unsigned int vertex = 0; vertex < GeometryInfo<3>::vertices_per_face; ++vertex)
+ interpolation_matrix (2, vertex) = 0.25;
+
+ int factorial_i = 1;
+ int factorial_ij;
+ int factorial_j;
+ int factorial_k;
+ int factorial_kl;
+ int factorial_l;
+
+ for (int i = 2; i <= (int) this->degree; ++i)
+ {
+ double tmp = std::pow (0.5, i + 1);
+ interpolation_matrix (i + 2, i + 2) = tmp;
+ interpolation_matrix (i + 2, i + this->degree + 1) = tmp;
+ interpolation_matrix (i + 3 * source_fe.degree - 1, i + 2 * this->degree) = tmp;
+ interpolation_matrix (i + 3 * source_fe.degree - 1, i + 3 * this->degree - 1) = tmp;
+ tmp *= -2.0;
+
+ for (unsigned int j = 0; j < this->degree - 1;)
+ {
+ interpolation_matrix (i + 2, j + (i + 2) * this->degree + 2 - i) = tmp;
+ interpolation_matrix (i + 3 * source_fe.degree - 1, i + (j + 4) * this->degree - j - 2) = tmp;
+ j = j + 2;
+ }
+
+ tmp *= - 1.0;
+ interpolation_matrix (i + source_fe.degree + 1, i + this->degree + 1) = tmp;
+ interpolation_matrix (i + 2 * source_fe.degree, i + 2 * this->degree) = tmp;
+ factorial_i *= i;
+ factorial_j = factorial_i;
+ factorial_ij = 1;
+
+ for (int j = i + 1; j <= (int) this->degree; ++j)
+ {
+ factorial_ij *= j - i;
+ factorial_j *= j;
+ tmp = std::pow (0.5, j) * factorial_j / (factorial_i * factorial_ij);
+ interpolation_matrix (i + 2 * source_fe.degree, j + 2 * this->degree) = tmp;
+ factorial_k = 1;
+
+ for (int k = 2; k <= (int) this->degree; ++k)
+ {
+ interpolation_matrix (i + (k + 2) * source_fe.degree - k, j + (k + 2) * this->degree - k) = tmp * std::pow (0.5, k);
+ factorial_k *= k;
+ factorial_l = factorial_k;
+ factorial_kl = 1;
+
+ for (int l = k + 1; l <= (int) this->degree; ++l)
+ {
+ factorial_kl *= l - k;
+ factorial_l *= l;
+
+ if ((k + l) & 1)
+ interpolation_matrix (i + (k + 2) * source_fe.degree - k, j + (l + 2) * this->degree - l) = -1.0 * tmp * std::pow (0.5, l) * factorial_l / (factorial_k * factorial_kl);
+
+ else
+ interpolation_matrix (i + (k + 2) * source_fe.degree - k, j + (l + 2) * this->degree - l) = tmp * std::pow (0.5, l) * factorial_l / (factorial_k * factorial_kl);
+ }
+ }
+
+ tmp *= -1.0;
+
+ for (unsigned int k = 0; k < this->degree - 1;)
+ {
+ interpolation_matrix (i + 3 * source_fe.degree - 1, j + (k + 4) * this->degree - k - 2) = tmp;
+ k = k + 2;
+ }
+
+ tmp *= -0.5;
+ interpolation_matrix (i + 3 * source_fe.degree - 1, j + 2 * this->degree) = tmp;
+ interpolation_matrix (i + 3 * source_fe.degree - 1, j + 3 * this->degree - 1) = tmp;
+
+ if ((i + j) & 1)
+ tmp *= -1.0;
+
+ interpolation_matrix (i + 2, j + 2) = tmp;
+ interpolation_matrix (i + 2, j + this->degree + 1) = tmp;
+ interpolation_matrix (i + source_fe.degree + 1, j + this->degree + 1) = 2.0 * tmp;
+ tmp *= -2.0;
+
+ for (unsigned int k = 0; k < this->degree - 1;)
+ {
+ interpolation_matrix (i + 2, k + (j + 2) * this->degree + 2 - j) = tmp;
+ k = k + 2;
+ }
+ }
+
+ factorial_k = 1;
+
+ for (int j = 2; j <= (int) this->degree; ++j)
+ {
+ interpolation_matrix (i + (j + 2) * source_fe.degree - j, i + (j + 2) * this->degree - j) = std::pow (0.5, i + j);
+ factorial_k *= j;
+ factorial_l = factorial_k;
+ factorial_kl = 1;
+
+ for (int k = j + 1; k <= (int) this->degree; ++k)
+ {
+ factorial_kl *= k - j;
+ factorial_l *= k;
+
+ if ((j + k) & 1)
+ interpolation_matrix (i + (j + 2) * source_fe.degree - j, i + (k + 2) * this->degree - k) = -1.0 * std::pow (0.5, i + k) * factorial_l / (factorial_k * factorial_kl);
+
+ else
+ interpolation_matrix (i + (j + 2) * source_fe.degree - j, i + (k + 2) * this->degree - k) = std::pow (0.5, i + k) * factorial_l / (factorial_k * factorial_kl);
+ }
+ }
+ }
break;
- }
+ }
- case 2:
- {
+ case 2:
+ {
interpolation_matrix (0, 0) = 0.5;
interpolation_matrix (0, 2) = 0.5;
interpolation_matrix (2, 2) = 1.0;
interpolation_matrix (3, 3) = 0.5;
for (unsigned int i = 0; i < this->degree - 1;)
- {
- for (unsigned int line = 0; line < GeometryInfo<3>::lines_per_face; ++line)
+ {
+ for (unsigned int line = 0; line < GeometryInfo<3>::lines_per_face; ++line)
interpolation_matrix (1, i + line * (this->degree - 1) + 4) = -0.5;
- for (unsigned int j = 0; j < this->degree - 1;)
- {
- interpolation_matrix (1, i + (j + 4) * this->degree - j) = 1.0;
- j = j + 2;
- }
+ for (unsigned int j = 0; j < this->degree - 1;)
+ {
+ interpolation_matrix (1, i + (j + 4) * this->degree - j) = 1.0;
+ j = j + 2;
+ }
- interpolation_matrix (0, i + 4) = -1.0;
- interpolation_matrix (3, i + 3 * this->degree + 1) = -1.0;
- i = i + 2;
- }
+ interpolation_matrix (0, i + 4) = -1.0;
+ interpolation_matrix (3, i + 3 * this->degree + 1) = -1.0;
+ i = i + 2;
+ }
for (unsigned int vertex = 0; vertex < GeometryInfo<3>::vertices_per_face; ++vertex)
- interpolation_matrix (1, vertex) = 0.25;
+ interpolation_matrix (1, vertex) = 0.25;
int factorial_i = 1;
int factorial_ij;
int factorial_l;
for (int i = 2; i <= (int) this->degree; ++i)
- {
- double tmp = std::pow (0.5, i);
- interpolation_matrix (i + 2, i + 2) = tmp;
- interpolation_matrix (i + 3 * source_fe.degree - 1, i + 3 * this->degree - 1) = tmp;
- tmp *= 0.5;
- interpolation_matrix (i + source_fe.degree + 1, i + 2) = tmp;
- interpolation_matrix (i + source_fe.degree + 1, i + this->degree + 1) = tmp;
- interpolation_matrix (i + 2 * source_fe.degree, i + 2 * this->degree) = tmp;
- interpolation_matrix (i + 2 * source_fe.degree, i + 3 * this->degree - 1) = tmp;
- tmp *= -2.0;
-
- for (unsigned int j = 0; j < this->degree - 1;)
- {
- interpolation_matrix (i + source_fe.degree + 1, j + (i + 2) * this->degree + 2 - i) = tmp;
- interpolation_matrix (i + 2 * source_fe.degree, i + (j + 4) * this->degree - j - 2) = tmp;
- j = j + 2;
- }
-
- factorial_k = 1;
-
- for (int j = 2; j <= (int) this->degree; ++j)
- {
- interpolation_matrix (i + (j + 2) * source_fe.degree - j, i + (j + 2) * this->degree - j) = std::pow (0.5, i + j);
- factorial_k *= j;
- factorial_l = factorial_k;
- factorial_kl = 1;
-
- for (int k = j + 1; k <= (int) this->degree; ++k)
- {
- factorial_kl *= k - j;
- factorial_l *= k;
- interpolation_matrix (i + (j + 2) * source_fe.degree - j, i + (k + 2) * this->degree - k) = std::pow (0.5, i + k) * factorial_l / (factorial_k * factorial_kl);
- }
- }
-
- factorial_i *= i;
- factorial_j = factorial_i;
- factorial_ij = 1;
-
- for (int j = i + 1; j <= (int) this->degree; ++j)
- {
- factorial_ij *= j - i;
- factorial_j *= j;
- tmp = std::pow (0.5, j) * factorial_j / (factorial_i * factorial_ij);
- interpolation_matrix (i + 2, j + 2) = tmp;
- tmp *= -1.0;
-
- for (unsigned int k = 0; k < this->degree - 1;)
- {
- interpolation_matrix (i + source_fe.degree + 1, k + (j + 2) * this->degree + 2 - j) = tmp;
- k = k + 2;
- }
-
- tmp *= -0.5;
- interpolation_matrix (i + source_fe.degree + 1, j + 2) = tmp;
- interpolation_matrix (i + source_fe.degree + 1, j + this->degree + 1) = tmp;
-
- if ((i + j) & 1)
- tmp *= -1.0;
-
- interpolation_matrix (i + 2 * source_fe.degree, j + 2 * this->degree) = tmp;
- interpolation_matrix (i + 2 * source_fe.degree, j + 3 * this->degree - 1) = tmp;
- tmp *= 2.0;
- interpolation_matrix (i + 3 * source_fe.degree - 1, j + 3 * this->degree - 1) = tmp;
- factorial_k = 1;
-
- for (int k = 2; k <= (int) this->degree; ++k)
- {
- interpolation_matrix (i + (k + 2) * source_fe.degree - k, j + (k + 2) * this->degree - k) = tmp * std::pow (0.5, k);
- factorial_k *= k;
- factorial_l = factorial_k;
- factorial_kl = 1;
-
- for (int l = k + 1; l <= (int) this->degree; ++l)
- {
- factorial_kl *= l - k;
- factorial_l *= l;
- interpolation_matrix (i + (k + 2) * source_fe.degree - k, j + (l + 2) * this->degree - l) = tmp * std::pow (0.5, l) * factorial_l / (factorial_k * factorial_kl);
- }
- }
-
- tmp *= -1.0;
-
- for (unsigned int k = 0; k < this->degree - 1;)
- {
- interpolation_matrix (i + 2 * source_fe.degree, j + (k + 4) * this->degree - k - 2) = tmp;
- k = k + 2;
- }
- }
- }
+ {
+ double tmp = std::pow (0.5, i);
+ interpolation_matrix (i + 2, i + 2) = tmp;
+ interpolation_matrix (i + 3 * source_fe.degree - 1, i + 3 * this->degree - 1) = tmp;
+ tmp *= 0.5;
+ interpolation_matrix (i + source_fe.degree + 1, i + 2) = tmp;
+ interpolation_matrix (i + source_fe.degree + 1, i + this->degree + 1) = tmp;
+ interpolation_matrix (i + 2 * source_fe.degree, i + 2 * this->degree) = tmp;
+ interpolation_matrix (i + 2 * source_fe.degree, i + 3 * this->degree - 1) = tmp;
+ tmp *= -2.0;
+
+ for (unsigned int j = 0; j < this->degree - 1;)
+ {
+ interpolation_matrix (i + source_fe.degree + 1, j + (i + 2) * this->degree + 2 - i) = tmp;
+ interpolation_matrix (i + 2 * source_fe.degree, i + (j + 4) * this->degree - j - 2) = tmp;
+ j = j + 2;
+ }
+
+ factorial_k = 1;
+
+ for (int j = 2; j <= (int) this->degree; ++j)
+ {
+ interpolation_matrix (i + (j + 2) * source_fe.degree - j, i + (j + 2) * this->degree - j) = std::pow (0.5, i + j);
+ factorial_k *= j;
+ factorial_l = factorial_k;
+ factorial_kl = 1;
+
+ for (int k = j + 1; k <= (int) this->degree; ++k)
+ {
+ factorial_kl *= k - j;
+ factorial_l *= k;
+ interpolation_matrix (i + (j + 2) * source_fe.degree - j, i + (k + 2) * this->degree - k) = std::pow (0.5, i + k) * factorial_l / (factorial_k * factorial_kl);
+ }
+ }
+
+ factorial_i *= i;
+ factorial_j = factorial_i;
+ factorial_ij = 1;
+
+ for (int j = i + 1; j <= (int) this->degree; ++j)
+ {
+ factorial_ij *= j - i;
+ factorial_j *= j;
+ tmp = std::pow (0.5, j) * factorial_j / (factorial_i * factorial_ij);
+ interpolation_matrix (i + 2, j + 2) = tmp;
+ tmp *= -1.0;
+
+ for (unsigned int k = 0; k < this->degree - 1;)
+ {
+ interpolation_matrix (i + source_fe.degree + 1, k + (j + 2) * this->degree + 2 - j) = tmp;
+ k = k + 2;
+ }
+
+ tmp *= -0.5;
+ interpolation_matrix (i + source_fe.degree + 1, j + 2) = tmp;
+ interpolation_matrix (i + source_fe.degree + 1, j + this->degree + 1) = tmp;
+
+ if ((i + j) & 1)
+ tmp *= -1.0;
+
+ interpolation_matrix (i + 2 * source_fe.degree, j + 2 * this->degree) = tmp;
+ interpolation_matrix (i + 2 * source_fe.degree, j + 3 * this->degree - 1) = tmp;
+ tmp *= 2.0;
+ interpolation_matrix (i + 3 * source_fe.degree - 1, j + 3 * this->degree - 1) = tmp;
+ factorial_k = 1;
+
+ for (int k = 2; k <= (int) this->degree; ++k)
+ {
+ interpolation_matrix (i + (k + 2) * source_fe.degree - k, j + (k + 2) * this->degree - k) = tmp * std::pow (0.5, k);
+ factorial_k *= k;
+ factorial_l = factorial_k;
+ factorial_kl = 1;
+
+ for (int l = k + 1; l <= (int) this->degree; ++l)
+ {
+ factorial_kl *= l - k;
+ factorial_l *= l;
+ interpolation_matrix (i + (k + 2) * source_fe.degree - k, j + (l + 2) * this->degree - l) = tmp * std::pow (0.5, l) * factorial_l / (factorial_k * factorial_kl);
+ }
+ }
+
+ tmp *= -1.0;
+
+ for (unsigned int k = 0; k < this->degree - 1;)
+ {
+ interpolation_matrix (i + 2 * source_fe.degree, j + (k + 4) * this->degree - k - 2) = tmp;
+ k = k + 2;
+ }
+ }
+ }
break;
- }
+ }
- case 3:
- {
+ case 3:
+ {
for (unsigned int vertex = 0; vertex < GeometryInfo<3>::vertices_per_face; ++vertex)
- interpolation_matrix (0, vertex) = 0.25;
+ interpolation_matrix (0, vertex) = 0.25;
for (unsigned int i = 0; i < this->degree - 1;)
- {
- for (unsigned int line = 0; line < GeometryInfo<3>::lines_per_face; ++line)
+ {
+ for (unsigned int line = 0; line < GeometryInfo<3>::lines_per_face; ++line)
interpolation_matrix (0, i + line * (this->degree - 1) + 4) = -0.5;
- for (unsigned int j = 0; j < this->degree - 1;)
- {
- interpolation_matrix (0, i + (j + 4) * this->degree - j) = 1.0;
- j = j + 2;
- }
+ for (unsigned int j = 0; j < this->degree - 1;)
+ {
+ interpolation_matrix (0, i + (j + 4) * this->degree - j) = 1.0;
+ j = j + 2;
+ }
- interpolation_matrix (1, i + 4) = -1.0;
- interpolation_matrix (2, i + 3 * this->degree + 1) = -1.0;
- i = i + 2;
- }
+ interpolation_matrix (1, i + 4) = -1.0;
+ interpolation_matrix (2, i + 3 * this->degree + 1) = -1.0;
+ i = i + 2;
+ }
interpolation_matrix (1, 0) = 0.5;
interpolation_matrix (1, 1) = 0.5;
int factorial_l;
for (int i = 2; i <= (int) this->degree; ++i)
- {
- double tmp = std::pow (0.5, i + 1);
- interpolation_matrix (i + 2, i + 2) = tmp;
- interpolation_matrix (i + 2, i + this->degree + 1) = tmp;
- interpolation_matrix (i + 2 * source_fe.degree, i + 2 * this->degree) = tmp;
- interpolation_matrix (i + 2 * source_fe.degree, i + 3 * this->degree - 1) = tmp;
- tmp *= -2.0;
-
- for (unsigned int j = 0; j < this->degree - 1;)
- {
- interpolation_matrix (i + 2, j + (i + 2) * this->degree + 2 - i) = tmp;
- interpolation_matrix (i + 2 * source_fe.degree, i + (j + 4) * this->degree - 2) = tmp;
- j = j + 2;
- }
-
- tmp *= -1.0;
- interpolation_matrix (i + source_fe.degree + 1, i + this->degree + 1) = tmp;
- interpolation_matrix (i + 3 * source_fe.degree - 1, i + 3 * this->degree - 1) = tmp;
- factorial_k = 1;
-
- for (int j = 2; j <= (int) this->degree; ++j)
- {
- interpolation_matrix (i + (j + 2) * source_fe.degree - j, i + (j + 2) * this->degree - j) = std::pow (0.5, i + j);
- factorial_k *= j;
- factorial_l = factorial_k;
- factorial_kl = 1;
-
- for (int k = j + 1; k <= (int) this->degree; ++k)
- {
- factorial_kl *= k - j;
- factorial_l *= k;
- interpolation_matrix (i + (j + 2) * source_fe.degree - j, i + (k + 2) * this->degree - k) = std::pow (0.5, i + k) * factorial_l / (factorial_k * factorial_kl);
- }
- }
-
- factorial_i *= i;
- factorial_j = factorial_i;
- factorial_ij = 1;
-
- for (int j = i + 1; j <= (int) this->degree; ++j)
- {
- factorial_ij *= j - i;
- factorial_j *= j;
- tmp = std::pow (0.5, j + 1) * factorial_j / (factorial_i * factorial_ij);
- interpolation_matrix (i + 2, j + 2) = tmp;
- interpolation_matrix (i + 2, j + this->degree + 1) = tmp;
- interpolation_matrix (i + 2 * source_fe.degree, j + 2 * this->degree) = tmp;
- interpolation_matrix (i + 2 * source_fe.degree, j + 3 * this->degree - 1) = tmp;
- tmp *= 2.0;
- interpolation_matrix (i + source_fe.degree + 1, j + this->degree + 1) = tmp;
- interpolation_matrix (i + 3 * source_fe.degree - 1, j + 3 * this->degree - 1) = tmp;
- factorial_k = 1;
-
- for (int k = 2; k <= (int) this->degree; ++k)
- {
- interpolation_matrix (i + (k + 2) * source_fe.degree - k, j + (k + 2) * this->degree - k) = tmp * std::pow (0.5, k);
- factorial_k *= k;
- factorial_l = factorial_k;
- factorial_kl = 1;
-
- for (int l = k + 1; l <= (int) this->degree; ++l)
- {
- factorial_kl *= l - k;
- factorial_l *= l;
- interpolation_matrix (i + (k + 2) * source_fe.degree - k, j + (l + 2) * this->degree - l) = tmp * std::pow (0.5, l) * factorial_l / (factorial_k * factorial_kl);
- }
- }
-
- tmp *= -1.0;
-
- for (unsigned int k = 0; k < this->degree - 1;)
- {
- interpolation_matrix (i + 2, k + (j + 2) * this->degree + 2 - j) = tmp;
- interpolation_matrix (i + 2 * source_fe.degree, j + (k + 4) * this->degree - 2) = tmp;
- k = k + 2;
- }
- }
- }
- }
- }
+ {
+ double tmp = std::pow (0.5, i + 1);
+ interpolation_matrix (i + 2, i + 2) = tmp;
+ interpolation_matrix (i + 2, i + this->degree + 1) = tmp;
+ interpolation_matrix (i + 2 * source_fe.degree, i + 2 * this->degree) = tmp;
+ interpolation_matrix (i + 2 * source_fe.degree, i + 3 * this->degree - 1) = tmp;
+ tmp *= -2.0;
+
+ for (unsigned int j = 0; j < this->degree - 1;)
+ {
+ interpolation_matrix (i + 2, j + (i + 2) * this->degree + 2 - i) = tmp;
+ interpolation_matrix (i + 2 * source_fe.degree, i + (j + 4) * this->degree - 2) = tmp;
+ j = j + 2;
+ }
+
+ tmp *= -1.0;
+ interpolation_matrix (i + source_fe.degree + 1, i + this->degree + 1) = tmp;
+ interpolation_matrix (i + 3 * source_fe.degree - 1, i + 3 * this->degree - 1) = tmp;
+ factorial_k = 1;
+
+ for (int j = 2; j <= (int) this->degree; ++j)
+ {
+ interpolation_matrix (i + (j + 2) * source_fe.degree - j, i + (j + 2) * this->degree - j) = std::pow (0.5, i + j);
+ factorial_k *= j;
+ factorial_l = factorial_k;
+ factorial_kl = 1;
+
+ for (int k = j + 1; k <= (int) this->degree; ++k)
+ {
+ factorial_kl *= k - j;
+ factorial_l *= k;
+ interpolation_matrix (i + (j + 2) * source_fe.degree - j, i + (k + 2) * this->degree - k) = std::pow (0.5, i + k) * factorial_l / (factorial_k * factorial_kl);
+ }
+ }
+
+ factorial_i *= i;
+ factorial_j = factorial_i;
+ factorial_ij = 1;
+
+ for (int j = i + 1; j <= (int) this->degree; ++j)
+ {
+ factorial_ij *= j - i;
+ factorial_j *= j;
+ tmp = std::pow (0.5, j + 1) * factorial_j / (factorial_i * factorial_ij);
+ interpolation_matrix (i + 2, j + 2) = tmp;
+ interpolation_matrix (i + 2, j + this->degree + 1) = tmp;
+ interpolation_matrix (i + 2 * source_fe.degree, j + 2 * this->degree) = tmp;
+ interpolation_matrix (i + 2 * source_fe.degree, j + 3 * this->degree - 1) = tmp;
+ tmp *= 2.0;
+ interpolation_matrix (i + source_fe.degree + 1, j + this->degree + 1) = tmp;
+ interpolation_matrix (i + 3 * source_fe.degree - 1, j + 3 * this->degree - 1) = tmp;
+ factorial_k = 1;
+
+ for (int k = 2; k <= (int) this->degree; ++k)
+ {
+ interpolation_matrix (i + (k + 2) * source_fe.degree - k, j + (k + 2) * this->degree - k) = tmp * std::pow (0.5, k);
+ factorial_k *= k;
+ factorial_l = factorial_k;
+ factorial_kl = 1;
+
+ for (int l = k + 1; l <= (int) this->degree; ++l)
+ {
+ factorial_kl *= l - k;
+ factorial_l *= l;
+ interpolation_matrix (i + (k + 2) * source_fe.degree - k, j + (l + 2) * this->degree - l) = tmp * std::pow (0.5, l) * factorial_l / (factorial_k * factorial_kl);
+ }
+ }
+
+ tmp *= -1.0;
+
+ for (unsigned int k = 0; k < this->degree - 1;)
+ {
+ interpolation_matrix (i + 2, k + (j + 2) * this->degree + 2 - j) = tmp;
+ interpolation_matrix (i + 2 * source_fe.degree, j + (k + 4) * this->degree - 2) = tmp;
+ k = k + 2;
+ }
+ }
+ }
+ }
+ }
}
}
}
{
const unsigned int codim = dim-1;
- // number of points: (degree+1)^codim
+ // number of points: (degree+1)^codim
unsigned int n = this->degree+1;
for (unsigned int i=1; i<codim; ++i)
n *= this->degree+1;
for (unsigned int iz=0; iz <= ((codim>2) ? this->degree : 0) ; ++iz)
for (unsigned int iy=0; iy <= ((codim>1) ? this->degree : 0) ; ++iy)
for (unsigned int ix=0; ix<=this->degree; ++ix)
- {
- if (ix==0)
- p(0) = 0.;
- else if (ix==1)
- p(0) = 1.;
- else
- p(0) = .5;
- if (codim>1)
- {
- if (iy==0)
- p(1) = 0.;
- else if (iy==1)
- p(1) = 1.;
- else
- p(1) = .5;
- }
- if (codim>2)
- {
- if (iz==0)
- p(2) = 0.;
- else if (iz==1)
- p(2) = 1.;
- else
- p(2) = .5;
- }
- this->unit_face_support_points[face_renumber[k++]] = p;
- };
+ {
+ if (ix==0)
+ p(0) = 0.;
+ else if (ix==1)
+ p(0) = 1.;
+ else
+ p(0) = .5;
+ if (codim>1)
+ {
+ if (iy==0)
+ p(1) = 0.;
+ else if (iy==1)
+ p(1) = 1.;
+ else
+ p(1) = .5;
+ }
+ if (codim>2)
+ {
+ if (iz==0)
+ p(2) = 0.;
+ else if (iz==1)
+ p(2) = 1.;
+ else
+ p(2) = .5;
+ }
+ this->unit_face_support_points[face_renumber[k++]] = p;
+ };
}
- // we use same dpo_vector as FE_Q
+ // we use same dpo_vector as FE_Q
template <int dim>
std::vector<unsigned int>
FE_Q_Hierarchical<dim>::get_dpo_vector(const unsigned int deg)
Assert (fe.n_components() == 1, ExcInternalError());
std::vector<unsigned int> h2l(fe.dofs_per_cell);
- // polynomial degree
+ // polynomial degree
const unsigned int degree = fe.dofs_per_line+1;
- // number of grid points in each
- // direction
+ // number of grid points in each
+ // direction
const unsigned int n = degree+1;
- // the following lines of code are
- // somewhat odd, due to the way the
- // hierarchic numbering is
- // organized. if someone would
- // really want to understand these
- // lines, you better draw some
- // pictures where you indicate the
- // indices and orders of vertices,
- // lines, etc, along with the
- // numbers of the degrees of
- // freedom in hierarchical and
- // lexicographical order
+ // the following lines of code are
+ // somewhat odd, due to the way the
+ // hierarchic numbering is
+ // organized. if someone would
+ // really want to understand these
+ // lines, you better draw some
+ // pictures where you indicate the
+ // indices and orders of vertices,
+ // lines, etc, along with the
+ // numbers of the degrees of
+ // freedom in hierarchical and
+ // lexicographical order
switch (dim)
{
case 1:
{
- for (unsigned int i=0; i<fe.dofs_per_cell; ++i)
- h2l[i] = i;
+ for (unsigned int i=0; i<fe.dofs_per_cell; ++i)
+ h2l[i] = i;
- break;
+ break;
}
case 2:
{
- // Example: degree=3
- //
- // hierarchical numbering:
- // 2 10 11 3
- // 5 14 15 7
- // 4 12 13 6
- // 0 8 9 1
- //
- // fe_q_hierarchical numbering:
- // 4 6 7 5
- // 12 14 15 13
- // 8 10 11 9
- // 0 2 3 1
- unsigned int next_index = 0;
- // first the four vertices
- h2l[next_index++] = 0;
- h2l[next_index++] = 1;
- h2l[next_index++] = n;
- h2l[next_index++] = n+1;
- // left line
- for (unsigned int i=0; i<fe.dofs_per_line; ++i)
- h2l[next_index++] = (2+i)*n;
- // right line
- for (unsigned int i=0; i<fe.dofs_per_line; ++i)
- h2l[next_index++] = (2+i)*n+1;
- // bottom line
- for (unsigned int i=0; i<fe.dofs_per_line; ++i)
- h2l[next_index++] = 2+i;
- // top line
- for (unsigned int i=0; i<fe.dofs_per_line; ++i)
- h2l[next_index++] = n+2+i;
- // inside quad
- Assert (fe.dofs_per_quad == fe.dofs_per_line*fe.dofs_per_line,
- ExcInternalError());
- for (unsigned int i=0; i<fe.dofs_per_line; ++i)
- for (unsigned int j=0; j<fe.dofs_per_line; ++j)
- h2l[next_index++] = (2+i)*n+2+j;
-
- Assert (next_index == fe.dofs_per_cell, ExcInternalError());
-
- break;
+ // Example: degree=3
+ //
+ // hierarchical numbering:
+ // 2 10 11 3
+ // 5 14 15 7
+ // 4 12 13 6
+ // 0 8 9 1
+ //
+ // fe_q_hierarchical numbering:
+ // 4 6 7 5
+ // 12 14 15 13
+ // 8 10 11 9
+ // 0 2 3 1
+ unsigned int next_index = 0;
+ // first the four vertices
+ h2l[next_index++] = 0;
+ h2l[next_index++] = 1;
+ h2l[next_index++] = n;
+ h2l[next_index++] = n+1;
+ // left line
+ for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+ h2l[next_index++] = (2+i)*n;
+ // right line
+ for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+ h2l[next_index++] = (2+i)*n+1;
+ // bottom line
+ for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+ h2l[next_index++] = 2+i;
+ // top line
+ for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+ h2l[next_index++] = n+2+i;
+ // inside quad
+ Assert (fe.dofs_per_quad == fe.dofs_per_line*fe.dofs_per_line,
+ ExcInternalError());
+ for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+ for (unsigned int j=0; j<fe.dofs_per_line; ++j)
+ h2l[next_index++] = (2+i)*n+2+j;
+
+ Assert (next_index == fe.dofs_per_cell, ExcInternalError());
+
+ break;
}
case 3:
{
- unsigned int next_index = 0;
- const unsigned int n2=n*n;
- // first the eight vertices
- // bottom face, lexicographic
- h2l[next_index++] = 0;
- h2l[next_index++] = 1;
- h2l[next_index++] = n;
- h2l[next_index++] = n+1;
- // top face, lexicographic
- h2l[next_index++] = n2;
- h2l[next_index++] = n2+1;
- h2l[next_index++] = n2+n;
- h2l[next_index++] = n2+n+1;
-
- // now the lines
- // bottom face
- for (unsigned int i=0; i<fe.dofs_per_line; ++i)
- h2l[next_index++] = (2+i)*n;
- for (unsigned int i=0; i<fe.dofs_per_line; ++i)
- h2l[next_index++] = (2+i)*n+1;
- for (unsigned int i=0; i<fe.dofs_per_line; ++i)
- h2l[next_index++] = 2+i;
- for (unsigned int i=0; i<fe.dofs_per_line; ++i)
- h2l[next_index++] = n+2+i;
- // top face
- for (unsigned int i=0; i<fe.dofs_per_line; ++i)
- h2l[next_index++] = n2+(2+i)*n;
- for (unsigned int i=0; i<fe.dofs_per_line; ++i)
- h2l[next_index++] = n2+(2+i)*n+1;
- for (unsigned int i=0; i<fe.dofs_per_line; ++i)
- h2l[next_index++] = n2+2+i;
- for (unsigned int i=0; i<fe.dofs_per_line; ++i)
- h2l[next_index++] = n2+n+2+i;
- // lines in z-direction
- for (unsigned int i=0; i<fe.dofs_per_line; ++i)
- h2l[next_index++] = (2+i)*n2;
- for (unsigned int i=0; i<fe.dofs_per_line; ++i)
- h2l[next_index++] = (2+i)*n2+1;
- for (unsigned int i=0; i<fe.dofs_per_line; ++i)
- h2l[next_index++] = (2+i)*n2+n;
- for (unsigned int i=0; i<fe.dofs_per_line; ++i)
- h2l[next_index++] = (2+i)*n2+n+1;
-
- // inside quads
- Assert (fe.dofs_per_quad == fe.dofs_per_line*fe.dofs_per_line,
- ExcInternalError());
- // left face
- for (unsigned int i=0; i<fe.dofs_per_line; ++i)
- for (unsigned int j=0; j<fe.dofs_per_line; ++j)
- h2l[next_index++] = (2+i)*n2+(2+j)*n;
- // right face
- for (unsigned int i=0; i<fe.dofs_per_line; ++i)
- for (unsigned int j=0; j<fe.dofs_per_line; ++j)
- h2l[next_index++] = (2+i)*n2+(2+j)*n+1;
- // front face
- for (unsigned int i=0; i<fe.dofs_per_line; ++i)
- for (unsigned int j=0; j<fe.dofs_per_line; ++j)
- h2l[next_index++] = (2+i)*n2+2+j;
- // back face
- for (unsigned int i=0; i<fe.dofs_per_line; ++i)
- for (unsigned int j=0; j<fe.dofs_per_line; ++j)
- h2l[next_index++] = (2+i)*n2+n+2+j;
- // bottom face
- for (unsigned int i=0; i<fe.dofs_per_line; ++i)
- for (unsigned int j=0; j<fe.dofs_per_line; ++j)
- h2l[next_index++] = (2+i)*n+2+j;
- // top face
- for (unsigned int i=0; i<fe.dofs_per_line; ++i)
- for (unsigned int j=0; j<fe.dofs_per_line; ++j)
- h2l[next_index++] = n2+(2+i)*n+2+j;
-
- // inside hex
- Assert (fe.dofs_per_hex == fe.dofs_per_quad*fe.dofs_per_line,
- ExcInternalError());
- for (unsigned int i=0; i<fe.dofs_per_line; ++i)
- for (unsigned int j=0; j<fe.dofs_per_line; ++j)
- for (unsigned int k=0; k<fe.dofs_per_line; ++k)
- h2l[next_index++] = (2+i)*n2+(2+j)*n+2+k;
-
- Assert (next_index == fe.dofs_per_cell, ExcInternalError());
-
- break;
+ unsigned int next_index = 0;
+ const unsigned int n2=n*n;
+ // first the eight vertices
+ // bottom face, lexicographic
+ h2l[next_index++] = 0;
+ h2l[next_index++] = 1;
+ h2l[next_index++] = n;
+ h2l[next_index++] = n+1;
+ // top face, lexicographic
+ h2l[next_index++] = n2;
+ h2l[next_index++] = n2+1;
+ h2l[next_index++] = n2+n;
+ h2l[next_index++] = n2+n+1;
+
+ // now the lines
+ // bottom face
+ for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+ h2l[next_index++] = (2+i)*n;
+ for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+ h2l[next_index++] = (2+i)*n+1;
+ for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+ h2l[next_index++] = 2+i;
+ for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+ h2l[next_index++] = n+2+i;
+ // top face
+ for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+ h2l[next_index++] = n2+(2+i)*n;
+ for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+ h2l[next_index++] = n2+(2+i)*n+1;
+ for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+ h2l[next_index++] = n2+2+i;
+ for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+ h2l[next_index++] = n2+n+2+i;
+ // lines in z-direction
+ for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+ h2l[next_index++] = (2+i)*n2;
+ for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+ h2l[next_index++] = (2+i)*n2+1;
+ for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+ h2l[next_index++] = (2+i)*n2+n;
+ for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+ h2l[next_index++] = (2+i)*n2+n+1;
+
+ // inside quads
+ Assert (fe.dofs_per_quad == fe.dofs_per_line*fe.dofs_per_line,
+ ExcInternalError());
+ // left face
+ for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+ for (unsigned int j=0; j<fe.dofs_per_line; ++j)
+ h2l[next_index++] = (2+i)*n2+(2+j)*n;
+ // right face
+ for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+ for (unsigned int j=0; j<fe.dofs_per_line; ++j)
+ h2l[next_index++] = (2+i)*n2+(2+j)*n+1;
+ // front face
+ for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+ for (unsigned int j=0; j<fe.dofs_per_line; ++j)
+ h2l[next_index++] = (2+i)*n2+2+j;
+ // back face
+ for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+ for (unsigned int j=0; j<fe.dofs_per_line; ++j)
+ h2l[next_index++] = (2+i)*n2+n+2+j;
+ // bottom face
+ for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+ for (unsigned int j=0; j<fe.dofs_per_line; ++j)
+ h2l[next_index++] = (2+i)*n+2+j;
+ // top face
+ for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+ for (unsigned int j=0; j<fe.dofs_per_line; ++j)
+ h2l[next_index++] = n2+(2+i)*n+2+j;
+
+ // inside hex
+ Assert (fe.dofs_per_hex == fe.dofs_per_quad*fe.dofs_per_line,
+ ExcInternalError());
+ for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+ for (unsigned int j=0; j<fe.dofs_per_line; ++j)
+ for (unsigned int k=0; k<fe.dofs_per_line; ++k)
+ h2l[next_index++] = (2+i)*n2+(2+j)*n+2+k;
+
+ Assert (next_index == fe.dofs_per_cell, ExcInternalError());
+
+ break;
}
default:
- Assert (false, ExcNotImplemented());
+ Assert (false, ExcNotImplemented());
}
return h2l;
}
{
FiniteElementData<dim-1> fe_data(FE_Q_Hierarchical<dim-1>::get_dpo_vector(degree),1,degree);
return invert_numbering(FE_Q_Hierarchical<dim-1>::
- hierarchic_to_fe_q_hierarchical_numbering (fe_data));
+ hierarchic_to_fe_q_hierarchical_numbering (fe_data));
}
template <int dim>
bool
FE_Q_Hierarchical<dim>::has_support_on_face (const unsigned int shape_index,
- const unsigned int face_index) const
+ const unsigned int face_index) const
{
Assert (shape_index < this->dofs_per_cell,
- ExcIndexRange (shape_index, 0, this->dofs_per_cell));
+ ExcIndexRange (shape_index, 0, this->dofs_per_cell));
Assert (face_index < GeometryInfo<dim>::faces_per_cell,
- ExcIndexRange (face_index, 0, GeometryInfo<dim>::faces_per_cell));
+ ExcIndexRange (face_index, 0, GeometryInfo<dim>::faces_per_cell));
// first, special-case interior
// shape functions, since they
((dim==3) && (shape_index>=this->first_hex_index)))
return false;
- // let's see whether this is a
- // vertex
+ // let's see whether this is a
+ // vertex
if (shape_index < this->first_line_index)
{
- // for Q elements, there is
- // one dof per vertex, so
- // shape_index==vertex_number. check
- // whether this vertex is
- // on the given face.
+ // for Q elements, there is
+ // one dof per vertex, so
+ // shape_index==vertex_number. check
+ // whether this vertex is
+ // on the given face.
const unsigned int vertex_no = shape_index;
Assert (vertex_no < GeometryInfo<dim>::vertices_per_cell,
- ExcInternalError());
+ ExcInternalError());
for (unsigned int i=0; i<GeometryInfo<dim>::vertices_per_face; ++i)
- if (GeometryInfo<dim>::face_to_cell_vertices(face_index,i) == vertex_no)
- return true;
+ if (GeometryInfo<dim>::face_to_cell_vertices(face_index,i) == vertex_no)
+ return true;
return false;
}
else if (shape_index < this->first_quad_index)
- // ok, dof is on a line
+ // ok, dof is on a line
{
const unsigned int line_index
- = (shape_index - this->first_line_index) / this->dofs_per_line;
+ = (shape_index - this->first_line_index) / this->dofs_per_line;
Assert (line_index < GeometryInfo<dim>::lines_per_cell,
- ExcInternalError());
+ ExcInternalError());
for (unsigned int i=0; i<GeometryInfo<dim>::lines_per_face; ++i)
- if (GeometryInfo<dim>::face_to_cell_lines(face_index,i) == line_index)
- return true;
+ if (GeometryInfo<dim>::face_to_cell_lines(face_index,i) == line_index)
+ return true;
return false;
}
else if (shape_index < this->first_hex_index)
- // dof is on a quad
+ // dof is on a quad
{
const unsigned int quad_index
- = (shape_index - this->first_quad_index) / this->dofs_per_quad;
+ = (shape_index - this->first_quad_index) / this->dofs_per_quad;
Assert (static_cast<signed int>(quad_index) <
- static_cast<signed int>(GeometryInfo<dim>::quads_per_cell),
- ExcInternalError());
+ static_cast<signed int>(GeometryInfo<dim>::quads_per_cell),
+ ExcInternalError());
- // in 2d, cell bubble are
- // zero on all faces. but
- // we have treated this
- // case above already
+ // in 2d, cell bubble are
+ // zero on all faces. but
+ // we have treated this
+ // case above already
Assert (dim != 2, ExcInternalError());
- // in 3d,
- // quad_index=face_index
+ // in 3d,
+ // quad_index=face_index
if (dim == 3)
- return (quad_index == face_index);
+ return (quad_index == face_index);
else
- Assert (false, ExcNotImplemented());
+ Assert (false, ExcNotImplemented());
}
else
- // dof on hex
+ // dof on hex
{
- // can only happen in 3d, but
- // this case has already been
- // covered above
+ // can only happen in 3d, but
+ // this case has already been
+ // covered above
Assert (false, ExcNotImplemented());
return false;
}
FE_Q_Hierarchical<dim>::get_embedding_dofs (const unsigned int sub_degree) const
{
Assert ((sub_degree>0) && (sub_degree<=this->degree),
- ExcIndexRange(sub_degree, 1, this->degree));
+ ExcIndexRange(sub_degree, 1, this->degree));
if (dim==1)
{
std::vector<unsigned int> embedding_dofs (sub_degree+1);
for (unsigned int i=0; i<(sub_degree+1); ++i)
- embedding_dofs[i] = i;
+ embedding_dofs[i] = i;
return embedding_dofs;
}
{
std::vector<unsigned int> embedding_dofs (GeometryInfo<dim>::vertices_per_cell);
for (unsigned int i=0; i<GeometryInfo<dim>::vertices_per_cell; ++i)
- embedding_dofs[i] = i;
+ embedding_dofs[i] = i;
return embedding_dofs;
}
{
std::vector<unsigned int> embedding_dofs (this->dofs_per_cell);
for (unsigned int i=0; i<this->dofs_per_cell; ++i)
- embedding_dofs[i] = i;
+ embedding_dofs[i] = i;
return embedding_dofs;
}
if ((dim==2) || (dim==3))
{
std::vector<unsigned int> embedding_dofs ( (dim==2) ?
- (sub_degree+1) * (sub_degree+1) :
- (sub_degree+1) * (sub_degree+1) * (sub_degree+1) );
+ (sub_degree+1) * (sub_degree+1) :
+ (sub_degree+1) * (sub_degree+1) * (sub_degree+1) );
for (unsigned int i=0; i<( (dim==2) ?
- (sub_degree+1) * (sub_degree+1) :
- (sub_degree+1) * (sub_degree+1) * (sub_degree+1) ); ++i)
- {
- // vertex
- if (i<GeometryInfo<dim>::vertices_per_cell)
- embedding_dofs[i] = i;
- // line
- else if (i<(GeometryInfo<dim>::vertices_per_cell +
- GeometryInfo<dim>::lines_per_cell * (sub_degree-1)))
- {
- const unsigned int j = (i - GeometryInfo<dim>::vertices_per_cell) %
- (sub_degree-1);
- const unsigned int line = (i - GeometryInfo<dim>::vertices_per_cell - j) / (sub_degree-1);
-
- embedding_dofs[i] = GeometryInfo<dim>::vertices_per_cell +
- line * (this->degree-1) + j;
- }
- // quad
- else if (i<(GeometryInfo<dim>::vertices_per_cell +
- GeometryInfo<dim>::lines_per_cell * (sub_degree-1)) +
- GeometryInfo<dim>::quads_per_cell * (sub_degree-1) * (sub_degree-1))
- {
- const unsigned int j = (i - GeometryInfo<dim>::vertices_per_cell -
- GeometryInfo<dim>::lines_per_cell * (sub_degree-1)) % (sub_degree-1);
- const unsigned int k = ( (i - GeometryInfo<dim>::vertices_per_cell -
- GeometryInfo<dim>::lines_per_cell * (sub_degree-1) - j) / (sub_degree-1) ) % (sub_degree-1);
- const unsigned int face = (i - GeometryInfo<dim>::vertices_per_cell -
- GeometryInfo<dim>::lines_per_cell * (sub_degree-1) - k * (sub_degree-1) - j) / ( (sub_degree-1) * (sub_degree-1) );
-
- embedding_dofs[i] = GeometryInfo<dim>::vertices_per_cell +
- GeometryInfo<dim>::lines_per_cell * (this->degree-1) +
- face * (this->degree-1) * (this->degree-1) +
- k * (this->degree-1) + j;
- }
- // hex
- else if (i<(GeometryInfo<dim>::vertices_per_cell +
- GeometryInfo<dim>::lines_per_cell * (sub_degree-1)) +
- GeometryInfo<dim>::quads_per_cell * (sub_degree-1) * (sub_degree-1) +
- GeometryInfo<dim>::hexes_per_cell * (sub_degree-1) * (sub_degree-1) * (sub_degree-1))
- {
- const unsigned int j = (i - GeometryInfo<dim>::vertices_per_cell -
- GeometryInfo<dim>::lines_per_cell * (sub_degree-1) -
- GeometryInfo<dim>::quads_per_cell * (sub_degree-1) * (sub_degree-1) ) % (sub_degree-1);
- const unsigned int k = ( (i - GeometryInfo<dim>::vertices_per_cell -
- GeometryInfo<dim>::lines_per_cell * (sub_degree-1) -
- GeometryInfo<dim>::quads_per_cell * (sub_degree-1) * (sub_degree-1) - j) / (sub_degree-1) ) % (sub_degree-1);
- const unsigned int l = (i - GeometryInfo<dim>::vertices_per_cell -
- GeometryInfo<dim>::lines_per_cell * (sub_degree-1) -
- GeometryInfo<dim>::quads_per_cell * (sub_degree-1) * (sub_degree-1) - j - k * (sub_degree-1)) / ( (sub_degree-1) * (sub_degree-1) );
-
- embedding_dofs[i] = GeometryInfo<dim>::vertices_per_cell +
- GeometryInfo<dim>::lines_per_cell * (this->degree-1) +
- GeometryInfo<dim>::quads_per_cell * (this->degree-1) * (this->degree-1) +
- l * (this->degree-1) * (this->degree-1) + k * (this->degree-1) + j;
- }
- }
+ (sub_degree+1) * (sub_degree+1) :
+ (sub_degree+1) * (sub_degree+1) * (sub_degree+1) ); ++i)
+ {
+ // vertex
+ if (i<GeometryInfo<dim>::vertices_per_cell)
+ embedding_dofs[i] = i;
+ // line
+ else if (i<(GeometryInfo<dim>::vertices_per_cell +
+ GeometryInfo<dim>::lines_per_cell * (sub_degree-1)))
+ {
+ const unsigned int j = (i - GeometryInfo<dim>::vertices_per_cell) %
+ (sub_degree-1);
+ const unsigned int line = (i - GeometryInfo<dim>::vertices_per_cell - j) / (sub_degree-1);
+
+ embedding_dofs[i] = GeometryInfo<dim>::vertices_per_cell +
+ line * (this->degree-1) + j;
+ }
+ // quad
+ else if (i<(GeometryInfo<dim>::vertices_per_cell +
+ GeometryInfo<dim>::lines_per_cell * (sub_degree-1)) +
+ GeometryInfo<dim>::quads_per_cell * (sub_degree-1) * (sub_degree-1))
+ {
+ const unsigned int j = (i - GeometryInfo<dim>::vertices_per_cell -
+ GeometryInfo<dim>::lines_per_cell * (sub_degree-1)) % (sub_degree-1);
+ const unsigned int k = ( (i - GeometryInfo<dim>::vertices_per_cell -
+ GeometryInfo<dim>::lines_per_cell * (sub_degree-1) - j) / (sub_degree-1) ) % (sub_degree-1);
+ const unsigned int face = (i - GeometryInfo<dim>::vertices_per_cell -
+ GeometryInfo<dim>::lines_per_cell * (sub_degree-1) - k * (sub_degree-1) - j) / ( (sub_degree-1) * (sub_degree-1) );
+
+ embedding_dofs[i] = GeometryInfo<dim>::vertices_per_cell +
+ GeometryInfo<dim>::lines_per_cell * (this->degree-1) +
+ face * (this->degree-1) * (this->degree-1) +
+ k * (this->degree-1) + j;
+ }
+ // hex
+ else if (i<(GeometryInfo<dim>::vertices_per_cell +
+ GeometryInfo<dim>::lines_per_cell * (sub_degree-1)) +
+ GeometryInfo<dim>::quads_per_cell * (sub_degree-1) * (sub_degree-1) +
+ GeometryInfo<dim>::hexes_per_cell * (sub_degree-1) * (sub_degree-1) * (sub_degree-1))
+ {
+ const unsigned int j = (i - GeometryInfo<dim>::vertices_per_cell -
+ GeometryInfo<dim>::lines_per_cell * (sub_degree-1) -
+ GeometryInfo<dim>::quads_per_cell * (sub_degree-1) * (sub_degree-1) ) % (sub_degree-1);
+ const unsigned int k = ( (i - GeometryInfo<dim>::vertices_per_cell -
+ GeometryInfo<dim>::lines_per_cell * (sub_degree-1) -
+ GeometryInfo<dim>::quads_per_cell * (sub_degree-1) * (sub_degree-1) - j) / (sub_degree-1) ) % (sub_degree-1);
+ const unsigned int l = (i - GeometryInfo<dim>::vertices_per_cell -
+ GeometryInfo<dim>::lines_per_cell * (sub_degree-1) -
+ GeometryInfo<dim>::quads_per_cell * (sub_degree-1) * (sub_degree-1) - j - k * (sub_degree-1)) / ( (sub_degree-1) * (sub_degree-1) );
+
+ embedding_dofs[i] = GeometryInfo<dim>::vertices_per_cell +
+ GeometryInfo<dim>::lines_per_cell * (this->degree-1) +
+ GeometryInfo<dim>::quads_per_cell * (this->degree-1) * (this->degree-1) +
+ l * (this->degree-1) * (this->degree-1) + k * (this->degree-1) + j;
+ }
+ }
return embedding_dofs;
}
// $Id$
// Version: $Name$
//
-// Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 by the deal.II authors
+// Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
template <int dim>
FE_RaviartThomas<dim>::FE_RaviartThomas (const unsigned int deg)
- :
- FE_PolyTensor<PolynomialsRaviartThomas<dim>, dim> (
- deg,
- FiniteElementData<dim>(get_dpo_vector(deg),
- dim, deg+1, FiniteElementData<dim>::Hdiv, 1),
- std::vector<bool>(PolynomialsRaviartThomas<dim>::compute_n_pols(deg), true),
- std::vector<std::vector<bool> >(PolynomialsRaviartThomas<dim>::compute_n_pols(deg),
- std::vector<bool>(dim,true)))
+ :
+ FE_PolyTensor<PolynomialsRaviartThomas<dim>, dim> (
+ deg,
+ FiniteElementData<dim>(get_dpo_vector(deg),
+ dim, deg+1, FiniteElementData<dim>::Hdiv, 1),
+ std::vector<bool>(PolynomialsRaviartThomas<dim>::compute_n_pols(deg), true),
+ std::vector<std::vector<bool> >(PolynomialsRaviartThomas<dim>::compute_n_pols(deg),
+ std::vector<bool>(dim,true)))
{
Assert (dim >= 2, ExcImpossibleInDim(dim));
const unsigned int n_dofs = this->dofs_per_cell;
this->mapping_type = mapping_raviart_thomas;
- // First, initialize the
- // generalized support points and
- // quadrature weights, since they
- // are required for interpolation.
+ // First, initialize the
+ // generalized support points and
+ // quadrature weights, since they
+ // are required for interpolation.
initialize_support_points(deg);
- // Now compute the inverse node
- //matrix, generating the correct
- //basis functions from the raw
- //ones.
-
- // We use an auxiliary matrix in
- // this function. Therefore,
- // inverse_node_matrix is still
- // empty and shape_value_component
- // returns the 'raw' shape values.
+ // Now compute the inverse node
+ //matrix, generating the correct
+ //basis functions from the raw
+ //ones.
+
+ // We use an auxiliary matrix in
+ // this function. Therefore,
+ // inverse_node_matrix is still
+ // empty and shape_value_component
+ // returns the 'raw' shape values.
FullMatrix<double> M(n_dofs, n_dofs);
FETools::compute_node_matrix(M, *this);
this->inverse_node_matrix.reinit(n_dofs, n_dofs);
this->inverse_node_matrix.invert(M);
- // From now on, the shape functions
- // will be the correct ones, not
- // the raw shape functions anymore.
-
- // Reinit the vectors of
- // restriction and prolongation
- // matrices to the right sizes.
- // Restriction only for isotropic
- // refinement
+ // From now on, the shape functions
+ // will be the correct ones, not
+ // the raw shape functions anymore.
+
+ // Reinit the vectors of
+ // restriction and prolongation
+ // matrices to the right sizes.
+ // Restriction only for isotropic
+ // refinement
this->reinit_restriction_and_prolongation_matrices(true);
- // Fill prolongation matrices with embedding operators
+ // Fill prolongation matrices with embedding operators
FETools::compute_embedding_matrices (*this, this->prolongation);
initialize_restriction();
- // TODO[TL]: for anisotropic refinement we will probably need a table of submatrices with an array for each refine case
+ // TODO[TL]: for anisotropic refinement we will probably need a table of submatrices with an array for each refine case
FullMatrix<double> face_embeddings[GeometryInfo<dim>::max_children_per_face];
for (unsigned int i=0; i<GeometryInfo<dim>::max_children_per_face; ++i)
face_embeddings[i].reinit (this->dofs_per_face, this->dofs_per_face);
FETools::compute_face_embedding_matrices<dim,double>(*this, face_embeddings, 0, 0);
this->interface_constraints.reinit((1<<(dim-1)) * this->dofs_per_face,
- this->dofs_per_face);
+ this->dofs_per_face);
unsigned int target_row=0;
for (unsigned int d=0;d<GeometryInfo<dim>::max_children_per_face;++d)
for (unsigned int i=0;i<face_embeddings[d].m();++i)
{
- for (unsigned int j=0;j<face_embeddings[d].n();++j)
- this->interface_constraints(target_row,j) = face_embeddings[d](i,j);
- ++target_row;
+ for (unsigned int j=0;j<face_embeddings[d].n();++j)
+ this->interface_constraints(target_row,j) = face_embeddings[d](i,j);
+ ++target_row;
}
}
std::string
FE_RaviartThomas<dim>::get_name () const
{
- // note that the
- // FETools::get_fe_from_name
- // function depends on the
- // particular format of the string
- // this function returns, so they
- // have to be kept in synch
-
- // note that this->degree is the maximal
- // polynomial degree and is thus one higher
- // than the argument given to the
- // constructor
+ // note that the
+ // FETools::get_fe_from_name
+ // function depends on the
+ // particular format of the string
+ // this function returns, so they
+ // have to be kept in synch
+
+ // note that this->degree is the maximal
+ // polynomial degree and is thus one higher
+ // than the argument given to the
+ // constructor
std::ostringstream namebuf;
namebuf << "FE_RaviartThomas<" << dim << ">(" << this->degree-1 << ")";
= (deg>0) ? cell_quadrature.size() : 0;
unsigned int n_face_points = (dim>1) ? 1 : 0;
- // compute (deg+1)^(dim-1)
+ // compute (deg+1)^(dim-1)
for (unsigned int d=1;d<dim;++d)
n_face_points *= deg+1;
this->generalized_support_points.resize (GeometryInfo<dim>::faces_per_cell*n_face_points
- + n_interior_points);
+ + n_interior_points);
this->generalized_face_support_points.resize (n_face_points);
- // Number of the point being entered
+ // Number of the point being entered
unsigned int current = 0;
if (dim>1)
{
QGauss<dim-1> face_points (deg+1);
TensorProductPolynomials<dim-1> legendre
- = Polynomials::Legendre::generate_complete_basis(deg);
+ = Polynomials::Legendre::generate_complete_basis(deg);
boundary_weights.reinit(n_face_points, legendre.n());
// Assert (face_points.size() == this->dofs_per_face,
-// ExcInternalError());
+// ExcInternalError());
for (unsigned int k=0;k<n_face_points;++k)
- {
- this->generalized_face_support_points[k] = face_points.point(k);
- // Compute its quadrature
- // contribution for each
- // moment.
- for (unsigned int i=0;i<legendre.n();++i)
- {
- boundary_weights(k, i)
- = face_points.weight(k)
- * legendre.compute_value(i, face_points.point(k));
- }
- }
+ {
+ this->generalized_face_support_points[k] = face_points.point(k);
+ // Compute its quadrature
+ // contribution for each
+ // moment.
+ for (unsigned int i=0;i<legendre.n();++i)
+ {
+ boundary_weights(k, i)
+ = face_points.weight(k)
+ * legendre.compute_value(i, face_points.point(k));
+ }
+ }
Quadrature<dim> faces = QProjector<dim>::project_to_all_faces(face_points);
for (;current<GeometryInfo<dim>::faces_per_cell*n_face_points;
- ++current)
- {
- // Enter the support point
- // into the vector
- this->generalized_support_points[current] = faces.point(current+QProjector<dim>::DataSetDescriptor::face(0,true,false,false,n_face_points));
- }
+ ++current)
+ {
+ // Enter the support point
+ // into the vector
+ this->generalized_support_points[current] = faces.point(current+QProjector<dim>::DataSetDescriptor::face(0,true,false,false,n_face_points));
+ }
}
if (deg==0) return;
- // Create Legendre basis for the
- // space D_xi Q_k
+ // Create Legendre basis for the
+ // space D_xi Q_k
std::vector<AnisotropicPolynomials<dim>* > polynomials(dim);
for (unsigned int dd=0;dd<dim;++dd)
{
std::vector<std::vector<Polynomials::Polynomial<double> > > poly(dim);
for (unsigned int d=0;d<dim;++d)
- poly[d] = Polynomials::Legendre::generate_complete_basis(deg);
+ poly[d] = Polynomials::Legendre::generate_complete_basis(deg);
poly[dd] = Polynomials::Legendre::generate_complete_basis(deg-1);
polynomials[dd] = new AnisotropicPolynomials<dim>(poly);
{
this->generalized_support_points[current++] = cell_quadrature.point(k);
for (unsigned int i=0;i<polynomials[0]->n();++i)
- for (unsigned int d=0;d<dim;++d)
- interior_weights(k,i,d) = cell_quadrature.weight(k)
- * polynomials[d]->compute_value(i,cell_quadrature.point(k));
+ for (unsigned int d=0;d<dim;++d)
+ interior_weights(k,i,d) = cell_quadrature.weight(k)
+ * polynomials[d]->compute_value(i,cell_quadrature.point(k));
}
for (unsigned int d=0;d<dim;++d)
delete polynomials[d];
Assert (current == this->generalized_support_points.size(),
- ExcInternalError());
+ ExcInternalError());
}
void
FE_RaviartThomas<1>::initialize_restriction()
{
- // there is only one refinement case in 1d,
- // which is the isotropic one (first index of
- // the matrix array has to be 0)
+ // there is only one refinement case in 1d,
+ // which is the isotropic one (first index of
+ // the matrix array has to be 0)
for (unsigned int i=0;i<GeometryInfo<1>::max_children_per_cell;++i)
this->restriction[0][i].reinit(0,0);
}
QGauss<dim-1> q_base (this->degree);
const unsigned int n_face_points = q_base.size();
- // First, compute interpolation on
- // subfaces
+ // First, compute interpolation on
+ // subfaces
for (unsigned int face=0;face<GeometryInfo<dim>::faces_per_cell;++face)
{
- // The shape functions of the
- // child cell are evaluated
- // in the quadrature points
- // of a full face.
+ // The shape functions of the
+ // child cell are evaluated
+ // in the quadrature points
+ // of a full face.
Quadrature<dim> q_face
- = QProjector<dim>::project_to_face(q_base, face);
- // Store shape values, since the
- // evaluation suffers if not
- // ordered by point
+ = QProjector<dim>::project_to_face(q_base, face);
+ // Store shape values, since the
+ // evaluation suffers if not
+ // ordered by point
Table<2,double> cached_values(this->dofs_per_cell, q_face.size());
for (unsigned int k=0;k<q_face.size();++k)
- for (unsigned int i = 0; i < this->dofs_per_cell; ++i)
- cached_values(i,k)
- = this->shape_value_component(i, q_face.point(k),
- GeometryInfo<dim>::unit_normal_direction[face]);
+ for (unsigned int i = 0; i < this->dofs_per_cell; ++i)
+ cached_values(i,k)
+ = this->shape_value_component(i, q_face.point(k),
+ GeometryInfo<dim>::unit_normal_direction[face]);
for (unsigned int sub=0;sub<GeometryInfo<dim>::max_children_per_face;++sub)
- {
- // The weight fuctions for
- // the coarse face are
- // evaluated on the subface
- // only.
- Quadrature<dim> q_sub
- = QProjector<dim>::project_to_subface(q_base, face, sub);
- const unsigned int child
- = GeometryInfo<dim>::child_cell_on_face(
- RefinementCase<dim>::isotropic_refinement, face, sub);
-
- // On a certain face, we must
- // compute the moments of ALL
- // fine level functions with
- // the coarse level weight
- // functions belonging to
- // that face. Due to the
- // orthogonalization process
- // when building the shape
- // functions, these weights
- // are equal to the
- // corresponding shape
- // functions.
- for (unsigned int k=0;k<n_face_points;++k)
- for (unsigned int i_child = 0; i_child < this->dofs_per_cell; ++i_child)
- for (unsigned int i_face = 0; i_face < this->dofs_per_face; ++i_face)
- {
- // The quadrature
- // weights on the
- // subcell are NOT
- // transformed, so we
- // have to do it here.
- this->restriction[iso][child](face*this->dofs_per_face+i_face,
- i_child)
- += Utilities::fixed_power<dim-1>(.5) * q_sub.weight(k)
- * cached_values(i_child, k)
- * this->shape_value_component(face*this->dofs_per_face+i_face,
- q_sub.point(k),
- GeometryInfo<dim>::unit_normal_direction[face]);
- }
- }
+ {
+ // The weight fuctions for
+ // the coarse face are
+ // evaluated on the subface
+ // only.
+ Quadrature<dim> q_sub
+ = QProjector<dim>::project_to_subface(q_base, face, sub);
+ const unsigned int child
+ = GeometryInfo<dim>::child_cell_on_face(
+ RefinementCase<dim>::isotropic_refinement, face, sub);
+
+ // On a certain face, we must
+ // compute the moments of ALL
+ // fine level functions with
+ // the coarse level weight
+ // functions belonging to
+ // that face. Due to the
+ // orthogonalization process
+ // when building the shape
+ // functions, these weights
+ // are equal to the
+ // corresponding shape
+ // functions.
+ for (unsigned int k=0;k<n_face_points;++k)
+ for (unsigned int i_child = 0; i_child < this->dofs_per_cell; ++i_child)
+ for (unsigned int i_face = 0; i_face < this->dofs_per_face; ++i_face)
+ {
+ // The quadrature
+ // weights on the
+ // subcell are NOT
+ // transformed, so we
+ // have to do it here.
+ this->restriction[iso][child](face*this->dofs_per_face+i_face,
+ i_child)
+ += Utilities::fixed_power<dim-1>(.5) * q_sub.weight(k)
+ * cached_values(i_child, k)
+ * this->shape_value_component(face*this->dofs_per_face+i_face,
+ q_sub.point(k),
+ GeometryInfo<dim>::unit_normal_direction[face]);
+ }
+ }
}
if (this->degree == 1) return;
- // Create Legendre basis for the
- // space D_xi Q_k. Here, we cannot
- // use the shape functions
+ // Create Legendre basis for the
+ // space D_xi Q_k. Here, we cannot
+ // use the shape functions
std::vector<AnisotropicPolynomials<dim>* > polynomials(dim);
for (unsigned int dd=0;dd<dim;++dd)
{
std::vector<std::vector<Polynomials::Polynomial<double> > > poly(dim);
for (unsigned int d=0;d<dim;++d)
- poly[d] = Polynomials::Legendre::generate_complete_basis(this->degree-1);
+ poly[d] = Polynomials::Legendre::generate_complete_basis(this->degree-1);
poly[dd] = Polynomials::Legendre::generate_complete_basis(this->degree-2);
polynomials[dd] = new AnisotropicPolynomials<dim>(poly);
const unsigned int start_cell_dofs
= GeometryInfo<dim>::faces_per_cell*this->dofs_per_face;
- // Store shape values, since the
- // evaluation suffers if not
- // ordered by point
+ // Store shape values, since the
+ // evaluation suffers if not
+ // ordered by point
Table<3,double> cached_values(this->dofs_per_cell, q_cell.size(), dim);
for (unsigned int k=0;k<q_cell.size();++k)
for (unsigned int i = 0; i < this->dofs_per_cell; ++i)
for (unsigned int d=0;d<dim;++d)
- cached_values(i,k,d) = this->shape_value_component(i, q_cell.point(k), d);
+ cached_values(i,k,d) = this->shape_value_component(i, q_cell.point(k), d);
for (unsigned int child=0;child<GeometryInfo<dim>::max_children_per_cell;++child)
{
Quadrature<dim> q_sub = QProjector<dim>::project_to_child(q_cell, child);
for (unsigned int k=0;k<q_sub.size();++k)
- for (unsigned int i_child = 0; i_child < this->dofs_per_cell; ++i_child)
- for (unsigned int d=0;d<dim;++d)
- for (unsigned int i_weight=0;i_weight<polynomials[d]->n();++i_weight)
- {
- this->restriction[iso][child](start_cell_dofs+i_weight*dim+d,
- i_child)
- += q_sub.weight(k)
- * cached_values(i_child, k, d)
- * polynomials[d]->compute_value(i_weight, q_sub.point(k));
- }
+ for (unsigned int i_child = 0; i_child < this->dofs_per_cell; ++i_child)
+ for (unsigned int d=0;d<dim;++d)
+ for (unsigned int i_weight=0;i_weight<polynomials[d]->n();++i_weight)
+ {
+ this->restriction[iso][child](start_cell_dofs+i_weight*dim+d,
+ i_child)
+ += q_sub.weight(k)
+ * cached_values(i_child, k, d)
+ * polynomials[d]->compute_value(i_weight, q_sub.point(k));
+ }
}
for (unsigned int d=0;d<dim;++d)
const unsigned int face_index) const
{
Assert (shape_index < this->dofs_per_cell,
- ExcIndexRange (shape_index, 0, this->dofs_per_cell));
+ ExcIndexRange (shape_index, 0, this->dofs_per_cell));
Assert (face_index < GeometryInfo<dim>::faces_per_cell,
- ExcIndexRange (face_index, 0, GeometryInfo<dim>::faces_per_cell));
+ ExcIndexRange (face_index, 0, GeometryInfo<dim>::faces_per_cell));
- // Return computed values if we
- // know them easily. Otherwise, it
- // is always safe to return true.
+ // Return computed values if we
+ // know them easily. Otherwise, it
+ // is always safe to return true.
switch (this->degree)
{
case 1:
}
default:
- return true;
+ return true;
};
};
default: // other rt_order
- return true;
+ return true;
};
return true;
unsigned int offset) const
{
Assert (values.size() == this->generalized_support_points.size(),
- ExcDimensionMismatch(values.size(), this->generalized_support_points.size()));
+ ExcDimensionMismatch(values.size(), this->generalized_support_points.size()));
Assert (local_dofs.size() == this->dofs_per_cell,
- ExcDimensionMismatch(local_dofs.size(),this->dofs_per_cell));
+ ExcDimensionMismatch(local_dofs.size(),this->dofs_per_cell));
Assert (values[0].size() >= offset+this->n_components(),
- ExcDimensionMismatch(values[0].size(),offset+this->n_components()));
+ ExcDimensionMismatch(values[0].size(),offset+this->n_components()));
std::fill(local_dofs.begin(), local_dofs.end(), 0.);
for (unsigned int k=0;k<n_face_points;++k)
for (unsigned int i=0;i<boundary_weights.size(1);++i)
{
- local_dofs[i+face*this->dofs_per_face] += boundary_weights(k,i)
- * values[face*n_face_points+k](GeometryInfo<dim>::unit_normal_direction[face]+offset);
+ local_dofs[i+face*this->dofs_per_face] += boundary_weights(k,i)
+ * values[face*n_face_points+k](GeometryInfo<dim>::unit_normal_direction[face]+offset);
}
const unsigned start_cell_dofs = GeometryInfo<dim>::faces_per_cell*this->dofs_per_face;
for (unsigned int k=0;k<interior_weights.size(0);++k)
for (unsigned int i=0;i<interior_weights.size(1);++i)
for (unsigned int d=0;d<dim;++d)
- local_dofs[start_cell_dofs+i*dim+d] += interior_weights(k,i,d) * values[k+start_cell_points](d+offset);
+ local_dofs[start_cell_dofs+i*dim+d] += interior_weights(k,i,d) * values[k+start_cell_points](d+offset);
}
const VectorSlice<const std::vector<std::vector<double> > >& values) const
{
Assert (values.size() == this->n_components(),
- ExcDimensionMismatch(values.size(), this->n_components()));
+ ExcDimensionMismatch(values.size(), this->n_components()));
Assert (values[0].size() == this->generalized_support_points.size(),
- ExcDimensionMismatch(values[0].size(), this->generalized_support_points.size()));
+ ExcDimensionMismatch(values[0].size(), this->generalized_support_points.size()));
Assert (local_dofs.size() == this->dofs_per_cell,
- ExcDimensionMismatch(local_dofs.size(),this->dofs_per_cell));
+ ExcDimensionMismatch(local_dofs.size(),this->dofs_per_cell));
std::fill(local_dofs.begin(), local_dofs.end(), 0.);
for (unsigned int k=0;k<n_face_points;++k)
for (unsigned int i=0;i<boundary_weights.size(1);++i)
{
- local_dofs[i+face*this->dofs_per_face] += boundary_weights(k,i)
- * values[GeometryInfo<dim>::unit_normal_direction[face]][face*n_face_points+k];
+ local_dofs[i+face*this->dofs_per_face] += boundary_weights(k,i)
+ * values[GeometryInfo<dim>::unit_normal_direction[face]][face*n_face_points+k];
}
const unsigned start_cell_dofs = GeometryInfo<dim>::faces_per_cell*this->dofs_per_face;
for (unsigned int k=0;k<interior_weights.size(0);++k)
for (unsigned int i=0;i<interior_weights.size(1);++i)
for (unsigned int d=0;d<dim;++d)
- local_dofs[start_cell_dofs+i*dim+d] += interior_weights(k,i,d) * values[d][k+start_cell_points];
+ local_dofs[start_cell_dofs+i*dim+d] += interior_weights(k,i,d) * values[d][k+start_cell_points];
}
// $Id$
// Version: $Name$
//
-// Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 by the deal.II authors
+// Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
template <int dim>
FE_RaviartThomasNodal<dim>::FE_RaviartThomasNodal (const unsigned int deg)
- :
- FE_PolyTensor<PolynomialsRaviartThomas<dim>, dim> (
- deg,
- FiniteElementData<dim>(get_dpo_vector(deg),
- dim, deg+1, FiniteElementData<dim>::Hdiv, 1),
- get_ria_vector (deg),
- std::vector<std::vector<bool> >(PolynomialsRaviartThomas<dim>::compute_n_pols(deg),
- std::vector<bool>(dim,true)))
+ :
+ FE_PolyTensor<PolynomialsRaviartThomas<dim>, dim> (
+ deg,
+ FiniteElementData<dim>(get_dpo_vector(deg),
+ dim, deg+1, FiniteElementData<dim>::Hdiv, 1),
+ get_ria_vector (deg),
+ std::vector<std::vector<bool> >(PolynomialsRaviartThomas<dim>::compute_n_pols(deg),
+ std::vector<bool>(dim,true)))
{
Assert (dim >= 2, ExcImpossibleInDim(dim));
const unsigned int n_dofs = this->dofs_per_cell;
this->mapping_type = mapping_raviart_thomas;
- // First, initialize the
- // generalized support points and
- // quadrature weights, since they
- // are required for interpolation.
+ // First, initialize the
+ // generalized support points and
+ // quadrature weights, since they
+ // are required for interpolation.
initialize_support_points(deg);
- // Now compute the inverse node
- //matrix, generating the correct
- //basis functions from the raw
- //ones.
-
- // We use an auxiliary matrix in
- // this function. Therefore,
- // inverse_node_matrix is still
- // empty and shape_value_component
- // returns the 'raw' shape values.
+ // Now compute the inverse node
+ //matrix, generating the correct
+ //basis functions from the raw
+ //ones.
+
+ // We use an auxiliary matrix in
+ // this function. Therefore,
+ // inverse_node_matrix is still
+ // empty and shape_value_component
+ // returns the 'raw' shape values.
FullMatrix<double> M(n_dofs, n_dofs);
FETools::compute_node_matrix(M, *this);
this->inverse_node_matrix.reinit(n_dofs, n_dofs);
this->inverse_node_matrix.invert(M);
- // From now on, the shape functions
- // will be the correct ones, not
- // the raw shape functions anymore.
-
- // Reinit the vectors of
- // prolongation matrices to the
- // right sizes. There are no
- // restriction matrices implemented
+ // From now on, the shape functions
+ // will be the correct ones, not
+ // the raw shape functions anymore.
+
+ // Reinit the vectors of
+ // prolongation matrices to the
+ // right sizes. There are no
+ // restriction matrices implemented
for (unsigned int ref_case=RefinementCase<dim>::cut_x;
ref_case<RefinementCase<dim>::isotropic_refinement+1; ++ref_case)
{
const unsigned int nc = GeometryInfo<dim>::n_children(RefinementCase<dim>(ref_case));
for (unsigned int i=0;i<nc;++i)
- this->prolongation[ref_case-1][i].reinit (n_dofs, n_dofs);
+ this->prolongation[ref_case-1][i].reinit (n_dofs, n_dofs);
}
- // Fill prolongation matrices with embedding operators
+ // Fill prolongation matrices with embedding operators
FETools::compute_embedding_matrices (*this, this->prolongation);
- // TODO[TL]: for anisotropic refinement we will probably need a table of submatrices with an array for each refine case
+ // TODO[TL]: for anisotropic refinement we will probably need a table of submatrices with an array for each refine case
FullMatrix<double> face_embeddings[GeometryInfo<dim>::max_children_per_face];
for (unsigned int i=0; i<GeometryInfo<dim>::max_children_per_face; ++i)
face_embeddings[i].reinit (this->dofs_per_face, this->dofs_per_face);
FETools::compute_face_embedding_matrices<dim,double>(*this, face_embeddings, 0, 0);
this->interface_constraints.reinit((1<<(dim-1)) * this->dofs_per_face,
- this->dofs_per_face);
+ this->dofs_per_face);
unsigned int target_row=0;
for (unsigned int d=0;d<GeometryInfo<dim>::max_children_per_face;++d)
for (unsigned int i=0;i<face_embeddings[d].m();++i)
{
- for (unsigned int j=0;j<face_embeddings[d].n();++j)
- this->interface_constraints(target_row,j) = face_embeddings[d](i,j);
- ++target_row;
+ for (unsigned int j=0;j<face_embeddings[d].n();++j)
+ this->interface_constraints(target_row,j) = face_embeddings[d](i,j);
+ ++target_row;
}
}
std::string
FE_RaviartThomasNodal<dim>::get_name () const
{
- // note that the
- // FETools::get_fe_from_name
- // function depends on the
- // particular format of the string
- // this function returns, so they
- // have to be kept in synch
-
- // note that this->degree is the maximal
- // polynomial degree and is thus one higher
- // than the argument given to the
- // constructor
+ // note that the
+ // FETools::get_fe_from_name
+ // function depends on the
+ // particular format of the string
+ // this function returns, so they
+ // have to be kept in synch
+
+ // note that this->degree is the maximal
+ // polynomial degree and is thus one higher
+ // than the argument given to the
+ // constructor
std::ostringstream namebuf;
namebuf << "FE_RaviartThomasNodal<" << dim << ">(" << this->degree-1 << ")";
this->generalized_support_points.resize (this->dofs_per_cell);
this->generalized_face_support_points.resize (this->dofs_per_face);
- // Number of the point being entered
+ // Number of the point being entered
unsigned int current = 0;
- // On the faces, we choose as many
- // Gauss points as necessary to
- // determine the normal component
- // uniquely. This is the deg of
- // the Raviart-Thomas element plus
- // one.
+ // On the faces, we choose as many
+ // Gauss points as necessary to
+ // determine the normal component
+ // uniquely. This is the deg of
+ // the Raviart-Thomas element plus
+ // one.
if (dim>1)
{
QGauss<dim-1> face_points (deg+1);
Assert (face_points.size() == this->dofs_per_face,
- ExcInternalError());
+ ExcInternalError());
for (unsigned int k=0;k<this->dofs_per_face;++k)
- this->generalized_face_support_points[k] = face_points.point(k);
+ this->generalized_face_support_points[k] = face_points.point(k);
Quadrature<dim> faces = QProjector<dim>::project_to_all_faces(face_points);
for (unsigned int k=0;
- k<this->dofs_per_face*GeometryInfo<dim>::faces_per_cell;
- ++k)
- this->generalized_support_points[k] = faces.point(k+QProjector<dim>
- ::DataSetDescriptor::face(0,
- true,
- false,
- false,
- this->dofs_per_face));
+ k<this->dofs_per_face*GeometryInfo<dim>::faces_per_cell;
+ ++k)
+ this->generalized_support_points[k] = faces.point(k+QProjector<dim>
+ ::DataSetDescriptor::face(0,
+ true,
+ false,
+ false,
+ this->dofs_per_face));
current = this->dofs_per_face*GeometryInfo<dim>::faces_per_cell;
}
if (deg==0) return;
- // In the interior, we need
- // anisotropic Gauss quadratures,
- // different for each direction.
+ // In the interior, we need
+ // anisotropic Gauss quadratures,
+ // different for each direction.
QGauss<1> high(deg+1);
QGauss<1> low(deg);
QAnisotropic<dim>* quadrature;
if (dim == 1) quadrature = new QAnisotropic<dim>(high);
if (dim == 2) quadrature = new QAnisotropic<dim>(((d==0) ? low : high),
- ((d==1) ? low : high));
+ ((d==1) ? low : high));
if (dim == 3) quadrature = new QAnisotropic<dim>(((d==0) ? low : high),
- ((d==1) ? low : high),
- ((d==2) ? low : high));
+ ((d==1) ? low : high),
+ ((d==2) ? low : high));
Assert(dim<=3, ExcNotImplemented());
for (unsigned int k=0;k<quadrature->size();++k)
- this->generalized_support_points[current++] = quadrature->point(k);
+ this->generalized_support_points[current++] = quadrature->point(k);
delete quadrature;
}
Assert (current == this->dofs_per_cell, ExcInternalError());
unsigned int dofs_per_face = deg+1;
for (unsigned int d=2;d<dim;++d)
dofs_per_face *= deg+1;
- // all face dofs need to be
- // non-additive, since they have
- // continuity requirements.
- // however, the interior dofs are
- // made additive
+ // all face dofs need to be
+ // non-additive, since they have
+ // continuity requirements.
+ // however, the interior dofs are
+ // made additive
std::vector<bool> ret_val(dofs_per_cell,false);
for (unsigned int i=GeometryInfo<dim>::faces_per_cell*dofs_per_face;
i < dofs_per_cell; ++i)
const unsigned int face_index) const
{
Assert (shape_index < this->dofs_per_cell,
- ExcIndexRange (shape_index, 0, this->dofs_per_cell));
+ ExcIndexRange (shape_index, 0, this->dofs_per_cell));
Assert (face_index < GeometryInfo<dim>::faces_per_cell,
- ExcIndexRange (face_index, 0, GeometryInfo<dim>::faces_per_cell));
+ ExcIndexRange (face_index, 0, GeometryInfo<dim>::faces_per_cell));
- // The first degrees of freedom are
- // on the faces and each face has
- // degree degrees.
+ // The first degrees of freedom are
+ // on the faces and each face has
+ // degree degrees.
const unsigned int support_face = shape_index / this->degree;
- // The only thing we know for sure
- // is that shape functions with
- // support on one face are zero on
- // the opposite face.
+ // The only thing we know for sure
+ // is that shape functions with
+ // support on one face are zero on
+ // the opposite face.
if (support_face < GeometryInfo<dim>::faces_per_cell)
return (face_index != GeometryInfo<dim>::opposite_face[support_face]);
- // In all other cases, return true,
- // which is safe
+ // In all other cases, return true,
+ // which is safe
return true;
}
unsigned int offset) const
{
Assert (values.size() == this->generalized_support_points.size(),
- ExcDimensionMismatch(values.size(), this->generalized_support_points.size()));
+ ExcDimensionMismatch(values.size(), this->generalized_support_points.size()));
Assert (local_dofs.size() == this->dofs_per_cell,
- ExcDimensionMismatch(local_dofs.size(),this->dofs_per_cell));
+ ExcDimensionMismatch(local_dofs.size(),this->dofs_per_cell));
Assert (values[0].size() >= offset+this->n_components(),
- ExcDimensionMismatch(values[0].size(),offset+this->n_components()));
+ ExcDimensionMismatch(values[0].size(),offset+this->n_components()));
- // First do interpolation on
- // faces. There, the component
- // evaluated depends on the face
- // direction and orientation.
+ // First do interpolation on
+ // faces. There, the component
+ // evaluated depends on the face
+ // direction and orientation.
unsigned int fbase = 0;
unsigned int f=0;
for (;f<GeometryInfo<dim>::faces_per_cell;
++f, fbase+=this->dofs_per_face)
{
for (unsigned int i=0;i<this->dofs_per_face;++i)
- {
- local_dofs[fbase+i] = values[fbase+i](offset+GeometryInfo<dim>::unit_normal_direction[f]);
- }
+ {
+ local_dofs[fbase+i] = values[fbase+i](offset+GeometryInfo<dim>::unit_normal_direction[f]);
+ }
}
- // The remaining points form dim
- // chunks, one for each component.
+ // The remaining points form dim
+ // chunks, one for each component.
const unsigned int istep = (this->dofs_per_cell - fbase) / dim;
Assert ((this->dofs_per_cell - fbase) % dim == 0, ExcInternalError());
while (fbase < this->dofs_per_cell)
{
for (unsigned int i=0;i<istep;++i)
- {
- local_dofs[fbase+i] = values[fbase+i](offset+f);
- }
+ {
+ local_dofs[fbase+i] = values[fbase+i](offset+f);
+ }
fbase+=istep;
++f;
}
const VectorSlice<const std::vector<std::vector<double> > >& values) const
{
Assert (values.size() == this->n_components(),
- ExcDimensionMismatch(values.size(), this->n_components()));
+ ExcDimensionMismatch(values.size(), this->n_components()));
Assert (values[0].size() == this->generalized_support_points.size(),
- ExcDimensionMismatch(values.size(), this->generalized_support_points.size()));
+ ExcDimensionMismatch(values.size(), this->generalized_support_points.size()));
Assert (local_dofs.size() == this->dofs_per_cell,
- ExcDimensionMismatch(local_dofs.size(),this->dofs_per_cell));
- // First do interpolation on
- // faces. There, the component
- // evaluated depends on the face
- // direction and orientation.
+ ExcDimensionMismatch(local_dofs.size(),this->dofs_per_cell));
+ // First do interpolation on
+ // faces. There, the component
+ // evaluated depends on the face
+ // direction and orientation.
unsigned int fbase = 0;
unsigned int f=0;
for (;f<GeometryInfo<dim>::faces_per_cell;
++f, fbase+=this->dofs_per_face)
{
for (unsigned int i=0;i<this->dofs_per_face;++i)
- {
- local_dofs[fbase+i] = values[GeometryInfo<dim>::unit_normal_direction[f]][fbase+i];
- }
+ {
+ local_dofs[fbase+i] = values[GeometryInfo<dim>::unit_normal_direction[f]][fbase+i];
+ }
}
- // The remaining points form dim
- // chunks, one for each component.
+ // The remaining points form dim
+ // chunks, one for each component.
const unsigned int istep = (this->dofs_per_cell - fbase) / dim;
Assert ((this->dofs_per_cell - fbase) % dim == 0, ExcInternalError());
while (fbase < this->dofs_per_cell)
{
for (unsigned int i=0;i<istep;++i)
- {
- local_dofs[fbase+i] = values[f][fbase+i];
- }
+ {
+ local_dofs[fbase+i] = values[f][fbase+i];
+ }
fbase+=istep;
++f;
}
FE_RaviartThomasNodal<dim>::hp_vertex_dof_identities (
const FiniteElement<dim> &fe_other) const
{
- // we can presently only compute these
- // identities if both FEs are
- // FE_RaviartThomasNodals. in that case, no
- // dofs are assigned on the vertex, so we
- // shouldn't be getting here at all.
+ // we can presently only compute these
+ // identities if both FEs are
+ // FE_RaviartThomasNodals. in that case, no
+ // dofs are assigned on the vertex, so we
+ // shouldn't be getting here at all.
if (dynamic_cast<const FE_RaviartThomasNodal<dim>*>(&fe_other)!=0)
return std::vector<std::pair<unsigned int, unsigned int> > ();
else
FE_RaviartThomasNodal<dim>::
hp_line_dof_identities (const FiniteElement<dim> &fe_other) const
{
- // we can presently only compute
- // these identities if both FEs are
- // FE_RaviartThomasNodals
+ // we can presently only compute
+ // these identities if both FEs are
+ // FE_RaviartThomasNodals
if (const FE_RaviartThomasNodal<dim> *fe_q_other
= dynamic_cast<const FE_RaviartThomasNodal<dim>*>(&fe_other))
{
- // dofs are located on faces; these are
- // only lines in 2d
+ // dofs are located on faces; these are
+ // only lines in 2d
if (dim != 2)
- return std::vector<std::pair<unsigned int, unsigned int> >();
-
- // dofs are located along lines, so two
- // dofs are identical only if in the
- // following two cases (remember that
- // the face support points are Gauss
- // points):
- //1. this->degree = fe_q_other->degree,
- // in the case, all the dofs on
- // the line are identical
- //2. this->degree-1 and fe_q_other->degree-1
- // are both even, i.e. this->dof_per_line
- // and fe_q_other->dof_per_line are both odd,
- // there exists only one point (the middle one)
- // such that dofs are identical on this point
- //
- // to understand this, note that
- // this->degree is the *maximal*
- // polynomial degree, and is thus one
- // higher than the argument given to
- // the constructor
+ return std::vector<std::pair<unsigned int, unsigned int> >();
+
+ // dofs are located along lines, so two
+ // dofs are identical only if in the
+ // following two cases (remember that
+ // the face support points are Gauss
+ // points):
+ //1. this->degree = fe_q_other->degree,
+ // in the case, all the dofs on
+ // the line are identical
+ //2. this->degree-1 and fe_q_other->degree-1
+ // are both even, i.e. this->dof_per_line
+ // and fe_q_other->dof_per_line are both odd,
+ // there exists only one point (the middle one)
+ // such that dofs are identical on this point
+ //
+ // to understand this, note that
+ // this->degree is the *maximal*
+ // polynomial degree, and is thus one
+ // higher than the argument given to
+ // the constructor
const unsigned int p = this->degree-1;
const unsigned int q = fe_q_other->degree-1;
std::vector<std::pair<unsigned int, unsigned int> > identities;
if (p==q)
- for (unsigned int i=0; i<p+1; ++i)
- identities.push_back (std::make_pair(i,i));
+ for (unsigned int i=0; i<p+1; ++i)
+ identities.push_back (std::make_pair(i,i));
else
- if (p%2==0 && q%2==0)
- identities.push_back(std::make_pair(p/2,q/2));
+ if (p%2==0 && q%2==0)
+ identities.push_back(std::make_pair(p/2,q/2));
return identities;
}
FE_RaviartThomasNodal<dim>::hp_quad_dof_identities (
const FiniteElement<dim>& fe_other) const
{
- // we can presently only compute
- // these identities if both FEs are
- // FE_RaviartThomasNodals
+ // we can presently only compute
+ // these identities if both FEs are
+ // FE_RaviartThomasNodals
if (const FE_RaviartThomasNodal<dim> *fe_q_other
= dynamic_cast<const FE_RaviartThomasNodal<dim>*>(&fe_other))
{
- // dofs are located on faces; these are
- // only quads in 3d
+ // dofs are located on faces; these are
+ // only quads in 3d
if (dim != 3)
- return std::vector<std::pair<unsigned int, unsigned int> >();
+ return std::vector<std::pair<unsigned int, unsigned int> >();
- // this works exactly like the line
- // case above
+ // this works exactly like the line
+ // case above
const unsigned int p = this->dofs_per_quad;
const unsigned int q = fe_q_other->dofs_per_quad;
std::vector<std::pair<unsigned int, unsigned int> > identities;
if (p==q)
- for (unsigned int i=0; i<p; ++i)
- identities.push_back (std::make_pair(i,i));
+ for (unsigned int i=0; i<p; ++i)
+ identities.push_back (std::make_pair(i,i));
else
- if (p%2!=0 && q%2!=0)
- identities.push_back(std::make_pair(p/2, q/2));
+ if (p%2!=0 && q%2!=0)
+ identities.push_back(std::make_pair(p/2, q/2));
return identities;
}
= dynamic_cast<const FE_RaviartThomasNodal<dim>*>(&fe_other))
{
if (this->degree < fe_q_other->degree)
- return FiniteElementDomination::this_element_dominates;
+ return FiniteElementDomination::this_element_dominates;
else if (this->degree == fe_q_other->degree)
- return FiniteElementDomination::either_element_can_dominate;
+ return FiniteElementDomination::either_element_can_dominate;
else
- return FiniteElementDomination::other_element_dominates;
+ return FiniteElementDomination::other_element_dominates;
}
Assert (false, ExcNotImplemented());
const FiniteElement<dim> &x_source_fe,
FullMatrix<double> &interpolation_matrix) const
{
- // this is only implemented, if the
- // source FE is also a
- // RaviartThomasNodal element
+ // this is only implemented, if the
+ // source FE is also a
+ // RaviartThomasNodal element
AssertThrow ((x_source_fe.get_name().find ("FE_RaviartThomasNodal<") == 0)
- ||
- (dynamic_cast<const FE_RaviartThomasNodal<dim>*>(&x_source_fe) != 0),
- typename FiniteElement<dim>::
- ExcInterpolationNotImplemented());
+ ||
+ (dynamic_cast<const FE_RaviartThomasNodal<dim>*>(&x_source_fe) != 0),
+ typename FiniteElement<dim>::
+ ExcInterpolationNotImplemented());
Assert (interpolation_matrix.n() == this->dofs_per_face,
- ExcDimensionMismatch (interpolation_matrix.n(),
- this->dofs_per_face));
+ ExcDimensionMismatch (interpolation_matrix.n(),
+ this->dofs_per_face));
Assert (interpolation_matrix.m() == x_source_fe.dofs_per_face,
- ExcDimensionMismatch (interpolation_matrix.m(),
- x_source_fe.dofs_per_face));
+ ExcDimensionMismatch (interpolation_matrix.m(),
+ x_source_fe.dofs_per_face));
- // ok, source is a RaviartThomasNodal element, so
- // we will be able to do the work
+ // ok, source is a RaviartThomasNodal element, so
+ // we will be able to do the work
const FE_RaviartThomasNodal<dim> &source_fe
= dynamic_cast<const FE_RaviartThomasNodal<dim>&>(x_source_fe);
- // Make sure, that the element,
- // for which the DoFs should be
- // constrained is the one with
- // the higher polynomial degree.
- // Actually the procedure will work
- // also if this assertion is not
- // satisfied. But the matrices
- // produced in that case might
- // lead to problems in the
- // hp procedures, which use this
- // method.
+ // Make sure, that the element,
+ // for which the DoFs should be
+ // constrained is the one with
+ // the higher polynomial degree.
+ // Actually the procedure will work
+ // also if this assertion is not
+ // satisfied. But the matrices
+ // produced in that case might
+ // lead to problems in the
+ // hp procedures, which use this
+ // method.
Assert (this->dofs_per_face <= source_fe.dofs_per_face,
- typename FiniteElement<dim>::
- ExcInterpolationNotImplemented ());
-
- // generate a quadrature
- // with the generalized support points.
- // This is later based as a
- // basis for the QProjector,
- // which returns the support
- // points on the face.
+ typename FiniteElement<dim>::
+ ExcInterpolationNotImplemented ());
+
+ // generate a quadrature
+ // with the generalized support points.
+ // This is later based as a
+ // basis for the QProjector,
+ // which returns the support
+ // points on the face.
Quadrature<dim-1> quad_face_support (source_fe.get_generalized_face_support_points ());
- // Rule of thumb for FP accuracy,
- // that can be expected for a
- // given polynomial degree.
- // This value is used to cut
- // off values close to zero.
+ // Rule of thumb for FP accuracy,
+ // that can be expected for a
+ // given polynomial degree.
+ // This value is used to cut
+ // off values close to zero.
double eps = 2e-13*this->degree*(dim-1);
- // compute the interpolation
- // matrix by simply taking the
- // value at the support points.
+ // compute the interpolation
+ // matrix by simply taking the
+ // value at the support points.
const Quadrature<dim> face_projection
= QProjector<dim>::project_to_face (quad_face_support, 0);
const Point<dim> &p = face_projection.point (i);
for (unsigned int j=0; j<this->dofs_per_face; ++j)
- {
- double matrix_entry
- = this->shape_value_component (this->face_to_cell_index(j, 0),
- p, 0);
-
- // Correct the interpolated
- // value. I.e. if it is close
- // to 1 or 0, make it exactly
- // 1 or 0. Unfortunately, this
- // is required to avoid problems
- // with higher order elements.
- if ( std::fabs(matrix_entry - 1.0) < eps )
- matrix_entry = 1.0;
- if ( std::fabs(matrix_entry) < eps )
- matrix_entry = 0.0;
-
- interpolation_matrix(i,j) = matrix_entry;
- }
+ {
+ double matrix_entry
+ = this->shape_value_component (this->face_to_cell_index(j, 0),
+ p, 0);
+
+ // Correct the interpolated
+ // value. I.e. if it is close
+ // to 1 or 0, make it exactly
+ // 1 or 0. Unfortunately, this
+ // is required to avoid problems
+ // with higher order elements.
+ if ( std::fabs(matrix_entry - 1.0) < eps )
+ matrix_entry = 1.0;
+ if ( std::fabs(matrix_entry) < eps )
+ matrix_entry = 0.0;
+
+ interpolation_matrix(i,j) = matrix_entry;
+ }
}
- // make sure that the row sum of
- // each of the matrices is 1 at
- // this point. this must be so
- // since the shape functions sum up
- // to 1
+ // make sure that the row sum of
+ // each of the matrices is 1 at
+ // this point. this must be so
+ // since the shape functions sum up
+ // to 1
for (unsigned int j=0; j<source_fe.dofs_per_face; ++j)
{
double sum = 0.;
for (unsigned int i=0; i<this->dofs_per_face; ++i)
- sum += interpolation_matrix(j,i);
+ sum += interpolation_matrix(j,i);
Assert (std::fabs(sum-1) < 2e-13*this->degree*(dim-1),
- ExcInternalError());
+ ExcInternalError());
}
}
const unsigned int subface,
FullMatrix<double> &interpolation_matrix) const
{
- // this is only implemented, if the
- // source FE is also a
- // RaviartThomasNodal element
+ // this is only implemented, if the
+ // source FE is also a
+ // RaviartThomasNodal element
AssertThrow ((x_source_fe.get_name().find ("FE_RaviartThomasNodal<") == 0)
- ||
- (dynamic_cast<const FE_RaviartThomasNodal<dim>*>(&x_source_fe) != 0),
- typename FiniteElement<dim>::
- ExcInterpolationNotImplemented());
+ ||
+ (dynamic_cast<const FE_RaviartThomasNodal<dim>*>(&x_source_fe) != 0),
+ typename FiniteElement<dim>::
+ ExcInterpolationNotImplemented());
Assert (interpolation_matrix.n() == this->dofs_per_face,
- ExcDimensionMismatch (interpolation_matrix.n(),
- this->dofs_per_face));
+ ExcDimensionMismatch (interpolation_matrix.n(),
+ this->dofs_per_face));
Assert (interpolation_matrix.m() == x_source_fe.dofs_per_face,
- ExcDimensionMismatch (interpolation_matrix.m(),
- x_source_fe.dofs_per_face));
+ ExcDimensionMismatch (interpolation_matrix.m(),
+ x_source_fe.dofs_per_face));
- // ok, source is a RaviartThomasNodal element, so
- // we will be able to do the work
+ // ok, source is a RaviartThomasNodal element, so
+ // we will be able to do the work
const FE_RaviartThomasNodal<dim> &source_fe
= dynamic_cast<const FE_RaviartThomasNodal<dim>&>(x_source_fe);
- // Make sure, that the element,
- // for which the DoFs should be
- // constrained is the one with
- // the higher polynomial degree.
- // Actually the procedure will work
- // also if this assertion is not
- // satisfied. But the matrices
- // produced in that case might
- // lead to problems in the
- // hp procedures, which use this
- // method.
+ // Make sure, that the element,
+ // for which the DoFs should be
+ // constrained is the one with
+ // the higher polynomial degree.
+ // Actually the procedure will work
+ // also if this assertion is not
+ // satisfied. But the matrices
+ // produced in that case might
+ // lead to problems in the
+ // hp procedures, which use this
+ // method.
Assert (this->dofs_per_face <= source_fe.dofs_per_face,
- typename FiniteElement<dim>::
- ExcInterpolationNotImplemented ());
-
- // generate a quadrature
- // with the generalized support points.
- // This is later based as a
- // basis for the QProjector,
- // which returns the support
- // points on the face.
+ typename FiniteElement<dim>::
+ ExcInterpolationNotImplemented ());
+
+ // generate a quadrature
+ // with the generalized support points.
+ // This is later based as a
+ // basis for the QProjector,
+ // which returns the support
+ // points on the face.
Quadrature<dim-1> quad_face_support (source_fe.get_generalized_face_support_points ());
- // Rule of thumb for FP accuracy,
- // that can be expected for a
- // given polynomial degree.
- // This value is used to cut
- // off values close to zero.
+ // Rule of thumb for FP accuracy,
+ // that can be expected for a
+ // given polynomial degree.
+ // This value is used to cut
+ // off values close to zero.
double eps = 2e-13*this->degree*(dim-1);
- // compute the interpolation
- // matrix by simply taking the
- // value at the support points.
+ // compute the interpolation
+ // matrix by simply taking the
+ // value at the support points.
const Quadrature<dim> subface_projection
= QProjector<dim>::project_to_subface (quad_face_support, 0, subface);
const Point<dim> &p = subface_projection.point (i);
for (unsigned int j=0; j<this->dofs_per_face; ++j)
- {
- double matrix_entry
- = this->shape_value_component (this->face_to_cell_index(j, 0), p, 0);
-
- // Correct the interpolated
- // value. I.e. if it is close
- // to 1 or 0, make it exactly
- // 1 or 0. Unfortunately, this
- // is required to avoid problems
- // with higher order elements.
- if ( std::fabs(matrix_entry - 1.0) < eps )
- matrix_entry = 1.0;
- if ( std::fabs(matrix_entry) < eps )
- matrix_entry = 0.0;
-
- interpolation_matrix(i,j) = matrix_entry;
- }
+ {
+ double matrix_entry
+ = this->shape_value_component (this->face_to_cell_index(j, 0), p, 0);
+
+ // Correct the interpolated
+ // value. I.e. if it is close
+ // to 1 or 0, make it exactly
+ // 1 or 0. Unfortunately, this
+ // is required to avoid problems
+ // with higher order elements.
+ if ( std::fabs(matrix_entry - 1.0) < eps )
+ matrix_entry = 1.0;
+ if ( std::fabs(matrix_entry) < eps )
+ matrix_entry = 0.0;
+
+ interpolation_matrix(i,j) = matrix_entry;
+ }
}
- // make sure that the row sum of
- // each of the matrices is 1 at
- // this point. this must be so
- // since the shape functions sum up
- // to 1
+ // make sure that the row sum of
+ // each of the matrices is 1 at
+ // this point. this must be so
+ // since the shape functions sum up
+ // to 1
for (unsigned int j=0; j<source_fe.dofs_per_face; ++j)
{
double sum = 0.;
for (unsigned int i=0; i<this->dofs_per_face; ++i)
- sum += interpolation_matrix(j,i);
+ sum += interpolation_matrix(j,i);
Assert (std::fabs(sum-1) < 2e-13*this->degree*(dim-1),
- ExcInternalError());
+ ExcInternalError());
}
}
template <int dim, int spacedim>
FESystem<dim,spacedim>::InternalData::InternalData(const unsigned int n_base_elements):
- base_fe_datas(n_base_elements),
- base_fe_values_datas(n_base_elements)
+ base_fe_datas(n_base_elements),
+ base_fe_values_datas(n_base_elements)
{}
template <int dim, int spacedim>
FESystem<dim,spacedim>::InternalData::~InternalData()
{
- // delete pointers and set them to
- // zero to avoid inadvertant use
+ // delete pointers and set them to
+ // zero to avoid inadvertant use
for (unsigned int i=0; i<base_fe_datas.size(); ++i)
if (base_fe_datas[i])
{
- delete base_fe_datas[i];
- base_fe_datas[i] = 0;
+ delete base_fe_datas[i];
+ base_fe_datas[i] = 0;
};
for (unsigned int i=0; i<base_fe_values_datas.size(); ++i)
if (base_fe_values_datas[i])
{
- delete base_fe_values_datas[i];
- base_fe_values_datas[i] = 0;
+ delete base_fe_values_datas[i];
+ base_fe_values_datas[i] = 0;
};
}
InternalData::get_fe_data (const unsigned int base_no) const
{
Assert(base_no<base_fe_datas.size(),
- ExcIndexRange(base_no,0,base_fe_datas.size()));
+ ExcIndexRange(base_no,0,base_fe_datas.size()));
return *base_fe_datas[base_no];
}
void
FESystem<dim,spacedim>::
InternalData::set_fe_data (const unsigned int base_no,
- typename FiniteElement<dim,spacedim>::InternalDataBase *ptr)
+ typename FiniteElement<dim,spacedim>::InternalDataBase *ptr)
{
Assert(base_no<base_fe_datas.size(),
- ExcIndexRange(base_no,0,base_fe_datas.size()));
+ ExcIndexRange(base_no,0,base_fe_datas.size()));
base_fe_datas[base_no]=ptr;
}
InternalData::get_fe_values_data (const unsigned int base_no) const
{
Assert(base_no<base_fe_values_datas.size(),
- ExcIndexRange(base_no,0,base_fe_values_datas.size()));
+ ExcIndexRange(base_no,0,base_fe_values_datas.size()));
Assert(base_fe_values_datas[base_no]!=0, ExcInternalError());
return *base_fe_values_datas[base_no];
}
void
FESystem<dim,spacedim>::
InternalData::set_fe_values_data (const unsigned int base_no,
- FEValuesData<dim,spacedim> *ptr)
+ FEValuesData<dim,spacedim> *ptr)
{
Assert(base_no<base_fe_values_datas.size(),
- ExcIndexRange(base_no,0,base_fe_values_datas.size()));
+ ExcIndexRange(base_no,0,base_fe_values_datas.size()));
base_fe_values_datas[base_no]=ptr;
}
InternalData::delete_fe_values_data (const unsigned int base_no)
{
Assert(base_no<base_fe_values_datas.size(),
- ExcIndexRange(base_no,0,base_fe_values_datas.size()));
+ ExcIndexRange(base_no,0,base_fe_values_datas.size()));
Assert(base_fe_values_datas[base_no]!=0, ExcInternalError());
delete base_fe_values_datas[base_no];
base_fe_values_datas[base_no]=0;
template <int dim, int spacedim>
FESystem<dim,spacedim>::FESystem (const FiniteElement<dim,spacedim> &fe,
- const unsigned int n_elements) :
- FiniteElement<dim,spacedim> (multiply_dof_numbers(fe, n_elements),
- compute_restriction_is_additive_flags (fe, n_elements),
- compute_nonzero_components(fe, n_elements)),
+ const unsigned int n_elements) :
+ FiniteElement<dim,spacedim> (multiply_dof_numbers(fe, n_elements),
+ compute_restriction_is_additive_flags (fe, n_elements),
+ compute_nonzero_components(fe, n_elements)),
base_elements(1)
{
this->base_to_block_indices.reinit(0, 0);
template <int dim, int spacedim>
FESystem<dim,spacedim>::FESystem (const FiniteElement<dim,spacedim> &fe1,
- const unsigned int n1,
- const FiniteElement<dim,spacedim> &fe2,
- const unsigned int n2) :
- FiniteElement<dim,spacedim> (multiply_dof_numbers(fe1, n1, fe2, n2),
- compute_restriction_is_additive_flags (fe1, n1,
- fe2, n2),
- compute_nonzero_components(fe1, n1,
- fe2, n2)),
+ const unsigned int n1,
+ const FiniteElement<dim,spacedim> &fe2,
+ const unsigned int n2) :
+ FiniteElement<dim,spacedim> (multiply_dof_numbers(fe1, n1, fe2, n2),
+ compute_restriction_is_additive_flags (fe1, n1,
+ fe2, n2),
+ compute_nonzero_components(fe1, n1,
+ fe2, n2)),
base_elements(2)
{
this->base_to_block_indices.reinit(0, 0);
template <int dim, int spacedim>
FESystem<dim,spacedim>::FESystem (const FiniteElement<dim,spacedim> &fe1,
- const unsigned int n1,
- const FiniteElement<dim,spacedim> &fe2,
- const unsigned int n2,
- const FiniteElement<dim,spacedim> &fe3,
- const unsigned int n3) :
+ const unsigned int n1,
+ const FiniteElement<dim,spacedim> &fe2,
+ const unsigned int n2,
+ const FiniteElement<dim,spacedim> &fe3,
+ const unsigned int n3) :
FiniteElement<dim,spacedim> (multiply_dof_numbers(fe1, n1,
- fe2, n2,
- fe3, n3),
- compute_restriction_is_additive_flags (fe1, n1,
- fe2, n2,
- fe3, n3),
- compute_nonzero_components(fe1, n1,
- fe2, n2,
- fe3, n3)),
+ fe2, n2,
+ fe3, n3),
+ compute_restriction_is_additive_flags (fe1, n1,
+ fe2, n2,
+ fe3, n3),
+ compute_nonzero_components(fe1, n1,
+ fe2, n2,
+ fe3, n3)),
base_elements(3)
{
this->base_to_block_indices.reinit(0, 0);
template <int dim, int spacedim>
FESystem<dim,spacedim>::FESystem (const FiniteElement<dim,spacedim> &fe1,
- const unsigned int n1,
- const FiniteElement<dim,spacedim> &fe2,
- const unsigned int n2,
- const FiniteElement<dim,spacedim> &fe3,
- const unsigned int n3,
- const FiniteElement<dim,spacedim> &fe4,
- const unsigned int n4) :
+ const unsigned int n1,
+ const FiniteElement<dim,spacedim> &fe2,
+ const unsigned int n2,
+ const FiniteElement<dim,spacedim> &fe3,
+ const unsigned int n3,
+ const FiniteElement<dim,spacedim> &fe4,
+ const unsigned int n4) :
FiniteElement<dim,spacedim> (multiply_dof_numbers(fe1, n1,
- fe2, n2,
- fe3, n3,
- fe4, n4),
- compute_restriction_is_additive_flags (fe1, n1,
- fe2, n2,
- fe3, n3,
- fe4, n4),
- compute_nonzero_components(fe1, n1,
- fe2, n2,
- fe3, n3,
- fe4 ,n4)),
+ fe2, n2,
+ fe3, n3,
+ fe4, n4),
+ compute_restriction_is_additive_flags (fe1, n1,
+ fe2, n2,
+ fe3, n3,
+ fe4, n4),
+ compute_nonzero_components(fe1, n1,
+ fe2, n2,
+ fe3, n3,
+ fe4 ,n4)),
base_elements(4)
{
this->base_to_block_indices.reinit(0, 0);
template <int dim, int spacedim>
FESystem<dim,spacedim>::FESystem (const FiniteElement<dim,spacedim> &fe1,
- const unsigned int n1,
- const FiniteElement<dim,spacedim> &fe2,
- const unsigned int n2,
- const FiniteElement<dim,spacedim> &fe3,
- const unsigned int n3,
- const FiniteElement<dim,spacedim> &fe4,
- const unsigned int n4,
- const FiniteElement<dim,spacedim> &fe5,
- const unsigned int n5) :
+ const unsigned int n1,
+ const FiniteElement<dim,spacedim> &fe2,
+ const unsigned int n2,
+ const FiniteElement<dim,spacedim> &fe3,
+ const unsigned int n3,
+ const FiniteElement<dim,spacedim> &fe4,
+ const unsigned int n4,
+ const FiniteElement<dim,spacedim> &fe5,
+ const unsigned int n5) :
FiniteElement<dim,spacedim> (multiply_dof_numbers(fe1, n1,
- fe2, n2,
- fe3, n3,
- fe4, n4,
- fe5, n5),
- compute_restriction_is_additive_flags (fe1, n1,
- fe2, n2,
- fe3, n3,
- fe4, n4,
- fe5, n5),
- compute_nonzero_components(fe1, n1,
- fe2, n2,
- fe3, n3,
- fe4 ,n4,
- fe5, n5)),
+ fe2, n2,
+ fe3, n3,
+ fe4, n4,
+ fe5, n5),
+ compute_restriction_is_additive_flags (fe1, n1,
+ fe2, n2,
+ fe3, n3,
+ fe4, n4,
+ fe5, n5),
+ compute_nonzero_components(fe1, n1,
+ fe2, n2,
+ fe3, n3,
+ fe4 ,n4,
+ fe5, n5)),
base_elements(5)
{
this->base_to_block_indices.reinit(0, 0);
FESystem<dim,spacedim>::FESystem (
const std::vector<const FiniteElement<dim,spacedim>*> &fes,
const std::vector<unsigned int> &multiplicities)
- :
- FiniteElement<dim,spacedim> (multiply_dof_numbers(fes, multiplicities),
- compute_restriction_is_additive_flags (fes, multiplicities),
- compute_nonzero_components(fes, multiplicities)),
- base_elements(fes.size())
+ :
+ FiniteElement<dim,spacedim> (multiply_dof_numbers(fes, multiplicities),
+ compute_restriction_is_additive_flags (fes, multiplicities),
+ compute_nonzero_components(fes, multiplicities)),
+ base_elements(fes.size())
{
Assert (fes.size() == multiplicities.size(),
- ExcDimensionMismatch (fes.size(), multiplicities.size()) );
+ ExcDimensionMismatch (fes.size(), multiplicities.size()) );
Assert (fes.size() > 0,
- ExcMessage ("Need to pass at least one finite element."));
+ ExcMessage ("Need to pass at least one finite element."));
this->base_to_block_indices.reinit(0, 0);
template <int dim, int spacedim>
FESystem<dim,spacedim>::~FESystem ()
{
- // delete base elements created in
- // the constructor
+ // delete base elements created in
+ // the constructor
for (unsigned i=0; i<base_elements.size(); ++i)
{
base_elements[i].first->unsubscribe(typeid(*this).name());
std::string
FESystem<dim,spacedim>::get_name () const
{
- // note that the
- // FETools::get_fe_from_name
- // function depends on the
- // particular format of the string
- // this function returns, so they
- // have to be kept in synch
+ // note that the
+ // FETools::get_fe_from_name
+ // function depends on the
+ // particular format of the string
+ // this function returns, so they
+ // have to be kept in synch
std::ostringstream namebuf;
{
namebuf << base_element(i).get_name();
if (this->element_multiplicity(i) != 1)
- namebuf << '^' << this->element_multiplicity(i);
+ namebuf << '^' << this->element_multiplicity(i);
if (i != this->n_base_elements()-1)
- namebuf << '-';
+ namebuf << '-';
}
namebuf << ']';
{
case 1:
return new FESystem(base_element(0),
- this->element_multiplicity(0));
+ this->element_multiplicity(0));
case 2:
return new FESystem(base_element(0),
- this->element_multiplicity(0),
- base_element(1),
- this->element_multiplicity(1));
+ this->element_multiplicity(0),
+ base_element(1),
+ this->element_multiplicity(1));
case 3:
return new FESystem(base_element(0),
- this->element_multiplicity(0),
- base_element(1),
- this->element_multiplicity(1),
- base_element(2),
- this->element_multiplicity(2));
+ this->element_multiplicity(0),
+ base_element(1),
+ this->element_multiplicity(1),
+ base_element(2),
+ this->element_multiplicity(2));
case 4:
return new FESystem(base_element(0),
- this->element_multiplicity(0),
- base_element(1),
- this->element_multiplicity(1),
- base_element(2),
- this->element_multiplicity(2),
- base_element(3),
- this->element_multiplicity(3));
+ this->element_multiplicity(0),
+ base_element(1),
+ this->element_multiplicity(1),
+ base_element(2),
+ this->element_multiplicity(2),
+ base_element(3),
+ this->element_multiplicity(3));
case 5:
return new FESystem(base_element(0),
- this->element_multiplicity(0),
- base_element(1),
- this->element_multiplicity(1),
- base_element(2),
- this->element_multiplicity(2),
- base_element(3),
- this->element_multiplicity(3),
- base_element(4),
- this->element_multiplicity(4));
+ this->element_multiplicity(0),
+ base_element(1),
+ this->element_multiplicity(1),
+ base_element(2),
+ this->element_multiplicity(2),
+ base_element(3),
+ this->element_multiplicity(3),
+ base_element(4),
+ this->element_multiplicity(4));
default:
- Assert(false, ExcNotImplemented());
+ Assert(false, ExcNotImplemented());
}
return 0;
}
template <int dim, int spacedim>
double
FESystem<dim,spacedim>::shape_value (const unsigned int i,
- const Point<dim> &p) const
+ const Point<dim> &p) const
{
Assert (i<this->dofs_per_cell, ExcIndexRange(i, 0, this->dofs_per_cell));
Assert (this->is_primitive(i),
- (typename FiniteElement<dim,spacedim>::ExcShapeFunctionNotPrimitive(i)));
+ (typename FiniteElement<dim,spacedim>::ExcShapeFunctionNotPrimitive(i)));
return (base_element(this->system_to_base_table[i].first.first)
- .shape_value(this->system_to_base_table[i].second, p));
+ .shape_value(this->system_to_base_table[i].second, p));
}
template <int dim, int spacedim>
double
FESystem<dim,spacedim>::shape_value_component (const unsigned int i,
- const Point<dim> &p,
- const unsigned int component) const
+ const Point<dim> &p,
+ const unsigned int component) const
{
Assert (i<this->dofs_per_cell, ExcIndexRange(i, 0, this->dofs_per_cell));
Assert (component < this->n_components(),
- ExcIndexRange (component, 0, this->n_components()));
+ ExcIndexRange (component, 0, this->n_components()));
// if this value is supposed to be
// zero, then return right away...
return 0;
// ...otherwise: first find out to
- // which of the base elements this
- // desired component belongs, and
- // which component within this base
- // element it is
+ // which of the base elements this
+ // desired component belongs, and
+ // which component within this base
+ // element it is
const unsigned int base = this->component_to_base_index(component).first;
const unsigned int component_in_base = this->component_to_base_index(component).second;
- // then get value from base
- // element. note that that will
- // throw an error should the
- // respective shape function not be
- // primitive; thus, there is no
- // need to check this here
+ // then get value from base
+ // element. note that that will
+ // throw an error should the
+ // respective shape function not be
+ // primitive; thus, there is no
+ // need to check this here
return (base_element(base).
- shape_value_component(this->system_to_base_table[i].second,
- p,
- component_in_base));
+ shape_value_component(this->system_to_base_table[i].second,
+ p,
+ component_in_base));
}
template <int dim, int spacedim>
Tensor<1,dim>
FESystem<dim,spacedim>::shape_grad (const unsigned int i,
- const Point<dim> &p) const
+ const Point<dim> &p) const
{
Assert (i<this->dofs_per_cell, ExcIndexRange(i, 0, this->dofs_per_cell));
Assert (this->is_primitive(i),
- (typename FiniteElement<dim,spacedim>::ExcShapeFunctionNotPrimitive(i)));
+ (typename FiniteElement<dim,spacedim>::ExcShapeFunctionNotPrimitive(i)));
return (base_element(this->system_to_base_table[i].first.first)
- .shape_grad(this->system_to_base_table[i].second, p));
+ .shape_grad(this->system_to_base_table[i].second, p));
}
template <int dim, int spacedim>
Tensor<1,dim>
FESystem<dim,spacedim>::shape_grad_component (const unsigned int i,
- const Point<dim> &p,
- const unsigned int component) const
+ const Point<dim> &p,
+ const unsigned int component) const
{
Assert (i<this->dofs_per_cell, ExcIndexRange(i, 0, this->dofs_per_cell));
Assert (component < this->n_components(),
- ExcIndexRange (component, 0, this->n_components()));
+ ExcIndexRange (component, 0, this->n_components()));
// if this value is supposed to be
// zero, then return right away...
return Tensor<1,dim>();
// ...otherwise: first find out to
- // which of the base elements this
- // desired component belongs, and
- // which component within this base
- // element it is
+ // which of the base elements this
+ // desired component belongs, and
+ // which component within this base
+ // element it is
const unsigned int base = this->component_to_base_index(component).first;
const unsigned int component_in_base = this->component_to_base_index(component).second;
- // then get value from base
- // element. note that that will
- // throw an error should the
- // respective shape function not be
- // primitive; thus, there is no
- // need to check this here
+ // then get value from base
+ // element. note that that will
+ // throw an error should the
+ // respective shape function not be
+ // primitive; thus, there is no
+ // need to check this here
return (base_element(base).
- shape_grad_component(this->system_to_base_table[i].second,
- p,
- component_in_base));
+ shape_grad_component(this->system_to_base_table[i].second,
+ p,
+ component_in_base));
}
template <int dim, int spacedim>
Tensor<2,dim>
FESystem<dim,spacedim>::shape_grad_grad (const unsigned int i,
- const Point<dim> &p) const
+ const Point<dim> &p) const
{
Assert (i<this->dofs_per_cell, ExcIndexRange(i, 0, this->dofs_per_cell));
Assert (this->is_primitive(i),
- (typename FiniteElement<dim,spacedim>::ExcShapeFunctionNotPrimitive(i)));
+ (typename FiniteElement<dim,spacedim>::ExcShapeFunctionNotPrimitive(i)));
return (base_element(this->system_to_base_table[i].first.first)
- .shape_grad_grad(this->system_to_base_table[i].second, p));
+ .shape_grad_grad(this->system_to_base_table[i].second, p));
}
template <int dim, int spacedim>
Tensor<2,dim>
FESystem<dim,spacedim>::shape_grad_grad_component (const unsigned int i,
- const Point<dim> &p,
- const unsigned int component) const
+ const Point<dim> &p,
+ const unsigned int component) const
{
Assert (i<this->dofs_per_cell, ExcIndexRange(i, 0, this->dofs_per_cell));
Assert (component < this->n_components(),
- ExcIndexRange (component, 0, this->n_components()));
+ ExcIndexRange (component, 0, this->n_components()));
// if this value is supposed to be
// zero, then return right away...
return Tensor<2,dim>();
// ...otherwise: first find out to
- // which of the base elements this
- // desired component belongs, and
- // which component within this base
- // element it is
+ // which of the base elements this
+ // desired component belongs, and
+ // which component within this base
+ // element it is
const unsigned int base = this->component_to_base_index(component).first;
const unsigned int component_in_base = this->component_to_base_index(component).second;
- // then get value from base
- // element. note that that will
- // throw an error should the
- // respective shape function not be
- // primitive; thus, there is no
- // need to check this here
+ // then get value from base
+ // element. note that that will
+ // throw an error should the
+ // respective shape function not be
+ // primitive; thus, there is no
+ // need to check this here
return (base_element(base).
- shape_grad_grad_component(this->system_to_base_table[i].second,
- p,
- component_in_base));
+ shape_grad_grad_component(this->system_to_base_table[i].second,
+ p,
+ component_in_base));
}
FullMatrix<double> &interpolation_matrix) const
{
Assert (interpolation_matrix.m() == this->dofs_per_cell,
- ExcDimensionMismatch (interpolation_matrix.m(),
- this->dofs_per_cell));
+ ExcDimensionMismatch (interpolation_matrix.m(),
+ this->dofs_per_cell));
Assert (interpolation_matrix.n() == x_source_fe.dofs_per_cell,
- ExcDimensionMismatch (interpolation_matrix.m(),
- x_source_fe.dofs_per_cell));
+ ExcDimensionMismatch (interpolation_matrix.m(),
+ x_source_fe.dofs_per_cell));
// there are certain conditions
// that the two elements have to
typename FEL::
ExcInterpolationNotImplemented());
- // ok, source is a system element,
- // so we may be able to do the work
+ // ok, source is a system element,
+ // so we may be able to do the work
const FESystem<dim,spacedim> &source_fe
= dynamic_cast<const FESystem<dim,spacedim>&>(x_source_fe);
FESystem<dim,spacedim>::update_once (const UpdateFlags flags) const
{
UpdateFlags out = update_default;
- // generate maximal set of flags
- // that are necessary
+ // generate maximal set of flags
+ // that are necessary
for (unsigned int base_no=0; base_no<this->n_base_elements(); ++base_no)
out |= base_element(base_no).update_once(flags);
return out;
FESystem<dim,spacedim>::update_each (const UpdateFlags flags) const
{
UpdateFlags out = update_default;
- // generate maximal set of flags
- // that are necessary
+ // generate maximal set of flags
+ // that are necessary
for (unsigned int base_no=0; base_no<this->n_base_elements(); ++base_no)
out |= base_element(base_no).update_each(flags);
- // second derivatives are handled
- // by the top-level finite element,
- // rather than by the base elements
- // since it is generated by finite
- // differencing. if second
- // derivatives are requested, we
- // therefore have to set the
- // respective flag since the base
- // elements don't have them
+ // second derivatives are handled
+ // by the top-level finite element,
+ // rather than by the base elements
+ // since it is generated by finite
+ // differencing. if second
+ // derivatives are requested, we
+ // therefore have to set the
+ // respective flag since the base
+ // elements don't have them
if (flags & update_hessians)
out |= update_hessians | update_covariant_transformation;
template <int dim, int spacedim>
typename Mapping<dim,spacedim>::InternalDataBase *
FESystem<dim,spacedim>::get_data (const UpdateFlags flags_,
- const Mapping<dim,spacedim> &mapping,
- const Quadrature<dim> &quadrature) const
+ const Mapping<dim,spacedim> &mapping,
+ const Quadrature<dim> &quadrature) const
{
UpdateFlags flags = flags_;
InternalData* data = new InternalData(this->n_base_elements());
flags = data->update_once | data->update_each;
UpdateFlags sub_flags = flags;
- // if second derivatives through
- // finite differencing are required,
- // then initialize some objects for
- // that
+ // if second derivatives through
+ // finite differencing are required,
+ // then initialize some objects for
+ // that
data->compute_hessians = flags & update_hessians;
if (data->compute_hessians)
{
- // delete
- // update_hessians
- // from flags list
+ // delete
+ // update_hessians
+ // from flags list
sub_flags = UpdateFlags (sub_flags ^ update_hessians);
data->initialize_2nd (this, mapping, quadrature);
}
- // get data objects from each of
- // the base elements and store them
+ // get data objects from each of
+ // the base elements and store them
for (unsigned int base_no=0; base_no<this->n_base_elements(); ++base_no)
{
typename Mapping<dim,spacedim>::InternalDataBase *base_fe_data_base =
- base_element(base_no).get_data(sub_flags, mapping, quadrature);
+ base_element(base_no).get_data(sub_flags, mapping, quadrature);
typename FiniteElement<dim,spacedim>::InternalDataBase *base_fe_data =
- dynamic_cast<typename FiniteElement<dim,spacedim>::InternalDataBase *>
- (base_fe_data_base);
+ dynamic_cast<typename FiniteElement<dim,spacedim>::InternalDataBase *>
+ (base_fe_data_base);
Assert (base_fe_data != 0, ExcInternalError());
data->set_fe_data(base_no, base_fe_data);
- // make sure that *we* compute
- // second derivatives, base
- // elements should not do it
+ // make sure that *we* compute
+ // second derivatives, base
+ // elements should not do it
Assert (!(base_fe_data->update_each & update_hessians),
- ExcInternalError());
+ ExcInternalError());
Assert (!(base_fe_data->update_once & update_hessians),
- ExcInternalError());
-
- // The FEValuesData @p{data}
- // given to the
- // @p{fill_fe_values} function
- // includes the FEValuesDatas
- // of the FESystem. Here the
- // FEValuesDatas @p{*base_data}
- // needs to be created that
- // later will be given to the
- // @p{fill_fe_values} functions
- // of the base
- // elements. @p{base_data->initialize}
- // cannot be called earlier as
- // in the @p{fill_fe_values}
- // function called for the
- // first cell. This is because
- // the initialize function
- // needs the update flags as
- // argument.
- //
- // The pointers @p{base_data}
- // are stored into the
- // FESystem::InternalData
- // @p{data}, similar to the
- // storing of the
- // @p{base_fe_data}s.
+ ExcInternalError());
+
+ // The FEValuesData @p{data}
+ // given to the
+ // @p{fill_fe_values} function
+ // includes the FEValuesDatas
+ // of the FESystem. Here the
+ // FEValuesDatas @p{*base_data}
+ // needs to be created that
+ // later will be given to the
+ // @p{fill_fe_values} functions
+ // of the base
+ // elements. @p{base_data->initialize}
+ // cannot be called earlier as
+ // in the @p{fill_fe_values}
+ // function called for the
+ // first cell. This is because
+ // the initialize function
+ // needs the update flags as
+ // argument.
+ //
+ // The pointers @p{base_data}
+ // are stored into the
+ // FESystem::InternalData
+ // @p{data}, similar to the
+ // storing of the
+ // @p{base_fe_data}s.
FEValuesData<dim,spacedim> *base_data = new FEValuesData<dim,spacedim>();
data->set_fe_values_data(base_no, base_data);
}
data->update_flags = data->update_once |
- data->update_each;
+ data->update_each;
return data;
}
for (unsigned int base_no=0; base_no<this->n_base_elements(); ++base_no)
{
typename Mapping<dim,spacedim>::InternalDataBase *base_fe_data_base =
- base_element(base_no).get_face_data(sub_flags, mapping, quadrature);
+ base_element(base_no).get_face_data(sub_flags, mapping, quadrature);
typename FiniteElement<dim,spacedim>::InternalDataBase *base_fe_data =
- dynamic_cast<typename FiniteElement<dim,spacedim>::InternalDataBase *>
- (base_fe_data_base);
+ dynamic_cast<typename FiniteElement<dim,spacedim>::InternalDataBase *>
+ (base_fe_data_base);
Assert (base_fe_data != 0, ExcInternalError());
data->set_fe_data(base_no, base_fe_data);
Assert (!(base_fe_data->update_each & update_hessians),
- ExcInternalError());
+ ExcInternalError());
Assert (!(base_fe_data->update_once & update_hessians),
- ExcInternalError());
+ ExcInternalError());
FEValuesData<dim,spacedim> *base_data = new FEValuesData<dim,spacedim>();
data->set_fe_values_data(base_no, base_data);
}
data->update_flags = data->update_once |
- data->update_each;
+ data->update_each;
return data;
}
for (unsigned int base_no=0; base_no<this->n_base_elements(); ++base_no)
{
typename Mapping<dim,spacedim>::InternalDataBase *base_fe_data_base =
- base_element(base_no).get_subface_data(sub_flags, mapping, quadrature);
+ base_element(base_no).get_subface_data(sub_flags, mapping, quadrature);
typename FiniteElement<dim,spacedim>::InternalDataBase *base_fe_data =
- dynamic_cast<typename FiniteElement<dim,spacedim>::InternalDataBase *>
- (base_fe_data_base);
+ dynamic_cast<typename FiniteElement<dim,spacedim>::InternalDataBase *>
+ (base_fe_data_base);
Assert (base_fe_data != 0, ExcInternalError());
data->set_fe_data(base_no, base_fe_data);
Assert (!(base_fe_data->update_each & update_hessians),
- ExcInternalError());
+ ExcInternalError());
Assert (!(base_fe_data->update_once & update_hessians),
- ExcInternalError());
+ ExcInternalError());
FEValuesData<dim,spacedim> *base_data = new FEValuesData<dim,spacedim>();
data->set_fe_values_data(base_no, base_data);
}
data->update_flags = data->update_once |
- data->update_each;
+ data->update_each;
return data;
}
CellSimilarity::Similarity &cell_similarity) const
{
compute_fill(mapping, cell, invalid_face_number, invalid_face_number,
- quadrature, cell_similarity, mapping_data, fe_data, data);
+ quadrature, cell_similarity, mapping_data, fe_data, data);
}
{
const unsigned int n_q_points = quadrature.size();
- // convert data object to internal
- // data for this class. fails with
- // an exception if that is not
- // possible
+ // convert data object to internal
+ // data for this class. fails with
+ // an exception if that is not
+ // possible
Assert (dynamic_cast<InternalData*> (&fedata) != 0, ExcInternalError());
InternalData & fe_data = static_cast<InternalData&> (fedata);
- // Either dim_1==dim
- // (fill_fe_values) or dim_1==dim-1
- // (fill_fe_(sub)face_values)
+ // Either dim_1==dim
+ // (fill_fe_values) or dim_1==dim-1
+ // (fill_fe_(sub)face_values)
Assert(dim_1==dim || dim_1==dim-1, ExcInternalError());
const UpdateFlags flags(dim_1==dim ?
- fe_data.current_update_flags() :
- fe_data.update_flags);
+ fe_data.current_update_flags() :
+ fe_data.update_flags);
if (flags & (update_values | update_gradients))
{
if (fe_data.is_first_cell())
- {
- // Initialize the
- // FEValuesDatas for the
- // base elements.
- // Originally this was the
- // task of
- // FEValues::FEValues() but
- // the latter initializes
- // the FEValuesDatas only
- // of the FESystem, not of
- // the FEValuesDatas needed
- // by the base elements
- // (and: how should it know
- // of their existence,
- // after all).
- for (unsigned int base_no=0; base_no<this->n_base_elements(); ++base_no)
- {
- // Pointer needed to get
- // the update flags of the
- // base element
- typename Mapping<dim,spacedim>::InternalDataBase &
- base_fe_data = fe_data.get_fe_data(base_no);
-
- // compute update flags ...
- const UpdateFlags base_update_flags
+ {
+ // Initialize the
+ // FEValuesDatas for the
+ // base elements.
+ // Originally this was the
+ // task of
+ // FEValues::FEValues() but
+ // the latter initializes
+ // the FEValuesDatas only
+ // of the FESystem, not of
+ // the FEValuesDatas needed
+ // by the base elements
+ // (and: how should it know
+ // of their existence,
+ // after all).
+ for (unsigned int base_no=0; base_no<this->n_base_elements(); ++base_no)
+ {
+ // Pointer needed to get
+ // the update flags of the
+ // base element
+ typename Mapping<dim,spacedim>::InternalDataBase &
+ base_fe_data = fe_data.get_fe_data(base_no);
+
+ // compute update flags ...
+ const UpdateFlags base_update_flags
= mapping_data.update_flags | base_fe_data.update_flags;
- // Initialize the FEValuesDatas
- // for the base elements.
- FEValuesData<dim,spacedim> &base_data=fe_data.get_fe_values_data(base_no);
- const FiniteElement<dim,spacedim> &base_fe=base_element(base_no);
- base_data.initialize (n_q_points, base_fe, base_update_flags);
- }
- }
-
- // fill_fe_face_values needs
- // argument Quadrature<dim-1>
- // for both cases
- // dim_1==dim-1 and
- // dim_1=dim. Hence the
- // following workaround
+ // Initialize the FEValuesDatas
+ // for the base elements.
+ FEValuesData<dim,spacedim> &base_data=fe_data.get_fe_values_data(base_no);
+ const FiniteElement<dim,spacedim> &base_fe=base_element(base_no);
+ base_data.initialize (n_q_points, base_fe, base_update_flags);
+ }
+ }
+
+ // fill_fe_face_values needs
+ // argument Quadrature<dim-1>
+ // for both cases
+ // dim_1==dim-1 and
+ // dim_1=dim. Hence the
+ // following workaround
const Quadrature<dim> *cell_quadrature = 0;
const Quadrature<dim-1> *face_quadrature = 0;
- // static cast to the
- // common base class of
- // quadrature being either
- // Quadrature<dim> or
- // Quadrature<dim-1>:
+ // static cast to the
+ // common base class of
+ // quadrature being either
+ // Quadrature<dim> or
+ // Quadrature<dim-1>:
const Subscriptor* quadrature_base_pointer = &quadrature;
if (face_no==invalid_face_number)
- {
- Assert(dim_1==dim, ExcDimensionMismatch(dim_1,dim));
-
- // Some Mac OS X versions
- // have a bug that makes
- // the following assertion
- // fail spuriously. In that
- // case, just disable the
- // Assert, as this is not
- // something that depends
- // on input parameters
- // provided by users; the
- // validity of the
- // assertion is still
- // checked on all systems
- // that don't have this bug
+ {
+ Assert(dim_1==dim, ExcDimensionMismatch(dim_1,dim));
+
+ // Some Mac OS X versions
+ // have a bug that makes
+ // the following assertion
+ // fail spuriously. In that
+ // case, just disable the
+ // Assert, as this is not
+ // something that depends
+ // on input parameters
+ // provided by users; the
+ // validity of the
+ // assertion is still
+ // checked on all systems
+ // that don't have this bug
#ifndef DEAL_II_HAVE_DARWIN_DYNACAST_BUG
- Assert (dynamic_cast<const Quadrature<dim> *>(quadrature_base_pointer) != 0,
- ExcInternalError());
+ Assert (dynamic_cast<const Quadrature<dim> *>(quadrature_base_pointer) != 0,
+ ExcInternalError());
#endif
- cell_quadrature
+ cell_quadrature
= static_cast<const Quadrature<dim> *>(quadrature_base_pointer);
- }
+ }
else
- {
- Assert(dim_1==dim-1, ExcDimensionMismatch(dim_1,dim-1));
+ {
+ Assert(dim_1==dim-1, ExcDimensionMismatch(dim_1,dim-1));
#ifndef DEAL_II_HAVE_DARWIN_DYNACAST_BUG
- Assert (dynamic_cast<const Quadrature<dim-1> *>(quadrature_base_pointer) != 0,
- ExcInternalError());
+ Assert (dynamic_cast<const Quadrature<dim-1> *>(quadrature_base_pointer) != 0,
+ ExcInternalError());
#endif
- face_quadrature
+ face_quadrature
= static_cast<const Quadrature<dim-1> *>(quadrature_base_pointer);
- }
+ }
// let base elements update the
// necessary data
for (unsigned int base_no=0; base_no<this->n_base_elements(); ++base_no)
- {
- const FiniteElement<dim,spacedim> &
+ {
+ const FiniteElement<dim,spacedim> &
base_fe = base_element(base_no);
- typename FiniteElement<dim,spacedim>::InternalDataBase &
- base_fe_data = fe_data.get_fe_data(base_no);
- FEValuesData<dim,spacedim> &
+ typename FiniteElement<dim,spacedim>::InternalDataBase &
+ base_fe_data = fe_data.get_fe_data(base_no);
+ FEValuesData<dim,spacedim> &
base_data = fe_data.get_fe_values_data(base_no);
- //TODO: Think about a smarter alternative
- // Copy quadrature points. These
- // are required for computing the
- // determinant in the FEPolyTensor
- // class. The determinant is
- // one ingredient of the Piola
- // transformation, which is applied
- // to correctly map the RT space from
- // the reference element to the global
- // coordinate system.
- if (cell_similarity != CellSimilarity::translation)
- base_data.JxW_values = data.JxW_values;
+ //TODO: Think about a smarter alternative
+ // Copy quadrature points. These
+ // are required for computing the
+ // determinant in the FEPolyTensor
+ // class. The determinant is
+ // one ingredient of the Piola
+ // transformation, which is applied
+ // to correctly map the RT space from
+ // the reference element to the global
+ // coordinate system.
+ if (cell_similarity != CellSimilarity::translation)
+ base_data.JxW_values = data.JxW_values;
// Make sure that in the
// data on each face,
// therefore use
// base_fe_data.update_flags.
- if (face_no==invalid_face_number)
- base_fe.fill_fe_values(mapping, cell, *cell_quadrature, mapping_data,
- base_fe_data, base_data, cell_similarity);
- else if (sub_no==invalid_face_number)
- base_fe.fill_fe_face_values(mapping, cell, face_no,
- *face_quadrature, mapping_data, base_fe_data, base_data);
- else
- base_fe.fill_fe_subface_values(mapping, cell, face_no, sub_no,
- *face_quadrature, mapping_data, base_fe_data, base_data);
+ if (face_no==invalid_face_number)
+ base_fe.fill_fe_values(mapping, cell, *cell_quadrature, mapping_data,
+ base_fe_data, base_data, cell_similarity);
+ else if (sub_no==invalid_face_number)
+ base_fe.fill_fe_face_values(mapping, cell, face_no,
+ *face_quadrature, mapping_data, base_fe_data, base_data);
+ else
+ base_fe.fill_fe_subface_values(mapping, cell, face_no, sub_no,
+ *face_quadrature, mapping_data, base_fe_data, base_data);
// now data has been
// generated, so copy
base_fe_data.current_update_flags() :
base_fe_data.update_flags);
- // if the current cell is just a
- // translation of the previous
- // one, the underlying data has
- // not changed, and we don't even
- // need to enter this section
- if (cell_similarity != CellSimilarity::translation)
- for (unsigned int system_index=0; system_index<this->dofs_per_cell;
- ++system_index)
- if (this->system_to_base_table[system_index].first.first == base_no)
- {
- const unsigned int
- base_index = this->system_to_base_table[system_index].second;
- Assert (base_index<base_fe.dofs_per_cell, ExcInternalError());
+ // if the current cell is just a
+ // translation of the previous
+ // one, the underlying data has
+ // not changed, and we don't even
+ // need to enter this section
+ if (cell_similarity != CellSimilarity::translation)
+ for (unsigned int system_index=0; system_index<this->dofs_per_cell;
+ ++system_index)
+ if (this->system_to_base_table[system_index].first.first == base_no)
+ {
+ const unsigned int
+ base_index = this->system_to_base_table[system_index].second;
+ Assert (base_index<base_fe.dofs_per_cell, ExcInternalError());
// now copy. if the
// shape function is
// this one value, and
// to which index to
// put
- unsigned int out_index = 0;
- for (unsigned int i=0; i<system_index; ++i)
- out_index += this->n_nonzero_components(i);
- unsigned int in_index = 0;
- for (unsigned int i=0; i<base_index; ++i)
- in_index += base_fe.n_nonzero_components(i);
+ unsigned int out_index = 0;
+ for (unsigned int i=0; i<system_index; ++i)
+ out_index += this->n_nonzero_components(i);
+ unsigned int in_index = 0;
+ for (unsigned int i=0; i<base_index; ++i)
+ in_index += base_fe.n_nonzero_components(i);
// then loop over the
// number of components
// to be copied
- Assert (this->n_nonzero_components(system_index) ==
- base_fe.n_nonzero_components(base_index),
- ExcInternalError());
- for (unsigned int s=0; s<this->n_nonzero_components(system_index); ++s)
- {
- if (base_flags & update_values)
- for (unsigned int q=0; q<n_q_points; ++q)
- data.shape_values[out_index+s][q] =
- base_data.shape_values(in_index+s,q);
-
- if (base_flags & update_gradients)
- for (unsigned int q=0; q<n_q_points; ++q)
- data.shape_gradients[out_index+s][q]=
- base_data.shape_gradients[in_index+s][q];
+ Assert (this->n_nonzero_components(system_index) ==
+ base_fe.n_nonzero_components(base_index),
+ ExcInternalError());
+ for (unsigned int s=0; s<this->n_nonzero_components(system_index); ++s)
+ {
+ if (base_flags & update_values)
+ for (unsigned int q=0; q<n_q_points; ++q)
+ data.shape_values[out_index+s][q] =
+ base_data.shape_values(in_index+s,q);
+
+ if (base_flags & update_gradients)
+ for (unsigned int q=0; q<n_q_points; ++q)
+ data.shape_gradients[out_index+s][q]=
+ base_data.shape_gradients[in_index+s][q];
// _we_ handle
// computation of
// should not
// have computed
// them!
- Assert (!(base_flags & update_hessians),
- ExcInternalError());
- };
- };
+ Assert (!(base_flags & update_hessians),
+ ExcInternalError());
+ };
+ };
};
}
{
unsigned int offset = 0;
if (face_no != invalid_face_number)
- {
- if (sub_no == invalid_face_number)
- offset=QProjector<dim>::DataSetDescriptor
- ::face(face_no,
- cell->face_orientation(face_no),
- cell->face_flip(face_no),
- cell->face_rotation(face_no),
- n_q_points);
- else
- offset=QProjector<dim>::DataSetDescriptor
- ::subface(face_no, sub_no,
- cell->face_orientation(face_no),
- cell->face_flip(face_no),
- cell->face_rotation(face_no),
- n_q_points,
- cell->subface_case(face_no));
- }
+ {
+ if (sub_no == invalid_face_number)
+ offset=QProjector<dim>::DataSetDescriptor
+ ::face(face_no,
+ cell->face_orientation(face_no),
+ cell->face_flip(face_no),
+ cell->face_rotation(face_no),
+ n_q_points);
+ else
+ offset=QProjector<dim>::DataSetDescriptor
+ ::subface(face_no, sub_no,
+ cell->face_orientation(face_no),
+ cell->face_flip(face_no),
+ cell->face_rotation(face_no),
+ n_q_points,
+ cell->subface_case(face_no));
+ }
this->compute_2nd (mapping, cell, offset, mapping_data, fe_data, data);
}
void
FESystem<dim,spacedim>::build_cell_tables()
{
- // If the system is not primitive,
- // these have not been initialized
- // by FiniteElement
+ // If the system is not primitive,
+ // these have not been initialized
+ // by FiniteElement
this->system_to_component_table.resize(this->dofs_per_cell);
this->face_system_to_component_table.resize(this->dofs_per_face);
for (unsigned int base=0; base < this->n_base_elements(); ++base)
for (unsigned int m = 0; m < this->element_multiplicity(base); ++m)
{
- this->block_indices_data.push_back(base_element(base).dofs_per_cell);
- for (unsigned int k=0; k<base_element(base).n_components(); ++k)
- this->component_to_base_table[total_index++]
- = std::make_pair(std::make_pair(base,k), m);
+ this->block_indices_data.push_back(base_element(base).dofs_per_cell);
+ for (unsigned int k=0; k<base_element(base).n_components(); ++k)
+ this->component_to_base_table[total_index++]
+ = std::make_pair(std::make_pair(base,k), m);
}
Assert (total_index == this->component_to_base_table.size(),
- ExcInternalError());
+ ExcInternalError());
- // Initialize index tables.
- // Multi-component base elements
- // have to be thought of. For
- // non-primitive shape functions,
- // have a special invalid index.
+ // Initialize index tables.
+ // Multi-component base elements
+ // have to be thought of. For
+ // non-primitive shape functions,
+ // have a special invalid index.
const std::pair<unsigned int, unsigned int>
non_primitive_index (numbers::invalid_unsigned_int,
- numbers::invalid_unsigned_int);
+ numbers::invalid_unsigned_int);
- // First enumerate vertex indices,
- // where we first enumerate all
- // indices on the first vertex in
- // the order of the base elements,
- // then of the second vertex, etc
+ // First enumerate vertex indices,
+ // where we first enumerate all
+ // indices on the first vertex in
+ // the order of the base elements,
+ // then of the second vertex, etc
total_index = 0;
for (unsigned int vertex_number=0;
vertex_number<GeometryInfo<dim>::vertices_per_cell;
{
unsigned comp_start = 0;
for(unsigned int base=0; base<this->n_base_elements(); ++base)
- for (unsigned int m=0; m<this->element_multiplicity(base);
- ++m, comp_start+=base_element(base).n_components())
- for (unsigned int local_index = 0;
- local_index < base_element(base).dofs_per_vertex;
- ++local_index, ++total_index)
- {
- const unsigned int index_in_base
- = (base_element(base).dofs_per_vertex*vertex_number +
- local_index);
-
- this->system_to_base_table[total_index]
- = std::make_pair (std::make_pair(base, m), index_in_base);
-
- if (base_element(base).is_primitive(index_in_base))
- {
- const unsigned int comp_in_base
- = base_element(base).system_to_component_index(index_in_base).first;
- const unsigned int comp
- = comp_start + comp_in_base;
- const unsigned int index_in_comp
- = base_element(base).system_to_component_index(index_in_base).second;
- this->system_to_component_table[total_index]
- = std::make_pair (comp, index_in_comp);
- }
- else
- this->system_to_component_table[total_index] = non_primitive_index;
- }
+ for (unsigned int m=0; m<this->element_multiplicity(base);
+ ++m, comp_start+=base_element(base).n_components())
+ for (unsigned int local_index = 0;
+ local_index < base_element(base).dofs_per_vertex;
+ ++local_index, ++total_index)
+ {
+ const unsigned int index_in_base
+ = (base_element(base).dofs_per_vertex*vertex_number +
+ local_index);
+
+ this->system_to_base_table[total_index]
+ = std::make_pair (std::make_pair(base, m), index_in_base);
+
+ if (base_element(base).is_primitive(index_in_base))
+ {
+ const unsigned int comp_in_base
+ = base_element(base).system_to_component_index(index_in_base).first;
+ const unsigned int comp
+ = comp_start + comp_in_base;
+ const unsigned int index_in_comp
+ = base_element(base).system_to_component_index(index_in_base).second;
+ this->system_to_component_table[total_index]
+ = std::make_pair (comp, index_in_comp);
+ }
+ else
+ this->system_to_component_table[total_index] = non_primitive_index;
+ }
}
- // 2. Lines
+ // 2. Lines
if (GeometryInfo<dim>::lines_per_cell > 0)
for (unsigned int line_number= 0;
- line_number != GeometryInfo<dim>::lines_per_cell;
- ++line_number)
+ line_number != GeometryInfo<dim>::lines_per_cell;
+ ++line_number)
{
- unsigned comp_start = 0;
- for (unsigned int base=0; base<this->n_base_elements(); ++base)
- for (unsigned int m=0; m<this->element_multiplicity(base);
- ++m, comp_start+=base_element(base).n_components())
- for (unsigned int local_index = 0;
- local_index < base_element(base).dofs_per_line;
- ++local_index, ++total_index)
- {
- const unsigned int index_in_base
- = (base_element(base).dofs_per_line*line_number +
- local_index +
- base_element(base).first_line_index);
-
- this->system_to_base_table[total_index]
- = std::make_pair (std::make_pair(base,m), index_in_base);
-
- if (base_element(base).is_primitive(index_in_base))
- {
- const unsigned int comp_in_base
- = base_element(base).system_to_component_index(index_in_base).first;
- const unsigned int comp
- = comp_start + comp_in_base;
- const unsigned int index_in_comp
- = base_element(base).system_to_component_index(index_in_base).second;
- this->system_to_component_table[total_index]
- = std::make_pair (comp, index_in_comp);
- }
- else
- this->system_to_component_table[total_index] = non_primitive_index;
- }
+ unsigned comp_start = 0;
+ for (unsigned int base=0; base<this->n_base_elements(); ++base)
+ for (unsigned int m=0; m<this->element_multiplicity(base);
+ ++m, comp_start+=base_element(base).n_components())
+ for (unsigned int local_index = 0;
+ local_index < base_element(base).dofs_per_line;
+ ++local_index, ++total_index)
+ {
+ const unsigned int index_in_base
+ = (base_element(base).dofs_per_line*line_number +
+ local_index +
+ base_element(base).first_line_index);
+
+ this->system_to_base_table[total_index]
+ = std::make_pair (std::make_pair(base,m), index_in_base);
+
+ if (base_element(base).is_primitive(index_in_base))
+ {
+ const unsigned int comp_in_base
+ = base_element(base).system_to_component_index(index_in_base).first;
+ const unsigned int comp
+ = comp_start + comp_in_base;
+ const unsigned int index_in_comp
+ = base_element(base).system_to_component_index(index_in_base).second;
+ this->system_to_component_table[total_index]
+ = std::make_pair (comp, index_in_comp);
+ }
+ else
+ this->system_to_component_table[total_index] = non_primitive_index;
+ }
}
- // 3. Quads
+ // 3. Quads
if (GeometryInfo<dim>::quads_per_cell > 0)
for (unsigned int quad_number= 0;
- quad_number != GeometryInfo<dim>::quads_per_cell;
- ++quad_number)
+ quad_number != GeometryInfo<dim>::quads_per_cell;
+ ++quad_number)
{
- unsigned int comp_start = 0;
- for (unsigned int base=0; base<this->n_base_elements(); ++base)
- for (unsigned int m=0; m<this->element_multiplicity(base);
- ++m, comp_start += base_element(base).n_components())
- for (unsigned int local_index = 0;
- local_index < base_element(base).dofs_per_quad;
- ++local_index, ++total_index)
- {
- const unsigned int index_in_base
- = (base_element(base).dofs_per_quad*quad_number +
- local_index +
- base_element(base).first_quad_index);
-
- this->system_to_base_table[total_index]
- = std::make_pair (std::make_pair(base,m), index_in_base);
-
- if (base_element(base).is_primitive(index_in_base))
- {
- const unsigned int comp_in_base
- = base_element(base).system_to_component_index(index_in_base).first;
- const unsigned int comp
- = comp_start + comp_in_base;
- const unsigned int index_in_comp
- = base_element(base).system_to_component_index(index_in_base).second;
- this->system_to_component_table[total_index]
- = std::make_pair (comp, index_in_comp);
- }
- else
- this->system_to_component_table[total_index] = non_primitive_index;
- }
+ unsigned int comp_start = 0;
+ for (unsigned int base=0; base<this->n_base_elements(); ++base)
+ for (unsigned int m=0; m<this->element_multiplicity(base);
+ ++m, comp_start += base_element(base).n_components())
+ for (unsigned int local_index = 0;
+ local_index < base_element(base).dofs_per_quad;
+ ++local_index, ++total_index)
+ {
+ const unsigned int index_in_base
+ = (base_element(base).dofs_per_quad*quad_number +
+ local_index +
+ base_element(base).first_quad_index);
+
+ this->system_to_base_table[total_index]
+ = std::make_pair (std::make_pair(base,m), index_in_base);
+
+ if (base_element(base).is_primitive(index_in_base))
+ {
+ const unsigned int comp_in_base
+ = base_element(base).system_to_component_index(index_in_base).first;
+ const unsigned int comp
+ = comp_start + comp_in_base;
+ const unsigned int index_in_comp
+ = base_element(base).system_to_component_index(index_in_base).second;
+ this->system_to_component_table[total_index]
+ = std::make_pair (comp, index_in_comp);
+ }
+ else
+ this->system_to_component_table[total_index] = non_primitive_index;
+ }
}
- // 4. Hexes
+ // 4. Hexes
if (GeometryInfo<dim>::hexes_per_cell > 0)
for (unsigned int hex_number= 0;
- hex_number != GeometryInfo<dim>::hexes_per_cell;
- ++hex_number)
+ hex_number != GeometryInfo<dim>::hexes_per_cell;
+ ++hex_number)
{
- unsigned int comp_start = 0;
- for(unsigned int base=0; base<this->n_base_elements(); ++base)
- for (unsigned int m=0; m<this->element_multiplicity(base);
- ++m, comp_start+=base_element(base).n_components())
- for (unsigned int local_index = 0;
- local_index < base_element(base).dofs_per_hex;
- ++local_index, ++total_index)
- {
- const unsigned int index_in_base
- = (base_element(base).dofs_per_hex*hex_number +
- local_index +
- base_element(base).first_hex_index);
-
- this->system_to_base_table[total_index]
- = std::make_pair (std::make_pair(base,m), index_in_base);
-
- if (base_element(base).is_primitive(index_in_base))
- {
- const unsigned int comp_in_base
- = base_element(base).system_to_component_index(index_in_base).first;
- const unsigned int comp
- = comp_start + comp_in_base;
- const unsigned int index_in_comp
- = base_element(base).system_to_component_index(index_in_base).second;
- this->system_to_component_table[total_index]
- = std::make_pair (comp, index_in_comp);
- }
- else
- this->system_to_component_table[total_index] = non_primitive_index;
- }
+ unsigned int comp_start = 0;
+ for(unsigned int base=0; base<this->n_base_elements(); ++base)
+ for (unsigned int m=0; m<this->element_multiplicity(base);
+ ++m, comp_start+=base_element(base).n_components())
+ for (unsigned int local_index = 0;
+ local_index < base_element(base).dofs_per_hex;
+ ++local_index, ++total_index)
+ {
+ const unsigned int index_in_base
+ = (base_element(base).dofs_per_hex*hex_number +
+ local_index +
+ base_element(base).first_hex_index);
+
+ this->system_to_base_table[total_index]
+ = std::make_pair (std::make_pair(base,m), index_in_base);
+
+ if (base_element(base).is_primitive(index_in_base))
+ {
+ const unsigned int comp_in_base
+ = base_element(base).system_to_component_index(index_in_base).first;
+ const unsigned int comp
+ = comp_start + comp_in_base;
+ const unsigned int index_in_comp
+ = base_element(base).system_to_component_index(index_in_base).second;
+ this->system_to_component_table[total_index]
+ = std::make_pair (comp, index_in_comp);
+ }
+ else
+ this->system_to_component_table[total_index] = non_primitive_index;
+ }
}
}
void
FESystem<dim,spacedim>::build_face_tables()
{
- // Initialize index tables. do this
- // in the same way as done for the
- // cell tables, except that we now
- // loop over the objects of faces
+ // Initialize index tables. do this
+ // in the same way as done for the
+ // cell tables, except that we now
+ // loop over the objects of faces
- // For non-primitive shape
- // functions, have a special
- // invalid index
+ // For non-primitive shape
+ // functions, have a special
+ // invalid index
const std::pair<unsigned int, unsigned int>
non_primitive_index (numbers::invalid_unsigned_int,
- numbers::invalid_unsigned_int);
+ numbers::invalid_unsigned_int);
- // 1. Vertices
+ // 1. Vertices
unsigned int total_index = 0;
for (unsigned int vertex_number=0;
vertex_number<GeometryInfo<dim>::vertices_per_face;
{
unsigned int comp_start = 0;
for(unsigned int base=0; base<this->n_base_elements(); ++base)
- for (unsigned int m=0; m<this->element_multiplicity(base);
- ++m, comp_start += base_element(base).n_components())
- for (unsigned int local_index = 0;
- local_index < base_element(base).dofs_per_vertex;
- ++local_index, ++total_index)
- {
- // get (cell) index of
- // this shape function
- // inside the base
- // element to see
- // whether the shape
- // function is
- // primitive (assume
- // that all shape
- // functions on
- // vertices share the
- // same primitivity
- // property; assume
- // likewise for all
- // shape functions
- // located on lines,
- // quads, etc. this
- // way, we can ask for
- // primitivity of only
- // _one_ shape
- // function, which is
- // taken as
- // representative for
- // all others located
- // on the same type of
- // object):
- const unsigned int index_in_base
- = (base_element(base).dofs_per_vertex*vertex_number +
- local_index);
-
- const unsigned int face_index_in_base
- = (base_element(base).dofs_per_vertex*vertex_number +
- local_index);
-
- this->face_system_to_base_table[total_index]
- = std::make_pair (std::make_pair(base,m), face_index_in_base);
-
- if (base_element(base).is_primitive(index_in_base))
- {
- const unsigned int comp_in_base
- = base_element(base).face_system_to_component_index(face_index_in_base).first;
- const unsigned int comp
- = comp_start + comp_in_base;
- const unsigned int face_index_in_comp
- = base_element(base).face_system_to_component_index(face_index_in_base).second;
- this->face_system_to_component_table[total_index]
- = std::make_pair (comp, face_index_in_comp);
- }
- else
- this->face_system_to_component_table[total_index] = non_primitive_index;
- }
+ for (unsigned int m=0; m<this->element_multiplicity(base);
+ ++m, comp_start += base_element(base).n_components())
+ for (unsigned int local_index = 0;
+ local_index < base_element(base).dofs_per_vertex;
+ ++local_index, ++total_index)
+ {
+ // get (cell) index of
+ // this shape function
+ // inside the base
+ // element to see
+ // whether the shape
+ // function is
+ // primitive (assume
+ // that all shape
+ // functions on
+ // vertices share the
+ // same primitivity
+ // property; assume
+ // likewise for all
+ // shape functions
+ // located on lines,
+ // quads, etc. this
+ // way, we can ask for
+ // primitivity of only
+ // _one_ shape
+ // function, which is
+ // taken as
+ // representative for
+ // all others located
+ // on the same type of
+ // object):
+ const unsigned int index_in_base
+ = (base_element(base).dofs_per_vertex*vertex_number +
+ local_index);
+
+ const unsigned int face_index_in_base
+ = (base_element(base).dofs_per_vertex*vertex_number +
+ local_index);
+
+ this->face_system_to_base_table[total_index]
+ = std::make_pair (std::make_pair(base,m), face_index_in_base);
+
+ if (base_element(base).is_primitive(index_in_base))
+ {
+ const unsigned int comp_in_base
+ = base_element(base).face_system_to_component_index(face_index_in_base).first;
+ const unsigned int comp
+ = comp_start + comp_in_base;
+ const unsigned int face_index_in_comp
+ = base_element(base).face_system_to_component_index(face_index_in_base).second;
+ this->face_system_to_component_table[total_index]
+ = std::make_pair (comp, face_index_in_comp);
+ }
+ else
+ this->face_system_to_component_table[total_index] = non_primitive_index;
+ }
}
- // 2. Lines
+ // 2. Lines
if (GeometryInfo<dim>::lines_per_face > 0)
for (unsigned line_number= 0;
- line_number != GeometryInfo<dim>::lines_per_face;
- ++line_number)
+ line_number != GeometryInfo<dim>::lines_per_face;
+ ++line_number)
{
- unsigned comp_start = 0;
- for(unsigned base = 0; base < this->n_base_elements(); ++base)
- for (unsigned m=0; m<this->element_multiplicity(base);
- ++m, comp_start += base_element(base).n_components())
- for (unsigned local_index = 0;
- local_index < base_element(base).dofs_per_line;
- ++local_index, ++total_index)
- {
- // do everything
- // alike for this
- // type of object
- const unsigned int index_in_base
- = (base_element(base).dofs_per_line*line_number +
- local_index +
- base_element(base).first_line_index);
-
- const unsigned int face_index_in_base
- = (base_element(base).first_face_line_index +
- base_element(base).dofs_per_line * line_number +
- local_index);
-
- this->face_system_to_base_table[total_index]
- = std::make_pair (std::make_pair(base,m), face_index_in_base);
-
- if (base_element(base).is_primitive(index_in_base))
- {
- const unsigned int comp_in_base
- = base_element(base).face_system_to_component_index(face_index_in_base).first;
- const unsigned int comp
- = comp_start + comp_in_base;
- const unsigned int face_index_in_comp
- = base_element(base).face_system_to_component_index(face_index_in_base).second;
- this->face_system_to_component_table[total_index]
- = std::make_pair (comp, face_index_in_comp);
- }
- else
- this->face_system_to_component_table[total_index] = non_primitive_index;
- }
+ unsigned comp_start = 0;
+ for(unsigned base = 0; base < this->n_base_elements(); ++base)
+ for (unsigned m=0; m<this->element_multiplicity(base);
+ ++m, comp_start += base_element(base).n_components())
+ for (unsigned local_index = 0;
+ local_index < base_element(base).dofs_per_line;
+ ++local_index, ++total_index)
+ {
+ // do everything
+ // alike for this
+ // type of object
+ const unsigned int index_in_base
+ = (base_element(base).dofs_per_line*line_number +
+ local_index +
+ base_element(base).first_line_index);
+
+ const unsigned int face_index_in_base
+ = (base_element(base).first_face_line_index +
+ base_element(base).dofs_per_line * line_number +
+ local_index);
+
+ this->face_system_to_base_table[total_index]
+ = std::make_pair (std::make_pair(base,m), face_index_in_base);
+
+ if (base_element(base).is_primitive(index_in_base))
+ {
+ const unsigned int comp_in_base
+ = base_element(base).face_system_to_component_index(face_index_in_base).first;
+ const unsigned int comp
+ = comp_start + comp_in_base;
+ const unsigned int face_index_in_comp
+ = base_element(base).face_system_to_component_index(face_index_in_base).second;
+ this->face_system_to_component_table[total_index]
+ = std::make_pair (comp, face_index_in_comp);
+ }
+ else
+ this->face_system_to_component_table[total_index] = non_primitive_index;
+ }
}
- // 3. Quads
+ // 3. Quads
if (GeometryInfo<dim>::quads_per_face > 0)
for (unsigned quad_number= 0;
- quad_number != GeometryInfo<dim>::quads_per_face;
- ++quad_number)
+ quad_number != GeometryInfo<dim>::quads_per_face;
+ ++quad_number)
{
- unsigned comp_start = 0;
- for(unsigned base=0; base<this->n_base_elements(); ++base)
- for (unsigned m=0; m<this->element_multiplicity(base);
- ++m, comp_start += base_element(base).n_components())
- for (unsigned local_index = 0;
- local_index < base_element(base).dofs_per_quad;
- ++local_index, ++total_index)
- {
- // do everything
- // alike for this
- // type of object
- const unsigned int index_in_base
- = (base_element(base).dofs_per_quad*quad_number +
- local_index +
- base_element(base).first_quad_index);
-
- const unsigned int face_index_in_base
- = (base_element(base).first_face_quad_index +
- base_element(base).dofs_per_quad * quad_number +
- local_index);
-
- this->face_system_to_base_table[total_index]
- = std::make_pair (std::make_pair(base,m), face_index_in_base);
-
- if (base_element(base).is_primitive(index_in_base))
- {
- const unsigned int comp_in_base
- = base_element(base).face_system_to_component_index(face_index_in_base).first;
- const unsigned int comp
- = comp_start + comp_in_base;
- const unsigned int face_index_in_comp
- = base_element(base).face_system_to_component_index(face_index_in_base).second;
- this->face_system_to_component_table[total_index]
- = std::make_pair (comp, face_index_in_comp);
- }
- else
- this->face_system_to_component_table[total_index] = non_primitive_index;
- }
+ unsigned comp_start = 0;
+ for(unsigned base=0; base<this->n_base_elements(); ++base)
+ for (unsigned m=0; m<this->element_multiplicity(base);
+ ++m, comp_start += base_element(base).n_components())
+ for (unsigned local_index = 0;
+ local_index < base_element(base).dofs_per_quad;
+ ++local_index, ++total_index)
+ {
+ // do everything
+ // alike for this
+ // type of object
+ const unsigned int index_in_base
+ = (base_element(base).dofs_per_quad*quad_number +
+ local_index +
+ base_element(base).first_quad_index);
+
+ const unsigned int face_index_in_base
+ = (base_element(base).first_face_quad_index +
+ base_element(base).dofs_per_quad * quad_number +
+ local_index);
+
+ this->face_system_to_base_table[total_index]
+ = std::make_pair (std::make_pair(base,m), face_index_in_base);
+
+ if (base_element(base).is_primitive(index_in_base))
+ {
+ const unsigned int comp_in_base
+ = base_element(base).face_system_to_component_index(face_index_in_base).first;
+ const unsigned int comp
+ = comp_start + comp_in_base;
+ const unsigned int face_index_in_comp
+ = base_element(base).face_system_to_component_index(face_index_in_base).second;
+ this->face_system_to_component_table[total_index]
+ = std::make_pair (comp, face_index_in_comp);
+ }
+ else
+ this->face_system_to_component_table[total_index] = non_primitive_index;
+ }
}
Assert (total_index == this->dofs_per_face, ExcInternalError());
Assert (total_index == this->face_system_to_component_table.size(),
- ExcInternalError());
+ ExcInternalError());
Assert (total_index == this->face_system_to_base_table.size(),
- ExcInternalError());
+ ExcInternalError());
}
this->interface_constraints.
TableBase<2,double>::reinit (this->interface_constraints_size());
- // the layout of the constraints
- // matrix is described in the
- // FiniteElement class. you may
- // want to look there first before
- // trying to understand the
- // following, especially the
- // mapping of the @p{m} index.
- //
- // in order to map it to the
- // fe-system class, we have to know
- // which base element a degree of
- // freedom within a vertex, line,
- // etc belongs to. this can be
- // accomplished by the
- // system_to_component_index
- // function in conjunction with the
- // numbers
- // first_{line,quad,...}_index
+ // the layout of the constraints
+ // matrix is described in the
+ // FiniteElement class. you may
+ // want to look there first before
+ // trying to understand the
+ // following, especially the
+ // mapping of the @p{m} index.
+ //
+ // in order to map it to the
+ // fe-system class, we have to know
+ // which base element a degree of
+ // freedom within a vertex, line,
+ // etc belongs to. this can be
+ // accomplished by the
+ // system_to_component_index
+ // function in conjunction with the
+ // numbers
+ // first_{line,quad,...}_index
for (unsigned int n=0; n<this->interface_constraints.n(); ++n)
for (unsigned int m=0; m<this->interface_constraints.m(); ++m)
{
- // for the pair (n,m) find
- // out which base element
- // they belong to and the
- // number therein
- //
- // first for the n
- // index. this is simple
- // since the n indices are in
- // the same order as they are
- // usually on a face. note
- // that for the data type,
- // first value in pair is
- // (base element,instance of
- // base element), second is
- // index within this instance
- const std::pair<std::pair<unsigned int,unsigned int>, unsigned int> n_index
- = this->face_system_to_base_table[n];
-
- // likewise for the m
- // index. this is more
- // complicated due to the
- // strange ordering we have
- // for the dofs on the
- // refined faces.
- std::pair<std::pair<unsigned int,unsigned int>, unsigned int> m_index;
- switch (dim)
- {
- case 1:
+ // for the pair (n,m) find
+ // out which base element
+ // they belong to and the
+ // number therein
+ //
+ // first for the n
+ // index. this is simple
+ // since the n indices are in
+ // the same order as they are
+ // usually on a face. note
+ // that for the data type,
+ // first value in pair is
+ // (base element,instance of
+ // base element), second is
+ // index within this instance
+ const std::pair<std::pair<unsigned int,unsigned int>, unsigned int> n_index
+ = this->face_system_to_base_table[n];
+
+ // likewise for the m
+ // index. this is more
+ // complicated due to the
+ // strange ordering we have
+ // for the dofs on the
+ // refined faces.
+ std::pair<std::pair<unsigned int,unsigned int>, unsigned int> m_index;
+ switch (dim)
+ {
+ case 1:
{
// we should never get here!
// (in 1d, the constraints matrix
break;
};
- case 2:
+ case 2:
{
// the indices m=0..d_v-1 are
// from the center vertex.
break;
};
- case 3:
+ case 3:
{
// same way as above,
// although a little
break;
};
- default:
+ default:
Assert (false, ExcNotImplemented());
- };
-
- // now that we gathered all
- // information: use it to
- // build the matrix. note
- // that if n and m belong to
- // different base elements or
- // instances, then there
- // definitely will be no
- // coupling
- if (n_index.first == m_index.first)
- this->interface_constraints(m,n)
- = (base_element(n_index.first.first).constraints()(m_index.second,
- n_index.second));
+ };
+
+ // now that we gathered all
+ // information: use it to
+ // build the matrix. note
+ // that if n and m belong to
+ // different base elements or
+ // instances, then there
+ // definitely will be no
+ // coupling
+ if (n_index.first == m_index.first)
+ this->interface_constraints(m,n)
+ = (base_element(n_index.first.first).constraints()(m_index.second,
+ n_index.second));
};
}
ref_case<RefinementCase<dim>::isotropic_refinement+1;
++ref_case)
{
- // Check if some of the matrices of
- // the base elements are void.
- // repeat this check for each RefineCase
+ // Check if some of the matrices of
+ // the base elements are void.
+ // repeat this check for each RefineCase
bool do_restriction = true;
bool do_prolongation = true;
for (unsigned int i=0; i<this->n_base_elements(); ++i)
- {
- if (base_element(i).restriction[ref_case-1][0].n() != base_element(i).dofs_per_cell)
- do_restriction = false;
- if (base_element(i).prolongation[ref_case-1][0].n() != base_element(i).dofs_per_cell)
- do_prolongation = false;
- }
-
- // if we did not encounter void
- // matrices, initialize the
- // respective matrix sizes
+ {
+ if (base_element(i).restriction[ref_case-1][0].n() != base_element(i).dofs_per_cell)
+ do_restriction = false;
+ if (base_element(i).prolongation[ref_case-1][0].n() != base_element(i).dofs_per_cell)
+ do_prolongation = false;
+ }
+
+ // if we did not encounter void
+ // matrices, initialize the
+ // respective matrix sizes
if (do_restriction)
- for (unsigned int i=0;i<GeometryInfo<dim>::n_children(RefinementCase<dim>(ref_case));++i)
- this->restriction[ref_case-1][i].reinit(this->dofs_per_cell,
- this->dofs_per_cell);
+ for (unsigned int i=0;i<GeometryInfo<dim>::n_children(RefinementCase<dim>(ref_case));++i)
+ this->restriction[ref_case-1][i].reinit(this->dofs_per_cell,
+ this->dofs_per_cell);
if (do_prolongation)
- for (unsigned int i=0;i<GeometryInfo<dim>::n_children(RefinementCase<dim>(ref_case));++i)
- this->prolongation[ref_case-1][i].reinit(this->dofs_per_cell,
- this->dofs_per_cell);
-
- // distribute the matrices of the
- // base finite elements to the
- // matrices of this object. for
- // this, loop over all degrees of
- // freedom and take the respective
- // entry of the underlying base
- // element.
- //
- // note that we by definition of a
- // base element, they are
- // independent, i.e. do not
- // couple. only DoFs that belong to
- // the same instance of a base
- // element may couple
+ for (unsigned int i=0;i<GeometryInfo<dim>::n_children(RefinementCase<dim>(ref_case));++i)
+ this->prolongation[ref_case-1][i].reinit(this->dofs_per_cell,
+ this->dofs_per_cell);
+
+ // distribute the matrices of the
+ // base finite elements to the
+ // matrices of this object. for
+ // this, loop over all degrees of
+ // freedom and take the respective
+ // entry of the underlying base
+ // element.
+ //
+ // note that we by definition of a
+ // base element, they are
+ // independent, i.e. do not
+ // couple. only DoFs that belong to
+ // the same instance of a base
+ // element may couple
for (unsigned int i=0; i<this->dofs_per_cell; ++i)
- for (unsigned int j=0; j<this->dofs_per_cell; ++j)
- {
- // first find out to which
- // base element indices i and
- // j belong, and which
- // instance thereof in case
- // the base element has a
- // multiplicity greater than
- // one. if they should not
- // happen to belong to the
- // same instance of a base
- // element, then they cannot
- // couple, so go on with the
- // next index
- if (this->system_to_base_table[i].first !=
- this->system_to_base_table[j].first)
- continue;
-
- // so get the common base
- // element and the indices
- // therein:
- const unsigned int
- base = this->system_to_base_table[i].first.first;
-
- const unsigned int
- base_index_i = this->system_to_base_table[i].second,
- base_index_j = this->system_to_base_table[j].second;
-
- // if we are sure that DoFs i
- // and j may couple, then
- // copy entries of the
- // matrices:
- for (unsigned int child=0; child<GeometryInfo<dim>::n_children(RefinementCase<dim>(ref_case)); ++child)
- {
- if (do_restriction)
- this->restriction[ref_case-1][child] (i,j)
- = (base_element(base)
- .get_restriction_matrix(child, RefinementCase<dim>(ref_case))(
- base_index_i,base_index_j));
-
- if (do_prolongation)
- this->prolongation[ref_case-1][child] (i,j)
- = (base_element(base)
- .get_prolongation_matrix(child, RefinementCase<dim>(ref_case))(
- base_index_i,base_index_j));
- };
- };
+ for (unsigned int j=0; j<this->dofs_per_cell; ++j)
+ {
+ // first find out to which
+ // base element indices i and
+ // j belong, and which
+ // instance thereof in case
+ // the base element has a
+ // multiplicity greater than
+ // one. if they should not
+ // happen to belong to the
+ // same instance of a base
+ // element, then they cannot
+ // couple, so go on with the
+ // next index
+ if (this->system_to_base_table[i].first !=
+ this->system_to_base_table[j].first)
+ continue;
+
+ // so get the common base
+ // element and the indices
+ // therein:
+ const unsigned int
+ base = this->system_to_base_table[i].first.first;
+
+ const unsigned int
+ base_index_i = this->system_to_base_table[i].second,
+ base_index_j = this->system_to_base_table[j].second;
+
+ // if we are sure that DoFs i
+ // and j may couple, then
+ // copy entries of the
+ // matrices:
+ for (unsigned int child=0; child<GeometryInfo<dim>::n_children(RefinementCase<dim>(ref_case)); ++child)
+ {
+ if (do_restriction)
+ this->restriction[ref_case-1][child] (i,j)
+ = (base_element(base)
+ .get_restriction_matrix(child, RefinementCase<dim>(ref_case))(
+ base_index_i,base_index_j));
+
+ if (do_prolongation)
+ this->prolongation[ref_case-1][child] (i,j)
+ = (base_element(base)
+ .get_prolongation_matrix(child, RefinementCase<dim>(ref_case))(
+ base_index_i,base_index_j));
+ };
+ };
}
- // now set up the interface constraints.
- // this is kind'o hairy, so don't try
- // to do it dimension independent
+ // now set up the interface constraints.
+ // this is kind'o hairy, so don't try
+ // to do it dimension independent
build_interface_constraints ();
- // finally fill in support points
- // on cell and face
+ // finally fill in support points
+ // on cell and face
initialize_unit_support_points ();
initialize_unit_face_support_points ();
template <int dim, int spacedim>
FiniteElementData<dim>
FESystem<dim,spacedim>::multiply_dof_numbers (const FiniteElementData<dim> &fe_data,
- const unsigned int N)
+ const unsigned int N)
{
std::vector<unsigned int> dpo;
dpo.push_back(fe_data.dofs_per_vertex * N);
if (dim>2) dpo.push_back(fe_data.dofs_per_hex * N);
return FiniteElementData<dim> (dpo,
- fe_data.n_components() * N,
- fe_data.tensor_degree(),
- fe_data.conforming_space,
- N);
+ fe_data.n_components() * N,
+ fe_data.tensor_degree(),
+ fe_data.conforming_space,
+ N);
}
FESystem<dim,spacedim>::
initialize_unit_support_points ()
{
- // if one of the base elements
- // has no support points, then
- // it makes no sense to define
- // support points for the
- // composed element, so return
- // an empty array to
- // demonstrate that
- // fact
+ // if one of the base elements
+ // has no support points, then
+ // it makes no sense to define
+ // support points for the
+ // composed element, so return
+ // an empty array to
+ // demonstrate that
+ // fact
for (unsigned int base_el=0; base_el<this->n_base_elements(); ++base_el)
if (!base_element(base_el).has_support_points())
{
- this->unit_support_points.resize(0);
- return;
+ this->unit_support_points.resize(0);
+ return;
};
- // generate unit support points
- // from unit support points of sub
- // elements
+ // generate unit support points
+ // from unit support points of sub
+ // elements
this->unit_support_points.resize(this->dofs_per_cell);
for (unsigned int i=0; i<this->dofs_per_cell; ++i)
{
const unsigned int
- base = this->system_to_base_table[i].first.first,
- base_index = this->system_to_base_table[i].second;
+ base = this->system_to_base_table[i].first.first,
+ base_index = this->system_to_base_table[i].second;
Assert (base<this->n_base_elements(), ExcInternalError());
Assert (base_index<base_element(base).unit_support_points.size(),
- ExcInternalError());
+ ExcInternalError());
this->unit_support_points[i] = base_element(base).unit_support_points[base_index];
};
}
FESystem<dim,spacedim>::
initialize_unit_face_support_points ()
{
- // Nothing to do in 1D
+ // Nothing to do in 1D
if (dim == 1)
return;
- // if one of the base elements has no
- // support points, then it makes no sense
- // to define support points for the
- // composed element. In that case, return
- // an empty array to demonstrate that fact
- // (note that we ask whether the base
- // element has no support points at all,
- // not only none on the face!)
- //
- // on the other hand, if there is an
- // element that simply has no degrees of
- // freedom on the face at all, then we
- // don't care whether it has support points
- // or not. this is, for example, the case
- // for the stable Stokes element Q(p)^dim
- // \times DGP(p-1).
+ // if one of the base elements has no
+ // support points, then it makes no sense
+ // to define support points for the
+ // composed element. In that case, return
+ // an empty array to demonstrate that fact
+ // (note that we ask whether the base
+ // element has no support points at all,
+ // not only none on the face!)
+ //
+ // on the other hand, if there is an
+ // element that simply has no degrees of
+ // freedom on the face at all, then we
+ // don't care whether it has support points
+ // or not. this is, for example, the case
+ // for the stable Stokes element Q(p)^dim
+ // \times DGP(p-1).
for (unsigned int base_el=0; base_el<this->n_base_elements(); ++base_el)
if (!base_element(base_el).has_support_points()
- &&
- (base_element(base_el).dofs_per_face > 0))
+ &&
+ (base_element(base_el).dofs_per_face > 0))
{
- this->unit_face_support_points.resize(0);
- return;
+ this->unit_face_support_points.resize(0);
+ return;
}
- // generate unit face support points
- // from unit support points of sub
- // elements
+ // generate unit face support points
+ // from unit support points of sub
+ // elements
this->unit_face_support_points.resize(this->dofs_per_face);
for (unsigned int i=0; i<this->dofs_per_face; ++i)
const unsigned int index_in_base = this->face_system_to_base_table[i].second;
Assert (index_in_base < base_element(base_i).unit_face_support_points.size(),
- ExcInternalError());
+ ExcInternalError());
this->unit_face_support_points[i]
- = base_element(base_i).unit_face_support_points[index_in_base];
+ = base_element(base_i).unit_face_support_points[index_in_base];
}
}
void
FESystem<dim,spacedim>::initialize_quad_dof_index_permutation ()
{
- // nothing to do in other dimensions than 3
+ // nothing to do in other dimensions than 3
if (dim < 3)
return;
- // the array into which we want to write
- // should have the correct size already.
+ // the array into which we want to write
+ // should have the correct size already.
Assert (this->adjust_quad_dof_index_for_face_orientation_table.n_elements()==
- 8*this->dofs_per_quad, ExcInternalError());
+ 8*this->dofs_per_quad, ExcInternalError());
- // to obtain the shifts for this composed
- // element, copy the shift information of
- // the base elements
+ // to obtain the shifts for this composed
+ // element, copy the shift information of
+ // the base elements
unsigned int index = 0;
for (unsigned int b=0; b<this->n_base_elements();++b)
{
const Table<2,int> &temp
- = this->base_element(b).adjust_quad_dof_index_for_face_orientation_table;
+ = this->base_element(b).adjust_quad_dof_index_for_face_orientation_table;
for (unsigned int c=0; c<this->element_multiplicity(b); ++c)
- {
- for (unsigned int i=0; i<temp.size(0); ++i)
- for (unsigned int j=0; j<8; ++j)
- this->adjust_quad_dof_index_for_face_orientation_table(index+i,j)=
- temp(i,j);
- index += temp.size(0);
- }
+ {
+ for (unsigned int i=0; i<temp.size(0); ++i)
+ for (unsigned int j=0; j<8; ++j)
+ this->adjust_quad_dof_index_for_face_orientation_table(index+i,j)=
+ temp(i,j);
+ index += temp.size(0);
+ }
}
Assert (index == this->dofs_per_quad,
- ExcInternalError());
+ ExcInternalError());
- // aditionally compose the permutation
- // information for lines
+ // aditionally compose the permutation
+ // information for lines
Assert (this->adjust_line_dof_index_for_line_orientation_table.size()==
- this->dofs_per_line, ExcInternalError());
+ this->dofs_per_line, ExcInternalError());
index = 0;
for (unsigned int b=0; b<this->n_base_elements();++b)
{
const std::vector<int> &temp2
- = this->base_element(b).adjust_line_dof_index_for_line_orientation_table;
+ = this->base_element(b).adjust_line_dof_index_for_line_orientation_table;
for (unsigned int c=0; c<this->element_multiplicity(b); ++c)
- {
- std::copy(temp2.begin(), temp2.end(),
- this->adjust_line_dof_index_for_line_orientation_table.begin()
- +index);
- index += temp2.size();
- }
+ {
+ std::copy(temp2.begin(), temp2.end(),
+ this->adjust_line_dof_index_for_line_orientation_table.begin()
+ +index);
+ index += temp2.size();
+ }
}
Assert (index == this->dofs_per_line,
- ExcInternalError());
+ ExcInternalError());
}
void
FESystem<dim,spacedim>::
get_face_interpolation_matrix (const FiniteElement<dim,spacedim> &x_source_fe,
- FullMatrix<double> &interpolation_matrix) const
+ FullMatrix<double> &interpolation_matrix) const
{
typedef FiniteElement<dim,spacedim> FEL;
AssertThrow ((x_source_fe.get_name().find ("FE_System<") == 0)
- ||
- (dynamic_cast<const FESystem<dim,spacedim>*>(&x_source_fe) != 0),
- typename FEL::
- ExcInterpolationNotImplemented());
+ ||
+ (dynamic_cast<const FESystem<dim,spacedim>*>(&x_source_fe) != 0),
+ typename FEL::
+ ExcInterpolationNotImplemented());
Assert (interpolation_matrix.n() == this->dofs_per_face,
- ExcDimensionMismatch (interpolation_matrix.n(),
- this->dofs_per_face));
+ ExcDimensionMismatch (interpolation_matrix.n(),
+ this->dofs_per_face));
Assert (interpolation_matrix.m() == x_source_fe.dofs_per_face,
- ExcDimensionMismatch (interpolation_matrix.m(),
- x_source_fe.dofs_per_face));
-
- // since dofs for each base are
- // independent, we only have to stack
- // things up from base element to base
- // element
- //
- // the problem is that we have to work with
- // two FEs (this and fe_other). only deal
- // with the case that both are FESystems
- // and that they both have the same number
- // of bases (counting multiplicity) each of
- // which match in their number of
- // components. this covers
- // FESystem(FE_Q(p),1,FE_Q(q),2) vs
- // FESystem(FE_Q(r),2,FE_Q(s),1), but not
- // FESystem(FE_Q(p),1,FE_Q(q),2) vs
- // FESystem(FESystem(FE_Q(r),2),1,FE_Q(s),1)
+ ExcDimensionMismatch (interpolation_matrix.m(),
+ x_source_fe.dofs_per_face));
+
+ // since dofs for each base are
+ // independent, we only have to stack
+ // things up from base element to base
+ // element
+ //
+ // the problem is that we have to work with
+ // two FEs (this and fe_other). only deal
+ // with the case that both are FESystems
+ // and that they both have the same number
+ // of bases (counting multiplicity) each of
+ // which match in their number of
+ // components. this covers
+ // FESystem(FE_Q(p),1,FE_Q(q),2) vs
+ // FESystem(FE_Q(r),2,FE_Q(s),1), but not
+ // FESystem(FE_Q(p),1,FE_Q(q),2) vs
+ // FESystem(FESystem(FE_Q(r),2),1,FE_Q(s),1)
const FESystem<dim,spacedim> *fe_other_system
= dynamic_cast<const FESystem<dim,spacedim>*>(&x_source_fe);
- // clear matrix, since we will not get to
- // set all elements
+ // clear matrix, since we will not get to
+ // set all elements
interpolation_matrix = 0;
- // loop over all the base elements of
- // this and the other element, counting
- // their multiplicities
+ // loop over all the base elements of
+ // this and the other element, counting
+ // their multiplicities
unsigned int base_index = 0,
- base_index_other = 0;
+ base_index_other = 0;
unsigned int multiplicity = 0,
- multiplicity_other = 0;
+ multiplicity_other = 0;
FullMatrix<double> base_to_base_interpolation;
while (true)
{
const FiniteElement<dim,spacedim>
- &base = base_element(base_index),
- &base_other = fe_other_system->base_element(base_index_other);
+ &base = base_element(base_index),
+ &base_other = fe_other_system->base_element(base_index_other);
Assert (base.n_components() == base_other.n_components(),
- ExcNotImplemented());
+ ExcNotImplemented());
- // get the interpolation from the bases
+ // get the interpolation from the bases
base_to_base_interpolation.reinit (base_other.dofs_per_face,
- base.dofs_per_face);
+ base.dofs_per_face);
base.get_face_interpolation_matrix (base_other,
- base_to_base_interpolation);
+ base_to_base_interpolation);
- // now translate entries. we'd like to
- // have something like
- // face_base_to_system_index, but that
- // doesn't exist. rather, all we have
- // is the reverse. well, use that then
+ // now translate entries. we'd like to
+ // have something like
+ // face_base_to_system_index, but that
+ // doesn't exist. rather, all we have
+ // is the reverse. well, use that then
for (unsigned int i=0; i<this->dofs_per_face; ++i)
- if (this->face_system_to_base_index(i).first
- ==
- std::make_pair (base_index, multiplicity))
- for (unsigned int j=0; j<fe_other_system->dofs_per_face; ++j)
- if (fe_other_system->face_system_to_base_index(j).first
- ==
- std::make_pair (base_index_other, multiplicity_other))
- interpolation_matrix(j, i)
- = base_to_base_interpolation(fe_other_system->face_system_to_base_index(j).second,
- this->face_system_to_base_index(i).second);
-
- // advance to the next base element
- // for this and the other
- // fe_system; see if we can simply
- // advance the multiplicity by one,
- // or if have to move on to the
- // next base element
+ if (this->face_system_to_base_index(i).first
+ ==
+ std::make_pair (base_index, multiplicity))
+ for (unsigned int j=0; j<fe_other_system->dofs_per_face; ++j)
+ if (fe_other_system->face_system_to_base_index(j).first
+ ==
+ std::make_pair (base_index_other, multiplicity_other))
+ interpolation_matrix(j, i)
+ = base_to_base_interpolation(fe_other_system->face_system_to_base_index(j).second,
+ this->face_system_to_base_index(i).second);
+
+ // advance to the next base element
+ // for this and the other
+ // fe_system; see if we can simply
+ // advance the multiplicity by one,
+ // or if have to move on to the
+ // next base element
++multiplicity;
if (multiplicity == this->element_multiplicity(base_index))
- {
- multiplicity = 0;
- ++base_index;
- }
+ {
+ multiplicity = 0;
+ ++base_index;
+ }
++multiplicity_other;
if (multiplicity_other ==
- fe_other_system->element_multiplicity(base_index_other))
- {
- multiplicity_other = 0;
- ++base_index_other;
- }
-
- // see if we have reached the end
- // of the present element. if so,
- // we should have reached the end
- // of the other one as well
+ fe_other_system->element_multiplicity(base_index_other))
+ {
+ multiplicity_other = 0;
+ ++base_index_other;
+ }
+
+ // see if we have reached the end
+ // of the present element. if so,
+ // we should have reached the end
+ // of the other one as well
if (base_index == this->n_base_elements())
- {
- Assert (base_index_other == fe_other_system->n_base_elements(),
- ExcInternalError());
- break;
- }
-
- // if we haven't reached the end of
- // this element, we shouldn't have
- // reached the end of the other one
- // either
+ {
+ Assert (base_index_other == fe_other_system->n_base_elements(),
+ ExcInternalError());
+ break;
+ }
+
+ // if we haven't reached the end of
+ // this element, we shouldn't have
+ // reached the end of the other one
+ // either
Assert (base_index_other != fe_other_system->n_base_elements(),
- ExcInternalError());
+ ExcInternalError());
}
}
void
FESystem<dim,spacedim>::
get_subface_interpolation_matrix (const FiniteElement<dim,spacedim> &x_source_fe,
- const unsigned int subface,
- FullMatrix<double> &interpolation_matrix) const
+ const unsigned int subface,
+ FullMatrix<double> &interpolation_matrix) const
{
typedef FiniteElement<dim,spacedim> FEL;
AssertThrow ((x_source_fe.get_name().find ("FE_System<") == 0)
- ||
- (dynamic_cast<const FESystem<dim,spacedim>*>(&x_source_fe) != 0),
- typename FEL::
- ExcInterpolationNotImplemented());
+ ||
+ (dynamic_cast<const FESystem<dim,spacedim>*>(&x_source_fe) != 0),
+ typename FEL::
+ ExcInterpolationNotImplemented());
Assert (interpolation_matrix.n() == this->dofs_per_face,
- ExcDimensionMismatch (interpolation_matrix.n(),
- this->dofs_per_face));
+ ExcDimensionMismatch (interpolation_matrix.n(),
+ this->dofs_per_face));
Assert (interpolation_matrix.m() == x_source_fe.dofs_per_face,
- ExcDimensionMismatch (interpolation_matrix.m(),
- x_source_fe.dofs_per_face));
-
- // since dofs for each base are
- // independent, we only have to stack
- // things up from base element to base
- // element
- //
- // the problem is that we have to work with
- // two FEs (this and fe_other). only deal
- // with the case that both are FESystems
- // and that they both have the same number
- // of bases (counting multiplicity) each of
- // which match in their number of
- // components. this covers
- // FESystem(FE_Q(p),1,FE_Q(q),2) vs
- // FESystem(FE_Q(r),2,FE_Q(s),1), but not
- // FESystem(FE_Q(p),1,FE_Q(q),2) vs
- // FESystem(FESystem(FE_Q(r),2),1,FE_Q(s),1)
+ ExcDimensionMismatch (interpolation_matrix.m(),
+ x_source_fe.dofs_per_face));
+
+ // since dofs for each base are
+ // independent, we only have to stack
+ // things up from base element to base
+ // element
+ //
+ // the problem is that we have to work with
+ // two FEs (this and fe_other). only deal
+ // with the case that both are FESystems
+ // and that they both have the same number
+ // of bases (counting multiplicity) each of
+ // which match in their number of
+ // components. this covers
+ // FESystem(FE_Q(p),1,FE_Q(q),2) vs
+ // FESystem(FE_Q(r),2,FE_Q(s),1), but not
+ // FESystem(FE_Q(p),1,FE_Q(q),2) vs
+ // FESystem(FESystem(FE_Q(r),2),1,FE_Q(s),1)
const FESystem<dim,spacedim> *fe_other_system
= dynamic_cast<const FESystem<dim,spacedim>*>(&x_source_fe);
- // clear matrix, since we will not get to
- // set all elements
+ // clear matrix, since we will not get to
+ // set all elements
interpolation_matrix = 0;
- // loop over all the base elements of
- // this and the other element, counting
- // their multiplicities
+ // loop over all the base elements of
+ // this and the other element, counting
+ // their multiplicities
unsigned int base_index = 0,
- base_index_other = 0;
+ base_index_other = 0;
unsigned int multiplicity = 0,
- multiplicity_other = 0;
+ multiplicity_other = 0;
FullMatrix<double> base_to_base_interpolation;
while (true)
{
const FiniteElement<dim,spacedim>
- &base = base_element(base_index),
- &base_other = fe_other_system->base_element(base_index_other);
+ &base = base_element(base_index),
+ &base_other = fe_other_system->base_element(base_index_other);
Assert (base.n_components() == base_other.n_components(),
- ExcNotImplemented());
+ ExcNotImplemented());
- // get the interpolation from the bases
+ // get the interpolation from the bases
base_to_base_interpolation.reinit (base_other.dofs_per_face,
- base.dofs_per_face);
+ base.dofs_per_face);
base.get_subface_interpolation_matrix (base_other,
- subface,
- base_to_base_interpolation);
-
- // now translate entries. we'd like to
- // have something like
- // face_base_to_system_index, but that
- // doesn't exist. rather, all we have
- // is the reverse. well, use that then
+ subface,
+ base_to_base_interpolation);
+
+ // now translate entries. we'd like to
+ // have something like
+ // face_base_to_system_index, but that
+ // doesn't exist. rather, all we have
+ // is the reverse. well, use that then
for (unsigned int i=0; i<this->dofs_per_face; ++i)
- if (this->face_system_to_base_index(i).first
- ==
- std::make_pair (base_index, multiplicity))
- for (unsigned int j=0; j<fe_other_system->dofs_per_face; ++j)
- if (fe_other_system->face_system_to_base_index(j).first
- ==
- std::make_pair (base_index_other, multiplicity_other))
- interpolation_matrix(j, i)
- = base_to_base_interpolation(fe_other_system->face_system_to_base_index(j).second,
- this->face_system_to_base_index(i).second);
-
- // advance to the next base element
- // for this and the other
- // fe_system; see if we can simply
- // advance the multiplicity by one,
- // or if have to move on to the
- // next base element
+ if (this->face_system_to_base_index(i).first
+ ==
+ std::make_pair (base_index, multiplicity))
+ for (unsigned int j=0; j<fe_other_system->dofs_per_face; ++j)
+ if (fe_other_system->face_system_to_base_index(j).first
+ ==
+ std::make_pair (base_index_other, multiplicity_other))
+ interpolation_matrix(j, i)
+ = base_to_base_interpolation(fe_other_system->face_system_to_base_index(j).second,
+ this->face_system_to_base_index(i).second);
+
+ // advance to the next base element
+ // for this and the other
+ // fe_system; see if we can simply
+ // advance the multiplicity by one,
+ // or if have to move on to the
+ // next base element
++multiplicity;
if (multiplicity == this->element_multiplicity(base_index))
- {
- multiplicity = 0;
- ++base_index;
- }
+ {
+ multiplicity = 0;
+ ++base_index;
+ }
++multiplicity_other;
if (multiplicity_other ==
- fe_other_system->element_multiplicity(base_index_other))
- {
- multiplicity_other = 0;
- ++base_index_other;
- }
-
- // see if we have reached the end
- // of the present element. if so,
- // we should have reached the end
- // of the other one as well
+ fe_other_system->element_multiplicity(base_index_other))
+ {
+ multiplicity_other = 0;
+ ++base_index_other;
+ }
+
+ // see if we have reached the end
+ // of the present element. if so,
+ // we should have reached the end
+ // of the other one as well
if (base_index == this->n_base_elements())
- {
- Assert (base_index_other == fe_other_system->n_base_elements(),
- ExcInternalError());
- break;
- }
-
- // if we haven't reached the end of
- // this element, we shouldn't have
- // reached the end of the other one
- // either
+ {
+ Assert (base_index_other == fe_other_system->n_base_elements(),
+ ExcInternalError());
+ break;
+ }
+
+ // if we haven't reached the end of
+ // this element, we shouldn't have
+ // reached the end of the other one
+ // either
Assert (base_index_other != fe_other_system->n_base_elements(),
- ExcInternalError());
+ ExcInternalError());
}
}
std::vector<std::pair<unsigned int, unsigned int> >
FESystem<dim,spacedim>::hp_object_dof_identities (const FiniteElement<dim,spacedim> &fe_other) const
{
- // since dofs on each subobject (vertex,
- // line, ...) are ordered such that first
- // come all from the first base element all
- // multiplicities, then second base element
- // all multiplicities, etc., we simply have
- // to stack all the identities after each
- // other
- //
- // the problem is that we have to work with
- // two FEs (this and fe_other). only deal
- // with the case that both are FESystems
- // and that they both have the same number
- // of bases (counting multiplicity) each of
- // which match in their number of
- // components. this covers
- // FESystem(FE_Q(p),1,FE_Q(q),2) vs
- // FESystem(FE_Q(r),2,FE_Q(s),1), but not
- // FESystem(FE_Q(p),1,FE_Q(q),2) vs
- // FESystem(FESystem(FE_Q(r),2),1,FE_Q(s),1)
+ // since dofs on each subobject (vertex,
+ // line, ...) are ordered such that first
+ // come all from the first base element all
+ // multiplicities, then second base element
+ // all multiplicities, etc., we simply have
+ // to stack all the identities after each
+ // other
+ //
+ // the problem is that we have to work with
+ // two FEs (this and fe_other). only deal
+ // with the case that both are FESystems
+ // and that they both have the same number
+ // of bases (counting multiplicity) each of
+ // which match in their number of
+ // components. this covers
+ // FESystem(FE_Q(p),1,FE_Q(q),2) vs
+ // FESystem(FE_Q(r),2,FE_Q(s),1), but not
+ // FESystem(FE_Q(p),1,FE_Q(q),2) vs
+ // FESystem(FESystem(FE_Q(r),2),1,FE_Q(s),1)
if (const FESystem<dim,spacedim> *fe_other_system
= dynamic_cast<const FESystem<dim,spacedim>*>(&fe_other))
{
- // loop over all the base elements of
- // this and the other element, counting
- // their multiplicities
+ // loop over all the base elements of
+ // this and the other element, counting
+ // their multiplicities
unsigned int base_index = 0,
- base_index_other = 0;
+ base_index_other = 0;
unsigned int multiplicity = 0,
- multiplicity_other = 0;
+ multiplicity_other = 0;
- // we also need to keep track of the
- // number of dofs already treated for
- // each of the elements
+ // we also need to keep track of the
+ // number of dofs already treated for
+ // each of the elements
unsigned int dof_offset = 0,
- dof_offset_other = 0;
+ dof_offset_other = 0;
std::vector<std::pair<unsigned int, unsigned int> > identities;
while (true)
- {
- const FiniteElement<dim,spacedim>
- &base = base_element(base_index),
- &base_other = fe_other_system->base_element(base_index_other);
-
- Assert (base.n_components() == base_other.n_components(),
- ExcNotImplemented());
-
- // now translate the identities
- // returned by the base elements to
- // the indices of this system
- // element
- std::vector<std::pair<unsigned int, unsigned int> > base_identities;
- switch (structdim)
- {
- case 0:
- base_identities = base.hp_vertex_dof_identities (base_other);
- break;
- case 1:
- base_identities = base.hp_line_dof_identities (base_other);
- break;
- case 2:
- base_identities = base.hp_quad_dof_identities (base_other);
- break;
- default:
- Assert (false, ExcNotImplemented());
- }
-
- for (unsigned int i=0; i<base_identities.size(); ++i)
- identities.push_back
- (std::make_pair (base_identities[i].first + dof_offset,
- base_identities[i].second + dof_offset_other));
-
- // record the dofs treated above as
- // already taken care of
- dof_offset += base.template n_dofs_per_object<structdim>();
- dof_offset_other += base_other.template n_dofs_per_object<structdim>();
-
- // advance to the next base element
- // for this and the other
- // fe_system; see if we can simply
- // advance the multiplicity by one,
- // or if have to move on to the
- // next base element
- ++multiplicity;
- if (multiplicity == this->element_multiplicity(base_index))
- {
- multiplicity = 0;
- ++base_index;
- }
- ++multiplicity_other;
- if (multiplicity_other ==
- fe_other_system->element_multiplicity(base_index_other))
- {
- multiplicity_other = 0;
- ++base_index_other;
- }
-
- // see if we have reached the end
- // of the present element. if so,
- // we should have reached the end
- // of the other one as well
- if (base_index == this->n_base_elements())
- {
- Assert (base_index_other == fe_other_system->n_base_elements(),
- ExcInternalError());
- break;
- }
-
- // if we haven't reached the end of
- // this element, we shouldn't have
- // reached the end of the other one
- // either
- Assert (base_index_other != fe_other_system->n_base_elements(),
- ExcInternalError());
- }
+ {
+ const FiniteElement<dim,spacedim>
+ &base = base_element(base_index),
+ &base_other = fe_other_system->base_element(base_index_other);
+
+ Assert (base.n_components() == base_other.n_components(),
+ ExcNotImplemented());
+
+ // now translate the identities
+ // returned by the base elements to
+ // the indices of this system
+ // element
+ std::vector<std::pair<unsigned int, unsigned int> > base_identities;
+ switch (structdim)
+ {
+ case 0:
+ base_identities = base.hp_vertex_dof_identities (base_other);
+ break;
+ case 1:
+ base_identities = base.hp_line_dof_identities (base_other);
+ break;
+ case 2:
+ base_identities = base.hp_quad_dof_identities (base_other);
+ break;
+ default:
+ Assert (false, ExcNotImplemented());
+ }
+
+ for (unsigned int i=0; i<base_identities.size(); ++i)
+ identities.push_back
+ (std::make_pair (base_identities[i].first + dof_offset,
+ base_identities[i].second + dof_offset_other));
+
+ // record the dofs treated above as
+ // already taken care of
+ dof_offset += base.template n_dofs_per_object<structdim>();
+ dof_offset_other += base_other.template n_dofs_per_object<structdim>();
+
+ // advance to the next base element
+ // for this and the other
+ // fe_system; see if we can simply
+ // advance the multiplicity by one,
+ // or if have to move on to the
+ // next base element
+ ++multiplicity;
+ if (multiplicity == this->element_multiplicity(base_index))
+ {
+ multiplicity = 0;
+ ++base_index;
+ }
+ ++multiplicity_other;
+ if (multiplicity_other ==
+ fe_other_system->element_multiplicity(base_index_other))
+ {
+ multiplicity_other = 0;
+ ++base_index_other;
+ }
+
+ // see if we have reached the end
+ // of the present element. if so,
+ // we should have reached the end
+ // of the other one as well
+ if (base_index == this->n_base_elements())
+ {
+ Assert (base_index_other == fe_other_system->n_base_elements(),
+ ExcInternalError());
+ break;
+ }
+
+ // if we haven't reached the end of
+ // this element, we shouldn't have
+ // reached the end of the other one
+ // either
+ Assert (base_index_other != fe_other_system->n_base_elements(),
+ ExcInternalError());
+ }
return identities;
}
FESystem<dim,spacedim>::
compare_for_face_domination (const FiniteElement<dim,spacedim> &fe_other) const
{
- // at present all we can do is to compare
- // with other FESystems that have the same
- // number of components and bases
+ // at present all we can do is to compare
+ // with other FESystems that have the same
+ // number of components and bases
if (const FESystem<dim,spacedim> *fe_sys_other
= dynamic_cast<const FESystem<dim,spacedim>*>(&fe_other))
{
Assert (this->n_components() == fe_sys_other->n_components(),
- ExcNotImplemented());
+ ExcNotImplemented());
Assert (this->n_base_elements() == fe_sys_other->n_base_elements(),
- ExcNotImplemented());
+ ExcNotImplemented());
FiniteElementDomination::Domination
- domination = FiniteElementDomination::no_requirements;
+ domination = FiniteElementDomination::no_requirements;
- // loop over all base elements and do
- // some sanity checks
+ // loop over all base elements and do
+ // some sanity checks
for (unsigned int b=0; b<this->n_base_elements(); ++b)
- {
- Assert (this->base_element(b).n_components() ==
- fe_sys_other->base_element(b).n_components(),
- ExcNotImplemented());
- Assert (this->element_multiplicity(b) ==
- fe_sys_other->element_multiplicity(b),
- ExcNotImplemented());
-
- // for this pair of base elements,
- // check who dominates and combine
- // with previous result
- const FiniteElementDomination::Domination
- base_domination = (this->base_element(b)
- .compare_for_face_domination (fe_sys_other->base_element(b)));
- domination = domination & base_domination;
- }
-
- // if we've gotten here, then we've
- // either found a winner or either
- // element is fine being dominated
+ {
+ Assert (this->base_element(b).n_components() ==
+ fe_sys_other->base_element(b).n_components(),
+ ExcNotImplemented());
+ Assert (this->element_multiplicity(b) ==
+ fe_sys_other->element_multiplicity(b),
+ ExcNotImplemented());
+
+ // for this pair of base elements,
+ // check who dominates and combine
+ // with previous result
+ const FiniteElementDomination::Domination
+ base_domination = (this->base_element(b)
+ .compare_for_face_domination (fe_sys_other->base_element(b)));
+ domination = domination & base_domination;
+ }
+
+ // if we've gotten here, then we've
+ // either found a winner or either
+ // element is fine being dominated
Assert (domination !=
- FiniteElementDomination::neither_element_dominates,
- ExcInternalError());
+ FiniteElementDomination::neither_element_dominates,
+ ExcInternalError());
return domination;
}
template <int dim, int spacedim>
FiniteElementData<dim>
FESystem<dim,spacedim>::multiply_dof_numbers (const FiniteElementData<dim> &fe1,
- const unsigned int N1,
- const FiniteElementData<dim> &fe2,
- const unsigned int N2)
+ const unsigned int N1,
+ const FiniteElementData<dim> &fe2,
+ const unsigned int N2)
{
std::vector<unsigned int> dpo;
dpo.push_back(fe1.dofs_per_vertex * N1 + fe2.dofs_per_vertex * N2);
if (dim>1) dpo.push_back(fe1.dofs_per_quad * N1 + fe2.dofs_per_quad * N2);
if (dim>2) dpo.push_back(fe1.dofs_per_hex * N1 + fe2.dofs_per_hex * N2);
- // degree is the maximal degree of
- // the components. max also makes
- // sure that one unknown degree
- // makes the degree of the system
- // unknown.
+ // degree is the maximal degree of
+ // the components. max also makes
+ // sure that one unknown degree
+ // makes the degree of the system
+ // unknown.
unsigned int degree = std::max(fe1.tensor_degree(), fe2.tensor_degree());
return FiniteElementData<dim> (
dpo,
fe1.n_components() * N1 + fe2.n_components() * N2,
degree,
typename FiniteElementData<dim>::Conformity(fe1.conforming_space
- & fe2.conforming_space),
+ & fe2.conforming_space),
N1 + N2);
}
template <int dim, int spacedim>
FiniteElementData<dim>
FESystem<dim,spacedim>::multiply_dof_numbers (const FiniteElementData<dim> &fe1,
- const unsigned int N1,
- const FiniteElementData<dim> &fe2,
- const unsigned int N2,
- const FiniteElementData<dim> &fe3,
- const unsigned int N3)
+ const unsigned int N1,
+ const FiniteElementData<dim> &fe2,
+ const unsigned int N2,
+ const FiniteElementData<dim> &fe3,
+ const unsigned int N3)
{
std::vector<unsigned int> dpo;
dpo.push_back(fe1.dofs_per_vertex * N1 +
- fe2.dofs_per_vertex * N2 +
- fe3.dofs_per_vertex * N3);
+ fe2.dofs_per_vertex * N2 +
+ fe3.dofs_per_vertex * N3);
dpo.push_back(fe1.dofs_per_line * N1 +
- fe2.dofs_per_line * N2 +
- fe3.dofs_per_line * N3);
+ fe2.dofs_per_line * N2 +
+ fe3.dofs_per_line * N3);
if (dim>1) dpo.push_back(fe1.dofs_per_quad * N1 +
- fe2.dofs_per_quad * N2 +
- fe3.dofs_per_quad * N3);
+ fe2.dofs_per_quad * N2 +
+ fe3.dofs_per_quad * N3);
if (dim>2) dpo.push_back(fe1.dofs_per_hex * N1 +
- fe2.dofs_per_hex * N2 +
- fe3.dofs_per_hex * N3);
- // degree is the maximal degree of the components
+ fe2.dofs_per_hex * N2 +
+ fe3.dofs_per_hex * N3);
+ // degree is the maximal degree of the components
const unsigned int
degree = std::max (std::max(fe1.tensor_degree(),
- fe2.tensor_degree()),
- fe3.tensor_degree());
+ fe2.tensor_degree()),
+ fe3.tensor_degree());
return FiniteElementData<dim> (
dpo,
fe1.n_components() * N1 + fe2.n_components() * N2 + fe3.n_components() * N3,
degree,
typename FiniteElementData<dim>::Conformity(fe1.conforming_space
- & fe2.conforming_space
- & fe3.conforming_space),
+ & fe2.conforming_space
+ & fe3.conforming_space),
N1 + N2 + N3);
}
template <int dim, int spacedim>
FiniteElementData<dim>
FESystem<dim,spacedim>::multiply_dof_numbers (const FiniteElementData<dim> &fe1,
- const unsigned int N1,
- const FiniteElementData<dim> &fe2,
- const unsigned int N2,
- const FiniteElementData<dim> &fe3,
- const unsigned int N3,
- const FiniteElementData<dim> &fe4,
- const unsigned int N4)
+ const unsigned int N1,
+ const FiniteElementData<dim> &fe2,
+ const unsigned int N2,
+ const FiniteElementData<dim> &fe3,
+ const unsigned int N3,
+ const FiniteElementData<dim> &fe4,
+ const unsigned int N4)
{
std::vector<unsigned int> dpo;
dpo.push_back(fe1.dofs_per_vertex * N1 +
- fe2.dofs_per_vertex * N2 +
- fe3.dofs_per_vertex * N3 +
- fe4.dofs_per_vertex * N4);
+ fe2.dofs_per_vertex * N2 +
+ fe3.dofs_per_vertex * N3 +
+ fe4.dofs_per_vertex * N4);
dpo.push_back(fe1.dofs_per_line * N1 +
- fe2.dofs_per_line * N2 +
- fe3.dofs_per_line * N3 +
- fe4.dofs_per_line * N4);
+ fe2.dofs_per_line * N2 +
+ fe3.dofs_per_line * N3 +
+ fe4.dofs_per_line * N4);
if (dim>1) dpo.push_back(fe1.dofs_per_quad * N1 +
- fe2.dofs_per_quad * N2 +
- fe3.dofs_per_quad * N3 +
- fe4.dofs_per_quad * N4);
+ fe2.dofs_per_quad * N2 +
+ fe3.dofs_per_quad * N3 +
+ fe4.dofs_per_quad * N4);
if (dim>2) dpo.push_back(fe1.dofs_per_hex * N1 +
- fe2.dofs_per_hex * N2 +
- fe3.dofs_per_hex * N3 +
- fe4.dofs_per_hex * N4);
- // degree is the maximal degree of the components
+ fe2.dofs_per_hex * N2 +
+ fe3.dofs_per_hex * N3 +
+ fe4.dofs_per_hex * N4);
+ // degree is the maximal degree of the components
const unsigned int
degree = std::max(std::max (std::max(fe1.tensor_degree(),fe2.tensor_degree()),fe3.tensor_degree()), fe4.tensor_degree());
fe4.n_components() * N4,
degree,
typename FiniteElementData<dim>::Conformity(fe1.conforming_space
- & fe2.conforming_space
- & fe3.conforming_space
- & fe4.conforming_space),
+ & fe2.conforming_space
+ & fe3.conforming_space
+ & fe4.conforming_space),
N1 + N2 + N3 + N4);
}
template <int dim, int spacedim>
FiniteElementData<dim>
FESystem<dim,spacedim>::multiply_dof_numbers (const FiniteElementData<dim> &fe1,
- const unsigned int N1,
- const FiniteElementData<dim> &fe2,
- const unsigned int N2,
- const FiniteElementData<dim> &fe3,
- const unsigned int N3,
- const FiniteElementData<dim> &fe4,
- const unsigned int N4,
- const FiniteElementData<dim> &fe5,
- const unsigned int N5)
+ const unsigned int N1,
+ const FiniteElementData<dim> &fe2,
+ const unsigned int N2,
+ const FiniteElementData<dim> &fe3,
+ const unsigned int N3,
+ const FiniteElementData<dim> &fe4,
+ const unsigned int N4,
+ const FiniteElementData<dim> &fe5,
+ const unsigned int N5)
{
std::vector<unsigned int> dpo;
dpo.push_back(fe1.dofs_per_vertex * N1 +
- fe2.dofs_per_vertex * N2 +
- fe3.dofs_per_vertex * N3 +
- fe4.dofs_per_vertex * N4 +
- fe5.dofs_per_vertex * N5);
+ fe2.dofs_per_vertex * N2 +
+ fe3.dofs_per_vertex * N3 +
+ fe4.dofs_per_vertex * N4 +
+ fe5.dofs_per_vertex * N5);
dpo.push_back(fe1.dofs_per_line * N1 +
- fe2.dofs_per_line * N2 +
- fe3.dofs_per_line * N3 +
- fe4.dofs_per_line * N4 +
- fe5.dofs_per_line * N5);
+ fe2.dofs_per_line * N2 +
+ fe3.dofs_per_line * N3 +
+ fe4.dofs_per_line * N4 +
+ fe5.dofs_per_line * N5);
if (dim>1) dpo.push_back(fe1.dofs_per_quad * N1 +
- fe2.dofs_per_quad * N2 +
- fe3.dofs_per_quad * N3 +
- fe4.dofs_per_quad * N4 +
- fe5.dofs_per_quad * N5);
+ fe2.dofs_per_quad * N2 +
+ fe3.dofs_per_quad * N3 +
+ fe4.dofs_per_quad * N4 +
+ fe5.dofs_per_quad * N5);
if (dim>2) dpo.push_back(fe1.dofs_per_hex * N1 +
- fe2.dofs_per_hex * N2 +
- fe3.dofs_per_hex * N3 +
- fe4.dofs_per_hex * N4 +
- fe5.dofs_per_hex * N5);
- // degree is the maximal degree of the components
+ fe2.dofs_per_hex * N2 +
+ fe3.dofs_per_hex * N3 +
+ fe4.dofs_per_hex * N4 +
+ fe5.dofs_per_hex * N5);
+ // degree is the maximal degree of the components
const unsigned int
degree = std::max(std::max(std::max (std::max(fe1.tensor_degree(),fe2.tensor_degree()),fe3.tensor_degree()), fe4.tensor_degree()), fe5.tensor_degree());
fe4.n_components() * N4 + fe5.n_components() * N5,
degree,
typename FiniteElementData<dim>::Conformity(fe1.conforming_space
- & fe2.conforming_space
- & fe3.conforming_space
- & fe4.conforming_space
- & fe5.conforming_space),
+ & fe2.conforming_space
+ & fe3.conforming_space
+ & fe4.conforming_space
+ & fe5.conforming_space),
N1 + N2 + N3 + N4 + N5);
}
template <int dim, int spacedim>
std::vector<bool>
FESystem<dim,spacedim>::compute_restriction_is_additive_flags (const FiniteElement<dim,spacedim> &fe,
- const unsigned int n_elements)
+ const unsigned int n_elements)
{
std::vector<const FiniteElement<dim,spacedim>*> fe_list;
std::vector<unsigned int> multiplicities;
template <int dim, int spacedim>
std::vector<bool>
FESystem<dim,spacedim>::compute_restriction_is_additive_flags (const FiniteElement<dim,spacedim> &fe1,
- const unsigned int N1,
- const FiniteElement<dim,spacedim> &fe2,
- const unsigned int N2)
+ const unsigned int N1,
+ const FiniteElement<dim,spacedim> &fe2,
+ const unsigned int N2)
{
std::vector<const FiniteElement<dim,spacedim>*> fe_list;
std::vector<unsigned int> multiplicities;
template <int dim, int spacedim>
std::vector<bool>
FESystem<dim,spacedim>::compute_restriction_is_additive_flags (const FiniteElement<dim,spacedim> &fe1,
- const unsigned int N1,
- const FiniteElement<dim,spacedim> &fe2,
- const unsigned int N2,
- const FiniteElement<dim,spacedim> &fe3,
- const unsigned int N3)
+ const unsigned int N1,
+ const FiniteElement<dim,spacedim> &fe2,
+ const unsigned int N2,
+ const FiniteElement<dim,spacedim> &fe3,
+ const unsigned int N3)
{
std::vector<const FiniteElement<dim,spacedim>*> fe_list;
std::vector<unsigned int> multiplicities;
template <int dim, int spacedim>
std::vector<bool>
FESystem<dim,spacedim>::compute_restriction_is_additive_flags (const FiniteElement<dim,spacedim> &fe1,
- const unsigned int N1,
- const FiniteElement<dim,spacedim> &fe2,
- const unsigned int N2,
- const FiniteElement<dim,spacedim> &fe3,
- const unsigned int N3,
- const FiniteElement<dim,spacedim> &fe4,
- const unsigned int N4)
+ const unsigned int N1,
+ const FiniteElement<dim,spacedim> &fe2,
+ const unsigned int N2,
+ const FiniteElement<dim,spacedim> &fe3,
+ const unsigned int N3,
+ const FiniteElement<dim,spacedim> &fe4,
+ const unsigned int N4)
{
std::vector<const FiniteElement<dim,spacedim>*> fe_list;
std::vector<unsigned int> multiplicities;
template <int dim, int spacedim>
std::vector<bool>
FESystem<dim,spacedim>::compute_restriction_is_additive_flags (const FiniteElement<dim,spacedim> &fe1,
- const unsigned int N1,
- const FiniteElement<dim,spacedim> &fe2,
- const unsigned int N2,
- const FiniteElement<dim,spacedim> &fe3,
- const unsigned int N3,
- const FiniteElement<dim,spacedim> &fe4,
- const unsigned int N4,
- const FiniteElement<dim,spacedim> &fe5,
- const unsigned int N5)
+ const unsigned int N1,
+ const FiniteElement<dim,spacedim> &fe2,
+ const unsigned int N2,
+ const FiniteElement<dim,spacedim> &fe3,
+ const unsigned int N3,
+ const FiniteElement<dim,spacedim> &fe4,
+ const unsigned int N4,
+ const FiniteElement<dim,spacedim> &fe5,
+ const unsigned int N5)
{
std::vector<const FiniteElement<dim,spacedim>*> fe_list;
std::vector<unsigned int> multiplicities;
{
Assert (fes.size() == multiplicities.size(), ExcInternalError());
- // first count the number of dofs
- // and components that will emerge
- // from the given FEs
+ // first count the number of dofs
+ // and components that will emerge
+ // from the given FEs
unsigned int n_shape_functions = 0;
for (unsigned int i=0; i<fes.size(); ++i)
n_shape_functions += fes[i]->dofs_per_cell * multiplicities[i];
- // generate the array that will
- // hold the output
+ // generate the array that will
+ // hold the output
std::vector<bool> retval (n_shape_functions, false);
- // finally go through all the shape
- // functions of the base elements,
- // and copy their flags. this
- // somehow copies the code in
- // build_cell_table, which is not
- // nice as it uses too much
- // implicit knowledge about the
- // layout of the individual bases
- // in the composed FE, but there
- // seems no way around...
- //
- // for each shape function, copy
- // the flags from the base element
- // to this one, taking into account
- // multiplicities, and other
- // complications
+ // finally go through all the shape
+ // functions of the base elements,
+ // and copy their flags. this
+ // somehow copies the code in
+ // build_cell_table, which is not
+ // nice as it uses too much
+ // implicit knowledge about the
+ // layout of the individual bases
+ // in the composed FE, but there
+ // seems no way around...
+ //
+ // for each shape function, copy
+ // the flags from the base element
+ // to this one, taking into account
+ // multiplicities, and other
+ // complications
unsigned int total_index = 0;
for (unsigned int vertex_number=0;
vertex_number<GeometryInfo<dim>::vertices_per_cell;
++vertex_number)
{
for(unsigned int base=0; base<fes.size(); ++base)
- for (unsigned int m=0; m<multiplicities[base]; ++m)
- for (unsigned int local_index = 0;
- local_index < fes[base]->dofs_per_vertex;
- ++local_index, ++total_index)
- {
- const unsigned int index_in_base
- = (fes[base]->dofs_per_vertex*vertex_number +
- local_index);
+ for (unsigned int m=0; m<multiplicities[base]; ++m)
+ for (unsigned int local_index = 0;
+ local_index < fes[base]->dofs_per_vertex;
+ ++local_index, ++total_index)
+ {
+ const unsigned int index_in_base
+ = (fes[base]->dofs_per_vertex*vertex_number +
+ local_index);
Assert (index_in_base < fes[base]->dofs_per_cell,
ExcInternalError());
retval[total_index] = fes[base]->restriction_is_additive(index_in_base);
- }
+ }
}
- // 2. Lines
+ // 2. Lines
if (GeometryInfo<dim>::lines_per_cell > 0)
for (unsigned int line_number= 0;
- line_number != GeometryInfo<dim>::lines_per_cell;
- ++line_number)
+ line_number != GeometryInfo<dim>::lines_per_cell;
+ ++line_number)
{
- for (unsigned int base=0; base<fes.size(); ++base)
- for (unsigned int m=0; m<multiplicities[base]; ++m)
- for (unsigned int local_index = 0;
- local_index < fes[base]->dofs_per_line;
- ++local_index, ++total_index)
- {
- const unsigned int index_in_base
- = (fes[base]->dofs_per_line*line_number +
- local_index +
- fes[base]->first_line_index);
+ for (unsigned int base=0; base<fes.size(); ++base)
+ for (unsigned int m=0; m<multiplicities[base]; ++m)
+ for (unsigned int local_index = 0;
+ local_index < fes[base]->dofs_per_line;
+ ++local_index, ++total_index)
+ {
+ const unsigned int index_in_base
+ = (fes[base]->dofs_per_line*line_number +
+ local_index +
+ fes[base]->first_line_index);
Assert (index_in_base < fes[base]->dofs_per_cell,
ExcInternalError());
retval[total_index] = fes[base]->restriction_is_additive(index_in_base);
- }
+ }
}
- // 3. Quads
+ // 3. Quads
if (GeometryInfo<dim>::quads_per_cell > 0)
for (unsigned int quad_number= 0;
- quad_number != GeometryInfo<dim>::quads_per_cell;
- ++quad_number)
+ quad_number != GeometryInfo<dim>::quads_per_cell;
+ ++quad_number)
{
- for (unsigned int base=0; base<fes.size(); ++base)
- for (unsigned int m=0; m<multiplicities[base]; ++m)
- for (unsigned int local_index = 0;
- local_index < fes[base]->dofs_per_quad;
- ++local_index, ++total_index)
- {
- const unsigned int index_in_base
- = (fes[base]->dofs_per_quad*quad_number +
- local_index +
- fes[base]->first_quad_index);
+ for (unsigned int base=0; base<fes.size(); ++base)
+ for (unsigned int m=0; m<multiplicities[base]; ++m)
+ for (unsigned int local_index = 0;
+ local_index < fes[base]->dofs_per_quad;
+ ++local_index, ++total_index)
+ {
+ const unsigned int index_in_base
+ = (fes[base]->dofs_per_quad*quad_number +
+ local_index +
+ fes[base]->first_quad_index);
Assert (index_in_base < fes[base]->dofs_per_cell,
ExcInternalError());
retval[total_index] = fes[base]->restriction_is_additive(index_in_base);
- }
+ }
}
- // 4. Hexes
+ // 4. Hexes
if (GeometryInfo<dim>::hexes_per_cell > 0)
for (unsigned int hex_number= 0;
- hex_number != GeometryInfo<dim>::hexes_per_cell;
- ++hex_number)
+ hex_number != GeometryInfo<dim>::hexes_per_cell;
+ ++hex_number)
{
- for(unsigned int base=0; base<fes.size(); ++base)
- for (unsigned int m=0; m<multiplicities[base]; ++m)
- for (unsigned int local_index = 0;
- local_index < fes[base]->dofs_per_hex;
- ++local_index, ++total_index)
- {
- const unsigned int index_in_base
- = (fes[base]->dofs_per_hex*hex_number +
- local_index +
- fes[base]->first_hex_index);
+ for(unsigned int base=0; base<fes.size(); ++base)
+ for (unsigned int m=0; m<multiplicities[base]; ++m)
+ for (unsigned int local_index = 0;
+ local_index < fes[base]->dofs_per_hex;
+ ++local_index, ++total_index)
+ {
+ const unsigned int index_in_base
+ = (fes[base]->dofs_per_hex*hex_number +
+ local_index +
+ fes[base]->first_hex_index);
Assert (index_in_base < fes[base]->dofs_per_cell,
ExcInternalError());
retval[total_index] = fes[base]->restriction_is_additive(index_in_base);
- }
+ }
}
Assert (total_index == n_shape_functions, ExcInternalError());
template <int dim, int spacedim>
std::vector<std::vector<bool> >
FESystem<dim,spacedim>::compute_nonzero_components (const FiniteElement<dim,spacedim> &fe1,
- const unsigned int N1)
+ const unsigned int N1)
{
std::vector<const FiniteElement<dim,spacedim>*> fe_list;
std::vector<unsigned int> multiplicities;
template <int dim, int spacedim>
std::vector<std::vector<bool> >
FESystem<dim,spacedim>::compute_nonzero_components (const FiniteElement<dim,spacedim> &fe1,
- const unsigned int N1,
- const FiniteElement<dim,spacedim> &fe2,
- const unsigned int N2)
+ const unsigned int N1,
+ const FiniteElement<dim,spacedim> &fe2,
+ const unsigned int N2)
{
std::vector<const FiniteElement<dim,spacedim>*> fe_list;
std::vector<unsigned int> multiplicities;
template <int dim, int spacedim>
std::vector<std::vector<bool> >
FESystem<dim,spacedim>::compute_nonzero_components (const FiniteElement<dim,spacedim> &fe1,
- const unsigned int N1,
- const FiniteElement<dim,spacedim> &fe2,
- const unsigned int N2,
- const FiniteElement<dim,spacedim> &fe3,
- const unsigned int N3)
+ const unsigned int N1,
+ const FiniteElement<dim,spacedim> &fe2,
+ const unsigned int N2,
+ const FiniteElement<dim,spacedim> &fe3,
+ const unsigned int N3)
{
std::vector<const FiniteElement<dim,spacedim>*> fe_list;
std::vector<unsigned int> multiplicities;
template <int dim, int spacedim>
std::vector<std::vector<bool> >
FESystem<dim,spacedim>::compute_nonzero_components (const FiniteElement<dim,spacedim> &fe1,
- const unsigned int N1,
- const FiniteElement<dim,spacedim> &fe2,
- const unsigned int N2,
- const FiniteElement<dim,spacedim> &fe3,
- const unsigned int N3,
- const FiniteElement<dim,spacedim> &fe4,
- const unsigned int N4)
+ const unsigned int N1,
+ const FiniteElement<dim,spacedim> &fe2,
+ const unsigned int N2,
+ const FiniteElement<dim,spacedim> &fe3,
+ const unsigned int N3,
+ const FiniteElement<dim,spacedim> &fe4,
+ const unsigned int N4)
{
std::vector<const FiniteElement<dim,spacedim>*> fe_list;
std::vector<unsigned int> multiplicities;
template <int dim, int spacedim>
std::vector<std::vector<bool> >
FESystem<dim,spacedim>::compute_nonzero_components (const FiniteElement<dim,spacedim> &fe1,
- const unsigned int N1,
- const FiniteElement<dim,spacedim> &fe2,
- const unsigned int N2,
- const FiniteElement<dim,spacedim> &fe3,
- const unsigned int N3,
- const FiniteElement<dim,spacedim> &fe4,
- const unsigned int N4,
- const FiniteElement<dim,spacedim> &fe5,
- const unsigned int N5)
+ const unsigned int N1,
+ const FiniteElement<dim,spacedim> &fe2,
+ const unsigned int N2,
+ const FiniteElement<dim,spacedim> &fe3,
+ const unsigned int N3,
+ const FiniteElement<dim,spacedim> &fe4,
+ const unsigned int N4,
+ const FiniteElement<dim,spacedim> &fe5,
+ const unsigned int N5)
{
std::vector<const FiniteElement<dim,spacedim>*> fe_list;
std::vector<unsigned int> multiplicities;
std::vector<std::vector<bool> >
FESystem<dim,spacedim>::
compute_nonzero_components (const std::vector<const FiniteElement<dim,spacedim>*> &fes,
- const std::vector<unsigned int> &multiplicities)
+ const std::vector<unsigned int> &multiplicities)
{
Assert (fes.size() == multiplicities.size(), ExcInternalError());
- // first count the number of dofs
- // and components that will emerge
- // from the given FEs
+ // first count the number of dofs
+ // and components that will emerge
+ // from the given FEs
unsigned int n_shape_functions = 0;
for (unsigned int i=0; i<fes.size(); ++i)
n_shape_functions += fes[i]->dofs_per_cell * multiplicities[i];
for (unsigned int i=0; i<fes.size(); ++i)
n_components += fes[i]->n_components() * multiplicities[i];
- // generate the array that will
- // hold the output
+ // generate the array that will
+ // hold the output
std::vector<std::vector<bool> >
retval (n_shape_functions, std::vector<bool> (n_components, false));
- // finally go through all the shape
- // functions of the base elements,
- // and copy their flags. this
- // somehow copies the code in
- // build_cell_table, which is not
- // nice as it uses too much
- // implicit knowledge about the
- // layout of the individual bases
- // in the composed FE, but there
- // seems no way around...
- //
- // for each shape function, copy
- // the non-zero flags from the base
- // element to this one, taking into
- // account multiplicities, multiple
- // components in base elements, and
- // other complications
+ // finally go through all the shape
+ // functions of the base elements,
+ // and copy their flags. this
+ // somehow copies the code in
+ // build_cell_table, which is not
+ // nice as it uses too much
+ // implicit knowledge about the
+ // layout of the individual bases
+ // in the composed FE, but there
+ // seems no way around...
+ //
+ // for each shape function, copy
+ // the non-zero flags from the base
+ // element to this one, taking into
+ // account multiplicities, multiple
+ // components in base elements, and
+ // other complications
unsigned int total_index = 0;
for (unsigned int vertex_number=0;
vertex_number<GeometryInfo<dim>::vertices_per_cell;
{
unsigned comp_start = 0;
for(unsigned int base=0; base<fes.size(); ++base)
- for (unsigned int m=0; m<multiplicities[base];
- ++m, comp_start+=fes[base]->n_components())
- for (unsigned int local_index = 0;
- local_index < fes[base]->dofs_per_vertex;
- ++local_index, ++total_index)
- {
- const unsigned int index_in_base
- = (fes[base]->dofs_per_vertex*vertex_number +
- local_index);
-
- Assert (comp_start+fes[base]->n_components() <=
- retval[total_index].size(),
- ExcInternalError());
- for (unsigned int c=0; c<fes[base]->n_components(); ++c)
- {
- Assert (index_in_base < fes[base]->nonzero_components.size(),
- ExcInternalError());
- Assert (c < fes[base]->nonzero_components[index_in_base].size(),
- ExcInternalError());
- retval[total_index][comp_start+c]
- = fes[base]->nonzero_components[index_in_base][c];
- };
- }
+ for (unsigned int m=0; m<multiplicities[base];
+ ++m, comp_start+=fes[base]->n_components())
+ for (unsigned int local_index = 0;
+ local_index < fes[base]->dofs_per_vertex;
+ ++local_index, ++total_index)
+ {
+ const unsigned int index_in_base
+ = (fes[base]->dofs_per_vertex*vertex_number +
+ local_index);
+
+ Assert (comp_start+fes[base]->n_components() <=
+ retval[total_index].size(),
+ ExcInternalError());
+ for (unsigned int c=0; c<fes[base]->n_components(); ++c)
+ {
+ Assert (index_in_base < fes[base]->nonzero_components.size(),
+ ExcInternalError());
+ Assert (c < fes[base]->nonzero_components[index_in_base].size(),
+ ExcInternalError());
+ retval[total_index][comp_start+c]
+ = fes[base]->nonzero_components[index_in_base][c];
+ };
+ }
}
- // 2. Lines
+ // 2. Lines
if (GeometryInfo<dim>::lines_per_cell > 0)
for (unsigned int line_number= 0;
- line_number != GeometryInfo<dim>::lines_per_cell;
- ++line_number)
+ line_number != GeometryInfo<dim>::lines_per_cell;
+ ++line_number)
{
- unsigned comp_start = 0;
- for (unsigned int base=0; base<fes.size(); ++base)
- for (unsigned int m=0; m<multiplicities[base];
- ++m, comp_start+=fes[base]->n_components())
- for (unsigned int local_index = 0;
- local_index < fes[base]->dofs_per_line;
- ++local_index, ++total_index)
- {
- const unsigned int index_in_base
- = (fes[base]->dofs_per_line*line_number +
- local_index +
- fes[base]->first_line_index);
-
- Assert (comp_start+fes[base]->n_components() <=
- retval[total_index].size(),
- ExcInternalError());
- for (unsigned int c=0; c<fes[base]->n_components(); ++c)
- {
- Assert (index_in_base < fes[base]->nonzero_components.size(),
- ExcInternalError());
- Assert (c < fes[base]->nonzero_components[index_in_base].size(),
- ExcInternalError());
- retval[total_index][comp_start+c]
- = fes[base]->nonzero_components[index_in_base][c];
- };
- }
+ unsigned comp_start = 0;
+ for (unsigned int base=0; base<fes.size(); ++base)
+ for (unsigned int m=0; m<multiplicities[base];
+ ++m, comp_start+=fes[base]->n_components())
+ for (unsigned int local_index = 0;
+ local_index < fes[base]->dofs_per_line;
+ ++local_index, ++total_index)
+ {
+ const unsigned int index_in_base
+ = (fes[base]->dofs_per_line*line_number +
+ local_index +
+ fes[base]->first_line_index);
+
+ Assert (comp_start+fes[base]->n_components() <=
+ retval[total_index].size(),
+ ExcInternalError());
+ for (unsigned int c=0; c<fes[base]->n_components(); ++c)
+ {
+ Assert (index_in_base < fes[base]->nonzero_components.size(),
+ ExcInternalError());
+ Assert (c < fes[base]->nonzero_components[index_in_base].size(),
+ ExcInternalError());
+ retval[total_index][comp_start+c]
+ = fes[base]->nonzero_components[index_in_base][c];
+ };
+ }
}
- // 3. Quads
+ // 3. Quads
if (GeometryInfo<dim>::quads_per_cell > 0)
for (unsigned int quad_number= 0;
- quad_number != GeometryInfo<dim>::quads_per_cell;
- ++quad_number)
+ quad_number != GeometryInfo<dim>::quads_per_cell;
+ ++quad_number)
{
- unsigned int comp_start = 0;
- for (unsigned int base=0; base<fes.size(); ++base)
- for (unsigned int m=0; m<multiplicities[base];
- ++m, comp_start+=fes[base]->n_components())
- for (unsigned int local_index = 0;
- local_index < fes[base]->dofs_per_quad;
- ++local_index, ++total_index)
- {
- const unsigned int index_in_base
- = (fes[base]->dofs_per_quad*quad_number +
- local_index +
- fes[base]->first_quad_index);
-
- Assert (comp_start+fes[base]->n_components() <=
- retval[total_index].size(),
- ExcInternalError());
- for (unsigned int c=0; c<fes[base]->n_components(); ++c)
- {
- Assert (index_in_base < fes[base]->nonzero_components.size(),
- ExcInternalError());
- Assert (c < fes[base]->nonzero_components[index_in_base].size(),
- ExcInternalError());
- retval[total_index][comp_start+c]
- = fes[base]->nonzero_components[index_in_base][c];
- };
- }
+ unsigned int comp_start = 0;
+ for (unsigned int base=0; base<fes.size(); ++base)
+ for (unsigned int m=0; m<multiplicities[base];
+ ++m, comp_start+=fes[base]->n_components())
+ for (unsigned int local_index = 0;
+ local_index < fes[base]->dofs_per_quad;
+ ++local_index, ++total_index)
+ {
+ const unsigned int index_in_base
+ = (fes[base]->dofs_per_quad*quad_number +
+ local_index +
+ fes[base]->first_quad_index);
+
+ Assert (comp_start+fes[base]->n_components() <=
+ retval[total_index].size(),
+ ExcInternalError());
+ for (unsigned int c=0; c<fes[base]->n_components(); ++c)
+ {
+ Assert (index_in_base < fes[base]->nonzero_components.size(),
+ ExcInternalError());
+ Assert (c < fes[base]->nonzero_components[index_in_base].size(),
+ ExcInternalError());
+ retval[total_index][comp_start+c]
+ = fes[base]->nonzero_components[index_in_base][c];
+ };
+ }
}
- // 4. Hexes
+ // 4. Hexes
if (GeometryInfo<dim>::hexes_per_cell > 0)
for (unsigned int hex_number= 0;
- hex_number != GeometryInfo<dim>::hexes_per_cell;
- ++hex_number)
+ hex_number != GeometryInfo<dim>::hexes_per_cell;
+ ++hex_number)
{
- unsigned int comp_start = 0;
- for(unsigned int base=0; base<fes.size(); ++base)
- for (unsigned int m=0; m<multiplicities[base];
- ++m, comp_start+=fes[base]->n_components())
- for (unsigned int local_index = 0;
- local_index < fes[base]->dofs_per_hex;
- ++local_index, ++total_index)
- {
- const unsigned int index_in_base
- = (fes[base]->dofs_per_hex*hex_number +
- local_index +
- fes[base]->first_hex_index);
-
- Assert (comp_start+fes[base]->n_components() <=
- retval[total_index].size(),
- ExcInternalError());
- for (unsigned int c=0; c<fes[base]->n_components(); ++c)
- {
- Assert (index_in_base < fes[base]->nonzero_components.size(),
- ExcInternalError());
- Assert (c < fes[base]->nonzero_components[index_in_base].size(),
- ExcInternalError());
- retval[total_index][comp_start+c]
- = fes[base]->nonzero_components[index_in_base][c];
- };
- }
+ unsigned int comp_start = 0;
+ for(unsigned int base=0; base<fes.size(); ++base)
+ for (unsigned int m=0; m<multiplicities[base];
+ ++m, comp_start+=fes[base]->n_components())
+ for (unsigned int local_index = 0;
+ local_index < fes[base]->dofs_per_hex;
+ ++local_index, ++total_index)
+ {
+ const unsigned int index_in_base
+ = (fes[base]->dofs_per_hex*hex_number +
+ local_index +
+ fes[base]->first_hex_index);
+
+ Assert (comp_start+fes[base]->n_components() <=
+ retval[total_index].size(),
+ ExcInternalError());
+ for (unsigned int c=0; c<fes[base]->n_components(); ++c)
+ {
+ Assert (index_in_base < fes[base]->nonzero_components.size(),
+ ExcInternalError());
+ Assert (c < fes[base]->nonzero_components[index_in_base].size(),
+ ExcInternalError());
+ retval[total_index][comp_start+c]
+ = fes[base]->nonzero_components[index_in_base][c];
+ };
+ }
}
Assert (total_index == n_shape_functions, ExcInternalError());
FESystem<dim,spacedim>::base_element (const unsigned int index) const
{
Assert (index < base_elements.size(),
- ExcIndexRange(index, 0, base_elements.size()));
+ ExcIndexRange(index, 0, base_elements.size()));
return *base_elements[index].first;
}
template <int dim, int spacedim>
bool
FESystem<dim,spacedim>::has_support_on_face (const unsigned int shape_index,
- const unsigned int face_index) const
+ const unsigned int face_index) const
{
return (base_element(this->system_to_base_index(shape_index).first.first)
.has_support_on_face(this->system_to_base_index(shape_index).second,
std::size_t
FESystem<dim,spacedim>::memory_consumption () const
{
- // neglect size of data stored in
- // @p{base_elements} due to some
- // problems with teh
- // compiler. should be neglectable
- // after all, considering the size
- // of the data of the subelements
+ // neglect size of data stored in
+ // @p{base_elements} due to some
+ // problems with teh
+ // compiler. should be neglectable
+ // after all, considering the size
+ // of the data of the subelements
std::size_t mem = (FiniteElement<dim,spacedim>::memory_consumption () +
- sizeof (base_elements));
+ sizeof (base_elements));
for (unsigned int i=0; i<base_elements.size(); ++i)
mem += MemoryConsumption::memory_consumption (*base_elements[i].first);
return mem;
namespace FETools
{
- // Not implemented in the general case.
+ // Not implemented in the general case.
template <class FE>
FiniteElement<FE::dimension, FE::dimension>*
FEFactory<FE>::get (const Quadrature<1> &) const
return 0;
}
- // Specializations for FE_Q.
+ // Specializations for FE_Q.
template <>
FiniteElement<1, 1>*
FEFactory<FE_Q<1, 1> >::get (const Quadrature<1> &quad) const
}
- // Specializations for FE_DGQArbitraryNodes.
+ // Specializations for FE_DGQArbitraryNodes.
template <>
FiniteElement<1, 1>*
FEFactory<FE_DGQ<1> >::get (const Quadrature<1> &quad) const
// and accessing the fe_name_map
// variable. make this lock local
// to this file.
- //
- // this and the next variable are
- // declared static (even though
- // they're in an anonymous
- // namespace) in order to make icc
- // happy (which otherwise reports a
- // multiply defined symbol when
- // linking libraries for more than
- // one space dimension together
+ //
+ // this and the next variable are
+ // declared static (even though
+ // they're in an anonymous
+ // namespace) in order to make icc
+ // happy (which otherwise reports a
+ // multiply defined symbol when
+ // linking libraries for more than
+ // one space dimension together
static
Threads::ThreadMutex fe_name_map_lock;
// separate between them further down
static
std::map<std::string,
- std_cxx1x::shared_ptr<const FETools::FEFactoryBase<1> > >
+ std_cxx1x::shared_ptr<const FETools::FEFactoryBase<1> > >
fe_name_map_1d
= get_default_fe_names<1> ();
static
std::map<std::string,
- std_cxx1x::shared_ptr<const FETools::FEFactoryBase<2> > >
+ std_cxx1x::shared_ptr<const FETools::FEFactoryBase<2> > >
fe_name_map_2d
= get_default_fe_names<2> ();
static
std::map<std::string,
- std_cxx1x::shared_ptr<const FETools::FEFactoryBase<3> > >
+ std_cxx1x::shared_ptr<const FETools::FEFactoryBase<3> > >
fe_name_map_3d
= get_default_fe_names<3> ();
}
- // return how many characters
- // starting at the given position
- // of the string match either the
- // generic string "<dim>" or the
- // specialized string with "dim"
- // replaced with the numeric value
- // of the template argument
+ // return how many characters
+ // starting at the given position
+ // of the string match either the
+ // generic string "<dim>" or the
+ // specialized string with "dim"
+ // replaced with the numeric value
+ // of the template argument
template <int dim, int spacedim>
inline
unsigned int match_dimension (const std::string &name,
- const unsigned int position)
+ const unsigned int position)
{
if (position >= name.size())
return 0;
if ((position+5 < name.size())
- &&
- (name[position] == '<')
- &&
- (name[position+1] == 'd')
- &&
- (name[position+2] == 'i')
- &&
- (name[position+3] == 'm')
- &&
- (name[position+4] == '>'))
+ &&
+ (name[position] == '<')
+ &&
+ (name[position+1] == 'd')
+ &&
+ (name[position+2] == 'i')
+ &&
+ (name[position+3] == 'm')
+ &&
+ (name[position+4] == '>'))
return 5;
Assert (dim<10, ExcNotImplemented());
const char dim_char = '0'+dim;
if ((position+3 < name.size())
- &&
- (name[position] == '<')
- &&
- (name[position+1] == dim_char)
- &&
- (name[position+2] == '>'))
+ &&
+ (name[position] == '<')
+ &&
+ (name[position+1] == dim_char)
+ &&
+ (name[position+2] == '>'))
return 3;
- // some other string that doesn't
- // match
+ // some other string that doesn't
+ // match
return 0;
}
}
std::vector<std::vector<unsigned int> >& comp_start)
{
Assert(renumbering.size() == element.dofs_per_cell,
- ExcDimensionMismatch(renumbering.size(),
- element.dofs_per_cell));
+ ExcDimensionMismatch(renumbering.size(),
+ element.dofs_per_cell));
comp_start.resize(element.n_base_elements());
unsigned int k=0;
for (unsigned int i=0;i<comp_start.size();++i)
{
- comp_start[i].resize(element.element_multiplicity(i));
- const unsigned int increment
- = element.base_element(i).dofs_per_cell;
-
- for (unsigned int j=0;j<comp_start[i].size();++j)
- {
- comp_start[i][j] = k;
- k += increment;
- }
+ comp_start[i].resize(element.element_multiplicity(i));
+ const unsigned int increment
+ = element.base_element(i).dofs_per_cell;
+
+ for (unsigned int j=0;j<comp_start[i].size();++j)
+ {
+ comp_start[i][j] = k;
+ k += increment;
+ }
}
- // For each index i of the
- // unstructured cellwise
- // numbering, renumbering
- // contains the index of the
- // cell-block numbering
+ // For each index i of the
+ // unstructured cellwise
+ // numbering, renumbering
+ // contains the index of the
+ // cell-block numbering
for (unsigned int i=0;i<element.dofs_per_cell;++i)
{
- std::pair<std::pair<unsigned int, unsigned int>, unsigned int>
- indices = element.system_to_base_index(i);
- renumbering[i] = comp_start[indices.first.first][indices.first.second]
- +indices.second;
+ std::pair<std::pair<unsigned int, unsigned int>, unsigned int>
+ indices = element.system_to_base_index(i);
+ renumbering[i] = comp_start[indices.first.first][indices.first.second]
+ +indices.second;
}
}
bool return_start_indices)
{
Assert(renumbering.size() == element.dofs_per_cell,
- ExcDimensionMismatch(renumbering.size(),
- element.dofs_per_cell));
+ ExcDimensionMismatch(renumbering.size(),
+ element.dofs_per_cell));
Assert(block_data.size() == element.n_blocks(),
- ExcDimensionMismatch(block_data.size(),
- element.n_blocks()));
+ ExcDimensionMismatch(block_data.size(),
+ element.n_blocks()));
unsigned int k=0;
unsigned int i=0;
for (unsigned int b=0;b<element.n_base_elements();++b)
for (unsigned int m=0;m<element.element_multiplicity(b);++m)
- {
- block_data[i++] = (return_start_indices)
- ? k
- : (element.base_element(b).n_dofs_per_cell());
- k += element.base_element(b).n_dofs_per_cell();
- }
+ {
+ block_data[i++] = (return_start_indices)
+ ? k
+ : (element.base_element(b).n_dofs_per_cell());
+ k += element.base_element(b).n_dofs_per_cell();
+ }
Assert (i == element.n_blocks(), ExcInternalError());
std::vector<unsigned int> start_indices(block_data.size());
k = 0;
for (unsigned int i=0;i<block_data.size();++i)
if (return_start_indices)
- start_indices[i] = block_data[i];
+ start_indices[i] = block_data[i];
else
- {
- start_indices[i] = k;
- k += block_data[i];
- }
+ {
+ start_indices[i] = k;
+ k += block_data[i];
+ }
//TODO:[GK] This does not work for a single RT
for (unsigned int i=0;i<element.dofs_per_cell;++i)
{
- std::pair<unsigned int, unsigned int>
- indices = element.system_to_block_index(i);
- renumbering[i] = start_indices[indices.first]
- +indices.second;
+ std::pair<unsigned int, unsigned int>
+ indices = element.system_to_block_index(i);
+ renumbering[i] = start_indices[indices.first]
+ +indices.second;
}
}
template <int dim, typename number, int spacedim>
void get_interpolation_matrix (const FiniteElement<dim,spacedim> &fe1,
- const FiniteElement<dim,spacedim> &fe2,
- FullMatrix<number> &interpolation_matrix)
+ const FiniteElement<dim,spacedim> &fe2,
+ FullMatrix<number> &interpolation_matrix)
{
Assert (fe1.n_components() == fe2.n_components(),
- ExcDimensionMismatch(fe1.n_components(), fe2.n_components()));
+ ExcDimensionMismatch(fe1.n_components(), fe2.n_components()));
Assert(interpolation_matrix.m()==fe2.dofs_per_cell &&
- interpolation_matrix.n()==fe1.dofs_per_cell,
- ExcMatrixDimensionMismatch(interpolation_matrix.m(),
- interpolation_matrix.n(),
- fe2.dofs_per_cell,
- fe1.dofs_per_cell));
-
- // first try the easy way: maybe
- // the FE wants to implement things
- // itself:
+ interpolation_matrix.n()==fe1.dofs_per_cell,
+ ExcMatrixDimensionMismatch(interpolation_matrix.m(),
+ interpolation_matrix.n(),
+ fe2.dofs_per_cell,
+ fe1.dofs_per_cell));
+
+ // first try the easy way: maybe
+ // the FE wants to implement things
+ // itself:
bool fe_implements_interpolation = true;
try
{
- gim_forwarder (fe1, fe2, interpolation_matrix);
+ gim_forwarder (fe1, fe2, interpolation_matrix);
}
catch (typename FiniteElement<dim,spacedim>::ExcInterpolationNotImplemented &)
{
- // too bad....
- fe_implements_interpolation = false;
+ // too bad....
+ fe_implements_interpolation = false;
}
if (fe_implements_interpolation == true)
return;
- // uh, so this was not the
- // case. hm. then do it the hard
- // way. note that this will only
- // work if the element is
- // primitive, so check this first
+ // uh, so this was not the
+ // case. hm. then do it the hard
+ // way. note that this will only
+ // work if the element is
+ // primitive, so check this first
Assert (fe1.is_primitive() == true, ExcFENotPrimitive());
Assert (fe2.is_primitive() == true, ExcFENotPrimitive());
- // Initialize FEValues for fe1 at
- // the unit support points of the
- // fe2 element.
+ // Initialize FEValues for fe1 at
+ // the unit support points of the
+ // fe2 element.
const std::vector<Point<dim> > &
fe2_support_points = fe2.get_unit_support_points ();
typedef FiniteElement<dim,spacedim> FEL;
Assert(fe2_support_points.size()==fe2.dofs_per_cell,
- typename FEL::ExcFEHasNoSupportPoints());
+ typename FEL::ExcFEHasNoSupportPoints());
for (unsigned int i=0; i<fe2.dofs_per_cell; ++i)
{
- const unsigned int i1 = fe2.system_to_component_index(i).first;
- for (unsigned int j=0; j<fe1.dofs_per_cell; ++j)
- {
- const unsigned int j1 = fe1.system_to_component_index(j).first;
- if (i1==j1)
- interpolation_matrix(i,j) = fe1.shape_value (j,fe2_support_points[i]);
- else
- interpolation_matrix(i,j)=0.;
- }
+ const unsigned int i1 = fe2.system_to_component_index(i).first;
+ for (unsigned int j=0; j<fe1.dofs_per_cell; ++j)
+ {
+ const unsigned int j1 = fe1.system_to_component_index(j).first;
+ if (i1==j1)
+ interpolation_matrix(i,j) = fe1.shape_value (j,fe2_support_points[i]);
+ else
+ interpolation_matrix(i,j)=0.;
+ }
}
}
template <int dim, typename number, int spacedim>
void get_back_interpolation_matrix(const FiniteElement<dim,spacedim> &fe1,
- const FiniteElement<dim,spacedim> &fe2,
- FullMatrix<number> &interpolation_matrix)
+ const FiniteElement<dim,spacedim> &fe2,
+ FullMatrix<number> &interpolation_matrix)
{
Assert (fe1.n_components() == fe2.n_components(),
- ExcDimensionMismatch(fe1.n_components(), fe2.n_components()));
+ ExcDimensionMismatch(fe1.n_components(), fe2.n_components()));
Assert(interpolation_matrix.m()==fe1.dofs_per_cell &&
- interpolation_matrix.n()==fe1.dofs_per_cell,
- ExcMatrixDimensionMismatch(interpolation_matrix.m(),
- interpolation_matrix.n(),
- fe1.dofs_per_cell,
- fe1.dofs_per_cell));
+ interpolation_matrix.n()==fe1.dofs_per_cell,
+ ExcMatrixDimensionMismatch(interpolation_matrix.m(),
+ interpolation_matrix.n(),
+ fe1.dofs_per_cell,
+ fe1.dofs_per_cell));
FullMatrix<number> first_matrix (fe2.dofs_per_cell, fe1.dofs_per_cell);
FullMatrix<number> second_matrix(fe1.dofs_per_cell, fe2.dofs_per_cell);
get_interpolation_matrix(fe1, fe2, first_matrix);
get_interpolation_matrix(fe2, fe1, second_matrix);
- // int_matrix=second_matrix*first_matrix
+ // int_matrix=second_matrix*first_matrix
second_matrix.mmult(interpolation_matrix, first_matrix);
}
template <int dim, typename number, int spacedim>
void get_interpolation_difference_matrix (const FiniteElement<dim,spacedim> &fe1,
- const FiniteElement<dim,spacedim> &fe2,
- FullMatrix<number> &difference_matrix)
+ const FiniteElement<dim,spacedim> &fe2,
+ FullMatrix<number> &difference_matrix)
{
Assert (fe1.n_components() == fe2.n_components(),
- ExcDimensionMismatch(fe1.n_components(), fe2.n_components()));
+ ExcDimensionMismatch(fe1.n_components(), fe2.n_components()));
Assert(difference_matrix.m()==fe1.dofs_per_cell &&
- difference_matrix.n()==fe1.dofs_per_cell,
- ExcMatrixDimensionMismatch(difference_matrix.m(),
- difference_matrix.n(),
- fe1.dofs_per_cell,
- fe1.dofs_per_cell));
+ difference_matrix.n()==fe1.dofs_per_cell,
+ ExcMatrixDimensionMismatch(difference_matrix.m(),
+ difference_matrix.n(),
+ fe1.dofs_per_cell,
+ fe1.dofs_per_cell));
FullMatrix<number> interpolation_matrix(fe1.dofs_per_cell);
get_back_interpolation_matrix(fe1, fe2, interpolation_matrix);
for (unsigned int i=0; i<fe1.dofs_per_cell; ++i)
difference_matrix(i,i) = 1.;
- // compute difference
+ // compute difference
difference_matrix.add (-1, interpolation_matrix);
}
template <int dim, typename number, int spacedim>
void get_projection_matrix (const FiniteElement<dim,spacedim> &fe1,
- const FiniteElement<dim,spacedim> &fe2,
- FullMatrix<number> &matrix)
+ const FiniteElement<dim,spacedim> &fe2,
+ FullMatrix<number> &matrix)
{
Assert (fe1.n_components() == 1, ExcNotImplemented());
Assert (fe1.n_components() == fe2.n_components(),
- ExcDimensionMismatch(fe1.n_components(), fe2.n_components()));
+ ExcDimensionMismatch(fe1.n_components(), fe2.n_components()));
Assert(matrix.m()==fe2.dofs_per_cell && matrix.n()==fe1.dofs_per_cell,
- ExcMatrixDimensionMismatch(matrix.m(), matrix.n(),
- fe2.dofs_per_cell,
- fe1.dofs_per_cell));
+ ExcMatrixDimensionMismatch(matrix.m(), matrix.n(),
+ fe2.dofs_per_cell,
+ fe1.dofs_per_cell));
matrix = 0;
unsigned int n1 = fe1.dofs_per_cell;
unsigned int n2 = fe2.dofs_per_cell;
- // First, create a local mass matrix for
- // the unit cell
+ // First, create a local mass matrix for
+ // the unit cell
Triangulation<dim,spacedim> tr;
GridGenerator::hyper_cube(tr);
- // Choose a quadrature rule
- // Gauss is exact up to degree 2n-1
+ // Choose a quadrature rule
+ // Gauss is exact up to degree 2n-1
const unsigned int degree = std::max(fe1.tensor_degree(), fe2.tensor_degree());
Assert (degree != numbers::invalid_unsigned_int,
- ExcNotImplemented());
+ ExcNotImplemented());
QGauss<dim> quadrature(degree+1);
- // Set up FEValues.
+ // Set up FEValues.
const UpdateFlags flags = update_values | update_quadrature_points | update_JxW_values;
FEValues<dim> val1 (fe1, quadrature, update_values);
val1.reinit (tr.begin_active());
FEValues<dim> val2 (fe2, quadrature, flags);
val2.reinit (tr.begin_active());
- // Integrate and invert mass matrix
- // This happens in the target space
+ // Integrate and invert mass matrix
+ // This happens in the target space
FullMatrix<double> mass (n2, n2);
for (unsigned int k=0;k<quadrature.size();++k)
{
- const double w = val2.JxW(k);
- for (unsigned int i=0;i<n2;++i)
- {
- const double v = val2.shape_value(i,k);
- for (unsigned int j=0;j<n2;++j)
- mass(i,j) += w*v * val2.shape_value(j,k);
- }
+ const double w = val2.JxW(k);
+ for (unsigned int i=0;i<n2;++i)
+ {
+ const double v = val2.shape_value(i,k);
+ for (unsigned int j=0;j<n2;++j)
+ mass(i,j) += w*v * val2.shape_value(j,k);
+ }
}
- // Gauss-Jordan should be
- // sufficient since we expect the
- // mass matrix to be
- // well-conditioned
+ // Gauss-Jordan should be
+ // sufficient since we expect the
+ // mass matrix to be
+ // well-conditioned
mass.gauss_jordan();
- // Now, test every function of fe1
- // with test functions of fe2 and
- // compute the projection of each
- // unit vector.
+ // Now, test every function of fe1
+ // with test functions of fe2 and
+ // compute the projection of each
+ // unit vector.
Vector<double> b(n2);
Vector<double> x(n2);
for (unsigned int j=0;j<n1;++j)
{
- b = 0.;
- for (unsigned int i=0;i<n2;++i)
- for (unsigned int k=0;k<quadrature.size();++k)
- {
- const double w = val2.JxW(k);
- const double u = val1.shape_value(j,k);
- const double v = val2.shape_value(i,k);
- b(i) += u*v*w;
- }
-
- // Multiply by the inverse
- mass.vmult(x,b);
- for (unsigned int i=0;i<n2;++i)
- matrix(i,j) = x(i);
+ b = 0.;
+ for (unsigned int i=0;i<n2;++i)
+ for (unsigned int k=0;k<quadrature.size();++k)
+ {
+ const double w = val2.JxW(k);
+ const double u = val1.shape_value(j,k);
+ const double v = val2.shape_value(i,k);
+ b(i) += u*v*w;
+ }
+
+ // Multiply by the inverse
+ mass.vmult(x,b);
+ for (unsigned int i=0;i<n2;++i)
+ matrix(i,j) = x(i);
}
}
const std::vector<Point<dim> >& points = fe.get_generalized_support_points();
- // We need the values of the
- // polynomials in all generalized
- // support points.
+ // We need the values of the
+ // polynomials in all generalized
+ // support points.
std::vector<std::vector<double> >
values (dim, std::vector<double>(points.size()));
- // In this vector, we store the
- // result of the interpolation
+ // In this vector, we store the
+ // result of the interpolation
std::vector<double> local_dofs(n_dofs);
- // One row per shape
- // function. Remember that these
- // are the 'raw' shape functions
- // where the inverse node matrix is
- // empty. Otherwise, this would
- // yield identity.
+ // One row per shape
+ // function. Remember that these
+ // are the 'raw' shape functions
+ // where the inverse node matrix is
+ // empty. Otherwise, this would
+ // yield identity.
for (unsigned int i=0;i<n_dofs;++i)
{
- for (unsigned int k=0;k<values[0].size();++k)
- for (unsigned int d=0;d<dim;++d)
- values[d][k] = fe.shape_value_component(i,points[k],d);
- fe.interpolate(local_dofs, values);
- // Enter the interpolated dofs
- // into the matrix
- for (unsigned int j=0;j<n_dofs;++j)
- N(j,i) = local_dofs[j];
+ for (unsigned int k=0;k<values[0].size();++k)
+ for (unsigned int d=0;d<dim;++d)
+ values[d][k] = fe.shape_value_component(i,points[k],d);
+ fe.interpolate(local_dofs, values);
+ // Enter the interpolated dofs
+ // into the matrix
+ for (unsigned int j=0;j<n_dofs;++j)
+ N(j,i) = local_dofs[j];
}
}
template<>
void
compute_embedding_matrices(const FiniteElement<1,2> &,
- std::vector<std::vector<FullMatrix<double> > > &,
- const bool)
+ std::vector<std::vector<FullMatrix<double> > > &,
+ const bool)
{
Assert(false, ExcNotImplemented());
}
-
+
template<>
void
compute_embedding_matrices(const FiniteElement<1,3> &,
- std::vector<std::vector<FullMatrix<double> > > &,
- const bool)
+ std::vector<std::vector<FullMatrix<double> > > &,
+ const bool)
{
Assert(false, ExcNotImplemented());
}
-
+
template<>
void
compute_embedding_matrices(const FiniteElement<2,3>&,
- std::vector<std::vector<FullMatrix<double> > >&,
- const bool)
+ std::vector<std::vector<FullMatrix<double> > >&,
+ const bool)
{
Assert(false, ExcNotImplemented());
}
Vector<number> v_coarse(nq*nd);
Vector<number> v_fine(n);
- // The right hand side of
- // the least squares
- // problem consists of the
- // function values of the
- // coarse grid function in
- // each quadrature point.
+ // The right hand side of
+ // the least squares
+ // problem consists of the
+ // function values of the
+ // coarse grid function in
+ // each quadrature point.
if (fe.is_primitive ())
- {
- const unsigned int
- d = fe.system_to_component_index (i).first;
- const double* phi_i = &coarse.shape_value (i, 0);
+ {
+ const unsigned int
+ d = fe.system_to_component_index (i).first;
+ const double* phi_i = &coarse.shape_value (i, 0);
- for (unsigned int k = 0; k < nq; ++k)
- v_coarse (k * nd + d) = phi_i[k];
- }
+ for (unsigned int k = 0; k < nq; ++k)
+ v_coarse (k * nd + d) = phi_i[k];
+ }
else
- for (unsigned int d = 0; d < nd; ++d)
- for (unsigned int k = 0; k < nq; ++k)
- v_coarse (k * nd + d) = coarse.shape_value_component (i, k, d);
+ for (unsigned int d = 0; d < nd; ++d)
+ for (unsigned int k = 0; k < nq; ++k)
+ v_coarse (k * nd + d) = coarse.shape_value_component (i, k, d);
- // solve the least squares
- // problem.
+ // solve the least squares
+ // problem.
const double result = H.least_squares (v_fine, v_coarse);
Assert (result < 1.e-12, ExcLeastSquaresError (result));
- // Copy into the result
- // matrix. Since the matrix
- // maps a coarse grid
- // function to a fine grid
- // function, the columns
- // are fine grid.
+ // Copy into the result
+ // matrix. Since the matrix
+ // maps a coarse grid
+ // function to a fine grid
+ // function, the columns
+ // are fine grid.
for (unsigned int j = 0; j < n; ++j)
- this_matrix(j, i) = v_fine(j);
+ this_matrix(j, i) = v_fine(j);
}
const unsigned int n = fe.dofs_per_cell;
const unsigned int nc = GeometryInfo<dim>::n_children(RefinementCase<dim>(ref_case));
for (unsigned int i = 0; i < nc; ++i)
- {
- Assert(matrices[i].n() == n, ExcDimensionMismatch(matrices[i].n (), n));
- Assert(matrices[i].m() == n, ExcDimensionMismatch(matrices[i].m (), n));
- }
+ {
+ Assert(matrices[i].n() == n, ExcDimensionMismatch(matrices[i].n (), n));
+ Assert(matrices[i].m() == n, ExcDimensionMismatch(matrices[i].m (), n));
+ }
- // Set up meshes, one with a single
- // reference cell and refine it once
+ // Set up meshes, one with a single
+ // reference cell and refine it once
Triangulation<dim,spacedim> tria;
GridGenerator::hyper_cube (tria, 0, 1);
tria.begin_active()->set_refine_flag (RefinementCase<dim>(ref_case));
const unsigned int nq = q_fine.size();
FEValues<dim> fine (mapping, fe, q_fine,
- update_quadrature_points |
- update_JxW_values |
- update_values);
-
- // We search for the polynomial on
- // the small cell, being equal to
- // the coarse polynomial in all
- // quadrature points.
-
- // First build the matrix for this
- // least squares problem. This
- // contains the values of the fine
- // cell polynomials in the fine
- // cell grid points.
-
- // This matrix is the same for all
- // children.
+ update_quadrature_points |
+ update_JxW_values |
+ update_values);
+
+ // We search for the polynomial on
+ // the small cell, being equal to
+ // the coarse polynomial in all
+ // quadrature points.
+
+ // First build the matrix for this
+ // least squares problem. This
+ // contains the values of the fine
+ // cell polynomials in the fine
+ // cell grid points.
+
+ // This matrix is the same for all
+ // children.
fine.reinit (tria.begin_active ());
const unsigned int nd = fe.n_components ();
FullMatrix<number> A (nq*nd, n);
for (unsigned int j = 0; j < n; ++j)
- for (unsigned int d = 0; d < nd; ++d)
- for (unsigned int k = 0; k < nq; ++k)
- A (k * nd + d, j) = fine.shape_value_component (j, k, d);
+ for (unsigned int d = 0; d < nd; ++d)
+ for (unsigned int k = 0; k < nq; ++k)
+ A (k * nd + d, j) = fine.shape_value_component (j, k, d);
Householder<double> H (A);
unsigned int cell_number = 0;
Threads::TaskGroup<void> task_group;
for (typename Triangulation<dim>::active_cell_iterator
- fine_cell = tria.begin_active (); fine_cell != tria.end ();
- ++fine_cell, ++cell_number)
- {
- fine.reinit (fine_cell);
-
- // evaluate on the coarse cell (which
- // is the first -- inactive -- cell on
- // the lowest level of the
- // triangulation we have created)
- const Quadrature<dim> q_coarse (fine.get_quadrature_points (),
- fine.get_JxW_values ());
- FEValues<dim> coarse (mapping, fe, q_coarse, update_values);
-
- coarse.reinit (tria.begin (0));
-
- FullMatrix<double> &this_matrix = matrices[cell_number];
-
- // Compute this once for each
- // coarse grid basis function. can
- // spawn subtasks if n is
- // sufficiently large so that there
- // are more than about 5000
- // operations in the inner loop
- // (which is basically const * n^2
- // operations).
- if (n > 30)
- {
- for (unsigned int i = 0; i < n; ++i)
- {
- task_group +=
- Threads::new_task (&compute_embedding_for_shape_function<dim, number, spacedim>,
- i, fe, coarse, H, this_matrix);
- }
- task_group.join_all();
- }
- else
- {
- for (unsigned int i = 0; i < n; ++i)
- {
- compute_embedding_for_shape_function<dim, number, spacedim>
- (i, fe, coarse, H, this_matrix);
- }
- }
-
- // Remove small entries from
- // the matrix
- for (unsigned int i = 0; i < this_matrix.m (); ++i)
- for (unsigned int j = 0; j < this_matrix.n (); ++j)
- if (std::fabs (this_matrix (i, j)) < 1e-12)
- this_matrix (i, j) = 0.;
- }
+ fine_cell = tria.begin_active (); fine_cell != tria.end ();
+ ++fine_cell, ++cell_number)
+ {
+ fine.reinit (fine_cell);
+
+ // evaluate on the coarse cell (which
+ // is the first -- inactive -- cell on
+ // the lowest level of the
+ // triangulation we have created)
+ const Quadrature<dim> q_coarse (fine.get_quadrature_points (),
+ fine.get_JxW_values ());
+ FEValues<dim> coarse (mapping, fe, q_coarse, update_values);
+
+ coarse.reinit (tria.begin (0));
+
+ FullMatrix<double> &this_matrix = matrices[cell_number];
+
+ // Compute this once for each
+ // coarse grid basis function. can
+ // spawn subtasks if n is
+ // sufficiently large so that there
+ // are more than about 5000
+ // operations in the inner loop
+ // (which is basically const * n^2
+ // operations).
+ if (n > 30)
+ {
+ for (unsigned int i = 0; i < n; ++i)
+ {
+ task_group +=
+ Threads::new_task (&compute_embedding_for_shape_function<dim, number, spacedim>,
+ i, fe, coarse, H, this_matrix);
+ }
+ task_group.join_all();
+ }
+ else
+ {
+ for (unsigned int i = 0; i < n; ++i)
+ {
+ compute_embedding_for_shape_function<dim, number, spacedim>
+ (i, fe, coarse, H, this_matrix);
+ }
+ }
+
+ // Remove small entries from
+ // the matrix
+ for (unsigned int i = 0; i < this_matrix.m (); ++i)
+ for (unsigned int j = 0; j < this_matrix.n (); ++j)
+ if (std::fabs (this_matrix (i, j)) < 1e-12)
+ this_matrix (i, j) = 0.;
+ }
Assert (cell_number == GeometryInfo<dim>::n_children (RefinementCase<dim> (ref_case)),
- ExcInternalError ());
+ ExcInternalError ());
}
}
template <int dim, typename number, int spacedim>
void
compute_embedding_matrices(const FiniteElement<dim,spacedim>& fe,
- std::vector<std::vector<FullMatrix<number> > >& matrices,
- const bool isotropic_only)
+ std::vector<std::vector<FullMatrix<number> > >& matrices,
+ const bool isotropic_only)
{
Threads::TaskGroup<void> task_group;
- // loop over all possible refinement cases
+ // loop over all possible refinement cases
unsigned int ref_case = (isotropic_only)
- ? RefinementCase<dim>::isotropic_refinement
- : RefinementCase<dim>::cut_x;
+ ? RefinementCase<dim>::isotropic_refinement
+ : RefinementCase<dim>::cut_x;
for (;ref_case <= RefinementCase<dim>::isotropic_refinement; ++ref_case)
task_group += Threads::new_task (&compute_embedding_matrices_for_refinement_case<dim, number, spacedim>,
- fe, matrices[ref_case-1], ref_case);
+ fe, matrices[ref_case-1], ref_case);
task_group.join_all ();
}
template <int dim, typename number, int spacedim>
void
compute_face_embedding_matrices(const FiniteElement<dim,spacedim>& fe,
- FullMatrix<number> (&matrices)[GeometryInfo<dim>::max_children_per_face],
- const unsigned int face_coarse,
- const unsigned int face_fine)
+ FullMatrix<number> (&matrices)[GeometryInfo<dim>::max_children_per_face],
+ const unsigned int face_coarse,
+ const unsigned int face_fine)
{
Assert(face_coarse==0, ExcNotImplemented());
Assert(face_fine==0, ExcNotImplemented());
for (unsigned int i=0;i<nc;++i)
{
- Assert(matrices[i].n() == n, ExcDimensionMismatch(matrices[i].n(),n));
- Assert(matrices[i].m() == n, ExcDimensionMismatch(matrices[i].m(),n));
+ Assert(matrices[i].n() == n, ExcDimensionMismatch(matrices[i].n(),n));
+ Assert(matrices[i].m() == n, ExcDimensionMismatch(matrices[i].m(),n));
}
- // In order to make the loops below
- // simpler, we introduce vectors
- // containing for indices 0-n the
- // number of the corresponding
- // shape value on the cell.
+ // In order to make the loops below
+ // simpler, we introduce vectors
+ // containing for indices 0-n the
+ // number of the corresponding
+ // shape value on the cell.
std::vector<unsigned int> face_c_dofs(n);
std::vector<unsigned int> face_f_dofs(n);
unsigned int k=0;
for (unsigned int i=0;i<GeometryInfo<dim>::vertices_per_face;++i)
{
- const unsigned int offset_c = GeometryInfo<dim>::face_to_cell_vertices(face_coarse, i)
- *fe.dofs_per_vertex;
- const unsigned int offset_f = GeometryInfo<dim>::face_to_cell_vertices(face_fine, i)
- *fe.dofs_per_vertex;
- for (unsigned int j=0;j<fe.dofs_per_vertex;++j)
- {
- face_c_dofs[k] = offset_c + j;
- face_f_dofs[k] = offset_f + j;
- ++k;
- }
+ const unsigned int offset_c = GeometryInfo<dim>::face_to_cell_vertices(face_coarse, i)
+ *fe.dofs_per_vertex;
+ const unsigned int offset_f = GeometryInfo<dim>::face_to_cell_vertices(face_fine, i)
+ *fe.dofs_per_vertex;
+ for (unsigned int j=0;j<fe.dofs_per_vertex;++j)
+ {
+ face_c_dofs[k] = offset_c + j;
+ face_f_dofs[k] = offset_f + j;
+ ++k;
+ }
}
for (unsigned int i=1;i<=GeometryInfo<dim>::lines_per_face;++i)
{
- const unsigned int offset_c = fe.first_line_index
- + GeometryInfo<dim>::face_to_cell_lines(face_coarse, i-1)
- *fe.dofs_per_line;
- const unsigned int offset_f = fe.first_line_index
- + GeometryInfo<dim>::face_to_cell_lines(face_fine, i-1)
- *fe.dofs_per_line;
- for (unsigned int j=0;j<fe.dofs_per_line;++j)
- {
- face_c_dofs[k] = offset_c + j;
- face_f_dofs[k] = offset_f + j;
- ++k;
- }
+ const unsigned int offset_c = fe.first_line_index
+ + GeometryInfo<dim>::face_to_cell_lines(face_coarse, i-1)
+ *fe.dofs_per_line;
+ const unsigned int offset_f = fe.first_line_index
+ + GeometryInfo<dim>::face_to_cell_lines(face_fine, i-1)
+ *fe.dofs_per_line;
+ for (unsigned int j=0;j<fe.dofs_per_line;++j)
+ {
+ face_c_dofs[k] = offset_c + j;
+ face_f_dofs[k] = offset_f + j;
+ ++k;
+ }
}
for (unsigned int i=1;i<=GeometryInfo<dim>::quads_per_face;++i)
{
- const unsigned int offset_c = fe.first_quad_index
- + face_coarse
- *fe.dofs_per_quad;
- const unsigned int offset_f = fe.first_quad_index
- + face_fine
- *fe.dofs_per_quad;
- for (unsigned int j=0;j<fe.dofs_per_quad;++j)
- {
- face_c_dofs[k] = offset_c + j;
- face_f_dofs[k] = offset_f + j;
- ++k;
- }
+ const unsigned int offset_c = fe.first_quad_index
+ + face_coarse
+ *fe.dofs_per_quad;
+ const unsigned int offset_f = fe.first_quad_index
+ + face_fine
+ *fe.dofs_per_quad;
+ for (unsigned int j=0;j<fe.dofs_per_quad;++j)
+ {
+ face_c_dofs[k] = offset_c + j;
+ face_f_dofs[k] = offset_f + j;
+ ++k;
+ }
}
Assert (k == fe.dofs_per_face, ExcInternalError());
- // Set up meshes, one with a single
- // reference cell and refine it once
+ // Set up meshes, one with a single
+ // reference cell and refine it once
Triangulation<dim,spacedim> tria;
GridGenerator::hyper_cube (tria, 0, 1);
tria.refine_global(1);
MappingCartesian<dim> mapping;
- // Setup quadrature and FEValues
- // for a face. We cannot use
- // FEFaceValues and
- // FESubfaceValues because of
- // some nifty handling of
- // refinement cases. Guido stops
- // disliking and instead starts
- // hating the anisotropic implementation
+ // Setup quadrature and FEValues
+ // for a face. We cannot use
+ // FEFaceValues and
+ // FESubfaceValues because of
+ // some nifty handling of
+ // refinement cases. Guido stops
+ // disliking and instead starts
+ // hating the anisotropic implementation
QGauss<dim-1> q_gauss(degree+1);
const Quadrature<dim> q_fine = QProjector<dim>::project_to_face(q_gauss, face_fine);
const unsigned int nq = q_fine.size();
FEValues<dim> fine (mapping, fe, q_fine,
- update_quadrature_points | update_JxW_values | update_values);
+ update_quadrature_points | update_JxW_values | update_values);
- // We search for the polynomial on
- // the small cell, being equal to
- // the coarse polynomial in all
- // quadrature points.
+ // We search for the polynomial on
+ // the small cell, being equal to
+ // the coarse polynomial in all
+ // quadrature points.
- // First build the matrix for this
- // least squares problem. This
- // contains the values of the fine
- // cell polynomials in the fine
- // cell grid points.
+ // First build the matrix for this
+ // least squares problem. This
+ // contains the values of the fine
+ // cell polynomials in the fine
+ // cell grid points.
- // This matrix is the same for all
- // children.
+ // This matrix is the same for all
+ // children.
fine.reinit(tria.begin_active());
FullMatrix<number> A(nq*nd, n);
for (unsigned int j=0;j<n;++j)
for (unsigned int k=0;k<nq;++k)
- if (nd != dim)
- for (unsigned int d=0;d<nd;++d)
- A(k*nd+d,j) = fine.shape_value_component(face_f_dofs[j],k,d);
- else
- {
- if (normal)
- A(k*nd,j) = fine.shape_value_component(face_f_dofs[j],k,0);
- if (tangential)
- for (unsigned int d=1;d<dim;++d)
- A(k*nd+d,j) = fine.shape_value_component(face_f_dofs[j],k,d);
- }
+ if (nd != dim)
+ for (unsigned int d=0;d<nd;++d)
+ A(k*nd+d,j) = fine.shape_value_component(face_f_dofs[j],k,d);
+ else
+ {
+ if (normal)
+ A(k*nd,j) = fine.shape_value_component(face_f_dofs[j],k,0);
+ if (tangential)
+ for (unsigned int d=1;d<dim;++d)
+ A(k*nd+d,j) = fine.shape_value_component(face_f_dofs[j],k,d);
+ }
Householder<double> H(A);
for (unsigned int cell_number = 0; cell_number < GeometryInfo<dim>::max_children_per_face;
- ++cell_number)
+ ++cell_number)
{
- const Quadrature<dim> q_coarse
- = QProjector<dim>::project_to_subface(q_gauss, face_coarse, cell_number);
- FEValues<dim> coarse (mapping, fe, q_coarse, update_values);
-
- typename Triangulation<dim,spacedim>::active_cell_iterator fine_cell
- = tria.begin(0)->child(GeometryInfo<dim>::child_cell_on_face(
- tria.begin(0)->refinement_case(), face_coarse, cell_number));
- fine.reinit(fine_cell);
- coarse.reinit(tria.begin(0));
-
- FullMatrix<double> &this_matrix = matrices[cell_number];
-
- // Compute this once for each
- // coarse grid basis function
- for (unsigned int i=0;i<n;++i)
- {
- // The right hand side of
- // the least squares
- // problem consists of the
- // function values of the
- // coarse grid function in
- // each quadrature point.
- for (unsigned int k=0;k<nq;++k)
- if (nd != dim)
- for (unsigned int d=0;d<nd;++d)
- v_coarse(k*nd+d) = coarse.shape_value_component (face_c_dofs[i],k,d);
- else
- {
- if (normal)
- v_coarse(k*nd) = coarse.shape_value_component(face_c_dofs[i],k,0);
- if (tangential)
- for (unsigned int d=1;d<dim;++d)
- v_coarse(k*nd+d) = coarse.shape_value_component(face_c_dofs[i],k,d);
- }
- // solve the least squares
- // problem.
- const double result = H.least_squares(v_fine, v_coarse);
- Assert (result < 1.e-12, ExcLeastSquaresError(result));
-
- // Copy into the result
- // matrix. Since the matrix
- // maps a coarse grid
- // function to a fine grid
- // function, the columns
- // are fine grid.
- for (unsigned int j=0;j<n;++j)
- this_matrix(j,i) = v_fine(j);
- }
- // Remove small entries from
- // the matrix
- for (unsigned int i=0; i<this_matrix.m(); ++i)
- for (unsigned int j=0; j<this_matrix.n(); ++j)
- if (std::fabs(this_matrix(i,j)) < 1e-12)
- this_matrix(i,j) = 0.;
+ const Quadrature<dim> q_coarse
+ = QProjector<dim>::project_to_subface(q_gauss, face_coarse, cell_number);
+ FEValues<dim> coarse (mapping, fe, q_coarse, update_values);
+
+ typename Triangulation<dim,spacedim>::active_cell_iterator fine_cell
+ = tria.begin(0)->child(GeometryInfo<dim>::child_cell_on_face(
+ tria.begin(0)->refinement_case(), face_coarse, cell_number));
+ fine.reinit(fine_cell);
+ coarse.reinit(tria.begin(0));
+
+ FullMatrix<double> &this_matrix = matrices[cell_number];
+
+ // Compute this once for each
+ // coarse grid basis function
+ for (unsigned int i=0;i<n;++i)
+ {
+ // The right hand side of
+ // the least squares
+ // problem consists of the
+ // function values of the
+ // coarse grid function in
+ // each quadrature point.
+ for (unsigned int k=0;k<nq;++k)
+ if (nd != dim)
+ for (unsigned int d=0;d<nd;++d)
+ v_coarse(k*nd+d) = coarse.shape_value_component (face_c_dofs[i],k,d);
+ else
+ {
+ if (normal)
+ v_coarse(k*nd) = coarse.shape_value_component(face_c_dofs[i],k,0);
+ if (tangential)
+ for (unsigned int d=1;d<dim;++d)
+ v_coarse(k*nd+d) = coarse.shape_value_component(face_c_dofs[i],k,d);
+ }
+ // solve the least squares
+ // problem.
+ const double result = H.least_squares(v_fine, v_coarse);
+ Assert (result < 1.e-12, ExcLeastSquaresError(result));
+
+ // Copy into the result
+ // matrix. Since the matrix
+ // maps a coarse grid
+ // function to a fine grid
+ // function, the columns
+ // are fine grid.
+ for (unsigned int j=0;j<n;++j)
+ this_matrix(j,i) = v_fine(j);
+ }
+ // Remove small entries from
+ // the matrix
+ for (unsigned int i=0; i<this_matrix.m(); ++i)
+ for (unsigned int j=0; j<this_matrix.n(); ++j)
+ if (std::fabs(this_matrix(i,j)) < 1e-12)
+ this_matrix(i,j) = 0.;
}
}
template <>
void
compute_projection_matrices(const FiniteElement<1,2>&,
- std::vector<std::vector<FullMatrix<double> > >&, bool)
+ std::vector<std::vector<FullMatrix<double> > >&, bool)
{
Assert(false, ExcNotImplemented());
}
-
+
template <>
void
compute_projection_matrices(const FiniteElement<1,3>&,
- std::vector<std::vector<FullMatrix<double> > >&, bool)
+ std::vector<std::vector<FullMatrix<double> > >&, bool)
{
Assert(false, ExcNotImplemented());
}
template <>
void
compute_projection_matrices(const FiniteElement<2,3>&,
- std::vector<std::vector<FullMatrix<double> > >&, bool)
+ std::vector<std::vector<FullMatrix<double> > >&, bool)
{
Assert(false, ExcNotImplemented());
}
template <int dim, typename number, int spacedim>
void
compute_projection_matrices(const FiniteElement<dim,spacedim>& fe,
- std::vector<std::vector<FullMatrix<number> > >& matrices,
- const bool isotropic_only)
+ std::vector<std::vector<FullMatrix<number> > >& matrices,
+ const bool isotropic_only)
{
const unsigned int n = fe.dofs_per_cell;
const unsigned int nd = fe.n_components();
const unsigned int degree = fe.degree;
- // prepare FEValues, quadrature etc on
- // coarse cell
+ // prepare FEValues, quadrature etc on
+ // coarse cell
MappingCartesian<dim> mapping;
QGauss<dim> q_fine(degree+1);
const unsigned int nq = q_fine.size();
- // create mass matrix on coarse cell.
+ // create mass matrix on coarse cell.
FullMatrix<number> mass(n, n);
{
- // set up a triangulation for coarse cell
+ // set up a triangulation for coarse cell
Triangulation<dim,spacedim> tr;
GridGenerator::hyper_cube (tr, 0, 1);
FEValues<dim> coarse (mapping, fe, q_fine,
- update_JxW_values | update_values);
+ update_JxW_values | update_values);
typename Triangulation<dim,spacedim>::cell_iterator coarse_cell
- = tr.begin(0);
+ = tr.begin(0);
coarse.reinit (coarse_cell);
const std::vector<double> & JxW = coarse.get_JxW_values();
for (unsigned int i=0;i<n;++i)
- for (unsigned int j=0;j<n;++j)
- if (fe.is_primitive())
- {
- const double * coarse_i = &coarse.shape_value(i,0);
- const double * coarse_j = &coarse.shape_value(j,0);
- double mass_ij = 0;
- for (unsigned int k=0;k<nq;++k)
- mass_ij += JxW[k] * coarse_i[k] * coarse_j[k];
- mass(i,j) = mass_ij;
- }
- else
- {
- double mass_ij = 0;
- for (unsigned int d=0;d<nd;++d)
- for (unsigned int k=0;k<nq;++k)
- mass_ij += JxW[k] * coarse.shape_value_component(i,k,d)
- * coarse.shape_value_component(j,k,d);
- mass(i,j) = mass_ij;
- }
-
- // invert mass matrix
+ for (unsigned int j=0;j<n;++j)
+ if (fe.is_primitive())
+ {
+ const double * coarse_i = &coarse.shape_value(i,0);
+ const double * coarse_j = &coarse.shape_value(j,0);
+ double mass_ij = 0;
+ for (unsigned int k=0;k<nq;++k)
+ mass_ij += JxW[k] * coarse_i[k] * coarse_j[k];
+ mass(i,j) = mass_ij;
+ }
+ else
+ {
+ double mass_ij = 0;
+ for (unsigned int d=0;d<nd;++d)
+ for (unsigned int k=0;k<nq;++k)
+ mass_ij += JxW[k] * coarse.shape_value_component(i,k,d)
+ * coarse.shape_value_component(j,k,d);
+ mass(i,j) = mass_ij;
+ }
+
+ // invert mass matrix
mass.gauss_jordan();
}
- // loop over all possible
- // refinement cases
+ // loop over all possible
+ // refinement cases
unsigned int ref_case = (isotropic_only)
- ? RefinementCase<dim>::isotropic_refinement
- : RefinementCase<dim>::cut_x;
+ ? RefinementCase<dim>::isotropic_refinement
+ : RefinementCase<dim>::cut_x;
for (;ref_case <= RefinementCase<dim>::isotropic_refinement; ++ref_case)
{
- const unsigned int
- nc = GeometryInfo<dim>::n_children(RefinementCase<dim>(ref_case));
-
- for (unsigned int i=0;i<nc;++i)
- {
- Assert(matrices[ref_case-1][i].n() == n,
- ExcDimensionMismatch(matrices[ref_case-1][i].n(),n));
- Assert(matrices[ref_case-1][i].m() == n,
- ExcDimensionMismatch(matrices[ref_case-1][i].m(),n));
- }
-
- // create a respective refinement on the
- // triangulation
- Triangulation<dim,spacedim> tr;
- GridGenerator::hyper_cube (tr, 0, 1);
- tr.begin_active()->set_refine_flag(RefinementCase<dim>(ref_case));
- tr.execute_coarsening_and_refinement();
-
- FEValues<dim> fine (mapping, fe, q_fine,
- update_quadrature_points | update_JxW_values |
- update_values);
-
- typename Triangulation<dim,spacedim>::cell_iterator coarse_cell
- = tr.begin(0);
-
- Vector<number> v_coarse(n);
- Vector<number> v_fine(n);
-
- for (unsigned int cell_number=0;cell_number<nc;++cell_number)
- {
- FullMatrix<double> &this_matrix = matrices[ref_case-1][cell_number];
-
- // Compute right hand side,
- // which is a fine level basis
- // function tested with the
- // coarse level functions.
- fine.reinit(coarse_cell->child(cell_number));
- Quadrature<dim> q_coarse (fine.get_quadrature_points(),
- fine.get_JxW_values());
- FEValues<dim> coarse (mapping, fe, q_coarse, update_values);
- coarse.reinit(coarse_cell);
-
- // Build RHS
-
- const std::vector<double> & JxW = fine.get_JxW_values();
-
- // Outer loop over all fine
- // grid shape functions phi_j
- for (unsigned int j=0;j<fe.dofs_per_cell;++j)
- {
- for (unsigned int i=0; i<fe.dofs_per_cell;++i)
- {
- if (fe.is_primitive())
- {
- const double * coarse_i = &coarse.shape_value(i,0);
- const double * fine_j = &fine.shape_value(j,0);
-
- double update = 0;
- for (unsigned int k=0; k<nq; ++k)
- update += JxW[k] * coarse_i[k] * fine_j[k];
- v_fine(i) = update;
- }
- else
- {
- double update = 0;
- for (unsigned int d=0; d<nd; ++d)
- for (unsigned int k=0; k<nq; ++k)
- update += JxW[k] * coarse.shape_value_component(i,k,d)
- * fine.shape_value_component(j,k,d);
- v_fine(i) = update;
- }
- }
-
- // RHS ready. Solve system
- // and enter row into
- // matrix
- mass.vmult (v_coarse, v_fine);
- for (unsigned int i=0;i<fe.dofs_per_cell;++i)
- this_matrix(i,j) = v_coarse(i);
- }
-
- // Remove small entries from
- // the matrix
- for (unsigned int i=0; i<this_matrix.m(); ++i)
- for (unsigned int j=0; j<this_matrix.n(); ++j)
- if (std::fabs(this_matrix(i,j)) < 1e-12)
- this_matrix(i,j) = 0.;
- }
+ const unsigned int
+ nc = GeometryInfo<dim>::n_children(RefinementCase<dim>(ref_case));
+
+ for (unsigned int i=0;i<nc;++i)
+ {
+ Assert(matrices[ref_case-1][i].n() == n,
+ ExcDimensionMismatch(matrices[ref_case-1][i].n(),n));
+ Assert(matrices[ref_case-1][i].m() == n,
+ ExcDimensionMismatch(matrices[ref_case-1][i].m(),n));
+ }
+
+ // create a respective refinement on the
+ // triangulation
+ Triangulation<dim,spacedim> tr;
+ GridGenerator::hyper_cube (tr, 0, 1);
+ tr.begin_active()->set_refine_flag(RefinementCase<dim>(ref_case));
+ tr.execute_coarsening_and_refinement();
+
+ FEValues<dim> fine (mapping, fe, q_fine,
+ update_quadrature_points | update_JxW_values |
+ update_values);
+
+ typename Triangulation<dim,spacedim>::cell_iterator coarse_cell
+ = tr.begin(0);
+
+ Vector<number> v_coarse(n);
+ Vector<number> v_fine(n);
+
+ for (unsigned int cell_number=0;cell_number<nc;++cell_number)
+ {
+ FullMatrix<double> &this_matrix = matrices[ref_case-1][cell_number];
+
+ // Compute right hand side,
+ // which is a fine level basis
+ // function tested with the
+ // coarse level functions.
+ fine.reinit(coarse_cell->child(cell_number));
+ Quadrature<dim> q_coarse (fine.get_quadrature_points(),
+ fine.get_JxW_values());
+ FEValues<dim> coarse (mapping, fe, q_coarse, update_values);
+ coarse.reinit(coarse_cell);
+
+ // Build RHS
+
+ const std::vector<double> & JxW = fine.get_JxW_values();
+
+ // Outer loop over all fine
+ // grid shape functions phi_j
+ for (unsigned int j=0;j<fe.dofs_per_cell;++j)
+ {
+ for (unsigned int i=0; i<fe.dofs_per_cell;++i)
+ {
+ if (fe.is_primitive())
+ {
+ const double * coarse_i = &coarse.shape_value(i,0);
+ const double * fine_j = &fine.shape_value(j,0);
+
+ double update = 0;
+ for (unsigned int k=0; k<nq; ++k)
+ update += JxW[k] * coarse_i[k] * fine_j[k];
+ v_fine(i) = update;
+ }
+ else
+ {
+ double update = 0;
+ for (unsigned int d=0; d<nd; ++d)
+ for (unsigned int k=0; k<nq; ++k)
+ update += JxW[k] * coarse.shape_value_component(i,k,d)
+ * fine.shape_value_component(j,k,d);
+ v_fine(i) = update;
+ }
+ }
+
+ // RHS ready. Solve system
+ // and enter row into
+ // matrix
+ mass.vmult (v_coarse, v_fine);
+ for (unsigned int i=0;i<fe.dofs_per_cell;++i)
+ this_matrix(i,j) = v_coarse(i);
+ }
+
+ // Remove small entries from
+ // the matrix
+ for (unsigned int i=0; i<this_matrix.m(); ++i)
+ for (unsigned int j=0; j<this_matrix.n(); ++j)
+ if (std::fabs(this_matrix(i,j)) < 1e-12)
+ this_matrix(i,j) = 0.;
+ }
}
}
template <int dim, int spacedim,
- template <int, int> class DH1,
- template <int, int> class DH2,
- class InVector, class OutVector>
+ template <int, int> class DH1,
+ template <int, int> class DH2,
+ class InVector, class OutVector>
void
interpolate(const DH1<dim, spacedim> &dof1,
- const InVector &u1,
- const DH2<dim, spacedim> &dof2,
- OutVector &u2)
- {
- ConstraintMatrix dummy;
- dummy.close();
- interpolate(dof1, u1, dof2, dummy, u2);
- }
+ const InVector &u1,
+ const DH2<dim, spacedim> &dof2,
+ OutVector &u2)
+ {
+ ConstraintMatrix dummy;
+ dummy.close();
+ interpolate(dof1, u1, dof2, dummy, u2);
+ }
class InVector, class OutVector>
void
interpolate (const DH1<dim, spacedim> &dof1,
- const InVector &u1,
- const DH2<dim, spacedim> &dof2,
- const ConstraintMatrix &constraints,
- OutVector &u2)
+ const InVector &u1,
+ const DH2<dim, spacedim> &dof2,
+ const ConstraintMatrix &constraints,
+ OutVector &u2)
{
Assert(&dof1.get_tria()==&dof2.get_tria(), ExcTriangulationMismatch());
// for distributed triangulations,
// we can only interpolate u1 on
// a cell, which this processor owns,
- // so we have to know the subdomain_id
+ // so we have to know the subdomain_id
const types::subdomain_id_t subdomain_id =
dof1.get_tria().locally_owned_subdomain();
(constraints.n_constraints() == 0));
if (hanging_nodes_not_allowed)
- for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
- Assert (cell1->at_boundary(face) ||
- cell1->neighbor(face)->level() == cell1->level(),
- ExcHangingNodesNotAllowed(0));
+ for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
+ Assert (cell1->at_boundary(face) ||
+ cell1->neighbor(face)->level() == cell1->level(),
+ ExcHangingNodesNotAllowed(0));
const unsigned int dofs_per_cell1 = cell1->get_fe().dofs_per_cell;
= interpolation_matrix;
get_interpolation_matrix(cell1->get_fe(),
- cell2->get_fe(),
- *interpolation_matrix);
+ cell2->get_fe(),
+ *interpolation_matrix);
}
cell1->get_dof_values(u1, u1_local);
// work on dofs this processor owns.
IndexSet locally_owned_dofs = dof2.locally_owned_dofs();
- // when a discontinuous element is
- // interpolated to a continuous
- // one, we take the mean values.
- // for parallel vectors check,
- // if this component is owned by
- // this processor.
+ // when a discontinuous element is
+ // interpolated to a continuous
+ // one, we take the mean values.
+ // for parallel vectors check,
+ // if this component is owned by
+ // this processor.
for (unsigned int i=0; i<dof2.n_dofs(); ++i)
if (locally_owned_dofs.is_element(i))
{
u2(i) /= touch_count(i);
}
- // finish the work on parallel vectors
+ // finish the work on parallel vectors
u2.compress();
- // Apply hanging node constraints.
+ // Apply hanging node constraints.
constraints.distribute(u2);
- // and finally update ghost values
+ // and finally update ghost values
u2.update_ghost_values();
}
template <int dim, class InVector, class OutVector, int spacedim>
void
back_interpolate(const DoFHandler<dim,spacedim> &dof1,
- const InVector &u1,
- const FiniteElement<dim,spacedim> &fe2,
- OutVector &u1_interpolated)
+ const InVector &u1,
+ const FiniteElement<dim,spacedim> &fe2,
+ OutVector &u1_interpolated)
{
Assert(dof1.get_fe().n_components() == fe2.n_components(),
- ExcDimensionMismatch(dof1.get_fe().n_components(), fe2.n_components()));
+ ExcDimensionMismatch(dof1.get_fe().n_components(), fe2.n_components()));
Assert(u1.size()==dof1.n_dofs(), ExcDimensionMismatch(u1.size(), dof1.n_dofs()));
Assert(u1_interpolated.size()==dof1.n_dofs(),
- ExcDimensionMismatch(u1_interpolated.size(), dof1.n_dofs()));
+ ExcDimensionMismatch(u1_interpolated.size(), dof1.n_dofs()));
#ifdef DEAL_II_USE_PETSC
if (dynamic_cast<const PETScWrappers::MPI::Vector *>(&u1) != 0)
};
#endif
- // For continuous elements on grids
- // with hanging nodes we need
- // hanging node
- // constraints. Consequently, when
- // the elements are continuous no
- // hanging node constraints are
- // allowed.
+ // For continuous elements on grids
+ // with hanging nodes we need
+ // hanging node
+ // constraints. Consequently, when
+ // the elements are continuous no
+ // hanging node constraints are
+ // allowed.
const bool hanging_nodes_not_allowed=
(dof1.get_fe().dofs_per_vertex != 0) || (fe2.dofs_per_vertex != 0);
dof1.get_tria().locally_owned_subdomain();
typename DoFHandler<dim,spacedim>::active_cell_iterator cell = dof1.begin_active(),
- endc = dof1.end();
+ endc = dof1.end();
FullMatrix<double> interpolation_matrix(dofs_per_cell1, dofs_per_cell1);
get_back_interpolation_matrix(dof1.get_fe(), fe2,
- interpolation_matrix);
+ interpolation_matrix);
for (; cell!=endc; ++cell)
if ((cell->subdomain_id() == subdomain_id)
||
(subdomain_id == types::invalid_subdomain_id))
{
- if (hanging_nodes_not_allowed)
- for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
- Assert (cell->at_boundary(face) ||
- cell->neighbor(face)->level() == cell->level(),
- ExcHangingNodesNotAllowed(0));
-
- cell->get_dof_values(u1, u1_local);
- interpolation_matrix.vmult(u1_int_local, u1_local);
- cell->set_dof_values(u1_int_local, u1_interpolated);
+ if (hanging_nodes_not_allowed)
+ for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
+ Assert (cell->at_boundary(face) ||
+ cell->neighbor(face)->level() == cell->level(),
+ ExcHangingNodesNotAllowed(0));
+
+ cell->get_dof_values(u1, u1_local);
+ interpolation_matrix.vmult(u1_int_local, u1_local);
+ cell->set_dof_values(u1_int_local, u1_interpolated);
}
- // if we work on a parallel PETSc vector
- // we have to finish the work and
- // update ghost values
+ // if we work on a parallel PETSc vector
+ // we have to finish the work and
+ // update ghost values
u1_interpolated.compress();
u1_interpolated.update_ghost_values();
}
template <int dim,
- template <int> class DH,
- class InVector, class OutVector, int spacedim>
+ template <int> class DH,
+ class InVector, class OutVector, int spacedim>
void
back_interpolate(const DH<dim> &dof1,
- const InVector &u1,
- const FiniteElement<dim,spacedim> &fe2,
- OutVector &u1_interpolated)
+ const InVector &u1,
+ const FiniteElement<dim,spacedim> &fe2,
+ OutVector &u1_interpolated)
{
Assert(u1.size() == dof1.n_dofs(),
ExcDimensionMismatch(u1.size(), dof1.n_dofs()));
typename DH<dim>::active_cell_iterator cell = dof1.begin_active(),
endc = dof1.end();
- // map from possible fe objects in
- // dof1 to the back_interpolation
- // matrices
+ // map from possible fe objects in
+ // dof1 to the back_interpolation
+ // matrices
std::map<const FiniteElement<dim> *,
std_cxx1x::shared_ptr<FullMatrix<double> > > interpolation_matrices;
ExcDimensionMismatch(cell->get_fe().n_components(),
fe2.n_components()));
- // For continuous elements on
- // grids with hanging nodes we
- // need hanging node
- // constraints. Consequently,
- // when the elements are
- // continuous no hanging node
- // constraints are allowed.
+ // For continuous elements on
+ // grids with hanging nodes we
+ // need hanging node
+ // constraints. Consequently,
+ // when the elements are
+ // continuous no hanging node
+ // constraints are allowed.
const bool hanging_nodes_not_allowed=
(cell->get_fe().dofs_per_vertex != 0) || (fe2.dofs_per_vertex != 0);
const unsigned int dofs_per_cell1 = cell->get_fe().dofs_per_cell;
- // make sure back_interpolation
- // matrix is available
+ // make sure back_interpolation
+ // matrix is available
if (interpolation_matrices[&cell->get_fe()] != 0)
{
interpolation_matrices[&cell->get_fe()] =
cell->set_dof_values(u1_int_local, u1_interpolated);
};
- // if we work on a parallel PETSc vector
- // we have to finish the work and
- // update ghost values
+ // if we work on a parallel PETSc vector
+ // we have to finish the work and
+ // update ghost values
u1_interpolated.compress();
u1_interpolated.update_ghost_values();
}
template <int dim, class InVector, class OutVector, int spacedim>
void back_interpolate(const DoFHandler<dim,spacedim> &dof1,
- const ConstraintMatrix &constraints1,
- const InVector &u1,
- const DoFHandler<dim,spacedim> &dof2,
- const ConstraintMatrix &constraints2,
- OutVector &u1_interpolated)
+ const ConstraintMatrix &constraints1,
+ const InVector &u1,
+ const DoFHandler<dim,spacedim> &dof2,
+ const ConstraintMatrix &constraints2,
+ OutVector &u1_interpolated)
{
- // For discontinuous elements
- // without constraints take the
- // simpler version of the
- // back_interpolate function.
+ // For discontinuous elements
+ // without constraints take the
+ // simpler version of the
+ // back_interpolate function.
if (dof1.get_fe().dofs_per_vertex==0 && dof2.get_fe().dofs_per_vertex==0
- && constraints1.n_constraints()==0 && constraints2.n_constraints()==0)
+ && constraints1.n_constraints()==0 && constraints2.n_constraints()==0)
back_interpolate(dof1, u1, dof2.get_fe(), u1_interpolated);
else
{
- Assert(dof1.get_fe().n_components() == dof2.get_fe().n_components(),
- ExcDimensionMismatch(dof1.get_fe().n_components(), dof2.get_fe().n_components()));
- Assert(u1.size()==dof1.n_dofs(), ExcDimensionMismatch(u1.size(), dof1.n_dofs()));
- Assert(u1_interpolated.size()==dof1.n_dofs(),
- ExcDimensionMismatch(u1_interpolated.size(), dof1.n_dofs()));
-
- // For continuous elements
- // first interpolate to dof2,
- // taking into account
- // constraints2, and then
- // interpolate back to dof1
- // taking into account
- // constraints1
+ Assert(dof1.get_fe().n_components() == dof2.get_fe().n_components(),
+ ExcDimensionMismatch(dof1.get_fe().n_components(), dof2.get_fe().n_components()));
+ Assert(u1.size()==dof1.n_dofs(), ExcDimensionMismatch(u1.size(), dof1.n_dofs()));
+ Assert(u1_interpolated.size()==dof1.n_dofs(),
+ ExcDimensionMismatch(u1_interpolated.size(), dof1.n_dofs()));
+
+ // For continuous elements
+ // first interpolate to dof2,
+ // taking into account
+ // constraints2, and then
+ // interpolate back to dof1
+ // taking into account
+ // constraints1
#ifdef DEAL_II_USE_PETSC
if (dynamic_cast<const PETScWrappers::MPI::Vector *>(&u1) != 0)
{
AssertThrow (dynamic_cast<const PETScWrappers::MPI::Vector *>(&u1_interpolated) != 0,
ExcMessage("Interpolation can only be done between vectors of same type!"));
- // if u1 is a parallel distributed
- // PETSc vector, we create a vector u2
- // with based on the sets of locally owned
- // and relevant dofs of dof2
+ // if u1 is a parallel distributed
+ // PETSc vector, we create a vector u2
+ // with based on the sets of locally owned
+ // and relevant dofs of dof2
IndexSet dof2_locally_owned_dofs = dof2.locally_owned_dofs();
IndexSet dof2_locally_relevant_dofs;
DoFTools::extract_locally_relevant_dofs (dof2,
template <int dim, class InVector, class OutVector, int spacedim>
void interpolation_difference (const DoFHandler<dim,spacedim> &dof1,
- const InVector &u1,
- const FiniteElement<dim,spacedim> &fe2,
- OutVector &u1_difference)
+ const InVector &u1,
+ const FiniteElement<dim,spacedim> &fe2,
+ OutVector &u1_difference)
{
Assert(dof1.get_fe().n_components() == fe2.n_components(),
- ExcDimensionMismatch(dof1.get_fe().n_components(), fe2.n_components()));
+ ExcDimensionMismatch(dof1.get_fe().n_components(), fe2.n_components()));
Assert(u1.size()==dof1.n_dofs(), ExcDimensionMismatch(u1.size(), dof1.n_dofs()));
Assert(u1_difference.size()==dof1.n_dofs(),
- ExcDimensionMismatch(u1_difference.size(), dof1.n_dofs()));
+ ExcDimensionMismatch(u1_difference.size(), dof1.n_dofs()));
#ifdef DEAL_II_USE_PETSC
if (dynamic_cast<const PETScWrappers::MPI::Vector *>(&u1) != 0)
};
#endif
- // For continuous elements on grids
- // with hanging nodes we need
- // hanging node
- // constraints. Consequently, when
- // the elements are continuous no
- // hanging node constraints are
- // allowed.
+ // For continuous elements on grids
+ // with hanging nodes we need
+ // hanging node
+ // constraints. Consequently, when
+ // the elements are continuous no
+ // hanging node constraints are
+ // allowed.
const bool hanging_nodes_not_allowed=
(dof1.get_fe().dofs_per_vertex != 0) || (fe2.dofs_per_vertex != 0);
FullMatrix<double> difference_matrix(dofs_per_cell, dofs_per_cell);
get_interpolation_difference_matrix(dof1.get_fe(), fe2,
- difference_matrix);
+ difference_matrix);
typename DoFHandler<dim,spacedim>::active_cell_iterator cell = dof1.begin_active(),
- endc = dof1.end();
+ endc = dof1.end();
for (; cell!=endc; ++cell)
if ((cell->subdomain_id() == subdomain_id)
||
(subdomain_id == types::invalid_subdomain_id))
{
- if (hanging_nodes_not_allowed)
- for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
- Assert (cell->at_boundary(face) ||
- cell->neighbor(face)->level() == cell->level(),
- ExcHangingNodesNotAllowed(0));
-
- cell->get_dof_values(u1, u1_local);
- difference_matrix.vmult(u1_diff_local, u1_local);
- cell->set_dof_values(u1_diff_local, u1_difference);
+ if (hanging_nodes_not_allowed)
+ for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
+ Assert (cell->at_boundary(face) ||
+ cell->neighbor(face)->level() == cell->level(),
+ ExcHangingNodesNotAllowed(0));
+
+ cell->get_dof_values(u1, u1_local);
+ difference_matrix.vmult(u1_diff_local, u1_local);
+ cell->set_dof_values(u1_diff_local, u1_difference);
}
- // if we work on a parallel PETSc vector
- // we have to finish the work and
- // update ghost values
+ // if we work on a parallel PETSc vector
+ // we have to finish the work and
+ // update ghost values
u1_difference.compress();
u1_difference.update_ghost_values();
}
template <int dim, class InVector, class OutVector, int spacedim>
void interpolation_difference(const DoFHandler<dim,spacedim> &dof1,
- const ConstraintMatrix &constraints1,
- const InVector &u1,
- const DoFHandler<dim,spacedim> &dof2,
- const ConstraintMatrix &constraints2,
- OutVector &u1_difference)
+ const ConstraintMatrix &constraints1,
+ const InVector &u1,
+ const DoFHandler<dim,spacedim> &dof2,
+ const ConstraintMatrix &constraints2,
+ OutVector &u1_difference)
{
- // For discontinuous elements
- // without constraints take the
- // cheaper version of the
- // interpolation_difference function.
+ // For discontinuous elements
+ // without constraints take the
+ // cheaper version of the
+ // interpolation_difference function.
if (dof1.get_fe().dofs_per_vertex==0 && dof2.get_fe().dofs_per_vertex==0
- && constraints1.n_constraints()==0 && constraints2.n_constraints()==0)
+ && constraints1.n_constraints()==0 && constraints2.n_constraints()==0)
interpolation_difference(dof1, u1, dof2.get_fe(), u1_difference);
else
{
- back_interpolate(dof1, constraints1, u1, dof2, constraints2, u1_difference);
- u1_difference.sadd(-1, u1);
+ back_interpolate(dof1, constraints1, u1, dof2, constraints2, u1_difference);
+ u1_difference.sadd(-1, u1);
- // if we work on a parallel PETSc vector
- // we have to finish the work and
- // update ghost values
+ // if we work on a parallel PETSc vector
+ // we have to finish the work and
+ // update ghost values
u1_difference.compress();
u1_difference.update_ghost_values();
}
template <int dim, class InVector, class OutVector, int spacedim>
void project_dg(const DoFHandler<dim,spacedim> &dof1,
- const InVector &u1,
- const DoFHandler<dim,spacedim> &dof2,
- OutVector &u2)
+ const InVector &u1,
+ const DoFHandler<dim,spacedim> &dof2,
+ OutVector &u2)
{
Assert(&dof1.get_tria()==&dof2.get_tria(), ExcTriangulationMismatch());
Assert(dof1.get_fe().n_components() == dof2.get_fe().n_components(),
- ExcDimensionMismatch(dof1.get_fe().n_components(), dof2.get_fe().n_components()));
+ ExcDimensionMismatch(dof1.get_fe().n_components(), dof2.get_fe().n_components()));
Assert(u1.size()==dof1.n_dofs(), ExcDimensionMismatch(u1.size(), dof1.n_dofs()));
Assert(u2.size()==dof2.n_dofs(), ExcDimensionMismatch(u2.size(), dof2.n_dofs()));
while (cell2 != end)
{
- cell1->get_dof_values(u1, u1_local);
- matrix.vmult(u2_local, u1_local);
- cell2->get_dof_indices(dofs);
- for (unsigned int i=0; i<n2; ++i)
- {
- u2(dofs[i])+=u2_local(i);
- }
-
- ++cell1;
- ++cell2;
+ cell1->get_dof_values(u1, u1_local);
+ matrix.vmult(u2_local, u1_local);
+ cell2->get_dof_indices(dofs);
+ for (unsigned int i=0; i<n2; ++i)
+ {
+ u2(dofs[i])+=u2_local(i);
+ }
+
+ ++cell1;
+ ++cell2;
}
}
template <int dim, class InVector, class OutVector, int spacedim>
void extrapolate(const DoFHandler<dim,spacedim> &dof1,
- const InVector &u1,
- const DoFHandler<dim,spacedim> &dof2,
- OutVector &u2)
+ const InVector &u1,
+ const DoFHandler<dim,spacedim> &dof2,
+ OutVector &u2)
{
ConstraintMatrix dummy;
dummy.close();
template <int dim, class InVector, class OutVector, int spacedim>
void extrapolate(const DoFHandler<dim,spacedim> &dof1,
- const InVector &u1,
- const DoFHandler<dim,spacedim> &dof2,
- const ConstraintMatrix &constraints,
- OutVector &u2)
+ const InVector &u1,
+ const DoFHandler<dim,spacedim> &dof2,
+ const ConstraintMatrix &constraints,
+ OutVector &u2)
{
Assert(dof1.get_fe().n_components() == dof2.get_fe().n_components(),
- ExcDimensionMismatch(dof1.get_fe().n_components(), dof2.get_fe().n_components()));
+ ExcDimensionMismatch(dof1.get_fe().n_components(), dof2.get_fe().n_components()));
Assert(&dof1.get_tria()==&dof2.get_tria(), ExcTriangulationMismatch());
Assert(u1.size()==dof1.n_dofs(), ExcDimensionMismatch(u1.size(), dof1.n_dofs()));
Assert(u2.size()==dof2.n_dofs(), ExcDimensionMismatch(u2.size(), dof2.n_dofs()));
const unsigned int dofs_per_cell = dof2.get_fe().dofs_per_cell;
Vector<typename OutVector::value_type> dof_values(dofs_per_cell);
- // make sure that each cell on the
- // coarsest level is at least once
- // refined. otherwise, we can't
- // treat these cells and would
- // generate a bogus result
+ // make sure that each cell on the
+ // coarsest level is at least once
+ // refined. otherwise, we can't
+ // treat these cells and would
+ // generate a bogus result
{
typename DoFHandler<dim,spacedim>::cell_iterator cell = dof2.begin(0),
- endc = dof2.end(0);
+ endc = dof2.end(0);
for (; cell!=endc; ++cell)
- Assert (cell->has_children(), ExcGridNotRefinedAtLeastOnce());
+ Assert (cell->has_children(), ExcGridNotRefinedAtLeastOnce());
}
- // then traverse grid bottom up
+ // then traverse grid bottom up
for (unsigned int level=0; level<dof1.get_tria().n_levels()-1; ++level)
{
- typename DoFHandler<dim,spacedim>::cell_iterator cell=dof2.begin(level),
- endc=dof2.end(level);
-
- for (; cell!=endc; ++cell)
- if (!cell->active())
- {
- // check whether this
- // cell has active
- // children
- bool active_children=false;
- for (unsigned int child_n=0; child_n<cell->n_children(); ++child_n)
- if (cell->child(child_n)->active())
- {
- active_children=true;
- break;
- }
-
- // if there are active
- // children, the we have
- // to work on this
- // cell. get the data
- // from the one vector
- // and set it on the
- // other
- if (active_children)
- {
- cell->get_interpolated_dof_values(u3, dof_values);
- cell->set_dof_values_by_interpolation(dof_values, u2);
- }
- }
+ typename DoFHandler<dim,spacedim>::cell_iterator cell=dof2.begin(level),
+ endc=dof2.end(level);
+
+ for (; cell!=endc; ++cell)
+ if (!cell->active())
+ {
+ // check whether this
+ // cell has active
+ // children
+ bool active_children=false;
+ for (unsigned int child_n=0; child_n<cell->n_children(); ++child_n)
+ if (cell->child(child_n)->active())
+ {
+ active_children=true;
+ break;
+ }
+
+ // if there are active
+ // children, the we have
+ // to work on this
+ // cell. get the data
+ // from the one vector
+ // and set it on the
+ // other
+ if (active_children)
+ {
+ cell->get_interpolated_dof_values(u3, dof_values);
+ cell->set_dof_values_by_interpolation(dof_values, u2);
+ }
+ }
}
- // Apply hanging node constraints.
+ // Apply hanging node constraints.
constraints.distribute(u2);
}
template <>
void
add_fe_name(const std::string& parameter_name,
- const FEFactoryBase<1,1>* factory)
+ const FEFactoryBase<1,1>* factory)
{
- // Erase everything after the
- // actual class name
+ // Erase everything after the
+ // actual class name
std::string name = parameter_name;
unsigned int name_end =
name.find_first_not_of(std::string("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"));
if (name_end < name.size())
name.erase(name_end);
- // first make sure that no other
- // thread intercepts the
- // operation of this function;
- // for this, acquire the lock
- // until we quit this function
+ // first make sure that no other
+ // thread intercepts the
+ // operation of this function;
+ // for this, acquire the lock
+ // until we quit this function
Threads::ThreadMutex::ScopedLock lock(fe_name_map_lock);
Assert(fe_name_map_1d.find(name) == fe_name_map_1d.end(),
- ExcMessage("Cannot change existing element in finite element name list"));
+ ExcMessage("Cannot change existing element in finite element name list"));
- // Insert the normalized name into
- // the map
+ // Insert the normalized name into
+ // the map
fe_name_map_1d[name] =
std_cxx1x::shared_ptr<const FETools::FEFactoryBase<1> > (factory);
}
template <>
void
add_fe_name(const std::string& parameter_name,
- const FEFactoryBase<2,2>* factory)
+ const FEFactoryBase<2,2>* factory)
{
- // Erase everything after the
- // actual class name
+ // Erase everything after the
+ // actual class name
std::string name = parameter_name;
unsigned int name_end =
name.find_first_not_of(std::string("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"));
if (name_end < name.size())
name.erase(name_end);
- // first make sure that no other
- // thread intercepts the
- // operation of this function;
- // for this, acquire the lock
- // until we quit this function
+ // first make sure that no other
+ // thread intercepts the
+ // operation of this function;
+ // for this, acquire the lock
+ // until we quit this function
Threads::ThreadMutex::ScopedLock lock(fe_name_map_lock);
Assert(fe_name_map_2d.find(name) == fe_name_map_2d.end(),
- ExcMessage("Cannot change existing element in finite element name list"));
+ ExcMessage("Cannot change existing element in finite element name list"));
- // Insert the normalized name into
- // the map
+ // Insert the normalized name into
+ // the map
fe_name_map_2d[name] =
std_cxx1x::shared_ptr<const FETools::FEFactoryBase<2> > (factory);
}
template <>
void
add_fe_name(const std::string& parameter_name,
- const FEFactoryBase<3,3>* factory)
+ const FEFactoryBase<3,3>* factory)
{
- // Erase everything after the
- // actual class name
+ // Erase everything after the
+ // actual class name
std::string name = parameter_name;
unsigned int name_end =
name.find_first_not_of(std::string("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"));
if (name_end < name.size())
name.erase(name_end);
- // first make sure that no other
- // thread intercepts the
- // operation of this function;
- // for this, acquire the lock
- // until we quit this function
+ // first make sure that no other
+ // thread intercepts the
+ // operation of this function;
+ // for this, acquire the lock
+ // until we quit this function
Threads::ThreadMutex::ScopedLock lock(fe_name_map_lock);
Assert(fe_name_map_3d.find(name) == fe_name_map_3d.end(),
- ExcMessage("Cannot change existing element in finite element name list"));
+ ExcMessage("Cannot change existing element in finite element name list"));
- // Insert the normalized name into
- // the map
+ // Insert the normalized name into
+ // the map
fe_name_map_3d[name] =
std_cxx1x::shared_ptr<const FETools::FEFactoryBase<3> > (factory);
}
{
namespace
{
- // TODO: this encapsulates the call to the
- // dimension-dependent fe_name_map so that we
- // have a unique interface. could be done
- // smarter?
+ // TODO: this encapsulates the call to the
+ // dimension-dependent fe_name_map so that we
+ // have a unique interface. could be done
+ // smarter?
template <int dim, int spacedim>
FiniteElement<dim,spacedim>*
get_fe_from_name_ext (std::string &name,
- const std::map<std::string,
- std_cxx1x::shared_ptr<const FETools::FEFactoryBase<dim> > >
- &fe_name_map)
+ const std::map<std::string,
+ std_cxx1x::shared_ptr<const FETools::FEFactoryBase<dim> > >
+ &fe_name_map)
{
- // Extract the name of the
- // finite element class, which only
- // contains characters, numbers and
- // underscores.
- unsigned int name_end =
- name.find_first_not_of(std::string("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"));
- const std::string name_part(name, 0, name_end);
- name.erase(0, name_part.size());
-
- // now things get a little more
- // complicated: FESystem. it's
- // more complicated, since we
- // have to figure out what the
- // base elements are. this can
- // only be done recursively
-
-
-
-
- if (name_part == "FESystem")
- {
- // next we have to get at the
- // base elements. start with
- // the first. wrap the whole
- // block into try-catch to
- // make sure we destroy the
- // pointers we got from
- // recursive calls if one of
- // these calls should throw
- // an exception
- std::vector<const FiniteElement<dim,spacedim>*> base_fes;
- std::vector<unsigned int> base_multiplicities;
- try
- {
- // Now, just the [...]
- // part should be left.
- if (name.size() == 0 || name[0] != '[')
- throw (std::string("Invalid first character in ") + name);
- do
- {
- // Erase the
- // leading '[' or '-'
- name.erase(0,1);
- // Now, the name of the
- // first base element is
- // first... Let's get it
- base_fes.push_back (get_fe_from_name_ext<dim,spacedim> (name,
- fe_name_map));
- // next check whether
- // FESystem placed a
- // multiplicity after
- // the element name
- if (name[0] == '^')
- {
- // yes. Delete the '^'
- // and read this
- // multiplicity
- name.erase(0,1);
-
- const std::pair<int,unsigned int> tmp
- = Utilities::get_integer_at_position (name, 0);
- name.erase(0, tmp.second);
- // add to length,
- // including the '^'
- base_multiplicities.push_back (tmp.first);
- }
- else
- // no, so
- // multiplicity is
- // 1
- base_multiplicities.push_back (1);
-
- // so that's it for
- // this base
- // element. base
- // elements are
- // separated by '-',
- // and the list is
- // terminated by ']',
- // so loop while the
- // next character is
- // '-'
- }
- while (name[0] == '-');
-
- // so we got to the end
- // of the '-' separated
- // list. make sure that
- // we actually had a ']'
- // there
- if (name.size() == 0 || name[0] != ']')
- throw (std::string("Invalid first character in ") + name);
- name.erase(0,1);
- // just one more sanity check
- Assert ((base_fes.size() == base_multiplicities.size())
- &&
- (base_fes.size() > 0),
- ExcInternalError());
-
- // ok, apparently
- // everything went ok. so
- // generate the composed
- // element
- FiniteElement<dim,spacedim> *system_element = 0;
+ // Extract the name of the
+ // finite element class, which only
+ // contains characters, numbers and
+ // underscores.
+ unsigned int name_end =
+ name.find_first_not_of(std::string("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"));
+ const std::string name_part(name, 0, name_end);
+ name.erase(0, name_part.size());
+
+ // now things get a little more
+ // complicated: FESystem. it's
+ // more complicated, since we
+ // have to figure out what the
+ // base elements are. this can
+ // only be done recursively
+
+
+
+
+ if (name_part == "FESystem")
+ {
+ // next we have to get at the
+ // base elements. start with
+ // the first. wrap the whole
+ // block into try-catch to
+ // make sure we destroy the
+ // pointers we got from
+ // recursive calls if one of
+ // these calls should throw
+ // an exception
+ std::vector<const FiniteElement<dim,spacedim>*> base_fes;
+ std::vector<unsigned int> base_multiplicities;
+ try
+ {
+ // Now, just the [...]
+ // part should be left.
+ if (name.size() == 0 || name[0] != '[')
+ throw (std::string("Invalid first character in ") + name);
+ do
+ {
+ // Erase the
+ // leading '[' or '-'
+ name.erase(0,1);
+ // Now, the name of the
+ // first base element is
+ // first... Let's get it
+ base_fes.push_back (get_fe_from_name_ext<dim,spacedim> (name,
+ fe_name_map));
+ // next check whether
+ // FESystem placed a
+ // multiplicity after
+ // the element name
+ if (name[0] == '^')
+ {
+ // yes. Delete the '^'
+ // and read this
+ // multiplicity
+ name.erase(0,1);
+
+ const std::pair<int,unsigned int> tmp
+ = Utilities::get_integer_at_position (name, 0);
+ name.erase(0, tmp.second);
+ // add to length,
+ // including the '^'
+ base_multiplicities.push_back (tmp.first);
+ }
+ else
+ // no, so
+ // multiplicity is
+ // 1
+ base_multiplicities.push_back (1);
+
+ // so that's it for
+ // this base
+ // element. base
+ // elements are
+ // separated by '-',
+ // and the list is
+ // terminated by ']',
+ // so loop while the
+ // next character is
+ // '-'
+ }
+ while (name[0] == '-');
+
+ // so we got to the end
+ // of the '-' separated
+ // list. make sure that
+ // we actually had a ']'
+ // there
+ if (name.size() == 0 || name[0] != ']')
+ throw (std::string("Invalid first character in ") + name);
+ name.erase(0,1);
+ // just one more sanity check
+ Assert ((base_fes.size() == base_multiplicities.size())
+ &&
+ (base_fes.size() > 0),
+ ExcInternalError());
+
+ // ok, apparently
+ // everything went ok. so
+ // generate the composed
+ // element
+ FiniteElement<dim,spacedim> *system_element = 0;
// uses new FESystem constructor
// which is independent of
system_element = new FESystem<dim>(base_fes,
base_multiplicities);
- // now we don't need the
- // list of base elements
- // any more
- for (unsigned int i=0; i<base_fes.size(); ++i)
- delete base_fes[i];
-
- // finally return our
- // findings
- // Add the closing ']' to
- // the length
- return system_element;
-
- }
- catch (...)
- {
- // ups, some exception
- // was thrown. prevent a
- // memory leak, and then
- // pass on the exception
- // to the caller
- for (unsigned int i=0; i<base_fes.size(); ++i)
- delete base_fes[i];
- throw;
- }
-
- // this is a place where we
- // should really never get,
- // since above we have either
- // returned from the
- // try-clause, or have
- // re-thrown in the catch
- // clause. check that we
- // never get here
- Assert (false, ExcInternalError());
- }
- else if (name_part == "FE_Nothing")
- {
- // remove the () from FE_Nothing()
- name.erase(0,2);
-
- // this is a bit of a hack, as
- // FE_Nothing does not take a
- // degree, but it does take an
- // argument, which defaults to 1,
- // so this properly returns
- // FE_Nothing()
- return fe_name_map.find(name_part)->second->get(1);
- }
- else
- {
- // Make sure no other thread
- // is just adding an element
- Threads::ThreadMutex::ScopedLock lock (fe_name_map_lock);
-
- AssertThrow (fe_name_map.find(name_part) != fe_name_map.end(),
- ExcInvalidFEName(name));
- // Now, just the (degree)
- // or (Quadrature<1>(degree+1))
- // part should be left.
- if (name.size() == 0 || name[0] != '(')
- throw (std::string("Invalid first character in ") + name);
- name.erase(0,1);
- if (name[0] != 'Q')
- {
- const std::pair<int,unsigned int> tmp
- = Utilities::get_integer_at_position (name, 0);
- name.erase(0, tmp.second+1);
- return fe_name_map.find(name_part)->second->get(tmp.first);
- }
- else
- {
- unsigned int position = name.find('(');
- const std::string quadrature_name(name, 0, position);
- name.erase(0,position+1);
- if (quadrature_name.compare("QGaussLobatto") == 0)
- {
- const std::pair<int,unsigned int> tmp
- = Utilities::get_integer_at_position (name, 0);
- // delete "))"
- name.erase(0, tmp.second+2);
- return fe_name_map.find(name_part)->second->get(QGaussLobatto<1>(tmp.first));
- }
- else
- {
- AssertThrow (false,ExcNotImplemented());
- }
- }
- }
-
-
- // hm, if we have come thus far, we
- // didn't know what to do with the
- // string we got. so do as the docs
- // say: raise an exception
- AssertThrow (false, ExcInvalidFEName(name));
-
- // make some compilers happy that
- // do not realize that we can't get
- // here after throwing
- return 0;
+ // now we don't need the
+ // list of base elements
+ // any more
+ for (unsigned int i=0; i<base_fes.size(); ++i)
+ delete base_fes[i];
+
+ // finally return our
+ // findings
+ // Add the closing ']' to
+ // the length
+ return system_element;
+
+ }
+ catch (...)
+ {
+ // ups, some exception
+ // was thrown. prevent a
+ // memory leak, and then
+ // pass on the exception
+ // to the caller
+ for (unsigned int i=0; i<base_fes.size(); ++i)
+ delete base_fes[i];
+ throw;
+ }
+
+ // this is a place where we
+ // should really never get,
+ // since above we have either
+ // returned from the
+ // try-clause, or have
+ // re-thrown in the catch
+ // clause. check that we
+ // never get here
+ Assert (false, ExcInternalError());
+ }
+ else if (name_part == "FE_Nothing")
+ {
+ // remove the () from FE_Nothing()
+ name.erase(0,2);
+
+ // this is a bit of a hack, as
+ // FE_Nothing does not take a
+ // degree, but it does take an
+ // argument, which defaults to 1,
+ // so this properly returns
+ // FE_Nothing()
+ return fe_name_map.find(name_part)->second->get(1);
+ }
+ else
+ {
+ // Make sure no other thread
+ // is just adding an element
+ Threads::ThreadMutex::ScopedLock lock (fe_name_map_lock);
+
+ AssertThrow (fe_name_map.find(name_part) != fe_name_map.end(),
+ ExcInvalidFEName(name));
+ // Now, just the (degree)
+ // or (Quadrature<1>(degree+1))
+ // part should be left.
+ if (name.size() == 0 || name[0] != '(')
+ throw (std::string("Invalid first character in ") + name);
+ name.erase(0,1);
+ if (name[0] != 'Q')
+ {
+ const std::pair<int,unsigned int> tmp
+ = Utilities::get_integer_at_position (name, 0);
+ name.erase(0, tmp.second+1);
+ return fe_name_map.find(name_part)->second->get(tmp.first);
+ }
+ else
+ {
+ unsigned int position = name.find('(');
+ const std::string quadrature_name(name, 0, position);
+ name.erase(0,position+1);
+ if (quadrature_name.compare("QGaussLobatto") == 0)
+ {
+ const std::pair<int,unsigned int> tmp
+ = Utilities::get_integer_at_position (name, 0);
+ // delete "))"
+ name.erase(0, tmp.second+2);
+ return fe_name_map.find(name_part)->second->get(QGaussLobatto<1>(tmp.first));
+ }
+ else
+ {
+ AssertThrow (false,ExcNotImplemented());
+ }
+ }
+ }
+
+
+ // hm, if we have come thus far, we
+ // didn't know what to do with the
+ // string we got. so do as the docs
+ // say: raise an exception
+ AssertThrow (false, ExcInvalidFEName(name));
+
+ // make some compilers happy that
+ // do not realize that we can't get
+ // here after throwing
+ return 0;
}
- // need to work around problem with different
- // name map names for different dimensions
- // TODO: should be possible to do nicer!
+ // need to work around problem with different
+ // name map names for different dimensions
+ // TODO: should be possible to do nicer!
template <int dim,int spacedim>
FiniteElement<dim,spacedim>* get_fe_from_name (std::string &name);
FiniteElement<1,1>*
get_fe_from_name<1> (std::string &name)
{
- return get_fe_from_name_ext<1,1> (name, fe_name_map_1d);
+ return get_fe_from_name_ext<1,1> (name, fe_name_map_1d);
}
template <>
FiniteElement<2,2>*
get_fe_from_name<2> (std::string &name)
{
- return get_fe_from_name_ext<2,2> (name, fe_name_map_2d);
+ return get_fe_from_name_ext<2,2> (name, fe_name_map_2d);
}
template <>
FiniteElement<3,3>*
get_fe_from_name<3> (std::string &name)
{
- return get_fe_from_name_ext<3,3> (name, fe_name_map_3d);
+ return get_fe_from_name_ext<3,3> (name, fe_name_map_3d);
}
}
}
FiniteElement<dim, dim> *
get_fe_from_name (const std::string ¶meter_name)
{
- // Create a version of the name
- // string where all template
- // parameters are eliminated.
+ // Create a version of the name
+ // string where all template
+ // parameters are eliminated.
std::string name = parameter_name;
for (unsigned int pos1 = name.find('<');
- pos1 < name.size();
- pos1 = name.find('<'))
+ pos1 < name.size();
+ pos1 = name.find('<'))
{
- const unsigned int pos2 = name.find('>');
- // If there is only a single
- // character between those two,
- // it should be 'd' or the number
- // representing the dimension.
- if (pos2-pos1 == 2)
- {
- const char dimchar = '0' + dim;
- if (name.at(pos1+1) != 'd')
- Assert (name.at(pos1+1) == dimchar,
- ExcInvalidFEDimension(name.at(pos1+1), dim));
- }
- else
- Assert(pos2-pos1 == 4, ExcInvalidFEName(name));
-
- // If pos1==pos2, then we are
- // probably at the end of the
- // string
- if (pos2 != pos1)
- name.erase(pos1, pos2-pos1+1);
+ const unsigned int pos2 = name.find('>');
+ // If there is only a single
+ // character between those two,
+ // it should be 'd' or the number
+ // representing the dimension.
+ if (pos2-pos1 == 2)
+ {
+ const char dimchar = '0' + dim;
+ if (name.at(pos1+1) != 'd')
+ Assert (name.at(pos1+1) == dimchar,
+ ExcInvalidFEDimension(name.at(pos1+1), dim));
+ }
+ else
+ Assert(pos2-pos1 == 4, ExcInvalidFEName(name));
+
+ // If pos1==pos2, then we are
+ // probably at the end of the
+ // string
+ if (pos2 != pos1)
+ name.erase(pos1, pos2-pos1+1);
}
- // Replace all occurences of "^dim"
- // by "^d" to be handled by the
- // next loop
+ // Replace all occurences of "^dim"
+ // by "^d" to be handled by the
+ // next loop
for (unsigned int pos = name.find("^dim");
- pos < name.size();
- pos = name.find("^dim"))
+ pos < name.size();
+ pos = name.find("^dim"))
name.erase(pos+2, 2);
- // Replace all occurences of "^d"
- // by using the actual dimension
+ // Replace all occurences of "^d"
+ // by using the actual dimension
for (unsigned int pos = name.find("^d");
- pos < name.size();
- pos = name.find("^d"))
+ pos < name.size();
+ pos = name.find("^d"))
name.at(pos+1) = '0' + dim;
try
{
- FiniteElement<dim,dim> *fe = internal::get_fe_from_name<dim,dim> (name);
-
- // Make sure the auxiliary function
- // ate up all characters of the name.
- AssertThrow (name.size() == 0,
- ExcInvalidFEName(parameter_name
- + std::string(" extra characters after "
- "end of name")));
- return fe;
+ FiniteElement<dim,dim> *fe = internal::get_fe_from_name<dim,dim> (name);
+
+ // Make sure the auxiliary function
+ // ate up all characters of the name.
+ AssertThrow (name.size() == 0,
+ ExcInvalidFEName(parameter_name
+ + std::string(" extra characters after "
+ "end of name")));
+ return fe;
}
catch (const std::string &errline)
{
- AssertThrow(false, ExcInvalidFEName(parameter_name
- + std::string(" at ")
- + errline));
- return 0;
+ AssertThrow(false, ExcInvalidFEName(parameter_name
+ + std::string(" at ")
+ + errline));
+ return 0;
}
}
void
compute_projection_from_quadrature_points_matrix (const FiniteElement<dim,spacedim> &fe,
- const Quadrature<dim> &lhs_quadrature,
- const Quadrature<dim> &rhs_quadrature,
- FullMatrix<double> &X)
+ const Quadrature<dim> &lhs_quadrature,
+ const Quadrature<dim> &rhs_quadrature,
+ FullMatrix<double> &X)
{
Assert (fe.n_components() == 1, ExcNotImplemented());
- // first build the matrices M and Q
- // described in the documentation
+ // first build the matrices M and Q
+ // described in the documentation
FullMatrix<double> M (fe.dofs_per_cell, fe.dofs_per_cell);
FullMatrix<double> Q (fe.dofs_per_cell, rhs_quadrature.size());
for (unsigned int i=0; i<fe.dofs_per_cell; ++i)
for (unsigned int j=0; j<fe.dofs_per_cell; ++j)
- for (unsigned int q=0; q<lhs_quadrature.size(); ++q)
- M(i,j) += fe.shape_value (i, lhs_quadrature.point(q)) *
- fe.shape_value (j, lhs_quadrature.point(q)) *
- lhs_quadrature.weight(q);
+ for (unsigned int q=0; q<lhs_quadrature.size(); ++q)
+ M(i,j) += fe.shape_value (i, lhs_quadrature.point(q)) *
+ fe.shape_value (j, lhs_quadrature.point(q)) *
+ lhs_quadrature.weight(q);
for (unsigned int i=0; i<fe.dofs_per_cell; ++i)
for (unsigned int q=0; q<rhs_quadrature.size(); ++q)
- Q(i,q) += fe.shape_value (i, rhs_quadrature.point(q)) *
- rhs_quadrature.weight(q);
+ Q(i,q) += fe.shape_value (i, rhs_quadrature.point(q)) *
+ rhs_quadrature.weight(q);
- // then invert M
+ // then invert M
FullMatrix<double> M_inverse (fe.dofs_per_cell, fe.dofs_per_cell);
M_inverse.invert (M);
- // finally compute the result
+ // finally compute the result
X.reinit (fe.dofs_per_cell, rhs_quadrature.size());
M_inverse.mmult (X, Q);
template <int dim, int spacedim>
void
compute_interpolation_to_quadrature_points_matrix (const FiniteElement<dim,spacedim> &fe,
- const Quadrature<dim> &quadrature,
- FullMatrix<double> &I_q)
+ const Quadrature<dim> &quadrature,
+ FullMatrix<double> &I_q)
{
Assert (fe.n_components() == 1, ExcNotImplemented());
Assert (I_q.m() == quadrature.size(),
- ExcMessage ("Wrong matrix size"));
+ ExcMessage ("Wrong matrix size"));
Assert (I_q.n() == fe.dofs_per_cell, ExcMessage ("Wrong matrix size"));
for (unsigned int q=0; q<quadrature.size(); ++q)
for (unsigned int i=0; i<fe.dofs_per_cell; ++i)
- I_q(q,i) = fe.shape_value (i, quadrature.point(q));
+ I_q(q,i) = fe.shape_value (i, quadrature.point(q));
}
std::vector< Tensor<1, dim > > &vector_of_tensors_at_nodes)
{
- // check that the number columns of the projection_matrix
- // matches the size of the vector_of_tensors_at_qp
+ // check that the number columns of the projection_matrix
+ // matches the size of the vector_of_tensors_at_qp
Assert(projection_matrix.n_cols() == vector_of_tensors_at_qp.size(),
- ExcDimensionMismatch(projection_matrix.n_cols(),
- vector_of_tensors_at_qp.size()));
+ ExcDimensionMismatch(projection_matrix.n_cols(),
+ vector_of_tensors_at_qp.size()));
- // check that the number rows of the projection_matrix
- // matches the size of the vector_of_tensors_at_nodes
+ // check that the number rows of the projection_matrix
+ // matches the size of the vector_of_tensors_at_nodes
Assert(projection_matrix.n_rows() == vector_of_tensors_at_nodes.size(),
- ExcDimensionMismatch(projection_matrix.n_rows(),
- vector_of_tensors_at_nodes.size()));
+ ExcDimensionMismatch(projection_matrix.n_rows(),
+ vector_of_tensors_at_nodes.size()));
- // number of support points (nodes) to project to
+ // number of support points (nodes) to project to
const unsigned int n_support_points = projection_matrix.n_rows();
- // number of quadrature points to project from
+ // number of quadrature points to project from
const unsigned int n_quad_points = projection_matrix.n_cols();
- // component projected to the nodes
+ // component projected to the nodes
Vector<double> component_at_node(n_support_points);
- // component at the quadrature point
+ // component at the quadrature point
Vector<double> component_at_qp(n_quad_points);
for (unsigned int ii = 0; ii < dim; ++ii) {
component_at_qp = 0;
- // populate the vector of components at the qps
- // from vector_of_tensors_at_qp
- // vector_of_tensors_at_qp data is in form:
- // columns: 0, 1, ..., dim
- // rows: 0,1,...., n_quad_points
- // so extract the ii'th column of vector_of_tensors_at_qp
+ // populate the vector of components at the qps
+ // from vector_of_tensors_at_qp
+ // vector_of_tensors_at_qp data is in form:
+ // columns: 0, 1, ..., dim
+ // rows: 0,1,...., n_quad_points
+ // so extract the ii'th column of vector_of_tensors_at_qp
for (unsigned int q = 0; q < n_quad_points; ++q) {
- component_at_qp(q) = vector_of_tensors_at_qp[q][ii];
+ component_at_qp(q) = vector_of_tensors_at_qp[q][ii];
}
- // project from the qps -> nodes
- // component_at_node = projection_matrix_u * component_at_qp
+ // project from the qps -> nodes
+ // component_at_node = projection_matrix_u * component_at_qp
projection_matrix.vmult(component_at_node, component_at_qp);
- // rewrite the projection of the components
- // back into the vector of tensors
+ // rewrite the projection of the components
+ // back into the vector of tensors
for (unsigned int nn =0; nn <n_support_points; ++nn) {
- vector_of_tensors_at_nodes[nn][ii] = component_at_node(nn);
+ vector_of_tensors_at_nodes[nn][ii] = component_at_node(nn);
}
}
}
std::vector< SymmetricTensor<2, dim > > &vector_of_tensors_at_nodes)
{
- // check that the number columns of the projection_matrix
- // matches the size of the vector_of_tensors_at_qp
+ // check that the number columns of the projection_matrix
+ // matches the size of the vector_of_tensors_at_qp
Assert(projection_matrix.n_cols() == vector_of_tensors_at_qp.size(),
- ExcDimensionMismatch(projection_matrix.n_cols(),
- vector_of_tensors_at_qp.size()));
+ ExcDimensionMismatch(projection_matrix.n_cols(),
+ vector_of_tensors_at_qp.size()));
- // check that the number rows of the projection_matrix
- // matches the size of the vector_of_tensors_at_nodes
+ // check that the number rows of the projection_matrix
+ // matches the size of the vector_of_tensors_at_nodes
Assert(projection_matrix.n_rows() == vector_of_tensors_at_nodes.size(),
- ExcDimensionMismatch(projection_matrix.n_rows(),
- vector_of_tensors_at_nodes.size()));
+ ExcDimensionMismatch(projection_matrix.n_rows(),
+ vector_of_tensors_at_nodes.size()));
- // number of support points (nodes)
+ // number of support points (nodes)
const unsigned int n_support_points = projection_matrix.n_rows();
- // number of quadrature points to project from
+ // number of quadrature points to project from
const unsigned int n_quad_points = projection_matrix.n_cols();
- // number of unique entries in a symmetric second-order tensor
+ // number of unique entries in a symmetric second-order tensor
const unsigned int n_independent_components =
SymmetricTensor<2, dim >::n_independent_components;
- // component projected to the nodes
+ // component projected to the nodes
Vector<double> component_at_node(n_support_points);
- // component at the quadrature point
+ // component at the quadrature point
Vector<double> component_at_qp(n_quad_points);
- // loop over the number of unique dimensions of the tensor
+ // loop over the number of unique dimensions of the tensor
for (unsigned int ii = 0; ii < n_independent_components; ++ii) {
component_at_qp = 0;
- // row-column entry of tensor corresponding the unrolled index
+ // row-column entry of tensor corresponding the unrolled index
TableIndices<2> row_column_index = SymmetricTensor< 2, dim >::unrolled_to_component_indices(ii);
const unsigned int row = row_column_index[0];
const unsigned int column = row_column_index[1];
- // populate the vector of components at the qps
- // from vector_of_tensors_at_qp
- // vector_of_tensors_at_qp is in form:
- // columns: 0, 1, ..., n_independent_components
- // rows: 0,1,...., n_quad_points
- // so extract the ii'th column of vector_of_tensors_at_qp
+ // populate the vector of components at the qps
+ // from vector_of_tensors_at_qp
+ // vector_of_tensors_at_qp is in form:
+ // columns: 0, 1, ..., n_independent_components
+ // rows: 0,1,...., n_quad_points
+ // so extract the ii'th column of vector_of_tensors_at_qp
for (unsigned int q = 0; q < n_quad_points; ++q) {
- component_at_qp(q) = (vector_of_tensors_at_qp[q])[row][column];
+ component_at_qp(q) = (vector_of_tensors_at_qp[q])[row][column];
}
- // project from the qps -> nodes
- // component_at_node = projection_matrix_u * component_at_qp
+ // project from the qps -> nodes
+ // component_at_node = projection_matrix_u * component_at_qp
projection_matrix.vmult(component_at_node, component_at_qp);
- // rewrite the projection of the components back into the vector of tensors
+ // rewrite the projection of the components back into the vector of tensors
for (unsigned int nn =0; nn <n_support_points; ++nn) {
- (vector_of_tensors_at_nodes[nn])[row][column] = component_at_node(nn);
+ (vector_of_tensors_at_nodes[nn])[row][column] = component_at_node(nn);
}
}
}
template <int dim, int spacedim>
void
compute_projection_from_face_quadrature_points_matrix (const FiniteElement<dim, spacedim> &fe,
- const Quadrature<dim-1> &lhs_quadrature,
- const Quadrature<dim-1> &rhs_quadrature,
- const typename DoFHandler<dim, spacedim>::active_cell_iterator & cell,
- unsigned int face,
- FullMatrix<double> &X)
+ const Quadrature<dim-1> &lhs_quadrature,
+ const Quadrature<dim-1> &rhs_quadrature,
+ const typename DoFHandler<dim, spacedim>::active_cell_iterator & cell,
+ unsigned int face,
+ FullMatrix<double> &X)
{
Assert (fe.n_components() == 1, ExcNotImplemented());
Assert (lhs_quadrature.size () > fe.degree, ExcNotGreaterThan (lhs_quadrature.size (), fe.degree));
- // build the matrices M and Q
- // described in the documentation
+ // build the matrices M and Q
+ // described in the documentation
FullMatrix<double> M (fe.dofs_per_cell, fe.dofs_per_cell);
FullMatrix<double> Q (fe.dofs_per_cell, rhs_quadrature.size());
{
- // need an FEFaceValues object to evaluate shape function
- // values on the specified face.
+ // need an FEFaceValues object to evaluate shape function
+ // values on the specified face.
FEFaceValues <dim> fe_face_values (fe, lhs_quadrature, update_values);
fe_face_values.reinit (cell, face); // setup shape_value on this face.
for (unsigned int i=0; i<fe.dofs_per_cell; ++i)
- for (unsigned int j=0; j<fe.dofs_per_cell; ++j)
- for (unsigned int q=0; q<lhs_quadrature.size(); ++q)
- M(i,j) += fe_face_values.shape_value (i, q) *
- fe_face_values.shape_value (j, q) *
- lhs_quadrature.weight(q);
+ for (unsigned int j=0; j<fe.dofs_per_cell; ++j)
+ for (unsigned int q=0; q<lhs_quadrature.size(); ++q)
+ M(i,j) += fe_face_values.shape_value (i, q) *
+ fe_face_values.shape_value (j, q) *
+ lhs_quadrature.weight(q);
for (unsigned int i=0; i<fe.dofs_per_cell; ++i)
- {
- M(i,i) = (M(i,i) == 0 ? 1 : M(i,i));
- }
+ {
+ M(i,i) = (M(i,i) == 0 ? 1 : M(i,i));
+ }
}
{
fe_face_values.reinit (cell, face); // setup shape_value on this face.
for (unsigned int i=0; i<fe.dofs_per_cell; ++i)
- for (unsigned int q=0; q<rhs_quadrature.size(); ++q)
- Q(i,q) += fe_face_values.shape_value (i, q) *
- rhs_quadrature.weight(q);
+ for (unsigned int q=0; q<rhs_quadrature.size(); ++q)
+ Q(i,q) += fe_face_values.shape_value (i, q) *
+ rhs_quadrature.weight(q);
}
- // then invert M
+ // then invert M
FullMatrix<double> M_inverse (fe.dofs_per_cell, fe.dofs_per_cell);
M_inverse.invert (M);
- // finally compute the result
+ // finally compute the result
X.reinit (fe.dofs_per_cell, rhs_quadrature.size());
M_inverse.mmult (X, Q);
template <int dim>
void
hierarchic_to_lexicographic_numbering (const FiniteElementData<dim> &fe,
- std::vector<unsigned int> &h2l)
+ std::vector<unsigned int> &h2l)
{
Assert (h2l.size() == fe.dofs_per_cell,
- ExcDimensionMismatch (h2l.size(), fe.dofs_per_cell));
+ ExcDimensionMismatch (h2l.size(), fe.dofs_per_cell));
h2l = hierarchic_to_lexicographic_numbering (fe);
}
std::vector<unsigned int> h2l (fe.dofs_per_cell);
const unsigned int dofs_per_cell = fe.dofs_per_cell;
- // polynomial degree
+ // polynomial degree
const unsigned int degree = fe.dofs_per_line+1;
- // number of grid points in each
- // direction
+ // number of grid points in each
+ // direction
const unsigned int n = degree+1;
- // the following lines of code are
- // somewhat odd, due to the way the
- // hierarchic numbering is
- // organized. if someone would
- // really want to understand these
- // lines, you better draw some
- // pictures where you indicate the
- // indices and orders of vertices,
- // lines, etc, along with the
- // numbers of the degrees of
- // freedom in hierarchical and
- // lexicographical order
+ // the following lines of code are
+ // somewhat odd, due to the way the
+ // hierarchic numbering is
+ // organized. if someone would
+ // really want to understand these
+ // lines, you better draw some
+ // pictures where you indicate the
+ // indices and orders of vertices,
+ // lines, etc, along with the
+ // numbers of the degrees of
+ // freedom in hierarchical and
+ // lexicographical order
switch (dim)
{
- case 1:
- {
- h2l[0] = 0;
- h2l[1] = dofs_per_cell-1;
- for (unsigned int i=2; i<dofs_per_cell; ++i)
- h2l[i] = i-1;
-
- break;
- }
-
- case 2:
- {
- unsigned int next_index = 0;
- // first the four vertices
- h2l[next_index++] = 0;
- h2l[next_index++] = n-1;
- h2l[next_index++] = n*(n-1);
- h2l[next_index++] = n*n-1;
-
- // left line
- for (unsigned int i=0; i<fe.dofs_per_line; ++i)
- h2l[next_index++] = (1+i)*n;
-
- // right line
- for (unsigned int i=0; i<fe.dofs_per_line; ++i)
- h2l[next_index++] = (2+i)*n-1;
-
- // bottom line
- for (unsigned int i=0; i<fe.dofs_per_line; ++i)
- h2l[next_index++] = 1+i;
-
- // top line
- for (unsigned int i=0; i<fe.dofs_per_line; ++i)
- h2l[next_index++] = n*(n-1)+i+1;
-
- // inside quad
- Assert (fe.dofs_per_quad == fe.dofs_per_line*fe.dofs_per_line,
- ExcInternalError());
- for (unsigned int i=0; i<fe.dofs_per_line; ++i)
- for (unsigned int j=0; j<fe.dofs_per_line; ++j)
- h2l[next_index++] = n*(i+1)+j+1;
-
- Assert (next_index == fe.dofs_per_cell, ExcInternalError());
-
- break;
- }
-
- case 3:
- {
- unsigned int next_index = 0;
- // first the eight vertices
- h2l[next_index++] = 0; // 0
- h2l[next_index++] = ( 1)*degree; // 1
- h2l[next_index++] = ( n )*degree; // 2
- h2l[next_index++] = ( n+1)*degree; // 3
- h2l[next_index++] = (n*n )*degree; // 4
- h2l[next_index++] = (n*n +1)*degree; // 5
- h2l[next_index++] = (n*n+n )*degree; // 6
- h2l[next_index++] = (n*n+n+1)*degree; // 7
-
- // line 0
- for (unsigned int i=0; i<fe.dofs_per_line; ++i)
- h2l[next_index++] = (i+1)*n;
- // line 1
- for (unsigned int i=0; i<fe.dofs_per_line; ++i)
- h2l[next_index++] = n-1+(i+1)*n;
- // line 2
- for (unsigned int i=0; i<fe.dofs_per_line; ++i)
- h2l[next_index++] = 1+i;
- // line 3
- for (unsigned int i=0; i<fe.dofs_per_line; ++i)
- h2l[next_index++] = 1+i+n*(n-1);
-
- // line 4
- for (unsigned int i=0; i<fe.dofs_per_line; ++i)
- h2l[next_index++] = (n-1)*n*n+(i+1)*n;
- // line 5
- for (unsigned int i=0; i<fe.dofs_per_line; ++i)
- h2l[next_index++] = (n-1)*(n*n+1)+(i+1)*n;
- // line 6
- for (unsigned int i=0; i<fe.dofs_per_line; ++i)
- h2l[next_index++] = n*n*(n-1)+i+1;
- // line 7
- for (unsigned int i=0; i<fe.dofs_per_line; ++i)
- h2l[next_index++] = n*n*(n-1)+i+1+n*(n-1);
-
- // line 8
- for (unsigned int i=0; i<fe.dofs_per_line; ++i)
- h2l[next_index++] = (i+1)*n*n;
- // line 9
- for (unsigned int i=0; i<fe.dofs_per_line; ++i)
- h2l[next_index++] = n-1+(i+1)*n*n;
- // line 10
- for (unsigned int i=0; i<fe.dofs_per_line; ++i)
- h2l[next_index++] = (i+1)*n*n+n*(n-1);
- // line 11
- for (unsigned int i=0; i<fe.dofs_per_line; ++i)
- h2l[next_index++] = n-1+(i+1)*n*n+n*(n-1);
-
-
- // inside quads
- Assert (fe.dofs_per_quad == fe.dofs_per_line*fe.dofs_per_line,
- ExcInternalError());
- // face 0
- for (unsigned int i=0; i<fe.dofs_per_line; ++i)
- for (unsigned int j=0; j<fe.dofs_per_line; ++j)
- h2l[next_index++] = (i+1)*n*n+n*(j+1);
- // face 1
- for (unsigned int i=0; i<fe.dofs_per_line; ++i)
- for (unsigned int j=0; j<fe.dofs_per_line; ++j)
- h2l[next_index++] = (i+1)*n*n+n-1+n*(j+1);
- // face 2, note the orientation!
- for (unsigned int i=0; i<fe.dofs_per_line; ++i)
- for (unsigned int j=0; j<fe.dofs_per_line; ++j)
- h2l[next_index++] = (j+1)*n*n+i+1;
- // face 3, note the orientation!
- for (unsigned int i=0; i<fe.dofs_per_line; ++i)
- for (unsigned int j=0; j<fe.dofs_per_line; ++j)
- h2l[next_index++] = (j+1)*n*n+n*(n-1)+i+1;
- // face 4
- for (unsigned int i=0; i<fe.dofs_per_line; ++i)
- for (unsigned int j=0; j<fe.dofs_per_line; ++j)
- h2l[next_index++] = n*(i+1)+j+1;
- // face 5
- for (unsigned int i=0; i<fe.dofs_per_line; ++i)
- for (unsigned int j=0; j<fe.dofs_per_line; ++j)
- h2l[next_index++] = (n-1)*n*n+n*(i+1)+j+1;
-
- // inside hex
- Assert (fe.dofs_per_hex == fe.dofs_per_quad*fe.dofs_per_line,
- ExcInternalError());
- for (unsigned int i=0; i<fe.dofs_per_line; ++i)
- for (unsigned int j=0; j<fe.dofs_per_line; ++j)
- for (unsigned int k=0; k<fe.dofs_per_line; ++k)
- h2l[next_index++] = n*n*(i+1)+n*(j+1)+k+1;
-
- Assert (next_index == fe.dofs_per_cell, ExcInternalError());
-
- break;
- }
-
- default:
- Assert (false, ExcNotImplemented());
+ case 1:
+ {
+ h2l[0] = 0;
+ h2l[1] = dofs_per_cell-1;
+ for (unsigned int i=2; i<dofs_per_cell; ++i)
+ h2l[i] = i-1;
+
+ break;
+ }
+
+ case 2:
+ {
+ unsigned int next_index = 0;
+ // first the four vertices
+ h2l[next_index++] = 0;
+ h2l[next_index++] = n-1;
+ h2l[next_index++] = n*(n-1);
+ h2l[next_index++] = n*n-1;
+
+ // left line
+ for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+ h2l[next_index++] = (1+i)*n;
+
+ // right line
+ for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+ h2l[next_index++] = (2+i)*n-1;
+
+ // bottom line
+ for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+ h2l[next_index++] = 1+i;
+
+ // top line
+ for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+ h2l[next_index++] = n*(n-1)+i+1;
+
+ // inside quad
+ Assert (fe.dofs_per_quad == fe.dofs_per_line*fe.dofs_per_line,
+ ExcInternalError());
+ for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+ for (unsigned int j=0; j<fe.dofs_per_line; ++j)
+ h2l[next_index++] = n*(i+1)+j+1;
+
+ Assert (next_index == fe.dofs_per_cell, ExcInternalError());
+
+ break;
+ }
+
+ case 3:
+ {
+ unsigned int next_index = 0;
+ // first the eight vertices
+ h2l[next_index++] = 0; // 0
+ h2l[next_index++] = ( 1)*degree; // 1
+ h2l[next_index++] = ( n )*degree; // 2
+ h2l[next_index++] = ( n+1)*degree; // 3
+ h2l[next_index++] = (n*n )*degree; // 4
+ h2l[next_index++] = (n*n +1)*degree; // 5
+ h2l[next_index++] = (n*n+n )*degree; // 6
+ h2l[next_index++] = (n*n+n+1)*degree; // 7
+
+ // line 0
+ for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+ h2l[next_index++] = (i+1)*n;
+ // line 1
+ for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+ h2l[next_index++] = n-1+(i+1)*n;
+ // line 2
+ for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+ h2l[next_index++] = 1+i;
+ // line 3
+ for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+ h2l[next_index++] = 1+i+n*(n-1);
+
+ // line 4
+ for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+ h2l[next_index++] = (n-1)*n*n+(i+1)*n;
+ // line 5
+ for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+ h2l[next_index++] = (n-1)*(n*n+1)+(i+1)*n;
+ // line 6
+ for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+ h2l[next_index++] = n*n*(n-1)+i+1;
+ // line 7
+ for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+ h2l[next_index++] = n*n*(n-1)+i+1+n*(n-1);
+
+ // line 8
+ for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+ h2l[next_index++] = (i+1)*n*n;
+ // line 9
+ for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+ h2l[next_index++] = n-1+(i+1)*n*n;
+ // line 10
+ for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+ h2l[next_index++] = (i+1)*n*n+n*(n-1);
+ // line 11
+ for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+ h2l[next_index++] = n-1+(i+1)*n*n+n*(n-1);
+
+
+ // inside quads
+ Assert (fe.dofs_per_quad == fe.dofs_per_line*fe.dofs_per_line,
+ ExcInternalError());
+ // face 0
+ for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+ for (unsigned int j=0; j<fe.dofs_per_line; ++j)
+ h2l[next_index++] = (i+1)*n*n+n*(j+1);
+ // face 1
+ for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+ for (unsigned int j=0; j<fe.dofs_per_line; ++j)
+ h2l[next_index++] = (i+1)*n*n+n-1+n*(j+1);
+ // face 2, note the orientation!
+ for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+ for (unsigned int j=0; j<fe.dofs_per_line; ++j)
+ h2l[next_index++] = (j+1)*n*n+i+1;
+ // face 3, note the orientation!
+ for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+ for (unsigned int j=0; j<fe.dofs_per_line; ++j)
+ h2l[next_index++] = (j+1)*n*n+n*(n-1)+i+1;
+ // face 4
+ for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+ for (unsigned int j=0; j<fe.dofs_per_line; ++j)
+ h2l[next_index++] = n*(i+1)+j+1;
+ // face 5
+ for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+ for (unsigned int j=0; j<fe.dofs_per_line; ++j)
+ h2l[next_index++] = (n-1)*n*n+n*(i+1)+j+1;
+
+ // inside hex
+ Assert (fe.dofs_per_hex == fe.dofs_per_quad*fe.dofs_per_line,
+ ExcInternalError());
+ for (unsigned int i=0; i<fe.dofs_per_line; ++i)
+ for (unsigned int j=0; j<fe.dofs_per_line; ++j)
+ for (unsigned int k=0; k<fe.dofs_per_line; ++k)
+ h2l[next_index++] = n*n*(i+1)+n*(j+1)+k+1;
+
+ Assert (next_index == fe.dofs_per_cell, ExcInternalError());
+
+ break;
+ }
+
+ default:
+ Assert (false, ExcNotImplemented());
}
return h2l;
template <int dim>
void
lexicographic_to_hierarchic_numbering (const FiniteElementData<dim> &fe,
- std::vector<unsigned int> &l2h)
+ std::vector<unsigned int> &l2h)
{
l2h = lexicographic_to_hierarchic_numbering (fe);
}
template <class VectorType>
double
get_vector_element (const VectorType &vector,
- const unsigned int cell_number)
+ const unsigned int cell_number)
{
return vector[cell_number];
}
double
get_vector_element (const IndexSet &is,
- const unsigned int cell_number)
+ const unsigned int cell_number)
{
return (is.is_element(cell_number) ? 1 : 0);
}
unsigned int row = 0;
for (unsigned int i=0; i<fe.dofs_per_cell; ++i)
{
- shape_function_to_row_table[i] = row;
- row += fe.n_nonzero_components (i);
+ shape_function_to_row_table[i] = row;
+ row += fe.n_nonzero_components (i);
}
return shape_function_to_row_table;
{
template <int dim, int spacedim>
Scalar<dim,spacedim>::Scalar (const FEValuesBase<dim,spacedim> &fe_values,
- const unsigned int component)
- :
- fe_values (fe_values),
- component (component),
- shape_function_data (fe_values.fe->dofs_per_cell)
+ const unsigned int component)
+ :
+ fe_values (fe_values),
+ component (component),
+ shape_function_data (fe_values.fe->dofs_per_cell)
{
Assert (component < fe_values.fe->n_components(),
- ExcIndexRange(component, 0, fe_values.fe->n_components()));
+ ExcIndexRange(component, 0, fe_values.fe->n_components()));
const std::vector<unsigned int> shape_function_to_row_table
= make_shape_function_to_row_table (*fe_values.fe);
for (unsigned int i=0; i<fe_values.fe->dofs_per_cell; ++i)
{
- const bool is_primitive = (fe_values.fe->is_primitive() ||
- fe_values.fe->is_primitive(i));
-
- if (is_primitive == true)
- shape_function_data[i].is_nonzero_shape_function_component
- = (component ==
- fe_values.fe->system_to_component_index(i).first);
- else
- shape_function_data[i].is_nonzero_shape_function_component
- = (fe_values.fe->get_nonzero_components(i)[component]
- == true);
-
- if (shape_function_data[i].is_nonzero_shape_function_component == true)
- {
- if (is_primitive == true)
- shape_function_data[i].row_index = shape_function_to_row_table[i];
- else
- shape_function_data[i].row_index
- = (shape_function_to_row_table[i]
- +
- std::count (fe_values.fe->get_nonzero_components(i).begin(),
- fe_values.fe->get_nonzero_components(i).begin()+
- component,
- true));
- }
- else
- shape_function_data[i].row_index = numbers::invalid_unsigned_int;
+ const bool is_primitive = (fe_values.fe->is_primitive() ||
+ fe_values.fe->is_primitive(i));
+
+ if (is_primitive == true)
+ shape_function_data[i].is_nonzero_shape_function_component
+ = (component ==
+ fe_values.fe->system_to_component_index(i).first);
+ else
+ shape_function_data[i].is_nonzero_shape_function_component
+ = (fe_values.fe->get_nonzero_components(i)[component]
+ == true);
+
+ if (shape_function_data[i].is_nonzero_shape_function_component == true)
+ {
+ if (is_primitive == true)
+ shape_function_data[i].row_index = shape_function_to_row_table[i];
+ else
+ shape_function_data[i].row_index
+ = (shape_function_to_row_table[i]
+ +
+ std::count (fe_values.fe->get_nonzero_components(i).begin(),
+ fe_values.fe->get_nonzero_components(i).begin()+
+ component,
+ true));
+ }
+ else
+ shape_function_data[i].row_index = numbers::invalid_unsigned_int;
}
}
template <int dim, int spacedim>
Scalar<dim,spacedim>::Scalar ()
- :
- fe_values (*static_cast<dealii::FEValuesBase<dim,spacedim>*>(0)),
- component (numbers::invalid_unsigned_int)
+ :
+ fe_values (*static_cast<dealii::FEValuesBase<dim,spacedim>*>(0)),
+ component (numbers::invalid_unsigned_int)
{}
Scalar<dim,spacedim> &
Scalar<dim,spacedim>::operator= (const Scalar<dim,spacedim> &)
{
- // we shouldn't be copying these objects
+ // we shouldn't be copying these objects
Assert (false, ExcInternalError());
return *this;
}
template <int dim, int spacedim>
Vector<dim,spacedim>::Vector (const FEValuesBase<dim,spacedim> &fe_values,
- const unsigned int first_vector_component)
- :
- fe_values (fe_values),
- first_vector_component (first_vector_component),
- shape_function_data (fe_values.fe->dofs_per_cell)
+ const unsigned int first_vector_component)
+ :
+ fe_values (fe_values),
+ first_vector_component (first_vector_component),
+ shape_function_data (fe_values.fe->dofs_per_cell)
{
Assert (first_vector_component+spacedim-1 < fe_values.fe->n_components(),
- ExcIndexRange(first_vector_component+spacedim-1, 0,
- fe_values.fe->n_components()));
+ ExcIndexRange(first_vector_component+spacedim-1, 0,
+ fe_values.fe->n_components()));
const std::vector<unsigned int> shape_function_to_row_table
= make_shape_function_to_row_table (*fe_values.fe);
for (unsigned int d=0; d<spacedim; ++d)
{
- const unsigned int component = first_vector_component + d;
-
- for (unsigned int i=0; i<fe_values.fe->dofs_per_cell; ++i)
- {
- const bool is_primitive = (fe_values.fe->is_primitive() ||
- fe_values.fe->is_primitive(i));
-
- if (is_primitive == true)
- shape_function_data[i].is_nonzero_shape_function_component[d]
- = (component ==
- fe_values.fe->system_to_component_index(i).first);
- else
- shape_function_data[i].is_nonzero_shape_function_component[d]
- = (fe_values.fe->get_nonzero_components(i)[component]
- == true);
-
- if (shape_function_data[i].is_nonzero_shape_function_component[d]
- == true)
- {
- if (is_primitive == true)
- shape_function_data[i].row_index[d]
- = shape_function_to_row_table[i];
- else
- shape_function_data[i].row_index[d]
- = (shape_function_to_row_table[i]
- +
- std::count (fe_values.fe->get_nonzero_components(i).begin(),
- fe_values.fe->get_nonzero_components(i).begin()+
- component,
- true));
- }
- else
- shape_function_data[i].row_index[d]
- = numbers::invalid_unsigned_int;
- }
+ const unsigned int component = first_vector_component + d;
+
+ for (unsigned int i=0; i<fe_values.fe->dofs_per_cell; ++i)
+ {
+ const bool is_primitive = (fe_values.fe->is_primitive() ||
+ fe_values.fe->is_primitive(i));
+
+ if (is_primitive == true)
+ shape_function_data[i].is_nonzero_shape_function_component[d]
+ = (component ==
+ fe_values.fe->system_to_component_index(i).first);
+ else
+ shape_function_data[i].is_nonzero_shape_function_component[d]
+ = (fe_values.fe->get_nonzero_components(i)[component]
+ == true);
+
+ if (shape_function_data[i].is_nonzero_shape_function_component[d]
+ == true)
+ {
+ if (is_primitive == true)
+ shape_function_data[i].row_index[d]
+ = shape_function_to_row_table[i];
+ else
+ shape_function_data[i].row_index[d]
+ = (shape_function_to_row_table[i]
+ +
+ std::count (fe_values.fe->get_nonzero_components(i).begin(),
+ fe_values.fe->get_nonzero_components(i).begin()+
+ component,
+ true));
+ }
+ else
+ shape_function_data[i].row_index[d]
+ = numbers::invalid_unsigned_int;
+ }
}
for (unsigned int i=0; i<fe_values.fe->dofs_per_cell; ++i)
{
- unsigned int n_nonzero_components = 0;
- for (unsigned int d=0; d<spacedim; ++d)
- if (shape_function_data[i].is_nonzero_shape_function_component[d]
- == true)
- ++n_nonzero_components;
-
- if (n_nonzero_components == 0)
- shape_function_data[i].single_nonzero_component = -2;
- else if (n_nonzero_components > 1)
- shape_function_data[i].single_nonzero_component = -1;
- else
- {
- for (unsigned int d=0; d<spacedim; ++d)
- if (shape_function_data[i].is_nonzero_shape_function_component[d]
- == true)
- {
- shape_function_data[i].single_nonzero_component
- = shape_function_data[i].row_index[d];
- shape_function_data[i].single_nonzero_component_index
- = d;
- break;
- }
- }
+ unsigned int n_nonzero_components = 0;
+ for (unsigned int d=0; d<spacedim; ++d)
+ if (shape_function_data[i].is_nonzero_shape_function_component[d]
+ == true)
+ ++n_nonzero_components;
+
+ if (n_nonzero_components == 0)
+ shape_function_data[i].single_nonzero_component = -2;
+ else if (n_nonzero_components > 1)
+ shape_function_data[i].single_nonzero_component = -1;
+ else
+ {
+ for (unsigned int d=0; d<spacedim; ++d)
+ if (shape_function_data[i].is_nonzero_shape_function_component[d]
+ == true)
+ {
+ shape_function_data[i].single_nonzero_component
+ = shape_function_data[i].row_index[d];
+ shape_function_data[i].single_nonzero_component_index
+ = d;
+ break;
+ }
+ }
}
}
template <int dim, int spacedim>
Vector<dim,spacedim>::Vector ()
- :
- fe_values (*static_cast<dealii::FEValuesBase<dim,spacedim>*>(0)),
- first_vector_component (numbers::invalid_unsigned_int)
+ :
+ fe_values (*static_cast<dealii::FEValuesBase<dim,spacedim>*>(0)),
+ first_vector_component (numbers::invalid_unsigned_int)
{}
Vector<dim,spacedim> &
Vector<dim,spacedim>::operator= (const Vector<dim,spacedim> &)
{
- // we shouldn't be copying these objects
+ // we shouldn't be copying these objects
Assert (false, ExcInternalError());
return *this;
}
template <int dim, int spacedim>
SymmetricTensor<2, dim, spacedim>::
SymmetricTensor(const FEValuesBase<dim, spacedim> &fe_values,
- const unsigned int first_tensor_component)
- :
- fe_values(fe_values),
- first_tensor_component(first_tensor_component),
- shape_function_data(fe_values.fe->dofs_per_cell)
+ const unsigned int first_tensor_component)
+ :
+ fe_values(fe_values),
+ first_tensor_component(first_tensor_component),
+ shape_function_data(fe_values.fe->dofs_per_cell)
{
Assert(first_tensor_component + (dim*dim+dim)/2 - 1
- <
- fe_values.fe->n_components(),
- ExcIndexRange(first_tensor_component +
- dealii::SymmetricTensor<2,dim>::n_independent_components - 1,
- 0,
- fe_values.fe->n_components()));
+ <
+ fe_values.fe->n_components(),
+ ExcIndexRange(first_tensor_component +
+ dealii::SymmetricTensor<2,dim>::n_independent_components - 1,
+ 0,
+ fe_values.fe->n_components()));
const std::vector<unsigned int> shape_function_to_row_table
= make_shape_function_to_row_table(*fe_values.fe);
for (unsigned int d = 0; d < dealii::SymmetricTensor<2,dim>::n_independent_components; ++d)
{
- const unsigned int component = first_tensor_component + d;
-
- for (unsigned int i = 0; i < fe_values.fe->dofs_per_cell; ++i)
- {
- const bool is_primitive = (fe_values.fe->is_primitive() ||
- fe_values.fe->is_primitive(i));
-
- if (is_primitive == true)
- shape_function_data[i].is_nonzero_shape_function_component[d]
- = (component ==
- fe_values.fe->system_to_component_index(i).first);
- else
- shape_function_data[i].is_nonzero_shape_function_component[d]
- = (fe_values.fe->get_nonzero_components(i)[component]
- == true);
-
- if (shape_function_data[i].is_nonzero_shape_function_component[d]
- == true)
- {
- if (is_primitive == true)
- shape_function_data[i].row_index[d]
- = shape_function_to_row_table[i];
- else
- shape_function_data[i].row_index[d]
- = (shape_function_to_row_table[i]
- +
- std::count(fe_values.fe->get_nonzero_components(i).begin(),
- fe_values.fe->get_nonzero_components(i).begin() +
- component,
- true));
- }
- else
- shape_function_data[i].row_index[d]
- = numbers::invalid_unsigned_int;
- }
+ const unsigned int component = first_tensor_component + d;
+
+ for (unsigned int i = 0; i < fe_values.fe->dofs_per_cell; ++i)
+ {
+ const bool is_primitive = (fe_values.fe->is_primitive() ||
+ fe_values.fe->is_primitive(i));
+
+ if (is_primitive == true)
+ shape_function_data[i].is_nonzero_shape_function_component[d]
+ = (component ==
+ fe_values.fe->system_to_component_index(i).first);
+ else
+ shape_function_data[i].is_nonzero_shape_function_component[d]
+ = (fe_values.fe->get_nonzero_components(i)[component]
+ == true);
+
+ if (shape_function_data[i].is_nonzero_shape_function_component[d]
+ == true)
+ {
+ if (is_primitive == true)
+ shape_function_data[i].row_index[d]
+ = shape_function_to_row_table[i];
+ else
+ shape_function_data[i].row_index[d]
+ = (shape_function_to_row_table[i]
+ +
+ std::count(fe_values.fe->get_nonzero_components(i).begin(),
+ fe_values.fe->get_nonzero_components(i).begin() +
+ component,
+ true));
+ }
+ else
+ shape_function_data[i].row_index[d]
+ = numbers::invalid_unsigned_int;
+ }
}
for (unsigned int i = 0; i < fe_values.fe->dofs_per_cell; ++i)
{
- unsigned int n_nonzero_components = 0;
- for (unsigned int d = 0; d < dealii::SymmetricTensor<2,dim>::n_independent_components; ++d)
- if (shape_function_data[i].is_nonzero_shape_function_component[d]
- == true)
- ++n_nonzero_components;
-
- if (n_nonzero_components == 0)
- shape_function_data[i].single_nonzero_component = -2;
- else if (n_nonzero_components > 1)
- shape_function_data[i].single_nonzero_component = -1;
- else
- {
- for (unsigned int d = 0; d < dealii::SymmetricTensor<2,dim>::n_independent_components; ++d)
- if (shape_function_data[i].is_nonzero_shape_function_component[d]
- == true)
- {
- shape_function_data[i].single_nonzero_component
- = shape_function_data[i].row_index[d];
- shape_function_data[i].single_nonzero_component_index
- = d;
- break;
- }
- }
+ unsigned int n_nonzero_components = 0;
+ for (unsigned int d = 0; d < dealii::SymmetricTensor<2,dim>::n_independent_components; ++d)
+ if (shape_function_data[i].is_nonzero_shape_function_component[d]
+ == true)
+ ++n_nonzero_components;
+
+ if (n_nonzero_components == 0)
+ shape_function_data[i].single_nonzero_component = -2;
+ else if (n_nonzero_components > 1)
+ shape_function_data[i].single_nonzero_component = -1;
+ else
+ {
+ for (unsigned int d = 0; d < dealii::SymmetricTensor<2,dim>::n_independent_components; ++d)
+ if (shape_function_data[i].is_nonzero_shape_function_component[d]
+ == true)
+ {
+ shape_function_data[i].single_nonzero_component
+ = shape_function_data[i].row_index[d];
+ shape_function_data[i].single_nonzero_component_index
+ = d;
+ break;
+ }
+ }
}
}
template <int dim, int spacedim>
SymmetricTensor<2, dim, spacedim>::SymmetricTensor()
- :
- fe_values(*static_cast<dealii::FEValuesBase<dim, spacedim>*> (0)),
- first_tensor_component(numbers::invalid_unsigned_int)
+ :
+ fe_values(*static_cast<dealii::FEValuesBase<dim, spacedim>*> (0)),
+ first_tensor_component(numbers::invalid_unsigned_int)
{}
SymmetricTensor<2, dim, spacedim> &
SymmetricTensor<2, dim, spacedim>::operator=(const SymmetricTensor<2, dim, spacedim> &)
{
- // we shouldn't be copying these objects
+ // we shouldn't be copying these objects
Assert(false, ExcInternalError());
return *this;
}
void
Scalar<dim,spacedim>::
get_function_values (const InputVector &fe_function,
- std::vector<value_type> &values) const
+ std::vector<value_type> &values) const
{
typedef FEValuesBase<dim,spacedim> FVB;
Assert (fe_values.update_flags & update_values,
- typename FVB::ExcAccessToUninitializedField());
+ typename FVB::ExcAccessToUninitializedField());
Assert (values.size() == fe_values.n_quadrature_points,
- ExcDimensionMismatch(values.size(), fe_values.n_quadrature_points));
+ ExcDimensionMismatch(values.size(), fe_values.n_quadrature_points));
Assert (fe_values.present_cell.get() != 0,
- ExcMessage ("FEValues object is not reinit'ed to any cell"));
+ ExcMessage ("FEValues object is not reinit'ed to any cell"));
Assert (fe_function.size() == fe_values.present_cell->n_dofs_for_dof_handler(),
- ExcDimensionMismatch(fe_function.size(),
- fe_values.present_cell->n_dofs_for_dof_handler()));
+ ExcDimensionMismatch(fe_function.size(),
+ fe_values.present_cell->n_dofs_for_dof_handler()));
- // get function values of dofs
- // on this cell
+ // get function values of dofs
+ // on this cell
dealii::Vector<typename ValueType<InputVector>::type> dof_values (fe_values.dofs_per_cell);
fe_values.present_cell->get_interpolated_dof_values(fe_function, dof_values);
std::fill (values.begin(), values.end(), value_type());
for (unsigned int shape_function=0;
- shape_function<fe_values.fe->dofs_per_cell; ++shape_function)
+ shape_function<fe_values.fe->dofs_per_cell; ++shape_function)
if (shape_function_data[shape_function].is_nonzero_shape_function_component)
- {
- const double value = dof_values(shape_function);
- if (value == 0.)
- continue;
-
- const double * shape_value_ptr =
- &fe_values.shape_values(shape_function_data[shape_function].row_index, 0);
- for (unsigned int q_point=0; q_point<fe_values.n_quadrature_points; ++q_point)
- values[q_point] += value * *shape_value_ptr++;
- }
+ {
+ const double value = dof_values(shape_function);
+ if (value == 0.)
+ continue;
+
+ const double * shape_value_ptr =
+ &fe_values.shape_values(shape_function_data[shape_function].row_index, 0);
+ for (unsigned int q_point=0; q_point<fe_values.n_quadrature_points; ++q_point)
+ values[q_point] += value * *shape_value_ptr++;
+ }
}
void
Scalar<dim,spacedim>::
get_function_gradients (const InputVector &fe_function,
- std::vector<gradient_type> &gradients) const
+ std::vector<gradient_type> &gradients) const
{
typedef FEValuesBase<dim,spacedim> FVB;
Assert (fe_values.update_flags & update_gradients,
- typename FVB::ExcAccessToUninitializedField());
+ typename FVB::ExcAccessToUninitializedField());
Assert (gradients.size() == fe_values.n_quadrature_points,
- ExcDimensionMismatch(gradients.size(), fe_values.n_quadrature_points));
+ ExcDimensionMismatch(gradients.size(), fe_values.n_quadrature_points));
Assert (fe_values.present_cell.get() != 0,
- ExcMessage ("FEValues object is not reinit'ed to any cell"));
+ ExcMessage ("FEValues object is not reinit'ed to any cell"));
Assert (fe_function.size() == fe_values.present_cell->n_dofs_for_dof_handler(),
- ExcDimensionMismatch(fe_function.size(),
- fe_values.present_cell->n_dofs_for_dof_handler()));
+ ExcDimensionMismatch(fe_function.size(),
+ fe_values.present_cell->n_dofs_for_dof_handler()));
- // get function values of dofs
- // on this cell
+ // get function values of dofs
+ // on this cell
dealii::Vector<typename ValueType<InputVector>::type> dof_values (fe_values.dofs_per_cell);
fe_values.present_cell->get_interpolated_dof_values(fe_function, dof_values);
std::fill (gradients.begin(), gradients.end(), gradient_type());
for (unsigned int shape_function=0;
- shape_function<fe_values.fe->dofs_per_cell; ++shape_function)
+ shape_function<fe_values.fe->dofs_per_cell; ++shape_function)
if (shape_function_data[shape_function].is_nonzero_shape_function_component)
- {
- const double value = dof_values(shape_function);
- if (value == 0.)
- continue;
-
- const Tensor<1,spacedim> * shape_gradient_ptr =
- &fe_values.shape_gradients[shape_function_data[shape_function].
- row_index][0];
- for (unsigned int q_point=0; q_point<fe_values.n_quadrature_points; ++q_point)
- gradients[q_point] += value * *shape_gradient_ptr++;
- }
+ {
+ const double value = dof_values(shape_function);
+ if (value == 0.)
+ continue;
+
+ const Tensor<1,spacedim> * shape_gradient_ptr =
+ &fe_values.shape_gradients[shape_function_data[shape_function].
+ row_index][0];
+ for (unsigned int q_point=0; q_point<fe_values.n_quadrature_points; ++q_point)
+ gradients[q_point] += value * *shape_gradient_ptr++;
+ }
}
void
Scalar<dim,spacedim>::
get_function_hessians (const InputVector &fe_function,
- std::vector<hessian_type> &hessians) const
+ std::vector<hessian_type> &hessians) const
{
typedef FEValuesBase<dim,spacedim> FVB;
Assert (fe_values.update_flags & update_hessians,
- typename FVB::ExcAccessToUninitializedField());
+ typename FVB::ExcAccessToUninitializedField());
Assert (hessians.size() == fe_values.n_quadrature_points,
- ExcDimensionMismatch(hessians.size(), fe_values.n_quadrature_points));
+ ExcDimensionMismatch(hessians.size(), fe_values.n_quadrature_points));
Assert (fe_values.present_cell.get() != 0,
- ExcMessage ("FEValues object is not reinit'ed to any cell"));
+ ExcMessage ("FEValues object is not reinit'ed to any cell"));
Assert (fe_function.size() == fe_values.present_cell->n_dofs_for_dof_handler(),
- ExcDimensionMismatch(fe_function.size(),
- fe_values.present_cell->n_dofs_for_dof_handler()));
+ ExcDimensionMismatch(fe_function.size(),
+ fe_values.present_cell->n_dofs_for_dof_handler()));
- // get function values of dofs
- // on this cell
+ // get function values of dofs
+ // on this cell
dealii::Vector<typename ValueType<InputVector>::type> dof_values (fe_values.dofs_per_cell);
fe_values.present_cell->get_interpolated_dof_values(fe_function, dof_values);
std::fill (hessians.begin(), hessians.end(), hessian_type());
for (unsigned int shape_function=0;
- shape_function<fe_values.fe->dofs_per_cell; ++shape_function)
+ shape_function<fe_values.fe->dofs_per_cell; ++shape_function)
if (shape_function_data[shape_function].is_nonzero_shape_function_component)
- {
- const double value = dof_values(shape_function);
- if (value == 0.)
- continue;
-
- const Tensor<2,spacedim> * shape_hessian_ptr =
- &fe_values.shape_hessians[shape_function_data[shape_function].
- row_index][0];
- for (unsigned int q_point=0; q_point<fe_values.n_quadrature_points; ++q_point)
- hessians[q_point] += value * *shape_hessian_ptr++;
- }
+ {
+ const double value = dof_values(shape_function);
+ if (value == 0.)
+ continue;
+
+ const Tensor<2,spacedim> * shape_hessian_ptr =
+ &fe_values.shape_hessians[shape_function_data[shape_function].
+ row_index][0];
+ for (unsigned int q_point=0; q_point<fe_values.n_quadrature_points; ++q_point)
+ hessians[q_point] += value * *shape_hessian_ptr++;
+ }
}
void
Scalar<dim,spacedim>::
get_function_laplacians (const InputVector &fe_function,
- std::vector<value_type> &laplacians) const
+ std::vector<value_type> &laplacians) const
{
typedef FEValuesBase<dim,spacedim> FVB;
Assert (fe_values.update_flags & update_hessians,
- typename FVB::ExcAccessToUninitializedField());
+ typename FVB::ExcAccessToUninitializedField());
Assert (laplacians.size() == fe_values.n_quadrature_points,
- ExcDimensionMismatch(laplacians.size(), fe_values.n_quadrature_points));
+ ExcDimensionMismatch(laplacians.size(), fe_values.n_quadrature_points));
Assert (fe_values.present_cell.get() != 0,
- ExcMessage ("FEValues object is not reinit'ed to any cell"));
+ ExcMessage ("FEValues object is not reinit'ed to any cell"));
Assert (fe_function.size() == fe_values.present_cell->n_dofs_for_dof_handler(),
- ExcDimensionMismatch(fe_function.size(),
- fe_values.present_cell->n_dofs_for_dof_handler()));
+ ExcDimensionMismatch(fe_function.size(),
+ fe_values.present_cell->n_dofs_for_dof_handler()));
- // get function values of dofs
- // on this cell
+ // get function values of dofs
+ // on this cell
dealii::Vector<typename ValueType<InputVector>::type> dof_values (fe_values.dofs_per_cell);
fe_values.present_cell->get_interpolated_dof_values(fe_function, dof_values);
std::fill (laplacians.begin(), laplacians.end(), value_type());
for (unsigned int shape_function=0;
- shape_function<fe_values.fe->dofs_per_cell; ++shape_function)
+ shape_function<fe_values.fe->dofs_per_cell; ++shape_function)
if (shape_function_data[shape_function].is_nonzero_shape_function_component)
- {
- const double value = dof_values(shape_function);
- if (value == 0.)
- continue;
-
- const unsigned int row_index = shape_function_data[shape_function].row_index;
- for (unsigned int q_point=0; q_point<fe_values.n_quadrature_points; ++q_point)
- laplacians[q_point] +=
- value * trace(fe_values.shape_hessians[row_index][q_point]);
- }
+ {
+ const double value = dof_values(shape_function);
+ if (value == 0.)
+ continue;
+
+ const unsigned int row_index = shape_function_data[shape_function].row_index;
+ for (unsigned int q_point=0; q_point<fe_values.n_quadrature_points; ++q_point)
+ laplacians[q_point] +=
+ value * trace(fe_values.shape_hessians[row_index][q_point]);
+ }
}
void
Vector<dim,spacedim>::
get_function_values (const InputVector &fe_function,
- std::vector<value_type> &values) const
+ std::vector<value_type> &values) const
{
typedef FEValuesBase<dim,spacedim> FVB;
Assert (fe_values.update_flags & update_values,
- typename FVB::ExcAccessToUninitializedField());
+ typename FVB::ExcAccessToUninitializedField());
Assert (values.size() == fe_values.n_quadrature_points,
- ExcDimensionMismatch(values.size(), fe_values.n_quadrature_points));
+ ExcDimensionMismatch(values.size(), fe_values.n_quadrature_points));
Assert (fe_values.present_cell.get() != 0,
- ExcMessage ("FEValues object is not reinit'ed to any cell"));
+ ExcMessage ("FEValues object is not reinit'ed to any cell"));
Assert (fe_function.size() == fe_values.present_cell->n_dofs_for_dof_handler(),
- ExcDimensionMismatch(fe_function.size(),
- fe_values.present_cell->n_dofs_for_dof_handler()));
+ ExcDimensionMismatch(fe_function.size(),
+ fe_values.present_cell->n_dofs_for_dof_handler()));
- // get function values of dofs
- // on this cell
+ // get function values of dofs
+ // on this cell
dealii::Vector<typename ValueType<InputVector>::type> dof_values (fe_values.dofs_per_cell);
fe_values.present_cell->get_interpolated_dof_values(fe_function, dof_values);
std::fill (values.begin(), values.end(), value_type());
for (unsigned int shape_function=0;
- shape_function<fe_values.fe->dofs_per_cell; ++shape_function)
+ shape_function<fe_values.fe->dofs_per_cell; ++shape_function)
{
- const int snc = shape_function_data[shape_function].single_nonzero_component;
-
- if (snc == -2)
- // shape function is zero for the
- // selected components
- continue;
-
- const double value = dof_values(shape_function);
- if (value == 0.)
- continue;
-
- if (snc != -1)
- {
- const unsigned int comp =
- shape_function_data[shape_function].single_nonzero_component_index;
- const double * shape_value_ptr = &fe_values.shape_values(snc,0);
- for (unsigned int q_point=0; q_point<fe_values.n_quadrature_points; ++q_point)
- values[q_point][comp] += value * *shape_value_ptr++;
- }
- else
- for (unsigned int d=0; d<dim; ++d)
- if (shape_function_data[shape_function].is_nonzero_shape_function_component[d])
- {
- const double * shape_value_ptr =
- &fe_values.shape_values(shape_function_data[shape_function].row_index[d],0);
- for (unsigned int q_point=0; q_point<fe_values.n_quadrature_points; ++q_point)
- values[q_point][d] += value * *shape_value_ptr++;
- }
+ const int snc = shape_function_data[shape_function].single_nonzero_component;
+
+ if (snc == -2)
+ // shape function is zero for the
+ // selected components
+ continue;
+
+ const double value = dof_values(shape_function);
+ if (value == 0.)
+ continue;
+
+ if (snc != -1)
+ {
+ const unsigned int comp =
+ shape_function_data[shape_function].single_nonzero_component_index;
+ const double * shape_value_ptr = &fe_values.shape_values(snc,0);
+ for (unsigned int q_point=0; q_point<fe_values.n_quadrature_points; ++q_point)
+ values[q_point][comp] += value * *shape_value_ptr++;
+ }
+ else
+ for (unsigned int d=0; d<dim; ++d)
+ if (shape_function_data[shape_function].is_nonzero_shape_function_component[d])
+ {
+ const double * shape_value_ptr =
+ &fe_values.shape_values(shape_function_data[shape_function].row_index[d],0);
+ for (unsigned int q_point=0; q_point<fe_values.n_quadrature_points; ++q_point)
+ values[q_point][d] += value * *shape_value_ptr++;
+ }
}
}
void
Vector<dim,spacedim>::
get_function_gradients (const InputVector &fe_function,
- std::vector<gradient_type> &gradients) const
+ std::vector<gradient_type> &gradients) const
{
typedef FEValuesBase<dim,spacedim> FVB;
Assert (fe_values.update_flags & update_gradients,
- typename FVB::ExcAccessToUninitializedField());
+ typename FVB::ExcAccessToUninitializedField());
Assert (gradients.size() == fe_values.n_quadrature_points,
- ExcDimensionMismatch(gradients.size(), fe_values.n_quadrature_points));
+ ExcDimensionMismatch(gradients.size(), fe_values.n_quadrature_points));
Assert (fe_values.present_cell.get() != 0,
- ExcMessage ("FEValues object is not reinit'ed to any cell"));
+ ExcMessage ("FEValues object is not reinit'ed to any cell"));
Assert (fe_function.size() == fe_values.present_cell->n_dofs_for_dof_handler(),
- ExcDimensionMismatch(fe_function.size(),
- fe_values.present_cell->n_dofs_for_dof_handler()));
+ ExcDimensionMismatch(fe_function.size(),
+ fe_values.present_cell->n_dofs_for_dof_handler()));
- // get function values of dofs
- // on this cell
+ // get function values of dofs
+ // on this cell
dealii::Vector<typename ValueType<InputVector>::type> dof_values (fe_values.dofs_per_cell);
fe_values.present_cell->get_interpolated_dof_values(fe_function, dof_values);
std::fill (gradients.begin(), gradients.end(), gradient_type());
for (unsigned int shape_function=0;
- shape_function<fe_values.fe->dofs_per_cell; ++shape_function)
+ shape_function<fe_values.fe->dofs_per_cell; ++shape_function)
{
- const int snc = shape_function_data[shape_function].single_nonzero_component;
-
- if (snc == -2)
- // shape function is zero for the
- // selected components
- continue;
-
- const double value = dof_values(shape_function);
- if (value == 0.)
- continue;
-
- if (snc != -1)
- {
- const unsigned int comp =
- shape_function_data[shape_function].single_nonzero_component_index;
- const Tensor<1,spacedim> * shape_gradient_ptr =
- &fe_values.shape_gradients[snc][0];
- for (unsigned int q_point=0; q_point<fe_values.n_quadrature_points; ++q_point)
- gradients[q_point][comp] += value * *shape_gradient_ptr++;
- }
- else
- for (unsigned int d=0; d<dim; ++d)
- if (shape_function_data[shape_function].is_nonzero_shape_function_component[d])
- {
- const Tensor<1,spacedim> * shape_gradient_ptr =
- &fe_values.shape_gradients[shape_function_data[shape_function].
- row_index[d]][0];
- for (unsigned int q_point=0; q_point<fe_values.n_quadrature_points; ++q_point)
- gradients[q_point][d] += value * *shape_gradient_ptr++;
- }
+ const int snc = shape_function_data[shape_function].single_nonzero_component;
+
+ if (snc == -2)
+ // shape function is zero for the
+ // selected components
+ continue;
+
+ const double value = dof_values(shape_function);
+ if (value == 0.)
+ continue;
+
+ if (snc != -1)
+ {
+ const unsigned int comp =
+ shape_function_data[shape_function].single_nonzero_component_index;
+ const Tensor<1,spacedim> * shape_gradient_ptr =
+ &fe_values.shape_gradients[snc][0];
+ for (unsigned int q_point=0; q_point<fe_values.n_quadrature_points; ++q_point)
+ gradients[q_point][comp] += value * *shape_gradient_ptr++;
+ }
+ else
+ for (unsigned int d=0; d<dim; ++d)
+ if (shape_function_data[shape_function].is_nonzero_shape_function_component[d])
+ {
+ const Tensor<1,spacedim> * shape_gradient_ptr =
+ &fe_values.shape_gradients[shape_function_data[shape_function].
+ row_index[d]][0];
+ for (unsigned int q_point=0; q_point<fe_values.n_quadrature_points; ++q_point)
+ gradients[q_point][d] += value * *shape_gradient_ptr++;
+ }
}
}
void
Vector<dim,spacedim>::
get_function_symmetric_gradients (const InputVector &fe_function,
- std::vector<symmetric_gradient_type> &symmetric_gradients) const
+ std::vector<symmetric_gradient_type> &symmetric_gradients) const
{
typedef FEValuesBase<dim,spacedim> FVB;
Assert (fe_values.update_flags & update_gradients,
- typename FVB::ExcAccessToUninitializedField());
+ typename FVB::ExcAccessToUninitializedField());
Assert (symmetric_gradients.size() == fe_values.n_quadrature_points,
- ExcDimensionMismatch(symmetric_gradients.size(), fe_values.n_quadrature_points));
+ ExcDimensionMismatch(symmetric_gradients.size(), fe_values.n_quadrature_points));
Assert (fe_values.present_cell.get() != 0,
- ExcMessage ("FEValues object is not reinit'ed to any cell"));
+ ExcMessage ("FEValues object is not reinit'ed to any cell"));
Assert (fe_function.size() == fe_values.present_cell->n_dofs_for_dof_handler(),
- ExcDimensionMismatch(fe_function.size(),
- fe_values.present_cell->n_dofs_for_dof_handler()));
+ ExcDimensionMismatch(fe_function.size(),
+ fe_values.present_cell->n_dofs_for_dof_handler()));
- // get function values of dofs
- // on this cell
+ // get function values of dofs
+ // on this cell
dealii::Vector<typename ValueType<InputVector>::type> dof_values (fe_values.dofs_per_cell);
fe_values.present_cell->get_interpolated_dof_values(fe_function, dof_values);
std::fill (symmetric_gradients.begin(), symmetric_gradients.end(),
- symmetric_gradient_type());
+ symmetric_gradient_type());
for (unsigned int shape_function=0;
- shape_function<fe_values.fe->dofs_per_cell; ++shape_function)
+ shape_function<fe_values.fe->dofs_per_cell; ++shape_function)
{
- const int snc = shape_function_data[shape_function].single_nonzero_component;
-
- if (snc == -2)
- // shape function is zero for the
- // selected components
- continue;
-
- const double value = dof_values(shape_function);
- if (value == 0.)
- continue;
-
- if (snc != -1)
- {
- const unsigned int comp =
- shape_function_data[shape_function].single_nonzero_component_index;
- const Tensor<1,spacedim> * shape_gradient_ptr =
- &fe_values.shape_gradients[snc][0];
- for (unsigned int q_point=0; q_point<fe_values.n_quadrature_points; ++q_point)
- symmetric_gradients[q_point]
- += value * symmetrize_single_row (comp,*shape_gradient_ptr++);
- }
- else
- for (unsigned int q_point=0; q_point<fe_values.n_quadrature_points; ++q_point)
- {
- gradient_type grad;
- for (unsigned int d=0; d<dim; ++d)
- if (shape_function_data[shape_function].is_nonzero_shape_function_component[d])
- grad[d] = value *
- fe_values.shape_gradients[shape_function_data[shape_function].row_index[d]][q_point];
- symmetric_gradients[q_point] += symmetrize(grad);
- }
+ const int snc = shape_function_data[shape_function].single_nonzero_component;
+
+ if (snc == -2)
+ // shape function is zero for the
+ // selected components
+ continue;
+
+ const double value = dof_values(shape_function);
+ if (value == 0.)
+ continue;
+
+ if (snc != -1)
+ {
+ const unsigned int comp =
+ shape_function_data[shape_function].single_nonzero_component_index;
+ const Tensor<1,spacedim> * shape_gradient_ptr =
+ &fe_values.shape_gradients[snc][0];
+ for (unsigned int q_point=0; q_point<fe_values.n_quadrature_points; ++q_point)
+ symmetric_gradients[q_point]
+ += value * symmetrize_single_row (comp,*shape_gradient_ptr++);
+ }
+ else
+ for (unsigned int q_point=0; q_point<fe_values.n_quadrature_points; ++q_point)
+ {
+ gradient_type grad;
+ for (unsigned int d=0; d<dim; ++d)
+ if (shape_function_data[shape_function].is_nonzero_shape_function_component[d])
+ grad[d] = value *
+ fe_values.shape_gradients[shape_function_data[shape_function].row_index[d]][q_point];
+ symmetric_gradients[q_point] += symmetrize(grad);
+ }
}
}
void
Vector<dim,spacedim>::
get_function_divergences (const InputVector &fe_function,
- std::vector<divergence_type> &divergences) const
+ std::vector<divergence_type> &divergences) const
{
typedef FEValuesBase<dim,spacedim> FVB;
Assert (fe_values.update_flags & update_gradients,
- typename FVB::ExcAccessToUninitializedField());
+ typename FVB::ExcAccessToUninitializedField());
Assert (divergences.size() == fe_values.n_quadrature_points,
- ExcDimensionMismatch(divergences.size(), fe_values.n_quadrature_points));
+ ExcDimensionMismatch(divergences.size(), fe_values.n_quadrature_points));
Assert (fe_values.present_cell.get() != 0,
- ExcMessage ("FEValues object is not reinit'ed to any cell"));
+ ExcMessage ("FEValues object is not reinit'ed to any cell"));
Assert (fe_function.size() == fe_values.present_cell->n_dofs_for_dof_handler(),
- ExcDimensionMismatch(fe_function.size(),
- fe_values.present_cell->n_dofs_for_dof_handler()));
+ ExcDimensionMismatch(fe_function.size(),
+ fe_values.present_cell->n_dofs_for_dof_handler()));
- // get function values of dofs
- // on this cell
+ // get function values of dofs
+ // on this cell
dealii::Vector<typename ValueType<InputVector>::type> dof_values (fe_values.dofs_per_cell);
fe_values.present_cell->get_interpolated_dof_values(fe_function, dof_values);
std::fill (divergences.begin(), divergences.end(), divergence_type());
for (unsigned int shape_function=0;
- shape_function<fe_values.fe->dofs_per_cell; ++shape_function)
+ shape_function<fe_values.fe->dofs_per_cell; ++shape_function)
{
- const int snc = shape_function_data[shape_function].single_nonzero_component;
-
- if (snc == -2)
- // shape function is zero for the
- // selected components
- continue;
-
- const double value = dof_values(shape_function);
- if (value == 0.)
- continue;
-
- if (snc != -1)
- {
- const unsigned int comp =
- shape_function_data[shape_function].single_nonzero_component_index;
- const Tensor<1,spacedim> * shape_gradient_ptr =
- &fe_values.shape_gradients[snc][0];
- for (unsigned int q_point=0; q_point<fe_values.n_quadrature_points; ++q_point)
- divergences[q_point] += value * (*shape_gradient_ptr++)[comp];
- }
- else
- for (unsigned int d=0; d<dim; ++d)
- if (shape_function_data[shape_function].is_nonzero_shape_function_component[d])
- {
- const Tensor<1,spacedim> * shape_gradient_ptr =
- &fe_values.shape_gradients[shape_function_data[shape_function].
- row_index[d]][0];
- for (unsigned int q_point=0; q_point<fe_values.n_quadrature_points; ++q_point)
- divergences[q_point] += value * (*shape_gradient_ptr++)[d];
- }
+ const int snc = shape_function_data[shape_function].single_nonzero_component;
+
+ if (snc == -2)
+ // shape function is zero for the
+ // selected components
+ continue;
+
+ const double value = dof_values(shape_function);
+ if (value == 0.)
+ continue;
+
+ if (snc != -1)
+ {
+ const unsigned int comp =
+ shape_function_data[shape_function].single_nonzero_component_index;
+ const Tensor<1,spacedim> * shape_gradient_ptr =
+ &fe_values.shape_gradients[snc][0];
+ for (unsigned int q_point=0; q_point<fe_values.n_quadrature_points; ++q_point)
+ divergences[q_point] += value * (*shape_gradient_ptr++)[comp];
+ }
+ else
+ for (unsigned int d=0; d<dim; ++d)
+ if (shape_function_data[shape_function].is_nonzero_shape_function_component[d])
+ {
+ const Tensor<1,spacedim> * shape_gradient_ptr =
+ &fe_values.shape_gradients[shape_function_data[shape_function].
+ row_index[d]][0];
+ for (unsigned int q_point=0; q_point<fe_values.n_quadrature_points; ++q_point)
+ divergences[q_point] += value * (*shape_gradient_ptr++)[d];
+ }
}
}
void
Vector<dim,spacedim>::
get_function_curls (const InputVector &fe_function,
- std::vector<curl_type> &curls) const
+ std::vector<curl_type> &curls) const
{
typedef FEValuesBase<dim,spacedim> FVB;
Assert (fe_values.update_flags & update_gradients,
- typename FVB::ExcAccessToUninitializedField());
+ typename FVB::ExcAccessToUninitializedField());
Assert (curls.size() == fe_values.n_quadrature_points,
- ExcDimensionMismatch (curls.size(), fe_values.n_quadrature_points));
+ ExcDimensionMismatch (curls.size(), fe_values.n_quadrature_points));
Assert (fe_values.present_cell.get () != 0,
- ExcMessage ("FEValues object is not reinited to any cell"));
+ ExcMessage ("FEValues object is not reinited to any cell"));
Assert (fe_function.size () == fe_values.present_cell->n_dofs_for_dof_handler (),
- ExcDimensionMismatch (fe_function.size (), fe_values.present_cell->n_dofs_for_dof_handler ()));
- // get function values of dofs on this cell
+ ExcDimensionMismatch (fe_function.size (), fe_values.present_cell->n_dofs_for_dof_handler ()));
+ // get function values of dofs on this cell
dealii::Vector<typename ValueType<InputVector>::type> dof_values (fe_values.dofs_per_cell);
fe_values.present_cell->get_interpolated_dof_values (fe_function, dof_values);
switch (dim)
{
- case 1:
- {
- Assert (false, ExcMessage("Computing the curl in 1d is not a useful operation"));
- break;
- }
+ case 1:
+ {
+ Assert (false, ExcMessage("Computing the curl in 1d is not a useful operation"));
+ break;
+ }
case 2:
- {
- for (unsigned int shape_function = 0;
- shape_function < fe_values.fe->dofs_per_cell; ++shape_function)
- {
+ {
+ for (unsigned int shape_function = 0;
+ shape_function < fe_values.fe->dofs_per_cell; ++shape_function)
+ {
const int snc = shape_function_data[shape_function].single_nonzero_component;
if (snc == -2)
- // shape function is zero for the selected components
- continue;
+ // shape function is zero for the selected components
+ continue;
const double value = dof_values (shape_function);
if (value == 0.)
- continue;
+ continue;
if (snc != -1)
- {
- const Tensor<1, spacedim> * shape_gradient_ptr = &fe_values.shape_gradients[snc][0];
-
- switch (shape_function_data[shape_function].single_nonzero_component_index)
- {
- case 0:
- {
- for (unsigned int q_point = 0;
- q_point < fe_values.n_quadrature_points; ++q_point)
+ {
+ const Tensor<1, spacedim> * shape_gradient_ptr = &fe_values.shape_gradients[snc][0];
+
+ switch (shape_function_data[shape_function].single_nonzero_component_index)
+ {
+ case 0:
+ {
+ for (unsigned int q_point = 0;
+ q_point < fe_values.n_quadrature_points; ++q_point)
curls[q_point][0] -= value * (*shape_gradient_ptr++)[1];
- break;
- }
+ break;
+ }
- default:
- for (unsigned int q_point = 0;
- q_point < fe_values.n_quadrature_points; ++q_point)
- curls[q_point][0] += value * (*shape_gradient_ptr)[0];
- }
- }
+ default:
+ for (unsigned int q_point = 0;
+ q_point < fe_values.n_quadrature_points; ++q_point)
+ curls[q_point][0] += value * (*shape_gradient_ptr)[0];
+ }
+ }
else
- {
- if (shape_function_data[shape_function].is_nonzero_shape_function_component[0])
- {
- const Tensor<1,spacedim> * shape_gradient_ptr =
- &fe_values.shape_gradients[shape_function_data[shape_function].row_index[0]][0];
-
- for (unsigned int q_point = 0; q_point < fe_values.n_quadrature_points; ++q_point)
- curls[q_point][0] -= value * (*shape_gradient_ptr++)[1];
- }
-
- if (shape_function_data[shape_function].is_nonzero_shape_function_component[1])
- {
- const Tensor<1,spacedim> * shape_gradient_ptr =
- &fe_values.shape_gradients[shape_function_data[shape_function].row_index[1]][0];
-
- for (unsigned int q_point = 0; q_point < fe_values.n_quadrature_points; ++q_point)
- curls[q_point][0] += value * (*shape_gradient_ptr++)[0];
- }
- }
- }
- break;
+ {
+ if (shape_function_data[shape_function].is_nonzero_shape_function_component[0])
+ {
+ const Tensor<1,spacedim> * shape_gradient_ptr =
+ &fe_values.shape_gradients[shape_function_data[shape_function].row_index[0]][0];
+
+ for (unsigned int q_point = 0; q_point < fe_values.n_quadrature_points; ++q_point)
+ curls[q_point][0] -= value * (*shape_gradient_ptr++)[1];
+ }
+
+ if (shape_function_data[shape_function].is_nonzero_shape_function_component[1])
+ {
+ const Tensor<1,spacedim> * shape_gradient_ptr =
+ &fe_values.shape_gradients[shape_function_data[shape_function].row_index[1]][0];
+
+ for (unsigned int q_point = 0; q_point < fe_values.n_quadrature_points; ++q_point)
+ curls[q_point][0] += value * (*shape_gradient_ptr++)[0];
+ }
+ }
+ }
+ break;
}
case 3:
- {
- for (unsigned int shape_function = 0;
- shape_function < fe_values.fe->dofs_per_cell; ++shape_function)
- {
+ {
+ for (unsigned int shape_function = 0;
+ shape_function < fe_values.fe->dofs_per_cell; ++shape_function)
+ {
const int snc = shape_function_data[shape_function].single_nonzero_component;
if (snc == -2)
- // shape function is zero for the selected components
- continue;
+ // shape function is zero for the selected components
+ continue;
const double value = dof_values (shape_function);
if (value == 0.)
- continue;
+ continue;
if (snc != -1)
- {
- const Tensor<1, spacedim> * shape_gradient_ptr = &fe_values.shape_gradients[snc][0];
-
- switch (shape_function_data[shape_function].single_nonzero_component_index)
- {
- case 0:
- {
- for (unsigned int q_point = 0;
- q_point < fe_values.n_quadrature_points; ++q_point)
- {
- curls[q_point][1] += value * (*shape_gradient_ptr)[2];
- curls[q_point][2] -= value * (*shape_gradient_ptr++)[1];
- }
-
- break;
- }
-
- case 1:
- {
- for (unsigned int q_point = 0;
- q_point < fe_values.n_quadrature_points; ++q_point)
- {
- curls[q_point][0] -= value * (*shape_gradient_ptr)[2];
- curls[q_point][2] += value * (*shape_gradient_ptr++)[0];
- }
-
- break;
- }
-
- default:
- for (unsigned int q_point = 0;
- q_point < fe_values.n_quadrature_points; ++q_point)
- {
- curls[q_point][0] += value * (*shape_gradient_ptr)[1];
- curls[q_point][1] -= value * (*shape_gradient_ptr++)[0];
- }
- }
- }
+ {
+ const Tensor<1, spacedim> * shape_gradient_ptr = &fe_values.shape_gradients[snc][0];
+
+ switch (shape_function_data[shape_function].single_nonzero_component_index)
+ {
+ case 0:
+ {
+ for (unsigned int q_point = 0;
+ q_point < fe_values.n_quadrature_points; ++q_point)
+ {
+ curls[q_point][1] += value * (*shape_gradient_ptr)[2];
+ curls[q_point][2] -= value * (*shape_gradient_ptr++)[1];
+ }
+
+ break;
+ }
+
+ case 1:
+ {
+ for (unsigned int q_point = 0;
+ q_point < fe_values.n_quadrature_points; ++q_point)
+ {
+ curls[q_point][0] -= value * (*shape_gradient_ptr)[2];
+ curls[q_point][2] += value * (*shape_gradient_ptr++)[0];
+ }
+
+ break;
+ }
+
+ default:
+ for (unsigned int q_point = 0;
+ q_point < fe_values.n_quadrature_points; ++q_point)
+ {
+ curls[q_point][0] += value * (*shape_gradient_ptr)[1];
+ curls[q_point][1] -= value * (*shape_gradient_ptr++)[0];
+ }
+ }
+ }
else
- {
- if (shape_function_data[shape_function].is_nonzero_shape_function_component[0])
- {
- const Tensor<1,spacedim> * shape_gradient_ptr =
- &fe_values.shape_gradients[shape_function_data[shape_function].row_index[0]][0];
-
- for (unsigned int q_point = 0; q_point < fe_values.n_quadrature_points; ++q_point)
- {
- curls[q_point][1] += value * (*shape_gradient_ptr)[2];
- curls[q_point][2] -= value * (*shape_gradient_ptr++)[1];
- }
- }
-
- if (shape_function_data[shape_function].is_nonzero_shape_function_component[1])
- {
- const Tensor<1,spacedim> * shape_gradient_ptr =
- &fe_values.shape_gradients[shape_function_data[shape_function].row_index[1]][0];
-
- for (unsigned int q_point = 0; q_point < fe_values.n_quadrature_points; ++q_point)
- {
- curls[q_point][0] -= value * (*shape_gradient_ptr)[2];
- curls[q_point][2] += value * (*shape_gradient_ptr++)[0];
- }
- }
-
- if (shape_function_data[shape_function].is_nonzero_shape_function_component[2])
- {
- const Tensor<1,spacedim> * shape_gradient_ptr =
- &fe_values.shape_gradients[shape_function_data[shape_function].row_index[2]][0];
-
- for (unsigned int q_point = 0; q_point < fe_values.n_quadrature_points; ++q_point)
- {
- curls[q_point][0] += value * (*shape_gradient_ptr)[1];
- curls[q_point][1] -= value * (*shape_gradient_ptr++)[0];
- }
- }
- }
- }
+ {
+ if (shape_function_data[shape_function].is_nonzero_shape_function_component[0])
+ {
+ const Tensor<1,spacedim> * shape_gradient_ptr =
+ &fe_values.shape_gradients[shape_function_data[shape_function].row_index[0]][0];
+
+ for (unsigned int q_point = 0; q_point < fe_values.n_quadrature_points; ++q_point)
+ {
+ curls[q_point][1] += value * (*shape_gradient_ptr)[2];
+ curls[q_point][2] -= value * (*shape_gradient_ptr++)[1];
+ }
+ }
+
+ if (shape_function_data[shape_function].is_nonzero_shape_function_component[1])
+ {
+ const Tensor<1,spacedim> * shape_gradient_ptr =
+ &fe_values.shape_gradients[shape_function_data[shape_function].row_index[1]][0];
+
+ for (unsigned int q_point = 0; q_point < fe_values.n_quadrature_points; ++q_point)
+ {
+ curls[q_point][0] -= value * (*shape_gradient_ptr)[2];
+ curls[q_point][2] += value * (*shape_gradient_ptr++)[0];
+ }
+ }
+
+ if (shape_function_data[shape_function].is_nonzero_shape_function_component[2])
+ {
+ const Tensor<1,spacedim> * shape_gradient_ptr =
+ &fe_values.shape_gradients[shape_function_data[shape_function].row_index[2]][0];
+
+ for (unsigned int q_point = 0; q_point < fe_values.n_quadrature_points; ++q_point)
+ {
+ curls[q_point][0] += value * (*shape_gradient_ptr)[1];
+ curls[q_point][1] -= value * (*shape_gradient_ptr++)[0];
+ }
+ }
+ }
+ }
}
}
}
void
Vector<dim,spacedim>::
get_function_hessians (const InputVector &fe_function,
- std::vector<hessian_type> &hessians) const
+ std::vector<hessian_type> &hessians) const
{
typedef FEValuesBase<dim,spacedim> FVB;
Assert (fe_values.update_flags & update_hessians,
- typename FVB::ExcAccessToUninitializedField());
+ typename FVB::ExcAccessToUninitializedField());
Assert (hessians.size() == fe_values.n_quadrature_points,
- ExcDimensionMismatch(hessians.size(), fe_values.n_quadrature_points));
+ ExcDimensionMismatch(hessians.size(), fe_values.n_quadrature_points));
Assert (fe_values.present_cell.get() != 0,
- ExcMessage ("FEValues object is not reinit'ed to any cell"));
+ ExcMessage ("FEValues object is not reinit'ed to any cell"));
Assert (fe_function.size() == fe_values.present_cell->n_dofs_for_dof_handler(),
- ExcDimensionMismatch(fe_function.size(),
- fe_values.present_cell->n_dofs_for_dof_handler()));
+ ExcDimensionMismatch(fe_function.size(),
+ fe_values.present_cell->n_dofs_for_dof_handler()));
- // get function values of dofs
- // on this cell
+ // get function values of dofs
+ // on this cell
dealii::Vector<typename ValueType<InputVector>::type> dof_values (fe_values.dofs_per_cell);
fe_values.present_cell->get_interpolated_dof_values(fe_function, dof_values);
std::fill (hessians.begin(), hessians.end(), hessian_type());
for (unsigned int shape_function=0;
- shape_function<fe_values.fe->dofs_per_cell; ++shape_function)
+ shape_function<fe_values.fe->dofs_per_cell; ++shape_function)
{
- const int snc = shape_function_data[shape_function].single_nonzero_component;
-
- if (snc == -2)
- // shape function is zero for the
- // selected components
- continue;
-
- const double value = dof_values(shape_function);
- if (value == 0.)
- continue;
-
- if (snc != -1)
- {
- const unsigned int comp =
- shape_function_data[shape_function].single_nonzero_component_index;
- const Tensor<2,spacedim> * shape_hessian_ptr =
- &fe_values.shape_hessians[snc][0];
- for (unsigned int q_point=0; q_point<fe_values.n_quadrature_points; ++q_point)
- hessians[q_point][comp] += value * *shape_hessian_ptr++;
- }
- else
- for (unsigned int d=0; d<dim; ++d)
- if (shape_function_data[shape_function].is_nonzero_shape_function_component[d])
- {
- const Tensor<2,spacedim> * shape_hessian_ptr =
- &fe_values.shape_hessians[shape_function_data[shape_function].
- row_index[d]][0];
- for (unsigned int q_point=0; q_point<fe_values.n_quadrature_points; ++q_point)
- hessians[q_point][d] += value * *shape_hessian_ptr++;
- }
+ const int snc = shape_function_data[shape_function].single_nonzero_component;
+
+ if (snc == -2)
+ // shape function is zero for the
+ // selected components
+ continue;
+
+ const double value = dof_values(shape_function);
+ if (value == 0.)
+ continue;
+
+ if (snc != -1)
+ {
+ const unsigned int comp =
+ shape_function_data[shape_function].single_nonzero_component_index;
+ const Tensor<2,spacedim> * shape_hessian_ptr =
+ &fe_values.shape_hessians[snc][0];
+ for (unsigned int q_point=0; q_point<fe_values.n_quadrature_points; ++q_point)
+ hessians[q_point][comp] += value * *shape_hessian_ptr++;
+ }
+ else
+ for (unsigned int d=0; d<dim; ++d)
+ if (shape_function_data[shape_function].is_nonzero_shape_function_component[d])
+ {
+ const Tensor<2,spacedim> * shape_hessian_ptr =
+ &fe_values.shape_hessians[shape_function_data[shape_function].
+ row_index[d]][0];
+ for (unsigned int q_point=0; q_point<fe_values.n_quadrature_points; ++q_point)
+ hessians[q_point][d] += value * *shape_hessian_ptr++;
+ }
}
}
void
Vector<dim,spacedim>::
get_function_laplacians (const InputVector &fe_function,
- std::vector<value_type> &laplacians) const
+ std::vector<value_type> &laplacians) const
{
typedef FEValuesBase<dim,spacedim> FVB;
Assert (fe_values.update_flags & update_hessians,
- typename FVB::ExcAccessToUninitializedField());
+ typename FVB::ExcAccessToUninitializedField());
Assert (laplacians.size() == fe_values.n_quadrature_points,
- ExcDimensionMismatch(laplacians.size(), fe_values.n_quadrature_points));
+ ExcDimensionMismatch(laplacians.size(), fe_values.n_quadrature_points));
Assert (fe_values.present_cell.get() != 0,
- ExcMessage ("FEValues object is not reinit'ed to any cell"));
+ ExcMessage ("FEValues object is not reinit'ed to any cell"));
Assert (fe_function.size() == fe_values.present_cell->n_dofs_for_dof_handler(),
- ExcDimensionMismatch(fe_function.size(),
- fe_values.present_cell->n_dofs_for_dof_handler()));
+ ExcDimensionMismatch(fe_function.size(),
+ fe_values.present_cell->n_dofs_for_dof_handler()));
- // get function values of dofs
- // on this cell
+ // get function values of dofs
+ // on this cell
dealii::Vector<typename ValueType<InputVector>::type> dof_values (fe_values.dofs_per_cell);
fe_values.present_cell->get_interpolated_dof_values(fe_function, dof_values);
std::fill (laplacians.begin(), laplacians.end(), value_type());
for (unsigned int shape_function=0;
- shape_function<fe_values.fe->dofs_per_cell; ++shape_function)
+ shape_function<fe_values.fe->dofs_per_cell; ++shape_function)
{
- const int snc = shape_function_data[shape_function].single_nonzero_component;
-
- if (snc == -2)
- // shape function is zero for the
- // selected components
- continue;
-
- const double value = dof_values(shape_function);
- if (value == 0.)
- continue;
-
- if (snc != -1)
- {
- const unsigned int comp =
- shape_function_data[shape_function].single_nonzero_component_index;
- const Tensor<2,spacedim> * shape_hessian_ptr =
- &fe_values.shape_hessians[snc][0];
- for (unsigned int q_point=0; q_point<fe_values.n_quadrature_points; ++q_point)
- laplacians[q_point][comp] += value * trace(*shape_hessian_ptr++);
- }
- else
- for (unsigned int d=0; d<dim; ++d)
- if (shape_function_data[shape_function].is_nonzero_shape_function_component[d])
- {
- const Tensor<2,spacedim> * shape_hessian_ptr =
- &fe_values.shape_hessians[shape_function_data[shape_function].
- row_index[d]][0];
- for (unsigned int q_point=0; q_point<fe_values.n_quadrature_points; ++q_point)
- laplacians[q_point][d] += value * trace(*shape_hessian_ptr++);
- }
+ const int snc = shape_function_data[shape_function].single_nonzero_component;
+
+ if (snc == -2)
+ // shape function is zero for the
+ // selected components
+ continue;
+
+ const double value = dof_values(shape_function);
+ if (value == 0.)
+ continue;
+
+ if (snc != -1)
+ {
+ const unsigned int comp =
+ shape_function_data[shape_function].single_nonzero_component_index;
+ const Tensor<2,spacedim> * shape_hessian_ptr =
+ &fe_values.shape_hessians[snc][0];
+ for (unsigned int q_point=0; q_point<fe_values.n_quadrature_points; ++q_point)
+ laplacians[q_point][comp] += value * trace(*shape_hessian_ptr++);
+ }
+ else
+ for (unsigned int d=0; d<dim; ++d)
+ if (shape_function_data[shape_function].is_nonzero_shape_function_component[d])
+ {
+ const Tensor<2,spacedim> * shape_hessian_ptr =
+ &fe_values.shape_hessians[shape_function_data[shape_function].
+ row_index[d]][0];
+ for (unsigned int q_point=0; q_point<fe_values.n_quadrature_points; ++q_point)
+ laplacians[q_point][d] += value * trace(*shape_hessian_ptr++);
+ }
}
}
void
SymmetricTensor<2, dim, spacedim>::
get_function_values(const InputVector &fe_function,
- std::vector<value_type> &values) const
+ std::vector<value_type> &values) const
{
typedef FEValuesBase<dim, spacedim> FVB;
Assert(fe_values.update_flags & update_values,
- typename FVB::ExcAccessToUninitializedField());
+ typename FVB::ExcAccessToUninitializedField());
Assert(values.size() == fe_values.n_quadrature_points,
- ExcDimensionMismatch(values.size(), fe_values.n_quadrature_points));
+ ExcDimensionMismatch(values.size(), fe_values.n_quadrature_points));
Assert(fe_values.present_cell.get() != 0,
- ExcMessage("FEValues object is not reinit'ed to any cell"));
+ ExcMessage("FEValues object is not reinit'ed to any cell"));
Assert(fe_function.size() == fe_values.present_cell->n_dofs_for_dof_handler(),
- ExcDimensionMismatch(fe_function.size(),
- fe_values.present_cell->n_dofs_for_dof_handler()));
+ ExcDimensionMismatch(fe_function.size(),
+ fe_values.present_cell->n_dofs_for_dof_handler()));
- // get function values of dofs
- // on this cell
+ // get function values of dofs
+ // on this cell
dealii::Vector<typename ValueType<InputVector>::type > dof_values(fe_values.dofs_per_cell);
fe_values.present_cell->get_interpolated_dof_values(fe_function, dof_values);
std::fill(values.begin(), values.end(), value_type());
for (unsigned int shape_function = 0;
- shape_function < fe_values.fe->dofs_per_cell; ++shape_function)
+ shape_function < fe_values.fe->dofs_per_cell; ++shape_function)
{
- const int snc = shape_function_data[shape_function].single_nonzero_component;
-
- if (snc == -2)
- // shape function is zero for the
- // selected components
- continue;
-
- const double value = dof_values(shape_function);
- if (value == 0.)
- continue;
-
- if (snc != -1)
- {
- const unsigned int comp =
- shape_function_data[shape_function].single_nonzero_component_index;
- const double * shape_value_ptr = &fe_values.shape_values(snc, 0);
- for (unsigned int q_point = 0; q_point < fe_values.n_quadrature_points; ++q_point)
- values[q_point][value_type::unrolled_to_component_indices(comp)]
- += value * *shape_value_ptr++;
- }
- else
- {
- for (unsigned int d = 0; d < value_type::n_independent_components; ++d)
- if (shape_function_data[shape_function].is_nonzero_shape_function_component[d])
- {
- const double * shape_value_ptr =
- &fe_values.shape_values(shape_function_data[shape_function].row_index[d], 0);
- for (unsigned int q_point = 0; q_point < fe_values.n_quadrature_points; ++q_point)
- values[q_point][value_type::unrolled_to_component_indices(d)]
- += value * *shape_value_ptr++;
- }
- }
+ const int snc = shape_function_data[shape_function].single_nonzero_component;
+
+ if (snc == -2)
+ // shape function is zero for the
+ // selected components
+ continue;
+
+ const double value = dof_values(shape_function);
+ if (value == 0.)
+ continue;
+
+ if (snc != -1)
+ {
+ const unsigned int comp =
+ shape_function_data[shape_function].single_nonzero_component_index;
+ const double * shape_value_ptr = &fe_values.shape_values(snc, 0);
+ for (unsigned int q_point = 0; q_point < fe_values.n_quadrature_points; ++q_point)
+ values[q_point][value_type::unrolled_to_component_indices(comp)]
+ += value * *shape_value_ptr++;
+ }
+ else
+ {
+ for (unsigned int d = 0; d < value_type::n_independent_components; ++d)
+ if (shape_function_data[shape_function].is_nonzero_shape_function_component[d])
+ {
+ const double * shape_value_ptr =
+ &fe_values.shape_values(shape_function_data[shape_function].row_index[d], 0);
+ for (unsigned int q_point = 0; q_point < fe_values.n_quadrature_points; ++q_point)
+ values[q_point][value_type::unrolled_to_component_indices(d)]
+ += value * *shape_value_ptr++;
+ }
+ }
}
}
if (ii != jj)
divergences[q_point][jj] += value * (*shape_gradient_ptr)[ii];
}
- }
+ }
else
- {
+ {
for (unsigned int d = 0; d < value_type::n_independent_components; ++d)
if (shape_function_data[shape_function].is_nonzero_shape_function_component[d])
{
- Assert (false, ExcNotImplemented());
+ Assert (false, ExcNotImplemented());
// the following implementation needs to be looked over -- I think it
// can't be right, because we are in a case where there is no single
// mutliple non-zero entries in shape function and the representation
// as a symmetric second-order tensor
- const unsigned int comp =
+ const unsigned int comp =
shape_function_data[shape_function].single_nonzero_component_index;
- const Tensor < 1, spacedim> * shape_gradient_ptr =
+ const Tensor < 1, spacedim> * shape_gradient_ptr =
&fe_values.shape_gradients[shape_function_data[shape_function].
row_index[d]][0];
- for (unsigned int q_point = 0; q_point < fe_values.n_quadrature_points;
- ++q_point, ++shape_gradient_ptr) {
+ for (unsigned int q_point = 0; q_point < fe_values.n_quadrature_points;
+ ++q_point, ++shape_gradient_ptr) {
for (unsigned int j = 0; j < dim; ++j)
- {
+ {
const unsigned int vector_component = value_type::component_to_unrolled_index (TableIndices<2>(comp,j));
divergences[q_point][vector_component] += value * (*shape_gradient_ptr++)[j];
- }
- }
+ }
+ }
}
- }
+ }
}
}
}
{
const FiniteElement<dim,spacedim> &fe = fe_values.get_fe();
- // create the views objects. allocate a
- // bunch of default-constructed ones
- // then destroy them again and do
- // in-place construction of those we
- // actually want to use (copying stuff
- // is wasteful and we can't do that
- // anyway because the class has
- // reference members)
+ // create the views objects. allocate a
+ // bunch of default-constructed ones
+ // then destroy them again and do
+ // in-place construction of those we
+ // actually want to use (copying stuff
+ // is wasteful and we can't do that
+ // anyway because the class has
+ // reference members)
const unsigned int n_scalars = fe.n_components();
scalars.resize (n_scalars);
for (unsigned int component=0; component<n_scalars; ++component)
- {
+ {
#ifndef DEAL_II_EXPLICIT_DESTRUCTOR_BUG
- scalars[component].dealii::FEValuesViews::Scalar<dim,spacedim>::~Scalar ();
+ scalars[component].dealii::FEValuesViews::Scalar<dim,spacedim>::~Scalar ();
#else
- typedef dealii::FEValuesViews::Scalar<dim,spacedim> ScalarView;
- scalars[component].ScalarView::~ScalarView ();
+ typedef dealii::FEValuesViews::Scalar<dim,spacedim> ScalarView;
+ scalars[component].ScalarView::~ScalarView ();
#endif
- new (&scalars[component])
- dealii::FEValuesViews::Scalar<dim,spacedim>(fe_values,
- component);
- }
-
- // compute number of vectors
- // that we can fit into
- // this finite element. note
- // that this is based on the
- // dimensionality 'dim' of the
- // manifold, not 'spacedim' of
- // the output vector
+ new (&scalars[component])
+ dealii::FEValuesViews::Scalar<dim,spacedim>(fe_values,
+ component);
+ }
+
+ // compute number of vectors
+ // that we can fit into
+ // this finite element. note
+ // that this is based on the
+ // dimensionality 'dim' of the
+ // manifold, not 'spacedim' of
+ // the output vector
const unsigned int n_vectors = (fe.n_components() >= spacedim ?
- fe.n_components()-spacedim+1 :
- 0);
+ fe.n_components()-spacedim+1 :
+ 0);
vectors.resize (n_vectors);
for (unsigned int component=0; component<n_vectors; ++component)
- {
+ {
#ifndef DEAL_II_EXPLICIT_DESTRUCTOR_BUG
- vectors[component].dealii::FEValuesViews::Vector<dim,spacedim>::~Vector ();
+ vectors[component].dealii::FEValuesViews::Vector<dim,spacedim>::~Vector ();
#else
- typedef dealii::FEValuesViews::Vector<dim,spacedim> VectorView;
- vectors[component].VectorView::~VectorView ();
+ typedef dealii::FEValuesViews::Vector<dim,spacedim> VectorView;
+ vectors[component].VectorView::~VectorView ();
#endif
- new (&vectors[component])
- dealii::FEValuesViews::Vector<dim,spacedim>(fe_values,
- component);
- }
+ new (&vectors[component])
+ dealii::FEValuesViews::Vector<dim,spacedim>(fe_values,
+ component);
+ }
- // compute number of symmetric
- // tensors in the same way as above
+ // compute number of symmetric
+ // tensors in the same way as above
const unsigned int n_symmetric_second_order_tensors
- = (fe.n_components() >= (dim*dim + dim)/2 ?
- fe.n_components() - (dim*dim + dim)/2 + 1 :
- 0);
+ = (fe.n_components() >= (dim*dim + dim)/2 ?
+ fe.n_components() - (dim*dim + dim)/2 + 1 :
+ 0);
symmetric_second_order_tensors.resize(n_symmetric_second_order_tensors);
for (unsigned int component = 0; component < n_symmetric_second_order_tensors; ++component)
- {
+ {
#ifndef DEAL_II_EXPLICIT_DESTRUCTOR_BUG
- symmetric_second_order_tensors[component]
- .dealii::FEValuesViews::SymmetricTensor<2, dim, spacedim>::~SymmetricTensor();
+ symmetric_second_order_tensors[component]
+ .dealii::FEValuesViews::SymmetricTensor<2, dim, spacedim>::~SymmetricTensor();
#else
- typedef dealii::FEValuesViews::SymmetricTensor<2, dim, spacedim> SymmetricTensorView;
- symmetric_second_order_tensors[component].SymmetricTensorView::~SymmetricTensorView();
+ typedef dealii::FEValuesViews::SymmetricTensor<2, dim, spacedim> SymmetricTensorView;
+ symmetric_second_order_tensors[component].SymmetricTensorView::~SymmetricTensorView();
#endif
- new (&symmetric_second_order_tensors[component])
- dealii::FEValuesViews::SymmetricTensor<2, dim, spacedim > (fe_values,
- component);
- }
+ new (&symmetric_second_order_tensors[component])
+ dealii::FEValuesViews::SymmetricTensor<2, dim, spacedim > (fe_values,
+ component);
+ }
}
}
}
class FEValuesBase<dim,spacedim>::CellIteratorBase
{
public:
- /**
- * Destructor. Made virtual
- * since we store only
- * pointers to the base
- * class.
- */
+ /**
+ * Destructor. Made virtual
+ * since we store only
+ * pointers to the base
+ * class.
+ */
virtual ~CellIteratorBase ();
- /**
- * Conversion operator to an
- * iterator for
- * triangulations. This
- * conversion is implicit for
- * the original iterators,
- * since they are derived
- * classes. However, since
- * here we have kind of a
- * parallel class hierarchy,
- * we have to have a
- * conversion operator.
- */
+ /**
+ * Conversion operator to an
+ * iterator for
+ * triangulations. This
+ * conversion is implicit for
+ * the original iterators,
+ * since they are derived
+ * classes. However, since
+ * here we have kind of a
+ * parallel class hierarchy,
+ * we have to have a
+ * conversion operator.
+ */
virtual
operator typename Triangulation<dim,spacedim>::cell_iterator () const = 0;
- /**
- * Return the number of
- * degrees of freedom the DoF
- * handler object has to
- * which the iterator belongs
- * to.
- */
+ /**
+ * Return the number of
+ * degrees of freedom the DoF
+ * handler object has to
+ * which the iterator belongs
+ * to.
+ */
virtual
unsigned int
n_dofs_for_dof_handler () const = 0;
#include "fe_values.decl.1.inst"
- /// Call
- /// @p get_interpolated_dof_values
- /// of the iterator with the
- /// given arguments.
+ /// Call
+ /// @p get_interpolated_dof_values
+ /// of the iterator with the
+ /// given arguments.
virtual
void
get_interpolated_dof_values (const IndexSet &in,
- Vector<double> &out) const = 0;
+ Vector<double> &out) const = 0;
};
/* ---------------- classes derived from FEValuesBase<dim,spacedim>::CellIteratorBase --------- */
- /**
- * Implementation of derived
- * classes of the
- * CellIteratorBase
- * interface. See there for a
- * description of the use of
- * these classes.
- *
- * @author Wolfgang Bangerth, 2003
- */
+ /**
+ * Implementation of derived
+ * classes of the
+ * CellIteratorBase
+ * interface. See there for a
+ * description of the use of
+ * these classes.
+ *
+ * @author Wolfgang Bangerth, 2003
+ */
template <int dim, int spacedim>
template <typename CI>
class FEValuesBase<dim,spacedim>::CellIterator : public FEValuesBase<dim,spacedim>::CellIteratorBase
{
public:
- /**
- * Constructor. Take an
- * iterator and store it in
- * this class.
- */
+ /**
+ * Constructor. Take an
+ * iterator and store it in
+ * this class.
+ */
CellIterator (const CI &cell);
- /**
- * Conversion operator to an
- * iterator for
- * triangulations. This
- * conversion is implicit for
- * the original iterators,
- * since they are derived
- * classes. However, since
- * here we have kind of a
- * parallel class hierarchy,
- * we have to have a
- * conversion operator.
- */
+ /**
+ * Conversion operator to an
+ * iterator for
+ * triangulations. This
+ * conversion is implicit for
+ * the original iterators,
+ * since they are derived
+ * classes. However, since
+ * here we have kind of a
+ * parallel class hierarchy,
+ * we have to have a
+ * conversion operator.
+ */
virtual
operator typename Triangulation<dim,spacedim>::cell_iterator () const;
- /**
- * Return the number of
- * degrees of freedom the DoF
- * handler object has to
- * which the iterator belongs
- * to.
- */
+ /**
+ * Return the number of
+ * degrees of freedom the DoF
+ * handler object has to
+ * which the iterator belongs
+ * to.
+ */
virtual
unsigned int
n_dofs_for_dof_handler () const;
#include "fe_values.decl.2.inst"
- /// Call
- /// @p get_interpolated_dof_values
- /// of the iterator with the
- /// given arguments.
+ /// Call
+ /// @p get_interpolated_dof_values
+ /// of the iterator with the
+ /// given arguments.
virtual
void
get_interpolated_dof_values (const IndexSet &in,
- Vector<double> &out) const;
+ Vector<double> &out) const;
private:
- /**
- * Copy of the iterator which
- * we use in this object.
- */
+ /**
+ * Copy of the iterator which
+ * we use in this object.
+ */
const CI cell;
};
- /**
- * Implementation of a derived
- * class of the
- * CellIteratorBase
- * interface. See there for a
- * description of the use of
- * these classes.
- *
- * This class is basically a
- * specialization of the general
- * template for iterators into
- * Triangulation objects (but
- * since C++ does not allow
- * something like this for nested
- * classes, it runs under a
- * separate name). Since these do
- * not implement the interface
- * that we would like to call,
- * the functions of this class
- * cannot be implemented
- * meaningfully. However, most
- * functions of the FEValues
- * class do not make any use of
- * degrees of freedom at all, so
- * it should be possible to call
- * FEValues::reinit() with a tria
- * iterator only; this class
- * makes this possible, but
- * whenever one of the functions
- * of FEValues tries to call
- * any of the functions of this
- * class, an exception will be
- * raised reminding the user that
- * if she wants to use these
- * features, then the
- * FEValues object has to be
- * reinitialized with a cell
- * iterator that allows to
- * extract degree of freedom
- * information.
- *
- * @author Wolfgang Bangerth, 2003
- */
+ /**
+ * Implementation of a derived
+ * class of the
+ * CellIteratorBase
+ * interface. See there for a
+ * description of the use of
+ * these classes.
+ *
+ * This class is basically a
+ * specialization of the general
+ * template for iterators into
+ * Triangulation objects (but
+ * since C++ does not allow
+ * something like this for nested
+ * classes, it runs under a
+ * separate name). Since these do
+ * not implement the interface
+ * that we would like to call,
+ * the functions of this class
+ * cannot be implemented
+ * meaningfully. However, most
+ * functions of the FEValues
+ * class do not make any use of
+ * degrees of freedom at all, so
+ * it should be possible to call
+ * FEValues::reinit() with a tria
+ * iterator only; this class
+ * makes this possible, but
+ * whenever one of the functions
+ * of FEValues tries to call
+ * any of the functions of this
+ * class, an exception will be
+ * raised reminding the user that
+ * if she wants to use these
+ * features, then the
+ * FEValues object has to be
+ * reinitialized with a cell
+ * iterator that allows to
+ * extract degree of freedom
+ * information.
+ *
+ * @author Wolfgang Bangerth, 2003
+ */
template <int dim, int spacedim>
class FEValuesBase<dim,spacedim>::TriaCellIterator : public FEValuesBase<dim,spacedim>::CellIteratorBase
{
public:
- /**
- * Constructor. Take an
- * iterator and store it in
- * this class.
- */
+ /**
+ * Constructor. Take an
+ * iterator and store it in
+ * this class.
+ */
TriaCellIterator (const typename Triangulation<dim,spacedim>::cell_iterator &cell);
- /**
- * Conversion operator to an
- * iterator for
- * triangulations. This
- * conversion is implicit for
- * the original iterators,
- * since they are derived
- * classes. However, since
- * here we have kind of a
- * parallel class hierarchy,
- * we have to have a
- * conversion operator. Here,
- * the conversion is trivial,
- * from and to the same time.
- */
+ /**
+ * Conversion operator to an
+ * iterator for
+ * triangulations. This
+ * conversion is implicit for
+ * the original iterators,
+ * since they are derived
+ * classes. However, since
+ * here we have kind of a
+ * parallel class hierarchy,
+ * we have to have a
+ * conversion operator. Here,
+ * the conversion is trivial,
+ * from and to the same time.
+ */
virtual
operator typename Triangulation<dim,spacedim>::cell_iterator () const;
- /**
- * Implement the respective
- * function of the base
- * class. Since this is not
- * possible, we just raise an
- * error.
- */
+ /**
+ * Implement the respective
+ * function of the base
+ * class. Since this is not
+ * possible, we just raise an
+ * error.
+ */
virtual
unsigned int
n_dofs_for_dof_handler () const;
#include "fe_values.decl.2.inst"
- /// Call
- /// @p get_interpolated_dof_values
- /// of the iterator with the
- /// given arguments.
+ /// Call
+ /// @p get_interpolated_dof_values
+ /// of the iterator with the
+ /// given arguments.
virtual
void
get_interpolated_dof_values (const IndexSet &in,
- Vector<double> &out) const;
+ Vector<double> &out) const;
private:
- /**
- * Copy of the iterator which
- * we use in this object.
- */
+ /**
+ * Copy of the iterator which
+ * we use in this object.
+ */
const typename Triangulation<dim,spacedim>::cell_iterator cell;
- /**
- * String to be displayed
- * whenever one of the
- * functions of this class is
- * called. Make it a static
- * member variable, since we
- * show the same message for
- * all member functions.
- */
+ /**
+ * String to be displayed
+ * whenever one of the
+ * functions of this class is
+ * called. Make it a static
+ * member variable, since we
+ * show the same message for
+ * all member functions.
+ */
static const char * const message_string;
};
template <int dim, int spacedim>
template <typename CI>
FEValuesBase<dim,spacedim>::CellIterator<CI>::CellIterator (const CI &cell)
- :
- cell(cell)
+ :
+ cell(cell)
{}
void
FEValuesBase<dim,spacedim>::CellIterator<CI>::
get_interpolated_dof_values (const IndexSet &in,
- Vector<double> &out) const
+ Vector<double> &out) const
{
Assert (cell->has_children() == false, ExcNotImplemented());
template <int dim, int spacedim>
FEValuesBase<dim,spacedim>::TriaCellIterator::
TriaCellIterator (const typename Triangulation<dim,spacedim>::cell_iterator &cell)
- :
- cell(cell)
+ :
+ cell(cell)
{}
void
FEValuesBase<dim,spacedim>::TriaCellIterator::
get_interpolated_dof_values (const IndexSet &,
- Vector<double> &) const
+ Vector<double> &) const
{
Assert (false, ExcMessage (message_string));
}
template <int dim, int spacedim>
void
FEValuesData<dim,spacedim>::initialize (const unsigned int n_quadrature_points,
- const FiniteElement<dim,spacedim> &fe,
- const UpdateFlags flags)
+ const FiniteElement<dim,spacedim> &fe,
+ const UpdateFlags flags)
{
this->update_flags = flags;
- // initialize the table mapping
- // from shape function number to
- // the rows in the tables denoting
- // its first non-zero
- // component
+ // initialize the table mapping
+ // from shape function number to
+ // the rows in the tables denoting
+ // its first non-zero
+ // component
this->shape_function_to_row_table
= make_shape_function_to_row_table (fe);
- // count the total number of non-zero
- // components accumulated over all shape
- // functions
+ // count the total number of non-zero
+ // components accumulated over all shape
+ // functions
unsigned int n_nonzero_shape_components = 0;
for (unsigned int i=0; i<fe.dofs_per_cell; ++i)
n_nonzero_shape_components += fe.n_nonzero_components (i);
Assert (n_nonzero_shape_components >= fe.dofs_per_cell,
- ExcInternalError());
+ ExcInternalError());
- // with the number of rows now
- // known, initialize those fields
- // that we will need to their
- // correct size
+ // with the number of rows now
+ // known, initialize those fields
+ // that we will need to their
+ // correct size
if (flags & update_values)
this->shape_values.reinit(n_nonzero_shape_components,
- n_quadrature_points);
+ n_quadrature_points);
if (flags & update_gradients)
this->shape_gradients.resize (n_nonzero_shape_components,
- std::vector<Tensor<1,spacedim> > (n_quadrature_points));
+ std::vector<Tensor<1,spacedim> > (n_quadrature_points));
if (flags & update_hessians)
this->shape_hessians.resize (n_nonzero_shape_components,
- std::vector<Tensor<2,spacedim> > (n_quadrature_points));
+ std::vector<Tensor<2,spacedim> > (n_quadrature_points));
if (flags & update_quadrature_points)
this->quadrature_points.resize(n_quadrature_points);
template <int dim, int spacedim>
FEValuesBase<dim,spacedim>::FEValuesBase (const unsigned int n_q_points,
- const unsigned int dofs_per_cell,
- const UpdateFlags flags,
- const Mapping<dim,spacedim> &mapping,
- const FiniteElement<dim,spacedim> &fe)
- :
- n_quadrature_points (n_q_points),
- dofs_per_cell (dofs_per_cell),
- mapping(&mapping, typeid(*this).name()),
- fe(&fe, typeid(*this).name()),
- mapping_data(0, typeid(*this).name()),
- fe_data(0, typeid(*this).name()),
- fe_values_views_cache (*this)
+ const unsigned int dofs_per_cell,
+ const UpdateFlags flags,
+ const Mapping<dim,spacedim> &mapping,
+ const FiniteElement<dim,spacedim> &fe)
+ :
+ n_quadrature_points (n_q_points),
+ dofs_per_cell (dofs_per_cell),
+ mapping(&mapping, typeid(*this).name()),
+ fe(&fe, typeid(*this).name()),
+ mapping_data(0, typeid(*this).name()),
+ fe_data(0, typeid(*this).name()),
+ fe_values_views_cache (*this)
{
this->update_flags = flags;
}
template <int dim, int spacedim>
FEValuesBase<dim,spacedim>::~FEValuesBase ()
{
- // delete those fields that were
- // created by the mapping and
- // finite element objects,
- // respectively, but of which we
- // have assumed ownership
+ // delete those fields that were
+ // created by the mapping and
+ // finite element objects,
+ // respectively, but of which we
+ // have assumed ownership
if (fe_data != 0)
{
typename Mapping<dim,spacedim>::InternalDataBase *tmp1=fe_data;
{
Assert (this->update_flags & update_values, ExcAccessToUninitializedField());
Assert (fe->n_components() == 1,
- ExcDimensionMismatch(fe->n_components(), 1));
+ ExcDimensionMismatch(fe->n_components(), 1));
Assert (values.size() == n_quadrature_points,
- ExcDimensionMismatch(values.size(), n_quadrature_points));
+ ExcDimensionMismatch(values.size(), n_quadrature_points));
Assert (present_cell.get() != 0,
- ExcMessage ("FEValues object is not reinit'ed to any cell"));
+ ExcMessage ("FEValues object is not reinit'ed to any cell"));
Assert (fe_function.size() == present_cell->n_dofs_for_dof_handler(),
- ExcDimensionMismatch(fe_function.size(),
- present_cell->n_dofs_for_dof_handler()));
+ ExcDimensionMismatch(fe_function.size(),
+ present_cell->n_dofs_for_dof_handler()));
- // get function values of dofs
- // on this cell
+ // get function values of dofs
+ // on this cell
Vector<typename ValueType<InputVector>::type> dof_values (dofs_per_cell);
present_cell->get_interpolated_dof_values(fe_function, dof_values);
- // initialize with zero
+ // initialize with zero
std::fill_n (values.begin(), n_quadrature_points, 0);
- // add up contributions of trial
- // functions. note that here we
- // deal with scalar finite
- // elements, so no need to check
- // for non-primitivity of shape
- // functions. in order to increase
- // the speed of this function, we
- // directly access the data in the
- // shape_values array, and
- // increment pointers for accessing
- // the data. this saves some lookup
- // time and indexing. moreover, the
- // order of the loops is such that
- // we can access the shape_values
- // data stored contiguously (which
- // is also advantageous because
- // access to dof_values is
- // generally more expensive than
- // access to the std::vector values
- // - so we do the cheaper operation
- // in the innermost loop)
+ // add up contributions of trial
+ // functions. note that here we
+ // deal with scalar finite
+ // elements, so no need to check
+ // for non-primitivity of shape
+ // functions. in order to increase
+ // the speed of this function, we
+ // directly access the data in the
+ // shape_values array, and
+ // increment pointers for accessing
+ // the data. this saves some lookup
+ // time and indexing. moreover, the
+ // order of the loops is such that
+ // we can access the shape_values
+ // data stored contiguously (which
+ // is also advantageous because
+ // access to dof_values is
+ // generally more expensive than
+ // access to the std::vector values
+ // - so we do the cheaper operation
+ // in the innermost loop)
for (unsigned int shape_func=0; shape_func<dofs_per_cell; ++shape_func)
{
const double value = dof_values(shape_func);
if (value == 0.)
- continue;
+ continue;
const double *shape_value_ptr = &this->shape_values(shape_func, 0);
for (unsigned int point=0; point<n_quadrature_points; ++point)
- values[point] += value * *shape_value_ptr++;
+ values[point] += value * *shape_value_ptr++;
}
}
std::vector<number> &values) const
{
Assert (this->update_flags & update_values, ExcAccessToUninitializedField());
- // This function fills a single
- // component only
+ // This function fills a single
+ // component only
Assert (fe->n_components() == 1,
- ExcDimensionMismatch(fe->n_components(), 1));
- // One index for each dof
+ ExcDimensionMismatch(fe->n_components(), 1));
+ // One index for each dof
Assert (indices.size() == dofs_per_cell,
- ExcDimensionMismatch(indices.size(), dofs_per_cell));
- // This vector has one entry for
- // each quadrature point
+ ExcDimensionMismatch(indices.size(), dofs_per_cell));
+ // This vector has one entry for
+ // each quadrature point
Assert (values.size() == n_quadrature_points,
- ExcDimensionMismatch(values.size(), n_quadrature_points));
+ ExcDimensionMismatch(values.size(), n_quadrature_points));
- // initialize with zero
+ // initialize with zero
std::fill_n (values.begin(), n_quadrature_points, 0);
- // add up contributions of trial
- // functions. note that here we
- // deal with scalar finite
- // elements, so no need to check
- // for non-primitivity of shape
- // functions. in order to increase
- // the speed of this function, we
- // directly access the data in the
- // shape_values array, and
- // increment pointers for accessing
- // the data. this saves some lookup
- // time and indexing. moreover, the
- // order of the loops is such that
- // we can access the shape_values
- // data stored contiguously (which
- // is also advantageous because
- // access to the global vector
- // fe_function is more expensive
- // than access to the small
- // std::vector values - so we do
- // the cheaper operation in the
- // innermost loop)
+ // add up contributions of trial
+ // functions. note that here we
+ // deal with scalar finite
+ // elements, so no need to check
+ // for non-primitivity of shape
+ // functions. in order to increase
+ // the speed of this function, we
+ // directly access the data in the
+ // shape_values array, and
+ // increment pointers for accessing
+ // the data. this saves some lookup
+ // time and indexing. moreover, the
+ // order of the loops is such that
+ // we can access the shape_values
+ // data stored contiguously (which
+ // is also advantageous because
+ // access to the global vector
+ // fe_function is more expensive
+ // than access to the small
+ // std::vector values - so we do
+ // the cheaper operation in the
+ // innermost loop)
for (unsigned int shape_func=0; shape_func<dofs_per_cell; ++shape_func)
{
const double value = get_vector_element (fe_function, indices[shape_func]);
if (value == 0.)
- continue;
+ continue;
const double *shape_value_ptr = &this->shape_values(shape_func, 0);
for (unsigned int point=0; point<n_quadrature_points; ++point)
- values[point] += value * *shape_value_ptr++;
+ values[point] += value * *shape_value_ptr++;
}
}
std::vector<Vector<number> >& values) const
{
//TODO: Find out how to do this assertion.
- // This vector must correspond to a
- // complete discretization
+ // This vector must correspond to a
+ // complete discretization
// Assert (fe_function.size() == present_cell->get_dof_handler().n_dofs(),
-// ExcDimensionMismatch(fe_function.size(),
-// present_cell->get_dof_handler().n_dofs()));
- // One entry per quadrature point
+// ExcDimensionMismatch(fe_function.size(),
+// present_cell->get_dof_handler().n_dofs()));
+ // One entry per quadrature point
Assert (present_cell.get() != 0,
- ExcMessage ("FEValues object is not reinit'ed to any cell"));
+ ExcMessage ("FEValues object is not reinit'ed to any cell"));
Assert (values.size() == n_quadrature_points,
- ExcDimensionMismatch(values.size(), n_quadrature_points));
+ ExcDimensionMismatch(values.size(), n_quadrature_points));
const unsigned int n_components = fe->n_components();
- // Assert that we can write all
- // components into the result
- // vectors
+ // Assert that we can write all
+ // components into the result
+ // vectors
for (unsigned i=0;i<values.size();++i)
Assert (values[i].size() == n_components,
- ExcDimensionMismatch(values[i].size(), n_components));
+ ExcDimensionMismatch(values[i].size(), n_components));
Assert (this->update_flags & update_values, ExcAccessToUninitializedField());
Assert (fe_function.size() == present_cell->n_dofs_for_dof_handler(),
- ExcDimensionMismatch(fe_function.size(), present_cell->n_dofs_for_dof_handler()));
+ ExcDimensionMismatch(fe_function.size(), present_cell->n_dofs_for_dof_handler()));
- // get function values of dofs
- // on this cell
+ // get function values of dofs
+ // on this cell
Vector<typename ValueType<InputVector>::type> dof_values (dofs_per_cell);
present_cell->get_interpolated_dof_values(fe_function, dof_values);
- // initialize with zero
+ // initialize with zero
for (unsigned i=0;i<values.size();++i)
std::fill_n (values[i].begin(), values[i].size(), 0);
- // add up contributions of trial
- // functions. now check whether the
- // shape function is primitive or
- // not. if it is, then set its only
- // non-zero component, otherwise
- // loop over components. in order
- // to increase the speed of this
- // function, we directly access the
- // data in the shape_values array,
- // and increment pointers for
- // accessing the data. this saves
- // some lookup time and
- // indexing. moreover, in order of
- // the loops is such that we can
- // access the shape_values data
- // stored contiguously (which is
- // also advantageous because access
- // to the global vector fe_function
- // is more expensive than access to
- // the small std::vector values -
- // so we do the cheaper operation
- // in the innermost loop)
+ // add up contributions of trial
+ // functions. now check whether the
+ // shape function is primitive or
+ // not. if it is, then set its only
+ // non-zero component, otherwise
+ // loop over components. in order
+ // to increase the speed of this
+ // function, we directly access the
+ // data in the shape_values array,
+ // and increment pointers for
+ // accessing the data. this saves
+ // some lookup time and
+ // indexing. moreover, in order of
+ // the loops is such that we can
+ // access the shape_values data
+ // stored contiguously (which is
+ // also advantageous because access
+ // to the global vector fe_function
+ // is more expensive than access to
+ // the small std::vector values -
+ // so we do the cheaper operation
+ // in the innermost loop)
for (unsigned int shape_func=0; shape_func<dofs_per_cell; ++shape_func)
{
const double value = dof_values(shape_func);
if (value == 0.)
- continue;
+ continue;
if (fe->is_primitive(shape_func))
- {
- // compared to the scalar
- // functions, finding the correct
- // index in the shape_value table
- // is more involved, since we have
- // to find the row in shape_values
- // that corresponds to the present
- // shape_func. this is done
- // manually in the same way as in
- // shape_value_component() (that
- // function can't be used because
- // it doesn't return us a pointer
- // to the data).
- const unsigned int
- row = fe->is_primitive() ?
- shape_func : this->shape_function_to_row_table[shape_func];
-
- const double *shape_value_ptr = &this->shape_values(row, 0);
- const unsigned int comp = fe->system_to_component_index(shape_func).first;
- for (unsigned int point=0; point<n_quadrature_points; ++point)
- values[point](comp) += value * *shape_value_ptr++;
- }
- // non-primitive case (vector-valued
- // element)
+ {
+ // compared to the scalar
+ // functions, finding the correct
+ // index in the shape_value table
+ // is more involved, since we have
+ // to find the row in shape_values
+ // that corresponds to the present
+ // shape_func. this is done
+ // manually in the same way as in
+ // shape_value_component() (that
+ // function can't be used because
+ // it doesn't return us a pointer
+ // to the data).
+ const unsigned int
+ row = fe->is_primitive() ?
+ shape_func : this->shape_function_to_row_table[shape_func];
+
+ const double *shape_value_ptr = &this->shape_values(row, 0);
+ const unsigned int comp = fe->system_to_component_index(shape_func).first;
+ for (unsigned int point=0; point<n_quadrature_points; ++point)
+ values[point](comp) += value * *shape_value_ptr++;
+ }
+ // non-primitive case (vector-valued
+ // element)
else
- for (unsigned int c=0; c<n_components; ++c)
- {
- if (fe->get_nonzero_components(shape_func)[c] == false)
- continue;
-
- const unsigned int
- row = (this->shape_function_to_row_table[shape_func]
- +
- std::count (fe->get_nonzero_components(shape_func).begin(),
- fe->get_nonzero_components(shape_func).begin()+c,
- true));
-
- const double *shape_value_ptr = &this->shape_values(row, 0);
-
- for (unsigned int point=0; point<n_quadrature_points; ++point)
- values[point](c) += value * *shape_value_ptr++;
- }
+ for (unsigned int c=0; c<n_components; ++c)
+ {
+ if (fe->get_nonzero_components(shape_func)[c] == false)
+ continue;
+
+ const unsigned int
+ row = (this->shape_function_to_row_table[shape_func]
+ +
+ std::count (fe->get_nonzero_components(shape_func).begin(),
+ fe->get_nonzero_components(shape_func).begin()+c,
+ true));
+
+ const double *shape_value_ptr = &this->shape_values(row, 0);
+
+ for (unsigned int point=0; point<n_quadrature_points; ++point)
+ values[point](c) += value * *shape_value_ptr++;
+ }
}
}
const VectorSlice<const std::vector<unsigned int> >& indices,
std::vector<Vector<number> >& values) const
{
- // One value per quadrature point
+ // One value per quadrature point
Assert (n_quadrature_points == values.size(),
- ExcDimensionMismatch(values.size(), n_quadrature_points));
+ ExcDimensionMismatch(values.size(), n_quadrature_points));
const unsigned int n_components = fe->n_components();
- // Size of indices must be a
- // multiple of dofs_per_cell such
- // that an integer number of
- // function values is generated in
- // each point.
+ // Size of indices must be a
+ // multiple of dofs_per_cell such
+ // that an integer number of
+ // function values is generated in
+ // each point.
Assert (indices.size() % dofs_per_cell == 0,
- ExcNotMultiple(indices.size(), dofs_per_cell));
+ ExcNotMultiple(indices.size(), dofs_per_cell));
- // The number of components of the
- // result may be a multiple of the
- // number of components of the
- // finite element
+ // The number of components of the
+ // result may be a multiple of the
+ // number of components of the
+ // finite element
const unsigned int result_components = indices.size() * n_components / dofs_per_cell;
for (unsigned i=0;i<values.size();++i)
Assert (values[i].size() == result_components,
- ExcDimensionMismatch(values[i].size(), result_components));
+ ExcDimensionMismatch(values[i].size(), result_components));
- // If the result has more
- // components than the finite
- // element, we need this number for
- // loops filling all components
+ // If the result has more
+ // components than the finite
+ // element, we need this number for
+ // loops filling all components
const unsigned int component_multiple = result_components / n_components;
Assert (this->update_flags & update_values, ExcAccessToUninitializedField());
- // initialize with zero
+ // initialize with zero
for (unsigned i=0;i<values.size();++i)
std::fill_n (values[i].begin(), values[i].size(), 0);
- // add up contributions of trial
- // functions. now check whether the
- // shape function is primitive or
- // not. if it is, then set its only
- // non-zero component, otherwise
- // loop over components
+ // add up contributions of trial
+ // functions. now check whether the
+ // shape function is primitive or
+ // not. if it is, then set its only
+ // non-zero component, otherwise
+ // loop over components
for (unsigned int mc = 0; mc < component_multiple; ++mc)
for (unsigned int shape_func=0; shape_func<dofs_per_cell; ++shape_func)
{
- const double value = get_vector_element (fe_function, indices[shape_func+mc*dofs_per_cell]);
- if (value == 0.)
- continue;
-
- if (fe->is_primitive(shape_func))
- {
- const unsigned int
- row = fe->is_primitive() ?
- shape_func : this->shape_function_to_row_table[shape_func];
-
- const double *shape_value_ptr = &this->shape_values(row, 0);
- const unsigned int comp = fe->system_to_component_index(shape_func).first
- + mc * n_components;
- for (unsigned int point=0; point<n_quadrature_points; ++point)
- values[point](comp) += value * *shape_value_ptr++;
- }
- else
- for (unsigned int c=0; c<n_components; ++c)
- {
- if (fe->get_nonzero_components(shape_func)[c] == false)
- continue;
-
- const unsigned int
- row = (this->shape_function_to_row_table[shape_func]
- +
- std::count (fe->get_nonzero_components(shape_func).begin(),
- fe->get_nonzero_components(shape_func).begin()+c,
- true));
-
- const double *shape_value_ptr = &this->shape_values(row, 0);
- const unsigned int comp = c + mc * n_components;
-
- for (unsigned int point=0; point<n_quadrature_points; ++point)
- values[point](comp) += value * *shape_value_ptr++;
- }
+ const double value = get_vector_element (fe_function, indices[shape_func+mc*dofs_per_cell]);
+ if (value == 0.)
+ continue;
+
+ if (fe->is_primitive(shape_func))
+ {
+ const unsigned int
+ row = fe->is_primitive() ?
+ shape_func : this->shape_function_to_row_table[shape_func];
+
+ const double *shape_value_ptr = &this->shape_values(row, 0);
+ const unsigned int comp = fe->system_to_component_index(shape_func).first
+ + mc * n_components;
+ for (unsigned int point=0; point<n_quadrature_points; ++point)
+ values[point](comp) += value * *shape_value_ptr++;
+ }
+ else
+ for (unsigned int c=0; c<n_components; ++c)
+ {
+ if (fe->get_nonzero_components(shape_func)[c] == false)
+ continue;
+
+ const unsigned int
+ row = (this->shape_function_to_row_table[shape_func]
+ +
+ std::count (fe->get_nonzero_components(shape_func).begin(),
+ fe->get_nonzero_components(shape_func).begin()+c,
+ true));
+
+ const double *shape_value_ptr = &this->shape_values(row, 0);
+ const unsigned int comp = c + mc * n_components;
+
+ for (unsigned int point=0; point<n_quadrature_points; ++point)
+ values[point](comp) += value * *shape_value_ptr++;
+ }
}
}
{
const unsigned int n_components = fe->n_components();
- // Size of indices must be a
- // multiple of dofs_per_cell such
- // that an integer number of
- // function values is generated in
- // each point.
+ // Size of indices must be a
+ // multiple of dofs_per_cell such
+ // that an integer number of
+ // function values is generated in
+ // each point.
Assert (indices.size() % dofs_per_cell == 0,
- ExcNotMultiple(indices.size(), dofs_per_cell));
+ ExcNotMultiple(indices.size(), dofs_per_cell));
- // The number of components of the
- // result may be a multiple of the
- // number of components of the
- // finite element
+ // The number of components of the
+ // result may be a multiple of the
+ // number of components of the
+ // finite element
const unsigned int result_components = indices.size() * n_components / dofs_per_cell;
- // Check if the value argument is
- // initialized to the correct sizes
+ // Check if the value argument is
+ // initialized to the correct sizes
if (quadrature_points_fastest)
{
Assert (values.size() == result_components,
- ExcDimensionMismatch(values.size(), result_components));
+ ExcDimensionMismatch(values.size(), result_components));
for (unsigned i=0;i<values.size();++i)
- Assert (values[i].size() == n_quadrature_points,
- ExcDimensionMismatch(values[i].size(), n_quadrature_points));
+ Assert (values[i].size() == n_quadrature_points,
+ ExcDimensionMismatch(values[i].size(), n_quadrature_points));
}
else
{
Assert(values.size() == n_quadrature_points,
- ExcDimensionMismatch(values.size(), n_quadrature_points));
+ ExcDimensionMismatch(values.size(), n_quadrature_points));
for (unsigned i=0;i<values.size();++i)
- Assert (values[i].size() == result_components,
- ExcDimensionMismatch(values[i].size(), result_components));
+ Assert (values[i].size() == result_components,
+ ExcDimensionMismatch(values[i].size(), result_components));
}
- // If the result has more
- // components than the finite
- // element, we need this number for
- // loops filling all components
+ // If the result has more
+ // components than the finite
+ // element, we need this number for
+ // loops filling all components
const unsigned int component_multiple = result_components / n_components;
Assert (this->update_flags & update_values, ExcAccessToUninitializedField());
- // initialize with zero
+ // initialize with zero
for (unsigned i=0;i<values.size();++i)
std::fill_n (values[i].begin(), values[i].size(), 0);
- // add up contributions of trial
- // functions. now check whether the
- // shape function is primitive or
- // not. if it is, then set its only
- // non-zero component, otherwise
- // loop over components
+ // add up contributions of trial
+ // functions. now check whether the
+ // shape function is primitive or
+ // not. if it is, then set its only
+ // non-zero component, otherwise
+ // loop over components
for (unsigned int mc = 0; mc < component_multiple; ++mc)
for (unsigned int shape_func=0; shape_func<dofs_per_cell; ++shape_func)
{
- const double value = get_vector_element (fe_function, indices[shape_func+mc*dofs_per_cell]);
- if (value == 0.)
- continue;
-
- if (fe->is_primitive(shape_func))
- {
- const unsigned int
- row = fe->is_primitive() ?
- shape_func : this->shape_function_to_row_table[shape_func];
-
- const double *shape_value_ptr = &this->shape_values(row, 0);
- const unsigned int comp = fe->system_to_component_index(shape_func).first
- + mc * n_components;
-
- if (quadrature_points_fastest)
- for (unsigned int point=0; point<n_quadrature_points; ++point)
- values[comp][point] += value * *shape_value_ptr++;
- else
- for (unsigned int point=0; point<n_quadrature_points; ++point)
- values[point][comp] += value * *shape_value_ptr++;
- }
- else
- for (unsigned int c=0; c<n_components; ++c)
- {
- if (fe->get_nonzero_components(shape_func)[c] == false)
- continue;
-
- const unsigned int
- row = (this->shape_function_to_row_table[shape_func]
- +
- std::count (fe->get_nonzero_components(shape_func).begin(),
- fe->get_nonzero_components(shape_func).begin()+c,
- true));
-
- const double *shape_value_ptr = &this->shape_values(row, 0);
- const unsigned int comp = c + mc * n_components;
-
- if (quadrature_points_fastest)
- for (unsigned int point=0; point<n_quadrature_points; ++point)
- values[comp][point] += value * *shape_value_ptr++;
- else
- for (unsigned int point=0; point<n_quadrature_points; ++point)
- values[point][comp] += value * *shape_value_ptr++;
- }
+ const double value = get_vector_element (fe_function, indices[shape_func+mc*dofs_per_cell]);
+ if (value == 0.)
+ continue;
+
+ if (fe->is_primitive(shape_func))
+ {
+ const unsigned int
+ row = fe->is_primitive() ?
+ shape_func : this->shape_function_to_row_table[shape_func];
+
+ const double *shape_value_ptr = &this->shape_values(row, 0);
+ const unsigned int comp = fe->system_to_component_index(shape_func).first
+ + mc * n_components;
+
+ if (quadrature_points_fastest)
+ for (unsigned int point=0; point<n_quadrature_points; ++point)
+ values[comp][point] += value * *shape_value_ptr++;
+ else
+ for (unsigned int point=0; point<n_quadrature_points; ++point)
+ values[point][comp] += value * *shape_value_ptr++;
+ }
+ else
+ for (unsigned int c=0; c<n_components; ++c)
+ {
+ if (fe->get_nonzero_components(shape_func)[c] == false)
+ continue;
+
+ const unsigned int
+ row = (this->shape_function_to_row_table[shape_func]
+ +
+ std::count (fe->get_nonzero_components(shape_func).begin(),
+ fe->get_nonzero_components(shape_func).begin()+c,
+ true));
+
+ const double *shape_value_ptr = &this->shape_values(row, 0);
+ const unsigned int comp = c + mc * n_components;
+
+ if (quadrature_points_fastest)
+ for (unsigned int point=0; point<n_quadrature_points; ++point)
+ values[comp][point] += value * *shape_value_ptr++;
+ else
+ for (unsigned int point=0; point<n_quadrature_points; ++point)
+ values[point][comp] += value * *shape_value_ptr++;
+ }
}
}
Assert (this->update_flags & update_gradients, ExcAccessToUninitializedField());
Assert (fe->n_components() == 1,
- ExcDimensionMismatch(fe->n_components(), 1));
+ ExcDimensionMismatch(fe->n_components(), 1));
Assert (gradients.size() == n_quadrature_points,
- ExcDimensionMismatch(gradients.size(), n_quadrature_points));
+ ExcDimensionMismatch(gradients.size(), n_quadrature_points));
Assert (present_cell.get() != 0,
- ExcMessage ("FEValues object is not reinit'ed to any cell"));
+ ExcMessage ("FEValues object is not reinit'ed to any cell"));
Assert (fe_function.size() == present_cell->n_dofs_for_dof_handler(),
- ExcDimensionMismatch(fe_function.size(),
- present_cell->n_dofs_for_dof_handler()));
+ ExcDimensionMismatch(fe_function.size(),
+ present_cell->n_dofs_for_dof_handler()));
- // get function values of dofs
- // on this cell
+ // get function values of dofs
+ // on this cell
Vector<typename ValueType<InputVector>::type> dof_values (dofs_per_cell);
present_cell->get_interpolated_dof_values(fe_function, dof_values);
- // initialize with zero
+ // initialize with zero
std::fill_n (gradients.begin(), n_quadrature_points, Tensor<1,spacedim>());
- // add up contributions of trial
- // functions. note that here we
- // deal with scalar finite
- // elements, so no need to check
- // for non-primitivity of shape
- // functions. in order to increase
- // the speed of this function, we
- // directly access the data in the
- // shape_gradients array, and
- // increment pointers for accessing
- // the data. this saves some lookup
- // time and indexing. moreover, the
- // order of the loops is such that
- // we can access the
- // shape_gradients data stored
- // contiguously (which is also
- // advantageous because access to
- // the vector dof_values is
- // gerenally more expensive than
- // access to the std::vector
- // gradients - so we do the cheaper
- // operation in the innermost loop)
+ // add up contributions of trial
+ // functions. note that here we
+ // deal with scalar finite
+ // elements, so no need to check
+ // for non-primitivity of shape
+ // functions. in order to increase
+ // the speed of this function, we
+ // directly access the data in the
+ // shape_gradients array, and
+ // increment pointers for accessing
+ // the data. this saves some lookup
+ // time and indexing. moreover, the
+ // order of the loops is such that
+ // we can access the
+ // shape_gradients data stored
+ // contiguously (which is also
+ // advantageous because access to
+ // the vector dof_values is
+ // gerenally more expensive than
+ // access to the std::vector
+ // gradients - so we do the cheaper
+ // operation in the innermost loop)
for (unsigned int shape_func=0; shape_func<dofs_per_cell; ++shape_func)
{
const double value = dof_values(shape_func);
if (value == 0.)
- continue;
+ continue;
const Tensor<1,spacedim> *shape_gradient_ptr
- = &this->shape_gradients[shape_func][0];
+ = &this->shape_gradients[shape_func][0];
for (unsigned int point=0; point<n_quadrature_points; ++point)
- gradients[point] += value * *shape_gradient_ptr++;
+ gradients[point] += value * *shape_gradient_ptr++;
}
}
std::vector<Tensor<1,spacedim> > &gradients) const
{
Assert (this->update_flags & update_gradients, ExcAccessToUninitializedField());
- // This function fills a single
- // component only
+ // This function fills a single
+ // component only
Assert (fe->n_components() == 1,
- ExcDimensionMismatch(fe->n_components(), 1));
- // One index for each dof
+ ExcDimensionMismatch(fe->n_components(), 1));
+ // One index for each dof
Assert (indices.size() == dofs_per_cell,
- ExcDimensionMismatch(indices.size(), dofs_per_cell));
- // This vector has one entry for
- // each quadrature point
+ ExcDimensionMismatch(indices.size(), dofs_per_cell));
+ // This vector has one entry for
+ // each quadrature point
Assert (gradients.size() == n_quadrature_points,
- ExcDimensionMismatch(gradients.size(), n_quadrature_points));
+ ExcDimensionMismatch(gradients.size(), n_quadrature_points));
- // initialize with zero
+ // initialize with zero
std::fill_n (gradients.begin(), n_quadrature_points, Tensor<1,spacedim>());
- // add up contributions of trial
- // functions. note that here we
- // deal with scalar finite
- // elements, so no need to check
- // for non-primitivity of shape
- // functions. in order to increase
- // the speed of this function, we
- // directly access the data in the
- // shape_gradients array, and
- // increment pointers for accessing
- // the data. this saves some lookup
- // time and indexing. moreover, the
- // order of the loops is such that
- // we can access the
- // shape_gradients data stored
- // contiguously (which is also
- // advantageous because access to
- // the global vector fe_function is
- // more expensive than access to
- // the small std::vector gradients
- // - so we do the cheaper operation
- // in the innermost loop)
+ // add up contributions of trial
+ // functions. note that here we
+ // deal with scalar finite
+ // elements, so no need to check
+ // for non-primitivity of shape
+ // functions. in order to increase
+ // the speed of this function, we
+ // directly access the data in the
+ // shape_gradients array, and
+ // increment pointers for accessing
+ // the data. this saves some lookup
+ // time and indexing. moreover, the
+ // order of the loops is such that
+ // we can access the
+ // shape_gradients data stored
+ // contiguously (which is also
+ // advantageous because access to
+ // the global vector fe_function is
+ // more expensive than access to
+ // the small std::vector gradients
+ // - so we do the cheaper operation
+ // in the innermost loop)
for (unsigned int shape_func=0; shape_func<dofs_per_cell; ++shape_func)
{
const double value = get_vector_element (fe_function, indices[shape_func]);
if (value == 0.)
- continue;
+ continue;
const Tensor<1,spacedim> *shape_gradient_ptr
- = &this->shape_gradients[shape_func][0];
+ = &this->shape_gradients[shape_func][0];
for (unsigned int point=0; point<n_quadrature_points; ++point)
- gradients[point] += value * *shape_gradient_ptr++;
+ gradients[point] += value * *shape_gradient_ptr++;
}
}
std::vector<std::vector<Tensor<1,spacedim> > > &gradients) const
{
Assert (gradients.size() == n_quadrature_points,
- ExcDimensionMismatch(gradients.size(), n_quadrature_points));
+ ExcDimensionMismatch(gradients.size(), n_quadrature_points));
const unsigned int n_components = fe->n_components();
for (unsigned i=0; i<gradients.size(); ++i)
Assert (gradients[i].size() == n_components,
- ExcDimensionMismatch(gradients[i].size(), n_components));
+ ExcDimensionMismatch(gradients[i].size(), n_components));
Assert (this->update_flags & update_gradients, ExcAccessToUninitializedField());
Assert (present_cell.get() != 0,
- ExcMessage ("FEValues object is not reinit'ed to any cell"));
+ ExcMessage ("FEValues object is not reinit'ed to any cell"));
Assert (fe_function.size() == present_cell->n_dofs_for_dof_handler(),
- ExcDimensionMismatch(fe_function.size(),
- present_cell->n_dofs_for_dof_handler()));
+ ExcDimensionMismatch(fe_function.size(),
+ present_cell->n_dofs_for_dof_handler()));
- // get function values of dofs
- // on this cell
+ // get function values of dofs
+ // on this cell
Vector<typename ValueType<InputVector>::type> dof_values (dofs_per_cell);
present_cell->get_interpolated_dof_values(fe_function, dof_values);
- // initialize with zero
+ // initialize with zero
for (unsigned i=0;i<gradients.size();++i)
std::fill_n (gradients[i].begin(), gradients[i].size(), Tensor<1,spacedim>());
- // add up contributions of trial
- // functions. now check whether the
- // shape function is primitive or
- // not. if it is, then set its only
- // non-zero component, otherwise
- // loop over components
+ // add up contributions of trial
+ // functions. now check whether the
+ // shape function is primitive or
+ // not. if it is, then set its only
+ // non-zero component, otherwise
+ // loop over components
for (unsigned int shape_func=0; shape_func<dofs_per_cell; ++shape_func)
{
const double value = dof_values(shape_func);
if (value == 0.)
- continue;
+ continue;
if (fe->is_primitive(shape_func))
- {
- const unsigned int
- row = fe->is_primitive() ?
- shape_func : this->shape_function_to_row_table[shape_func];
- const Tensor<1,spacedim> *shape_gradient_ptr
- = &this->shape_gradients[row][0];
- const unsigned int comp = fe->system_to_component_index(shape_func).first;
- for (unsigned int point=0; point<n_quadrature_points; ++point)
- gradients[point][comp] += value * *shape_gradient_ptr++;
- }
+ {
+ const unsigned int
+ row = fe->is_primitive() ?
+ shape_func : this->shape_function_to_row_table[shape_func];
+ const Tensor<1,spacedim> *shape_gradient_ptr
+ = &this->shape_gradients[row][0];
+ const unsigned int comp = fe->system_to_component_index(shape_func).first;
+ for (unsigned int point=0; point<n_quadrature_points; ++point)
+ gradients[point][comp] += value * *shape_gradient_ptr++;
+ }
else
- for (unsigned int c=0; c<n_components; ++c)
- {
- if (fe->get_nonzero_components(shape_func)[c] == false)
- continue;
-
- const unsigned int
- row = (this->shape_function_to_row_table[shape_func]
- +
- std::count (fe->get_nonzero_components(shape_func).begin(),
- fe->get_nonzero_components(shape_func).begin()+c,
- true));
-
- const Tensor<1,spacedim> *shape_gradient_ptr
- = &this->shape_gradients[row][0];
-
- for (unsigned int point=0; point<n_quadrature_points; ++point)
- gradients[point][c] += value * *shape_gradient_ptr++;
- }
+ for (unsigned int c=0; c<n_components; ++c)
+ {
+ if (fe->get_nonzero_components(shape_func)[c] == false)
+ continue;
+
+ const unsigned int
+ row = (this->shape_function_to_row_table[shape_func]
+ +
+ std::count (fe->get_nonzero_components(shape_func).begin(),
+ fe->get_nonzero_components(shape_func).begin()+c,
+ true));
+
+ const Tensor<1,spacedim> *shape_gradient_ptr
+ = &this->shape_gradients[row][0];
+
+ for (unsigned int point=0; point<n_quadrature_points; ++point)
+ gradients[point][c] += value * *shape_gradient_ptr++;
+ }
}
}
{
const unsigned int n_components = fe->n_components();
- // Size of indices must be a
- // multiple of dofs_per_cell such
- // that an integer number of
- // function values is generated in
- // each point.
+ // Size of indices must be a
+ // multiple of dofs_per_cell such
+ // that an integer number of
+ // function values is generated in
+ // each point.
Assert (indices.size() % dofs_per_cell == 0,
- ExcNotMultiple(indices.size(), dofs_per_cell));
+ ExcNotMultiple(indices.size(), dofs_per_cell));
- // The number of components of the
- // result may be a multiple of the
- // number of components of the
- // finite element
+ // The number of components of the
+ // result may be a multiple of the
+ // number of components of the
+ // finite element
const unsigned int result_components = indices.size() * n_components / dofs_per_cell;
- // Check if the value argument is
- // initialized to the correct sizes
+ // Check if the value argument is
+ // initialized to the correct sizes
if (quadrature_points_fastest)
{
Assert (gradients.size() == result_components,
- ExcDimensionMismatch(gradients.size(), result_components));
+ ExcDimensionMismatch(gradients.size(), result_components));
for (unsigned i=0;i<gradients.size();++i)
- Assert (gradients[i].size() == n_quadrature_points,
- ExcDimensionMismatch(gradients[i].size(), n_quadrature_points));
+ Assert (gradients[i].size() == n_quadrature_points,
+ ExcDimensionMismatch(gradients[i].size(), n_quadrature_points));
}
else
{
Assert(gradients.size() == n_quadrature_points,
- ExcDimensionMismatch(gradients.size(), n_quadrature_points));
+ ExcDimensionMismatch(gradients.size(), n_quadrature_points));
for (unsigned i=0;i<gradients.size();++i)
- Assert (gradients[i].size() == result_components,
- ExcDimensionMismatch(gradients[i].size(), result_components));
+ Assert (gradients[i].size() == result_components,
+ ExcDimensionMismatch(gradients[i].size(), result_components));
}
- // If the result has more
- // components than the finite
- // element, we need this number for
- // loops filling all components
+ // If the result has more
+ // components than the finite
+ // element, we need this number for
+ // loops filling all components
const unsigned int component_multiple = result_components / n_components;
Assert (this->update_flags & update_gradients, ExcAccessToUninitializedField());
- // initialize with zero
+ // initialize with zero
for (unsigned i=0;i<gradients.size();++i)
std::fill_n (gradients[i].begin(), gradients[i].size(), Tensor<1,spacedim>());
- // add up contributions of trial
- // functions. now check whether the
- // shape function is primitive or
- // not. if it is, then set its only
- // non-zero component, otherwise
- // loop over components
+ // add up contributions of trial
+ // functions. now check whether the
+ // shape function is primitive or
+ // not. if it is, then set its only
+ // non-zero component, otherwise
+ // loop over components
for (unsigned int mc = 0; mc < component_multiple; ++mc)
for (unsigned int shape_func=0; shape_func<dofs_per_cell; ++shape_func)
{
- const double value = get_vector_element (fe_function, indices[shape_func+mc*dofs_per_cell]);
- if (value == 0.)
- continue;
-
- if (fe->is_primitive(shape_func))
- {
- const unsigned int
- row = fe->is_primitive() ?
- shape_func : this->shape_function_to_row_table[shape_func];
- const Tensor<1,spacedim> *shape_gradient_ptr
- = &this->shape_gradients[row][0];
- const unsigned int comp = fe->system_to_component_index(shape_func).first
- + mc * n_components;
-
- if (quadrature_points_fastest)
- for (unsigned int point=0; point<n_quadrature_points; ++point)
- gradients[comp][point] += value * *shape_gradient_ptr++;
- else
- for (unsigned int point=0; point<n_quadrature_points; ++point)
- gradients[point][comp] += value * *shape_gradient_ptr++;
- }
- else
- for (unsigned int c=0; c<n_components; ++c)
- {
- if (fe->get_nonzero_components(shape_func)[c] == false)
- continue;
-
- const unsigned int
- row = (this->shape_function_to_row_table[shape_func]
- +
- std::count (fe->get_nonzero_components(shape_func).begin(),
- fe->get_nonzero_components(shape_func).begin()+c,
- true));
-
- const Tensor<1,spacedim> *shape_gradient_ptr
- = &this->shape_gradients[row][0];
- const unsigned int comp = c + mc * n_components;
-
- if (quadrature_points_fastest)
- for (unsigned int point=0; point<n_quadrature_points; ++point)
- gradients[comp][point] += value * *shape_gradient_ptr++;
- else
- for (unsigned int point=0; point<n_quadrature_points; ++point)
- gradients[point][comp] += value * *shape_gradient_ptr++;
- }
+ const double value = get_vector_element (fe_function, indices[shape_func+mc*dofs_per_cell]);
+ if (value == 0.)
+ continue;
+
+ if (fe->is_primitive(shape_func))
+ {
+ const unsigned int
+ row = fe->is_primitive() ?
+ shape_func : this->shape_function_to_row_table[shape_func];
+ const Tensor<1,spacedim> *shape_gradient_ptr
+ = &this->shape_gradients[row][0];
+ const unsigned int comp = fe->system_to_component_index(shape_func).first
+ + mc * n_components;
+
+ if (quadrature_points_fastest)
+ for (unsigned int point=0; point<n_quadrature_points; ++point)
+ gradients[comp][point] += value * *shape_gradient_ptr++;
+ else
+ for (unsigned int point=0; point<n_quadrature_points; ++point)
+ gradients[point][comp] += value * *shape_gradient_ptr++;
+ }
+ else
+ for (unsigned int c=0; c<n_components; ++c)
+ {
+ if (fe->get_nonzero_components(shape_func)[c] == false)
+ continue;
+
+ const unsigned int
+ row = (this->shape_function_to_row_table[shape_func]
+ +
+ std::count (fe->get_nonzero_components(shape_func).begin(),
+ fe->get_nonzero_components(shape_func).begin()+c,
+ true));
+
+ const Tensor<1,spacedim> *shape_gradient_ptr
+ = &this->shape_gradients[row][0];
+ const unsigned int comp = c + mc * n_components;
+
+ if (quadrature_points_fastest)
+ for (unsigned int point=0; point<n_quadrature_points; ++point)
+ gradients[comp][point] += value * *shape_gradient_ptr++;
+ else
+ for (unsigned int point=0; point<n_quadrature_points; ++point)
+ gradients[point][comp] += value * *shape_gradient_ptr++;
+ }
}
}
void
FEValuesBase<dim,spacedim>::
get_function_hessians (const InputVector &fe_function,
- std::vector<Tensor<2,spacedim> > &hessians) const
+ std::vector<Tensor<2,spacedim> > &hessians) const
{
Assert (fe->n_components() == 1,
- ExcDimensionMismatch(fe->n_components(), 1));
+ ExcDimensionMismatch(fe->n_components(), 1));
Assert (hessians.size() == n_quadrature_points,
- ExcDimensionMismatch(hessians.size(), n_quadrature_points));
+ ExcDimensionMismatch(hessians.size(), n_quadrature_points));
Assert (this->update_flags & update_hessians, ExcAccessToUninitializedField());
Assert (present_cell.get() != 0,
- ExcMessage ("FEValues object is not reinit'ed to any cell"));
+ ExcMessage ("FEValues object is not reinit'ed to any cell"));
Assert (fe_function.size() == present_cell->n_dofs_for_dof_handler(),
- ExcDimensionMismatch(fe_function.size(),
- present_cell->n_dofs_for_dof_handler()));
+ ExcDimensionMismatch(fe_function.size(),
+ present_cell->n_dofs_for_dof_handler()));
- // get function values of dofs
- // on this cell
+ // get function values of dofs
+ // on this cell
Vector<typename ValueType<InputVector>::type> dof_values (dofs_per_cell);
present_cell->get_interpolated_dof_values(fe_function, dof_values);
- // initialize with zero
+ // initialize with zero
std::fill_n (hessians.begin(), n_quadrature_points, Tensor<2,spacedim>());
- // add up contributions of trial
- // functions. note that here we
- // deal with scalar finite
- // elements, so no need to check
- // for non-primitivity of shape
- // functions
+ // add up contributions of trial
+ // functions. note that here we
+ // deal with scalar finite
+ // elements, so no need to check
+ // for non-primitivity of shape
+ // functions
for (unsigned int shape_func=0; shape_func<dofs_per_cell; ++shape_func)
{
const double value = dof_values(shape_func);
if (value == 0.)
- continue;
+ continue;
const Tensor<2,spacedim> *shape_hessians_ptr
- = &this->shape_hessians[shape_func][0];
+ = &this->shape_hessians[shape_func][0];
for (unsigned int point=0; point<n_quadrature_points; ++point)
- hessians[point] += value * *shape_hessians_ptr++;
+ hessians[point] += value * *shape_hessians_ptr++;
}
}
std::vector<Tensor<2,spacedim> > &hessians) const
{
Assert (this->update_flags & update_second_derivatives, ExcAccessToUninitializedField());
- // This function fills a single
- // component only
+ // This function fills a single
+ // component only
Assert (fe->n_components() == 1,
- ExcDimensionMismatch(fe->n_components(), 1));
- // One index for each dof
+ ExcDimensionMismatch(fe->n_components(), 1));
+ // One index for each dof
Assert (indices.size() == dofs_per_cell,
- ExcDimensionMismatch(indices.size(), dofs_per_cell));
- // This vector has one entry for
- // each quadrature point
+ ExcDimensionMismatch(indices.size(), dofs_per_cell));
+ // This vector has one entry for
+ // each quadrature point
Assert (hessians.size() == n_quadrature_points,
- ExcDimensionMismatch(hessians.size(), n_quadrature_points));
+ ExcDimensionMismatch(hessians.size(), n_quadrature_points));
- // initialize with zero
+ // initialize with zero
std::fill_n (hessians.begin(), n_quadrature_points, Tensor<2,spacedim>());
- // add up contributions of trial
- // functions. note that here we
- // deal with scalar finite
- // elements, so no need to check
- // for non-primitivity of shape
- // functions
+ // add up contributions of trial
+ // functions. note that here we
+ // deal with scalar finite
+ // elements, so no need to check
+ // for non-primitivity of shape
+ // functions
for (unsigned int shape_func=0; shape_func<dofs_per_cell; ++shape_func)
{
const double value = get_vector_element (fe_function, indices[shape_func]);
if (value == 0.)
- continue;
+ continue;
const Tensor<2,spacedim> *shape_hessians_ptr
- = &this->shape_hessians[shape_func][0];
+ = &this->shape_hessians[shape_func][0];
for (unsigned int point=0; point<n_quadrature_points; ++point)
- hessians[point] += value * *shape_hessians_ptr++;
+ hessians[point] += value * *shape_hessians_ptr++;
}
}
void
FEValuesBase<dim,spacedim>::
get_function_hessians (const InputVector &fe_function,
- std::vector<std::vector<Tensor<2,spacedim> > > &hessians,
- bool quadrature_points_fastest) const
+ std::vector<std::vector<Tensor<2,spacedim> > > &hessians,
+ bool quadrature_points_fastest) const
{
Assert (n_quadrature_points == hessians.size(),
- ExcDimensionMismatch(hessians.size(), n_quadrature_points));
+ ExcDimensionMismatch(hessians.size(), n_quadrature_points));
const unsigned int n_components = fe->n_components();
for (unsigned i=0;i<hessians.size();++i)
Assert (hessians[i].size() == n_components,
- ExcDimensionMismatch(hessians[i].size(), n_components));
+ ExcDimensionMismatch(hessians[i].size(), n_components));
Assert (this->update_flags & update_hessians, ExcAccessToUninitializedField());
Assert (present_cell.get() != 0,
- ExcMessage ("FEValues object is not reinit'ed to any cell"));
+ ExcMessage ("FEValues object is not reinit'ed to any cell"));
Assert (fe_function.size() == present_cell->n_dofs_for_dof_handler(),
- ExcDimensionMismatch(fe_function.size(),
- present_cell->n_dofs_for_dof_handler()));
+ ExcDimensionMismatch(fe_function.size(),
+ present_cell->n_dofs_for_dof_handler()));
- // get function values of dofs
- // on this cell
+ // get function values of dofs
+ // on this cell
Vector<typename ValueType<InputVector>::type> dof_values (dofs_per_cell);
present_cell->get_interpolated_dof_values(fe_function, dof_values);
- // initialize with zero
+ // initialize with zero
for (unsigned i=0;i<hessians.size();++i)
std::fill_n (hessians[i].begin(), hessians[i].size(), Tensor<2,spacedim>());
- // add up contributions of trial
- // functions
+ // add up contributions of trial
+ // functions
for (unsigned int shape_func=0; shape_func<dofs_per_cell; ++shape_func)
{
const double value = dof_values(shape_func);
if (value == 0.)
- continue;
+ continue;
if (fe->is_primitive(shape_func))
- {
- const unsigned int
- row = fe->is_primitive() ?
- shape_func : this->shape_function_to_row_table[shape_func];
-
- const Tensor<2,spacedim> *shape_hessian_ptr
- = &this->shape_hessians[row][0];
- const unsigned int comp = fe->system_to_component_index(shape_func).first;
-
- if (quadrature_points_fastest)
- for (unsigned int point=0; point<n_quadrature_points; ++point)
- hessians[comp][point] += value * *shape_hessian_ptr++;
- else
- for (unsigned int point=0; point<n_quadrature_points; ++point)
- hessians[point][comp] += value * *shape_hessian_ptr++;
- }
+ {
+ const unsigned int
+ row = fe->is_primitive() ?
+ shape_func : this->shape_function_to_row_table[shape_func];
+
+ const Tensor<2,spacedim> *shape_hessian_ptr
+ = &this->shape_hessians[row][0];
+ const unsigned int comp = fe->system_to_component_index(shape_func).first;
+
+ if (quadrature_points_fastest)
+ for (unsigned int point=0; point<n_quadrature_points; ++point)
+ hessians[comp][point] += value * *shape_hessian_ptr++;
+ else
+ for (unsigned int point=0; point<n_quadrature_points; ++point)
+ hessians[point][comp] += value * *shape_hessian_ptr++;
+ }
else
- for (unsigned int c=0; c<n_components; ++c)
- {
- if (fe->get_nonzero_components(shape_func)[c] == false)
- continue;
-
- const unsigned int
- row = (this->shape_function_to_row_table[shape_func]
- +
- std::count (fe->get_nonzero_components(shape_func).begin(),
- fe->get_nonzero_components(shape_func).begin()+c,
- true));
-
- const Tensor<2,spacedim> *shape_hessian_ptr
- = &this->shape_hessians[row][0];
-
- if (quadrature_points_fastest)
- for (unsigned int point=0; point<n_quadrature_points; ++point)
- hessians[c][point] += value * *shape_hessian_ptr++;
- else
- for (unsigned int point=0; point<n_quadrature_points; ++point)
- hessians[point][c] += value * *shape_hessian_ptr++;
- }
+ for (unsigned int c=0; c<n_components; ++c)
+ {
+ if (fe->get_nonzero_components(shape_func)[c] == false)
+ continue;
+
+ const unsigned int
+ row = (this->shape_function_to_row_table[shape_func]
+ +
+ std::count (fe->get_nonzero_components(shape_func).begin(),
+ fe->get_nonzero_components(shape_func).begin()+c,
+ true));
+
+ const Tensor<2,spacedim> *shape_hessian_ptr
+ = &this->shape_hessians[row][0];
+
+ if (quadrature_points_fastest)
+ for (unsigned int point=0; point<n_quadrature_points; ++point)
+ hessians[c][point] += value * *shape_hessian_ptr++;
+ else
+ for (unsigned int point=0; point<n_quadrature_points; ++point)
+ hessians[point][c] += value * *shape_hessian_ptr++;
+ }
}
}
const unsigned int n_components = fe->n_components();
- // Size of indices must be a
- // multiple of dofs_per_cell such
- // that an integer number of
- // function values is generated in
- // each point.
+ // Size of indices must be a
+ // multiple of dofs_per_cell such
+ // that an integer number of
+ // function values is generated in
+ // each point.
Assert (indices.size() % dofs_per_cell == 0,
- ExcNotMultiple(indices.size(), dofs_per_cell));
+ ExcNotMultiple(indices.size(), dofs_per_cell));
- // The number of components of the
- // result may be a multiple of the
- // number of components of the
- // finite element
+ // The number of components of the
+ // result may be a multiple of the
+ // number of components of the
+ // finite element
const unsigned int result_components = indices.size() * n_components / dofs_per_cell;
- // Check if the value argument is
- // initialized to the correct sizes
+ // Check if the value argument is
+ // initialized to the correct sizes
if (quadrature_points_fastest)
{
Assert (hessians.size() == result_components,
- ExcDimensionMismatch(hessians.size(), result_components));
+ ExcDimensionMismatch(hessians.size(), result_components));
for (unsigned i=0;i<hessians.size();++i)
- Assert (hessians[i].size() == n_quadrature_points,
- ExcDimensionMismatch(hessians[i].size(), n_quadrature_points));
+ Assert (hessians[i].size() == n_quadrature_points,
+ ExcDimensionMismatch(hessians[i].size(), n_quadrature_points));
}
else
{
Assert(hessians.size() == n_quadrature_points,
- ExcDimensionMismatch(hessians.size(), n_quadrature_points));
+ ExcDimensionMismatch(hessians.size(), n_quadrature_points));
for (unsigned i=0;i<hessians.size();++i)
- Assert (hessians[i].size() == result_components,
- ExcDimensionMismatch(hessians[i].size(), result_components));
+ Assert (hessians[i].size() == result_components,
+ ExcDimensionMismatch(hessians[i].size(), result_components));
}
- // If the result has more
- // components than the finite
- // element, we need this number for
- // loops filling all components
+ // If the result has more
+ // components than the finite
+ // element, we need this number for
+ // loops filling all components
const unsigned int component_multiple = result_components / n_components;
- // initialize with zero
+ // initialize with zero
for (unsigned i=0;i<hessians.size();++i)
std::fill_n (hessians[i].begin(), hessians[i].size(), Tensor<2,spacedim>());
- // add up contributions of trial
- // functions. now check whether the
- // shape function is primitive or
- // not. if it is, then set its only
- // non-zero component, otherwise
- // loop over components
+ // add up contributions of trial
+ // functions. now check whether the
+ // shape function is primitive or
+ // not. if it is, then set its only
+ // non-zero component, otherwise
+ // loop over components
for (unsigned int mc = 0; mc < component_multiple; ++mc)
for (unsigned int shape_func=0; shape_func<dofs_per_cell; ++shape_func)
{
- const double value = get_vector_element (fe_function, indices[shape_func+mc*dofs_per_cell]);
- if (value == 0.)
- continue;
-
- if (fe->is_primitive(shape_func))
- {
- const unsigned int
- row = fe->is_primitive() ?
- shape_func : this->shape_function_to_row_table[shape_func];
-
- const Tensor<2,spacedim> *shape_hessian_ptr
- = &this->shape_hessians[row][0];
- const unsigned int comp = fe->system_to_component_index(shape_func).first
- + mc * n_components;
-
- if (quadrature_points_fastest)
- for (unsigned int point=0; point<n_quadrature_points; ++point)
- hessians[comp][point] += value * *shape_hessian_ptr++;
- else
- for (unsigned int point=0; point<n_quadrature_points; ++point)
- hessians[point][comp] += value * *shape_hessian_ptr++;
- }
- else
- for (unsigned int c=0; c<n_components; ++c)
- {
- if (fe->get_nonzero_components(shape_func)[c] == false)
- continue;
-
- const unsigned int
- row = (this->shape_function_to_row_table[shape_func]
- +
- std::count (fe->get_nonzero_components(shape_func).begin(),
- fe->get_nonzero_components(shape_func).begin()+c,
- true));
-
- const Tensor<2,spacedim> *shape_hessian_ptr
- = &this->shape_hessians[row][0];
- const unsigned int comp = c + mc * n_components;
-
- if (quadrature_points_fastest)
- for (unsigned int point=0; point<n_quadrature_points; ++point)
- hessians[comp][point] += value * *shape_hessian_ptr++;
- else
- for (unsigned int point=0; point<n_quadrature_points; ++point)
- hessians[point][comp] += value * *shape_hessian_ptr++;
- }
+ const double value = get_vector_element (fe_function, indices[shape_func+mc*dofs_per_cell]);
+ if (value == 0.)
+ continue;
+
+ if (fe->is_primitive(shape_func))
+ {
+ const unsigned int
+ row = fe->is_primitive() ?
+ shape_func : this->shape_function_to_row_table[shape_func];
+
+ const Tensor<2,spacedim> *shape_hessian_ptr
+ = &this->shape_hessians[row][0];
+ const unsigned int comp = fe->system_to_component_index(shape_func).first
+ + mc * n_components;
+
+ if (quadrature_points_fastest)
+ for (unsigned int point=0; point<n_quadrature_points; ++point)
+ hessians[comp][point] += value * *shape_hessian_ptr++;
+ else
+ for (unsigned int point=0; point<n_quadrature_points; ++point)
+ hessians[point][comp] += value * *shape_hessian_ptr++;
+ }
+ else
+ for (unsigned int c=0; c<n_components; ++c)
+ {
+ if (fe->get_nonzero_components(shape_func)[c] == false)
+ continue;
+
+ const unsigned int
+ row = (this->shape_function_to_row_table[shape_func]
+ +
+ std::count (fe->get_nonzero_components(shape_func).begin(),
+ fe->get_nonzero_components(shape_func).begin()+c,
+ true));
+
+ const Tensor<2,spacedim> *shape_hessian_ptr
+ = &this->shape_hessians[row][0];
+ const unsigned int comp = c + mc * n_components;
+
+ if (quadrature_points_fastest)
+ for (unsigned int point=0; point<n_quadrature_points; ++point)
+ hessians[comp][point] += value * *shape_hessian_ptr++;
+ else
+ for (unsigned int point=0; point<n_quadrature_points; ++point)
+ hessians[point][comp] += value * *shape_hessian_ptr++;
+ }
}
}
{
Assert (this->update_flags & update_hessians, ExcAccessToUninitializedField());
Assert (fe->n_components() == 1,
- ExcDimensionMismatch(fe->n_components(), 1));
+ ExcDimensionMismatch(fe->n_components(), 1));
Assert (laplacians.size() == n_quadrature_points,
- ExcDimensionMismatch(laplacians.size(), n_quadrature_points));
+ ExcDimensionMismatch(laplacians.size(), n_quadrature_points));
Assert (present_cell.get() != 0,
- ExcMessage ("FEValues object is not reinit'ed to any cell"));
+ ExcMessage ("FEValues object is not reinit'ed to any cell"));
Assert (fe_function.size() == present_cell->n_dofs_for_dof_handler(),
- ExcDimensionMismatch(fe_function.size(),
- present_cell->n_dofs_for_dof_handler()));
+ ExcDimensionMismatch(fe_function.size(),
+ present_cell->n_dofs_for_dof_handler()));
- // get function values of dofs
- // on this cell
+ // get function values of dofs
+ // on this cell
Vector<typename ValueType<InputVector>::type> dof_values (dofs_per_cell);
present_cell->get_interpolated_dof_values(fe_function, dof_values);
- // initialize with zero
+ // initialize with zero
std::fill_n (laplacians.begin(), n_quadrature_points, 0);
- // add up contributions of trial
- // functions. note that here we
- // deal with scalar finite
- // elements, so no need to check
- // for non-primitivity of shape
- // functions. note that the
- // laplacian is the trace of the
- // hessian, so we use a pointer to
- // the hessians and get their trace
+ // add up contributions of trial
+ // functions. note that here we
+ // deal with scalar finite
+ // elements, so no need to check
+ // for non-primitivity of shape
+ // functions. note that the
+ // laplacian is the trace of the
+ // hessian, so we use a pointer to
+ // the hessians and get their trace
for (unsigned int shape_func=0; shape_func<dofs_per_cell; ++shape_func)
{
const double value = dof_values(shape_func);
if (value == 0.)
- continue;
+ continue;
const Tensor<2,spacedim> *shape_hessian_ptr
- = &this->shape_hessians[shape_func][0];
+ = &this->shape_hessians[shape_func][0];
for (unsigned int point=0; point<n_quadrature_points; ++point)
- laplacians[point] += value * trace(*shape_hessian_ptr++);
+ laplacians[point] += value * trace(*shape_hessian_ptr++);
}
}
std::vector<number> &laplacians) const
{
Assert (this->update_flags & update_hessians, ExcAccessToUninitializedField());
- // This function fills a single
- // component only
+ // This function fills a single
+ // component only
Assert (fe->n_components() == 1,
- ExcDimensionMismatch(fe->n_components(), 1));
- // One index for each dof
+ ExcDimensionMismatch(fe->n_components(), 1));
+ // One index for each dof
Assert (indices.size() == dofs_per_cell,
- ExcDimensionMismatch(indices.size(), dofs_per_cell));
- // This vector has one entry for
- // each quadrature point
+ ExcDimensionMismatch(indices.size(), dofs_per_cell));
+ // This vector has one entry for
+ // each quadrature point
Assert (laplacians.size() == n_quadrature_points,
- ExcDimensionMismatch(laplacians.size(), n_quadrature_points));
+ ExcDimensionMismatch(laplacians.size(), n_quadrature_points));
- // initialize with zero
+ // initialize with zero
std::fill_n (laplacians.begin(), n_quadrature_points, 0);
- // add up contributions of trial
- // functions. note that here we
- // deal with scalar finite
- // elements, so no need to check
- // for non-primitivity of shape
- // functions. note that the
- // laplacian is the trace of the
- // hessian, so we use a pointer to
- // the hessians and get their trace
+ // add up contributions of trial
+ // functions. note that here we
+ // deal with scalar finite
+ // elements, so no need to check
+ // for non-primitivity of shape
+ // functions. note that the
+ // laplacian is the trace of the
+ // hessian, so we use a pointer to
+ // the hessians and get their trace
for (unsigned int shape_func=0; shape_func<dofs_per_cell; ++shape_func)
{
const double value = get_vector_element (fe_function, indices[shape_func]);
if (value == 0.)
- continue;
+ continue;
const Tensor<2,spacedim> *shape_hessian_ptr
- = &this->shape_hessians[shape_func][0];
+ = &this->shape_hessians[shape_func][0];
for (unsigned int point=0; point<n_quadrature_points; ++point)
- laplacians[point] += value * trace(*shape_hessian_ptr++);
+ laplacians[point] += value * trace(*shape_hessian_ptr++);
}
}
std::vector<Vector<number> >& laplacians) const
{
//TODO: Find out how to do this assertion.
- // This vector must correspond to a
- // complete discretization
+ // This vector must correspond to a
+ // complete discretization
// Assert (fe_function.size() == present_cell->get_dof_handler().n_dofs(),
-// ExcDimensionMismatch(fe_function.size(),
-// present_cell->get_dof_handler().n_dofs()));
- // One entry per quadrature point
+// ExcDimensionMismatch(fe_function.size(),
+// present_cell->get_dof_handler().n_dofs()));
+ // One entry per quadrature point
Assert (present_cell.get() != 0,
- ExcMessage ("FEValues object is not reinit'ed to any cell"));
+ ExcMessage ("FEValues object is not reinit'ed to any cell"));
Assert (laplacians.size() == n_quadrature_points,
- ExcDimensionMismatch(laplacians.size(), n_quadrature_points));
+ ExcDimensionMismatch(laplacians.size(), n_quadrature_points));
const unsigned int n_components = fe->n_components();
- // Assert that we can write all
- // components into the result
- // vectors
+ // Assert that we can write all
+ // components into the result
+ // vectors
for (unsigned i=0;i<laplacians.size();++i)
Assert (laplacians[i].size() == n_components,
- ExcDimensionMismatch(laplacians[i].size(), n_components));
+ ExcDimensionMismatch(laplacians[i].size(), n_components));
Assert (this->update_flags & update_hessians, ExcAccessToUninitializedField());
Assert (fe_function.size() == present_cell->n_dofs_for_dof_handler(),
- ExcDimensionMismatch(fe_function.size(), present_cell->n_dofs_for_dof_handler()));
+ ExcDimensionMismatch(fe_function.size(), present_cell->n_dofs_for_dof_handler()));
- // get function values of dofs
- // on this cell
+ // get function values of dofs
+ // on this cell
Vector<typename ValueType<InputVector>::type> dof_values (dofs_per_cell);
present_cell->get_interpolated_dof_values(fe_function, dof_values);
- // initialize with zero
+ // initialize with zero
for (unsigned i=0;i<laplacians.size();++i)
std::fill_n (laplacians[i].begin(), laplacians[i].size(), 0);
- // add up contributions of trial
- // functions. now check whether the
- // shape function is primitive or
- // not. if it is, then set its only
- // non-zero component, otherwise
- // loop over components
+ // add up contributions of trial
+ // functions. now check whether the
+ // shape function is primitive or
+ // not. if it is, then set its only
+ // non-zero component, otherwise
+ // loop over components
for (unsigned int shape_func=0; shape_func<dofs_per_cell; ++shape_func)
{
const double value = dof_values(shape_func);
if (value == 0.)
- continue;
+ continue;
if (fe->is_primitive(shape_func))
- {
- const unsigned int
- row = fe->is_primitive() ?
- shape_func : this->shape_function_to_row_table[shape_func];
-
- const Tensor<2,spacedim> *shape_hessian_ptr
- = &this->shape_hessians[row][0];
- const unsigned int comp = fe->system_to_component_index(shape_func).first;
- for (unsigned int point=0; point<n_quadrature_points; ++point)
- laplacians[point](comp) += value * trace(*shape_hessian_ptr++);
- }
+ {
+ const unsigned int
+ row = fe->is_primitive() ?
+ shape_func : this->shape_function_to_row_table[shape_func];
+
+ const Tensor<2,spacedim> *shape_hessian_ptr
+ = &this->shape_hessians[row][0];
+ const unsigned int comp = fe->system_to_component_index(shape_func).first;
+ for (unsigned int point=0; point<n_quadrature_points; ++point)
+ laplacians[point](comp) += value * trace(*shape_hessian_ptr++);
+ }
else
- for (unsigned int c=0; c<n_components; ++c)
- {
- if (fe->get_nonzero_components(shape_func)[c] == false)
- continue;
-
- const unsigned int
- row = (this->shape_function_to_row_table[shape_func]
- +
- std::count (fe->get_nonzero_components(shape_func).begin(),
- fe->get_nonzero_components(shape_func).begin()+c,
- true));
-
- const Tensor<2,spacedim> *shape_hessian_ptr
- = &this->shape_hessians[row][0];
-
- for (unsigned int point=0; point<n_quadrature_points; ++point)
- laplacians[point](c) += value * trace(*shape_hessian_ptr++);
- }
+ for (unsigned int c=0; c<n_components; ++c)
+ {
+ if (fe->get_nonzero_components(shape_func)[c] == false)
+ continue;
+
+ const unsigned int
+ row = (this->shape_function_to_row_table[shape_func]
+ +
+ std::count (fe->get_nonzero_components(shape_func).begin(),
+ fe->get_nonzero_components(shape_func).begin()+c,
+ true));
+
+ const Tensor<2,spacedim> *shape_hessian_ptr
+ = &this->shape_hessians[row][0];
+
+ for (unsigned int point=0; point<n_quadrature_points; ++point)
+ laplacians[point](c) += value * trace(*shape_hessian_ptr++);
+ }
}
}
const VectorSlice<const std::vector<unsigned int> >& indices,
std::vector<Vector<number> >& laplacians) const
{
- // One value per quadrature point
+ // One value per quadrature point
Assert (n_quadrature_points == laplacians.size(),
- ExcDimensionMismatch(laplacians.size(), n_quadrature_points));
+ ExcDimensionMismatch(laplacians.size(), n_quadrature_points));
const unsigned int n_components = fe->n_components();
- // Size of indices must be a
- // multiple of dofs_per_cell such
- // that an integer number of
- // function values is generated in
- // each point.
+ // Size of indices must be a
+ // multiple of dofs_per_cell such
+ // that an integer number of
+ // function values is generated in
+ // each point.
Assert (indices.size() % dofs_per_cell == 0,
- ExcNotMultiple(indices.size(), dofs_per_cell));
+ ExcNotMultiple(indices.size(), dofs_per_cell));
- // The number of components of the
- // result may be a multiple of the
- // number of components of the
- // finite element
+ // The number of components of the
+ // result may be a multiple of the
+ // number of components of the
+ // finite element
const unsigned int result_components = indices.size() * n_components / dofs_per_cell;
for (unsigned i=0;i<laplacians.size();++i)
Assert (laplacians[i].size() == result_components,
- ExcDimensionMismatch(laplacians[i].size(), result_components));
+ ExcDimensionMismatch(laplacians[i].size(), result_components));
- // If the result has more
- // components than the finite
- // element, we need this number for
- // loops filling all components
+ // If the result has more
+ // components than the finite
+ // element, we need this number for
+ // loops filling all components
const unsigned int component_multiple = result_components / n_components;
Assert (this->update_flags & update_hessians, ExcAccessToUninitializedField());
- // initialize with zero
+ // initialize with zero
for (unsigned i=0;i<laplacians.size();++i)
std::fill_n (laplacians[i].begin(), laplacians[i].size(), 0);
- // add up contributions of trial
- // functions. now check whether the
- // shape function is primitive or
- // not. if it is, then set its only
- // non-zero component, otherwise
- // loop over components
+ // add up contributions of trial
+ // functions. now check whether the
+ // shape function is primitive or
+ // not. if it is, then set its only
+ // non-zero component, otherwise
+ // loop over components
for (unsigned int mc = 0; mc < component_multiple; ++mc)
for (unsigned int shape_func=0; shape_func<dofs_per_cell; ++shape_func)
{
- const double value = get_vector_element (fe_function, indices[shape_func+mc*dofs_per_cell]);
- if (value == 0.)
- continue;
-
- if (fe->is_primitive(shape_func))
- {
- const unsigned int
- row = fe->is_primitive() ?
- shape_func : this->shape_function_to_row_table[shape_func];
-
- const Tensor<2,spacedim> *shape_hessian_ptr
- = &this->shape_hessians[row][0];
- const unsigned int comp = fe->system_to_component_index(shape_func).first
- + mc * n_components;
- for (unsigned int point=0; point<n_quadrature_points; ++point)
- laplacians[point](comp) += value * trace(*shape_hessian_ptr++);
- }
- else
- for (unsigned int c=0; c<n_components; ++c)
- {
- if (fe->get_nonzero_components(shape_func)[c] == false)
- continue;
-
- const unsigned int
- row = (this->shape_function_to_row_table[shape_func]
- +
- std::count (fe->get_nonzero_components(shape_func).begin(),
- fe->get_nonzero_components(shape_func).begin()+c,
- true));
-
- const Tensor<2,spacedim> *shape_hessian_ptr
- = &this->shape_hessians[row][0];
- const unsigned int comp = c + mc * n_components;
-
- for (unsigned int point=0; point<n_quadrature_points; ++point)
- laplacians[point](comp) += value * trace(*shape_hessian_ptr++);
- }
+ const double value = get_vector_element (fe_function, indices[shape_func+mc*dofs_per_cell]);
+ if (value == 0.)
+ continue;
+
+ if (fe->is_primitive(shape_func))
+ {
+ const unsigned int
+ row = fe->is_primitive() ?
+ shape_func : this->shape_function_to_row_table[shape_func];
+
+ const Tensor<2,spacedim> *shape_hessian_ptr
+ = &this->shape_hessians[row][0];
+ const unsigned int comp = fe->system_to_component_index(shape_func).first
+ + mc * n_components;
+ for (unsigned int point=0; point<n_quadrature_points; ++point)
+ laplacians[point](comp) += value * trace(*shape_hessian_ptr++);
+ }
+ else
+ for (unsigned int c=0; c<n_components; ++c)
+ {
+ if (fe->get_nonzero_components(shape_func)[c] == false)
+ continue;
+
+ const unsigned int
+ row = (this->shape_function_to_row_table[shape_func]
+ +
+ std::count (fe->get_nonzero_components(shape_func).begin(),
+ fe->get_nonzero_components(shape_func).begin()+c,
+ true));
+
+ const Tensor<2,spacedim> *shape_hessian_ptr
+ = &this->shape_hessians[row][0];
+ const unsigned int comp = c + mc * n_components;
+
+ for (unsigned int point=0; point<n_quadrature_points; ++point)
+ laplacians[point](comp) += value * trace(*shape_hessian_ptr++);
+ }
}
}
{
const unsigned int n_components = fe->n_components();
- // Size of indices must be a
- // multiple of dofs_per_cell such
- // that an integer number of
- // function values is generated in
- // each point.
+ // Size of indices must be a
+ // multiple of dofs_per_cell such
+ // that an integer number of
+ // function values is generated in
+ // each point.
Assert (indices.size() % dofs_per_cell == 0,
- ExcNotMultiple(indices.size(), dofs_per_cell));
+ ExcNotMultiple(indices.size(), dofs_per_cell));
- // The number of components of the
- // result may be a multiple of the
- // number of components of the
- // finite element
+ // The number of components of the
+ // result may be a multiple of the
+ // number of components of the
+ // finite element
const unsigned int result_components = indices.size() * n_components / dofs_per_cell;
- // Check if the value argument is
- // initialized to the correct sizes
+ // Check if the value argument is
+ // initialized to the correct sizes
if (quadrature_points_fastest)
{
Assert (laplacians.size() == result_components,
- ExcDimensionMismatch(laplacians.size(), result_components));
+ ExcDimensionMismatch(laplacians.size(), result_components));
for (unsigned i=0;i<laplacians.size();++i)
- Assert (laplacians[i].size() == n_quadrature_points,
- ExcDimensionMismatch(laplacians[i].size(), n_quadrature_points));
+ Assert (laplacians[i].size() == n_quadrature_points,
+ ExcDimensionMismatch(laplacians[i].size(), n_quadrature_points));
}
else
{
Assert(laplacians.size() == n_quadrature_points,
- ExcDimensionMismatch(laplacians.size(), n_quadrature_points));
+ ExcDimensionMismatch(laplacians.size(), n_quadrature_points));
for (unsigned i=0;i<laplacians.size();++i)
- Assert (laplacians[i].size() == result_components,
- ExcDimensionMismatch(laplacians[i].size(), result_components));
+ Assert (laplacians[i].size() == result_components,
+ ExcDimensionMismatch(laplacians[i].size(), result_components));
}
- // If the result has more
- // components than the finite
- // element, we need this number for
- // loops filling all components
+ // If the result has more
+ // components than the finite
+ // element, we need this number for
+ // loops filling all components
const unsigned int component_multiple = result_components / n_components;
Assert (this->update_flags & update_hessians, ExcAccessToUninitializedField());
- // initialize with zero
+ // initialize with zero
for (unsigned i=0;i<laplacians.size();++i)
std::fill_n (laplacians[i].begin(), laplacians[i].size(), 0);
- // add up contributions of trial
- // functions. now check whether the
- // shape function is primitive or
- // not. if it is, then set its only
- // non-zero component, otherwise
- // loop over components
+ // add up contributions of trial
+ // functions. now check whether the
+ // shape function is primitive or
+ // not. if it is, then set its only
+ // non-zero component, otherwise
+ // loop over components
for (unsigned int mc = 0; mc < component_multiple; ++mc)
for (unsigned int shape_func=0; shape_func<dofs_per_cell; ++shape_func)
{
- const double value = get_vector_element (fe_function, indices[shape_func+mc*dofs_per_cell]);
- if (value == 0.)
- continue;
-
- if (fe->is_primitive(shape_func))
- {
- const unsigned int
- row = fe->is_primitive() ?
- shape_func : this->shape_function_to_row_table[shape_func];
-
- const Tensor<2,spacedim> *shape_hessian_ptr
- = &this->shape_hessians[row][0];
- const unsigned int comp = fe->system_to_component_index(shape_func).first
- + mc * n_components;
- if (quadrature_points_fastest)
- for (unsigned int point=0; point<n_quadrature_points; ++point)
- laplacians[comp][point] += value * trace(*shape_hessian_ptr++);
- else
- for (unsigned int point=0; point<n_quadrature_points; ++point)
- laplacians[point][comp] += value * trace(*shape_hessian_ptr++);
- }
- else
- for (unsigned int c=0; c<n_components; ++c)
- {
- if (fe->get_nonzero_components(shape_func)[c] == false)
- continue;
-
- const unsigned int
- row = (this->shape_function_to_row_table[shape_func]
- +
- std::count (fe->get_nonzero_components(shape_func).begin(),
- fe->get_nonzero_components(shape_func).begin()+c,
- true));
-
- const Tensor<2,spacedim> *shape_hessian_ptr
- = &this->shape_hessians[row][0];
- const unsigned int comp = c + mc * n_components;
-
- if (quadrature_points_fastest)
- for (unsigned int point=0; point<n_quadrature_points; ++point)
- laplacians[comp][point] += value * trace(*shape_hessian_ptr++);
- else
- for (unsigned int point=0; point<n_quadrature_points; ++point)
- laplacians[point][comp] += value * trace(*shape_hessian_ptr++);
- }
+ const double value = get_vector_element (fe_function, indices[shape_func+mc*dofs_per_cell]);
+ if (value == 0.)
+ continue;
+
+ if (fe->is_primitive(shape_func))
+ {
+ const unsigned int
+ row = fe->is_primitive() ?
+ shape_func : this->shape_function_to_row_table[shape_func];
+
+ const Tensor<2,spacedim> *shape_hessian_ptr
+ = &this->shape_hessians[row][0];
+ const unsigned int comp = fe->system_to_component_index(shape_func).first
+ + mc * n_components;
+ if (quadrature_points_fastest)
+ for (unsigned int point=0; point<n_quadrature_points; ++point)
+ laplacians[comp][point] += value * trace(*shape_hessian_ptr++);
+ else
+ for (unsigned int point=0; point<n_quadrature_points; ++point)
+ laplacians[point][comp] += value * trace(*shape_hessian_ptr++);
+ }
+ else
+ for (unsigned int c=0; c<n_components; ++c)
+ {
+ if (fe->get_nonzero_components(shape_func)[c] == false)
+ continue;
+
+ const unsigned int
+ row = (this->shape_function_to_row_table[shape_func]
+ +
+ std::count (fe->get_nonzero_components(shape_func).begin(),
+ fe->get_nonzero_components(shape_func).begin()+c,
+ true));
+
+ const Tensor<2,spacedim> *shape_hessian_ptr
+ = &this->shape_hessians[row][0];
+ const unsigned int comp = c + mc * n_components;
+
+ if (quadrature_points_fastest)
+ for (unsigned int point=0; point<n_quadrature_points; ++point)
+ laplacians[comp][point] += value * trace(*shape_hessian_ptr++);
+ else
+ for (unsigned int point=0; point<n_quadrature_points; ++point)
+ laplacians[point][comp] += value * trace(*shape_hessian_ptr++);
+ }
}
}
{
typedef FEValuesBase<dim,spacedim> FEVB;
Assert (this->update_flags & update_normal_vectors,
- typename FEVB::ExcAccessToUninitializedField());
+ typename FEVB::ExcAccessToUninitializedField());
return this->normal_vectors;
}
FEValuesBase<dim,spacedim>::memory_consumption () const
{
return (MemoryConsumption::memory_consumption (this->shape_values) +
- MemoryConsumption::memory_consumption (this->shape_gradients) +
- MemoryConsumption::memory_consumption (this->shape_hessians) +
- MemoryConsumption::memory_consumption (this->JxW_values) +
- MemoryConsumption::memory_consumption (this->jacobians) +
- MemoryConsumption::memory_consumption (this->jacobian_grads) +
- MemoryConsumption::memory_consumption (this->inverse_jacobians) +
- MemoryConsumption::memory_consumption (this->quadrature_points) +
- MemoryConsumption::memory_consumption (this->normal_vectors) +
- MemoryConsumption::memory_consumption (this->boundary_forms) +
- sizeof(this->update_flags) +
- MemoryConsumption::memory_consumption (n_quadrature_points) +
- MemoryConsumption::memory_consumption (dofs_per_cell) +
- MemoryConsumption::memory_consumption (mapping) +
- MemoryConsumption::memory_consumption (fe) +
- MemoryConsumption::memory_consumption (mapping_data) +
- MemoryConsumption::memory_consumption (*mapping_data) +
- MemoryConsumption::memory_consumption (fe_data) +
- MemoryConsumption::memory_consumption (*fe_data) +
- MemoryConsumption::memory_consumption (this->shape_function_to_row_table));
+ MemoryConsumption::memory_consumption (this->shape_gradients) +
+ MemoryConsumption::memory_consumption (this->shape_hessians) +
+ MemoryConsumption::memory_consumption (this->JxW_values) +
+ MemoryConsumption::memory_consumption (this->jacobians) +
+ MemoryConsumption::memory_consumption (this->jacobian_grads) +
+ MemoryConsumption::memory_consumption (this->inverse_jacobians) +
+ MemoryConsumption::memory_consumption (this->quadrature_points) +
+ MemoryConsumption::memory_consumption (this->normal_vectors) +
+ MemoryConsumption::memory_consumption (this->boundary_forms) +
+ sizeof(this->update_flags) +
+ MemoryConsumption::memory_consumption (n_quadrature_points) +
+ MemoryConsumption::memory_consumption (dofs_per_cell) +
+ MemoryConsumption::memory_consumption (mapping) +
+ MemoryConsumption::memory_consumption (fe) +
+ MemoryConsumption::memory_consumption (mapping_data) +
+ MemoryConsumption::memory_consumption (*mapping_data) +
+ MemoryConsumption::memory_consumption (fe_data) +
+ MemoryConsumption::memory_consumption (*fe_data) +
+ MemoryConsumption::memory_consumption (this->shape_function_to_row_table));
}
FEValuesBase<dim,spacedim>::compute_update_flags (const UpdateFlags update_flags) const
{
- // first find out which objects
- // need to be recomputed on each
- // cell we visit. this we have to
- // ask the finite element and mapping.
- // elements are first since they
- // might require update in mapping
+ // first find out which objects
+ // need to be recomputed on each
+ // cell we visit. this we have to
+ // ask the finite element and mapping.
+ // elements are first since they
+ // might require update in mapping
UpdateFlags flags = update_flags
- | fe->update_once (update_flags)
- | fe->update_each (update_flags);
+ | fe->update_once (update_flags)
+ | fe->update_each (update_flags);
flags |= mapping->update_once (flags)
- | mapping->update_each (flags);
+ | mapping->update_each (flags);
return flags;
}
// connected via a signal to a triangulation
Assert (present_cell.get() != 0, ExcInternalError());
- // so delete the present cell and
- // disconnect from the signal we have with
- // it
+ // so delete the present cell and
+ // disconnect from the signal we have with
+ // it
tria_listener.disconnect ();
present_cell.reset ();
}
{
if (&cell->get_triangulation() !=
&present_cell->operator typename Triangulation<dim,spacedim>::cell_iterator()
- ->get_triangulation())
+ ->get_triangulation())
{
- // the triangulations for the previous cell and the current cell
- // do not match. disconnect from the previous triangulation and
- // connect to the current one; also invalidate the previous
- // cell because we shouldn't be comparing cells from different
- // triangulations
- tria_listener.disconnect ();
- invalidate_present_cell();
- tria_listener =
- cell->get_triangulation().signals.any_change.connect
- (std_cxx1x::bind (&FEValuesBase<dim,spacedim>::invalidate_present_cell,
- std_cxx1x::ref(static_cast<FEValuesBase<dim,spacedim>&>(*this))));
+ // the triangulations for the previous cell and the current cell
+ // do not match. disconnect from the previous triangulation and
+ // connect to the current one; also invalidate the previous
+ // cell because we shouldn't be comparing cells from different
+ // triangulations
+ tria_listener.disconnect ();
+ invalidate_present_cell();
+ tria_listener =
+ cell->get_triangulation().signals.any_change.connect
+ (std_cxx1x::bind (&FEValuesBase<dim,spacedim>::invalidate_present_cell,
+ std_cxx1x::ref(static_cast<FEValuesBase<dim,spacedim>&>(*this))));
}
}
else
tria_listener =
cell->get_triangulation().signals.post_refinement.connect
(std_cxx1x::bind (&FEValuesBase<dim,spacedim>::invalidate_present_cell,
- std_cxx1x::ref(static_cast<FEValuesBase<dim,spacedim>&>(*this))));
+ std_cxx1x::ref(static_cast<FEValuesBase<dim,spacedim>&>(*this))));
}
}
FEValuesBase<dim,spacedim>::check_cell_similarity
(const typename Triangulation<dim,spacedim>::cell_iterator &cell)
{
- // case that there has not been any cell
- // before
+ // case that there has not been any cell
+ // before
if (this->present_cell.get() == 0)
cell_similarity = CellSimilarity::none;
else
- // in MappingQ, data can have been
- // modified during the last call. Then,
- // we can't use that data on the new
- // cell.
+ // in MappingQ, data can have been
+ // modified during the last call. Then,
+ // we can't use that data on the new
+ // cell.
if (cell_similarity == CellSimilarity::invalid_next_cell)
cell_similarity = CellSimilarity::none;
else
cell_similarity = (cell->is_translation_of
- (static_cast<const typename Triangulation<dim,spacedim>::cell_iterator &>(*this->present_cell))
- ?
- CellSimilarity::translation
- :
- CellSimilarity::none);
+ (static_cast<const typename Triangulation<dim,spacedim>::cell_iterator &>(*this->present_cell))
+ ?
+ CellSimilarity::translation
+ :
+ CellSimilarity::none);
if ( (dim<spacedim) && (cell_similarity == CellSimilarity::translation) ) {
if (static_cast<const typename Triangulation<dim,spacedim>::cell_iterator &>
- (*this->present_cell)->direction_flag()
- != cell->direction_flag() )
+ (*this->present_cell)->direction_flag()
+ != cell->direction_flag() )
cell_similarity = CellSimilarity::inverted_translation;
}
- // TODO: here, one could implement other
- // checks for similarity, e.g. for
- // children of a parallelogram.
+ // TODO: here, one could implement other
+ // checks for similarity, e.g. for
+ // children of a parallelogram.
}
template <int dim, int spacedim>
FEValues<dim,spacedim>::FEValues (const Mapping<dim,spacedim> &mapping,
- const FiniteElement<dim,spacedim> &fe,
- const Quadrature<dim> &q,
- const UpdateFlags update_flags)
- :
- FEValuesBase<dim,spacedim> (q.size(),
- fe.dofs_per_cell,
- update_default,
- mapping,
- fe),
- quadrature (q)
+ const FiniteElement<dim,spacedim> &fe,
+ const Quadrature<dim> &q,
+ const UpdateFlags update_flags)
+ :
+ FEValuesBase<dim,spacedim> (q.size(),
+ fe.dofs_per_cell,
+ update_default,
+ mapping,
+ fe),
+ quadrature (q)
{
initialize (update_flags);
}
template <int dim, int spacedim>
FEValues<dim,spacedim>::FEValues (const FiniteElement<dim,spacedim> &fe,
- const Quadrature<dim> &q,
- const UpdateFlags update_flags)
- :
- FEValuesBase<dim,spacedim> (q.size(),
- fe.dofs_per_cell,
- update_default,
- StaticMappingQ1<dim,spacedim>::mapping,
- fe),
- quadrature (q)
+ const Quadrature<dim> &q,
+ const UpdateFlags update_flags)
+ :
+ FEValuesBase<dim,spacedim> (q.size(),
+ fe.dofs_per_cell,
+ update_default,
+ StaticMappingQ1<dim,spacedim>::mapping,
+ fe),
+ quadrature (q)
{
Assert (DEAL_II_COMPAT_MAPPING, ExcCompatibility("mapping"));
initialize (update_flags);
void
FEValues<dim,spacedim>::initialize (const UpdateFlags update_flags)
{
- // You can compute normal vectors
- // to the cells only in the
- // codimension one case.
+ // You can compute normal vectors
+ // to the cells only in the
+ // codimension one case.
typedef FEValuesBase<dim,spacedim> FEVB;
if (dim != spacedim-1)
Assert ((update_flags & update_normal_vectors) == false,
- typename FEVB::ExcInvalidUpdateFlag());
+ typename FEVB::ExcInvalidUpdateFlag());
const UpdateFlags flags = this->compute_update_flags (update_flags);
- // then get objects into which the
- // FE and the Mapping can store
- // intermediate data used across
- // calls to reinit
+ // then get objects into which the
+ // FE and the Mapping can store
+ // intermediate data used across
+ // calls to reinit
this->mapping_data = this->mapping->get_data(flags, quadrature);
this->fe_data = this->fe->get_data(flags, *this->mapping, quadrature);
- // set up objects within this class
+ // set up objects within this class
FEValuesData<dim,spacedim>::initialize (this->n_quadrature_points, *this->fe, flags);
}
void
FEValues<dim,spacedim>::reinit (const typename DoFHandler<dim,spacedim>::cell_iterator &cell)
{
- // assert that the finite elements
- // passed to the constructor and
- // used by the DoFHandler used by
- // this cell, are the same
+ // assert that the finite elements
+ // passed to the constructor and
+ // used by the DoFHandler used by
+ // this cell, are the same
typedef FEValuesBase<dim,spacedim> FEVB;
Assert (static_cast<const FiniteElementData<dim>&>(*this->fe) ==
- static_cast<const FiniteElementData<dim>&>(cell->get_fe()),
- typename FEVB::ExcFEDontMatch());
+ static_cast<const FiniteElementData<dim>&>(cell->get_fe()),
+ typename FEVB::ExcFEDontMatch());
this->maybe_invalidate_previous_present_cell (cell);
this->check_cell_similarity(cell);
- // set new cell. auto_ptr will take
- // care that old object gets
- // destroyed and also that this
- // object gets destroyed in the
- // destruction of this class
+ // set new cell. auto_ptr will take
+ // care that old object gets
+ // destroyed and also that this
+ // object gets destroyed in the
+ // destruction of this class
this->present_cell.reset
(new typename FEValuesBase<dim,spacedim>::template
CellIterator<typename DoFHandler<dim,spacedim>::cell_iterator> (cell));
- // this was the part of the work
- // that is dependent on the actual
- // data type of the iterator. now
- // pass on to the function doing
- // the real work.
+ // this was the part of the work
+ // that is dependent on the actual
+ // data type of the iterator. now
+ // pass on to the function doing
+ // the real work.
do_reinit ();
}
void
FEValues<dim,spacedim>::reinit (const typename hp::DoFHandler<dim,spacedim>::cell_iterator &cell)
{
- // assert that the finite elements
- // passed to the constructor and
- // used by the DoFHandler used by
- // this cell, are the same
+ // assert that the finite elements
+ // passed to the constructor and
+ // used by the DoFHandler used by
+ // this cell, are the same
typedef FEValuesBase<dim,spacedim> FEVB;
Assert (static_cast<const FiniteElementData<dim>&>(*this->fe) ==
- static_cast<const FiniteElementData<dim>&>(cell->get_fe()),
- typename FEVB::ExcFEDontMatch());
+ static_cast<const FiniteElementData<dim>&>(cell->get_fe()),
+ typename FEVB::ExcFEDontMatch());
this->maybe_invalidate_previous_present_cell (cell);
this->check_cell_similarity(cell);
- // set new cell. auto_ptr will take
- // care that old object gets
- // destroyed and also that this
- // object gets destroyed in the
- // destruction of this class
+ // set new cell. auto_ptr will take
+ // care that old object gets
+ // destroyed and also that this
+ // object gets destroyed in the
+ // destruction of this class
this->present_cell.reset
(new typename FEValuesBase<dim,spacedim>::template
CellIterator<typename hp::DoFHandler<dim,spacedim>::cell_iterator> (cell));
- // this was the part of the work
- // that is dependent on the actual
- // data type of the iterator. now
- // pass on to the function doing
- // the real work.
+ // this was the part of the work
+ // that is dependent on the actual
+ // data type of the iterator. now
+ // pass on to the function doing
+ // the real work.
do_reinit ();
}
return;
}
- // assert that the finite elements
- // passed to the constructor and
- // used by the DoFHandler used by
- // this cell, are the same
+ // assert that the finite elements
+ // passed to the constructor and
+ // used by the DoFHandler used by
+ // this cell, are the same
//TODO: This was documented out ith the repository. Why?
// Assert (static_cast<const FiniteElementData<dim>&>(*this->fe) ==
-// static_cast<const FiniteElementData<dim>&>(cell->get_fe()),
-// typename FEValuesBase<dim,spacedim>::ExcFEDontMatch());
+// static_cast<const FiniteElementData<dim>&>(cell->get_fe()),
+// typename FEValuesBase<dim,spacedim>::ExcFEDontMatch());
this->maybe_invalidate_previous_present_cell (cell);
this->check_cell_similarity(cell);
- // set new cell. auto_ptr will take
- // care that old object gets
- // destroyed and also that this
- // object gets destroyed in the
- // destruction of this class
+ // set new cell. auto_ptr will take
+ // care that old object gets
+ // destroyed and also that this
+ // object gets destroyed in the
+ // destruction of this class
this->present_cell.reset
(new typename FEValuesBase<dim,spacedim>::template
CellIterator<typename MGDoFHandler<dim,spacedim>::cell_iterator> (cell));
- // this was the part of the work
- // that is dependent on the actual
- // data type of the iterator. now
- // pass on to the function doing
- // the real work.
+ // this was the part of the work
+ // that is dependent on the actual
+ // data type of the iterator. now
+ // pass on to the function doing
+ // the real work.
do_reinit ();
}
template <int dim, int spacedim>
void FEValues<dim,spacedim>::reinit (const typename Triangulation<dim,spacedim>::cell_iterator &cell)
{
- // no FE in this cell, so no assertion
- // necessary here
+ // no FE in this cell, so no assertion
+ // necessary here
this->maybe_invalidate_previous_present_cell (cell);
this->check_cell_similarity(cell);
- // set new cell. auto_ptr will take
- // care that old object gets
- // destroyed and also that this
- // object gets destroyed in the
- // destruction of this class
+ // set new cell. auto_ptr will take
+ // care that old object gets
+ // destroyed and also that this
+ // object gets destroyed in the
+ // destruction of this class
this->present_cell.reset
(new typename FEValuesBase<dim,spacedim>::TriaCellIterator (cell));
- // this was the part of the work
- // that is dependent on the actual
- // data type of the iterator. now
- // pass on to the function doing
- // the real work.
+ // this was the part of the work
+ // that is dependent on the actual
+ // data type of the iterator. now
+ // pass on to the function doing
+ // the real work.
do_reinit ();
}
void FEValues<dim,spacedim>::do_reinit ()
{
this->get_mapping().fill_fe_values(*this->present_cell,
- quadrature,
- *this->mapping_data,
- this->quadrature_points,
- this->JxW_values,
- this->jacobians,
- this->jacobian_grads,
- this->inverse_jacobians,
- this->normal_vectors,
- this->cell_similarity);
+ quadrature,
+ *this->mapping_data,
+ this->quadrature_points,
+ this->JxW_values,
+ this->jacobians,
+ this->jacobian_grads,
+ this->inverse_jacobians,
+ this->normal_vectors,
+ this->cell_similarity);
this->get_fe().fill_fe_values(this->get_mapping(),
- *this->present_cell,
- quadrature,
- *this->mapping_data,
- *this->fe_data,
- *this,
- this->cell_similarity);
+ *this->present_cell,
+ quadrature,
+ *this->mapping_data,
+ *this->fe_data,
+ *this,
+ this->cell_similarity);
this->fe_data->clear_first_cell ();
this->mapping_data->clear_first_cell ();
FEValues<dim,spacedim>::memory_consumption () const
{
return (FEValuesBase<dim,spacedim>::memory_consumption () +
- MemoryConsumption::memory_consumption (quadrature));
+ MemoryConsumption::memory_consumption (quadrature));
}
template <int dim, int spacedim>
FEFaceValuesBase<dim,spacedim>::FEFaceValuesBase (const unsigned int n_q_points,
- const unsigned int dofs_per_cell,
- const UpdateFlags,
- const Mapping<dim,spacedim> &mapping,
- const FiniteElement<dim,spacedim> &fe,
- const Quadrature<dim-1>& quadrature)
- :
- FEValuesBase<dim,spacedim> (n_q_points,
- dofs_per_cell,
- update_default,
- mapping,
- fe),
- quadrature(quadrature)
+ const unsigned int dofs_per_cell,
+ const UpdateFlags,
+ const Mapping<dim,spacedim> &mapping,
+ const FiniteElement<dim,spacedim> &fe,
+ const Quadrature<dim-1>& quadrature)
+ :
+ FEValuesBase<dim,spacedim> (n_q_points,
+ dofs_per_cell,
+ update_default,
+ mapping,
+ fe),
+ quadrature(quadrature)
{}
{
typedef FEValuesBase<dim,spacedim> FEVB;
Assert (this->update_flags & update_boundary_forms,
- typename FEVB::ExcAccessToUninitializedField());
+ typename FEVB::ExcAccessToUninitializedField());
return this->boundary_forms;
}
FEFaceValuesBase<dim,spacedim>::memory_consumption () const
{
return (FEValuesBase<dim,spacedim>::memory_consumption () +
- MemoryConsumption::memory_consumption (quadrature));
+ MemoryConsumption::memory_consumption (quadrature));
}
template <int dim, int spacedim>
FEFaceValues<dim,spacedim>::FEFaceValues (const Mapping<dim,spacedim> &mapping,
- const FiniteElement<dim,spacedim> &fe,
- const Quadrature<dim-1> &quadrature,
- const UpdateFlags update_flags)
- :
- FEFaceValuesBase<dim,spacedim> (quadrature.size(),
- fe.dofs_per_cell,
- update_flags,
- mapping,
- fe, quadrature)
+ const FiniteElement<dim,spacedim> &fe,
+ const Quadrature<dim-1> &quadrature,
+ const UpdateFlags update_flags)
+ :
+ FEFaceValuesBase<dim,spacedim> (quadrature.size(),
+ fe.dofs_per_cell,
+ update_flags,
+ mapping,
+ fe, quadrature)
{
initialize (update_flags);
}
template <int dim, int spacedim>
FEFaceValues<dim,spacedim>::FEFaceValues (const FiniteElement<dim,spacedim> &fe,
- const Quadrature<dim-1> &quadrature,
- const UpdateFlags update_flags)
- :
- FEFaceValuesBase<dim,spacedim> (quadrature.size(),
- fe.dofs_per_cell,
- update_flags,
- StaticMappingQ1<dim,spacedim>::mapping,
- fe, quadrature)
+ const Quadrature<dim-1> &quadrature,
+ const UpdateFlags update_flags)
+ :
+ FEFaceValuesBase<dim,spacedim> (quadrature.size(),
+ fe.dofs_per_cell,
+ update_flags,
+ StaticMappingQ1<dim,spacedim>::mapping,
+ fe, quadrature)
{
Assert (DEAL_II_COMPAT_MAPPING, ExcCompatibility("mapping"));
initialize (update_flags);
{
const UpdateFlags flags = this->compute_update_flags (update_flags);
- // then get objects into which the
- // FE and the Mapping can store
- // intermediate data used across
- // calls to reinit
+ // then get objects into which the
+ // FE and the Mapping can store
+ // intermediate data used across
+ // calls to reinit
this->mapping_data = this->mapping->get_face_data(flags, this->quadrature);
this->fe_data = this->fe->get_face_data(flags, *this->mapping, this->quadrature);
- // set up objects within this class
+ // set up objects within this class
FEValuesData<dim,spacedim>::initialize(this->n_quadrature_points, *this->fe, flags);
}
template <int dim, int spacedim>
void FEFaceValues<dim,spacedim>::reinit (const typename DoFHandler<dim,spacedim>::cell_iterator &cell,
- const unsigned int face_no)
+ const unsigned int face_no)
{
- // assert that the finite elements
- // passed to the constructor and
- // used by the DoFHandler used by
- // this cell, are the same
+ // assert that the finite elements
+ // passed to the constructor and
+ // used by the DoFHandler used by
+ // this cell, are the same
// Assert (static_cast<const FiniteElementData<dim>&>(*this->fe) ==
-// static_cast<const FiniteElementData<dim>&>(cell->get_dof_handler().get_fe()),
-// typename FEValuesBase<dim,spacedim>::ExcFEDontMatch());
+// static_cast<const FiniteElementData<dim>&>(cell->get_dof_handler().get_fe()),
+// typename FEValuesBase<dim,spacedim>::ExcFEDontMatch());
Assert (face_no < GeometryInfo<dim>::faces_per_cell,
- ExcIndexRange (face_no, 0, GeometryInfo<dim>::faces_per_cell));
+ ExcIndexRange (face_no, 0, GeometryInfo<dim>::faces_per_cell));
- // set new cell. auto_ptr will take
- // care that old object gets
- // destroyed and also that this
- // object gets destroyed in the
- // destruction of this class
+ // set new cell. auto_ptr will take
+ // care that old object gets
+ // destroyed and also that this
+ // object gets destroyed in the
+ // destruction of this class
this->maybe_invalidate_previous_present_cell (cell);
this->present_cell.reset
(new typename FEValuesBase<dim,spacedim>::template
CellIterator<typename DoFHandler<dim,spacedim>::cell_iterator> (cell));
- // this was the part of the work
- // that is dependent on the actual
- // data type of the iterator. now
- // pass on to the function doing
- // the real work.
+ // this was the part of the work
+ // that is dependent on the actual
+ // data type of the iterator. now
+ // pass on to the function doing
+ // the real work.
do_reinit (face_no);
}
template <int dim, int spacedim>
void FEFaceValues<dim,spacedim>::reinit (const typename hp::DoFHandler<dim,spacedim>::cell_iterator &cell,
- const unsigned int face_no)
+ const unsigned int face_no)
{
- // assert that the finite elements
- // passed to the constructor and
- // used by the DoFHandler used by
- // this cell, are the same
+ // assert that the finite elements
+ // passed to the constructor and
+ // used by the DoFHandler used by
+ // this cell, are the same
typedef FEValuesBase<dim,spacedim> FEVB;
Assert (static_cast<const FiniteElementData<dim>&>(*this->fe) ==
- static_cast<const FiniteElementData<dim>&>(
- cell->get_dof_handler().get_fe()[cell->active_fe_index ()]),
- typename FEVB::ExcFEDontMatch());
+ static_cast<const FiniteElementData<dim>&>(
+ cell->get_dof_handler().get_fe()[cell->active_fe_index ()]),
+ typename FEVB::ExcFEDontMatch());
Assert (face_no < GeometryInfo<dim>::faces_per_cell,
- ExcIndexRange (face_no, 0, GeometryInfo<dim>::faces_per_cell));
+ ExcIndexRange (face_no, 0, GeometryInfo<dim>::faces_per_cell));
- // set new cell. auto_ptr will take
- // care that old object gets
- // destroyed and also that this
- // object gets destroyed in the
- // destruction of this class
+ // set new cell. auto_ptr will take
+ // care that old object gets
+ // destroyed and also that this
+ // object gets destroyed in the
+ // destruction of this class
this->maybe_invalidate_previous_present_cell (cell);
this->present_cell.reset
(new typename FEValuesBase<dim,spacedim>::template
CellIterator<typename hp::DoFHandler<dim,spacedim>::cell_iterator> (cell));
- // this was the part of the work
- // that is dependent on the actual
- // data type of the iterator. now
- // pass on to the function doing
- // the real work.
+ // this was the part of the work
+ // that is dependent on the actual
+ // data type of the iterator. now
+ // pass on to the function doing
+ // the real work.
do_reinit (face_no);
}
template <int dim, int spacedim>
void FEFaceValues<dim,spacedim>::reinit (const typename MGDoFHandler<dim,spacedim>::cell_iterator &cell,
- const unsigned int face_no)
+ const unsigned int face_no)
{
if (spacedim > dim)
{
Assert(false,ExcNotImplemented());
return;
}
- // assert that the finite elements
- // passed to the constructor and
- // used by the DoFHandler used by
- // this cell, are the same
+ // assert that the finite elements
+ // passed to the constructor and
+ // used by the DoFHandler used by
+ // this cell, are the same
typedef FEValuesBase<dim,spacedim> FEVB;
Assert (static_cast<const FiniteElementData<dim>&>(*this->fe) ==
- static_cast<const FiniteElementData<dim>&>(cell->get_dof_handler().get_fe()),
- typename FEVB::ExcFEDontMatch());
+ static_cast<const FiniteElementData<dim>&>(cell->get_dof_handler().get_fe()),
+ typename FEVB::ExcFEDontMatch());
Assert (face_no < GeometryInfo<dim>::faces_per_cell,
- ExcIndexRange (face_no, 0, GeometryInfo<dim>::faces_per_cell));
+ ExcIndexRange (face_no, 0, GeometryInfo<dim>::faces_per_cell));
- // set new cell. auto_ptr will take
- // care that old object gets
- // destroyed and also that this
- // object gets destroyed in the
- // destruction of this class
+ // set new cell. auto_ptr will take
+ // care that old object gets
+ // destroyed and also that this
+ // object gets destroyed in the
+ // destruction of this class
this->maybe_invalidate_previous_present_cell (cell);
this->present_cell.reset
(new typename FEValuesBase<dim,spacedim>::template
CellIterator<typename MGDoFHandler<dim,spacedim>::cell_iterator> (cell));
- // this was the part of the work
- // that is dependent on the actual
- // data type of the iterator. now
- // pass on to the function doing
- // the real work.
+ // this was the part of the work
+ // that is dependent on the actual
+ // data type of the iterator. now
+ // pass on to the function doing
+ // the real work.
do_reinit (face_no);
}
template <int dim, int spacedim>
void FEFaceValues<dim,spacedim>::reinit (const typename Triangulation<dim,spacedim>::cell_iterator &cell,
- const unsigned int face_no)
+ const unsigned int face_no)
{
Assert (face_no < GeometryInfo<dim>::faces_per_cell,
- ExcIndexRange (face_no, 0, GeometryInfo<dim>::faces_per_cell));
+ ExcIndexRange (face_no, 0, GeometryInfo<dim>::faces_per_cell));
- // set new cell. auto_ptr will take
- // care that old object gets
- // destroyed and also that this
- // object gets destroyed in the
- // destruction of this class
+ // set new cell. auto_ptr will take
+ // care that old object gets
+ // destroyed and also that this
+ // object gets destroyed in the
+ // destruction of this class
this->maybe_invalidate_previous_present_cell (cell);
this->present_cell.reset
(new typename FEValuesBase<dim,spacedim>::TriaCellIterator (cell));
- // this was the part of the work
- // that is dependent on the actual
- // data type of the iterator. now
- // pass on to the function doing
- // the real work.
+ // this was the part of the work
+ // that is dependent on the actual
+ // data type of the iterator. now
+ // pass on to the function doing
+ // the real work.
do_reinit (face_no);
}
template <int dim, int spacedim>
void FEFaceValues<dim,spacedim>::do_reinit (const unsigned int face_no)
{
- // first of all, set the
- // present_face_index (if
- // available)
+ // first of all, set the
+ // present_face_index (if
+ // available)
const typename Triangulation<dim,spacedim>::cell_iterator cell=*this->present_cell;
this->present_face_index=cell->face_index(face_no);
this->get_mapping().fill_fe_face_values(*this->present_cell, face_no,
- this->quadrature,
- *this->mapping_data,
- this->quadrature_points,
- this->JxW_values,
- this->boundary_forms,
- this->normal_vectors);
+ this->quadrature,
+ *this->mapping_data,
+ this->quadrature_points,
+ this->JxW_values,
+ this->boundary_forms,
+ this->normal_vectors);
this->get_fe().fill_fe_face_values(this->get_mapping(),
- *this->present_cell, face_no,
- this->quadrature,
- *this->mapping_data,
- *this->fe_data,
- *this);
+ *this->present_cell, face_no,
+ this->quadrature,
+ *this->mapping_data,
+ *this->fe_data,
+ *this);
this->fe_data->clear_first_cell ();
this->mapping_data->clear_first_cell ();
template <int dim, int spacedim>
FESubfaceValues<dim,spacedim>::FESubfaceValues (const Mapping<dim,spacedim> &mapping,
- const FiniteElement<dim,spacedim> &fe,
- const Quadrature<dim-1> &quadrature,
- const UpdateFlags update_flags)
- :
- FEFaceValuesBase<dim,spacedim> (quadrature.size(),
- fe.dofs_per_cell,
- update_flags,
- mapping,
- fe, quadrature)
+ const FiniteElement<dim,spacedim> &fe,
+ const Quadrature<dim-1> &quadrature,
+ const UpdateFlags update_flags)
+ :
+ FEFaceValuesBase<dim,spacedim> (quadrature.size(),
+ fe.dofs_per_cell,
+ update_flags,
+ mapping,
+ fe, quadrature)
{
initialize (update_flags);
}
template <int dim, int spacedim>
FESubfaceValues<dim,spacedim>::FESubfaceValues (const FiniteElement<dim,spacedim> &fe,
- const Quadrature<dim-1> &quadrature,
- const UpdateFlags update_flags)
- :
- FEFaceValuesBase<dim,spacedim> (quadrature.size(),
- fe.dofs_per_cell,
- update_flags,
- StaticMappingQ1<dim,spacedim>::mapping,
- fe, quadrature)
+ const Quadrature<dim-1> &quadrature,
+ const UpdateFlags update_flags)
+ :
+ FEFaceValuesBase<dim,spacedim> (quadrature.size(),
+ fe.dofs_per_cell,
+ update_flags,
+ StaticMappingQ1<dim,spacedim>::mapping,
+ fe, quadrature)
{
Assert (DEAL_II_COMPAT_MAPPING, ExcCompatibility("mapping"));
initialize (update_flags);
{
const UpdateFlags flags = this->compute_update_flags (update_flags);
- // then get objects into which the
- // FE and the Mapping can store
- // intermediate data used across
- // calls to reinit
+ // then get objects into which the
+ // FE and the Mapping can store
+ // intermediate data used across
+ // calls to reinit
this->mapping_data = this->mapping->get_subface_data(flags, this->quadrature);
this->fe_data = this->fe->get_subface_data(flags,
- *this->mapping,
- this->quadrature);
+ *this->mapping,
+ this->quadrature);
- // set up objects within this class
+ // set up objects within this class
FEValuesData<dim,spacedim>::initialize(this->n_quadrature_points, *this->fe, flags);
}
template <int dim, int spacedim>
void FESubfaceValues<dim,spacedim>::reinit (const typename DoFHandler<dim,spacedim>::cell_iterator &cell,
- const unsigned int face_no,
- const unsigned int subface_no)
+ const unsigned int face_no,
+ const unsigned int subface_no)
{
- // assert that the finite elements
- // passed to the constructor and
- // used by the DoFHandler used by
- // this cell, are the same
+ // assert that the finite elements
+ // passed to the constructor and
+ // used by the DoFHandler used by
+ // this cell, are the same
// Assert (static_cast<const FiniteElementData<dim>&>(*this->fe) ==
-// static_cast<const FiniteElementData<dim>&>(cell->get_dof_handler().get_fe()),
-// typename FEValuesBase<dim,spacedim>::ExcFEDontMatch());
+// static_cast<const FiniteElementData<dim>&>(cell->get_dof_handler().get_fe()),
+// typename FEValuesBase<dim,spacedim>::ExcFEDontMatch());
Assert (face_no < GeometryInfo<dim>::faces_per_cell,
- ExcIndexRange (face_no, 0, GeometryInfo<dim>::faces_per_cell));
- // We would like to check for
- // subface_no < cell->face(face_no)->n_children(),
- // but unfortunately the current
- // function is also called for
- // faces without children (see
- // tests/fe/mapping.cc). Therefore,
- // we must use following workaround
- // of two separate assertions
+ ExcIndexRange (face_no, 0, GeometryInfo<dim>::faces_per_cell));
+ // We would like to check for
+ // subface_no < cell->face(face_no)->n_children(),
+ // but unfortunately the current
+ // function is also called for
+ // faces without children (see
+ // tests/fe/mapping.cc). Therefore,
+ // we must use following workaround
+ // of two separate assertions
Assert (cell->face(face_no)->has_children() ||
- subface_no < GeometryInfo<dim>::max_children_per_face,
- ExcIndexRange (subface_no, 0, GeometryInfo<dim>::max_children_per_face));
+ subface_no < GeometryInfo<dim>::max_children_per_face,
+ ExcIndexRange (subface_no, 0, GeometryInfo<dim>::max_children_per_face));
Assert (!cell->face(face_no)->has_children() ||
- subface_no < cell->face(face_no)->number_of_children(),
- ExcIndexRange (subface_no, 0, cell->face(face_no)->number_of_children()));
+ subface_no < cell->face(face_no)->number_of_children(),
+ ExcIndexRange (subface_no, 0, cell->face(face_no)->number_of_children()));
Assert (cell->has_children() == false,
- ExcMessage ("You can't use subface data for cells that are "
- "already refined. Iterate over their children "
- "instead in these cases."));
-
- // set new cell. auto_ptr will take
- // care that old object gets
- // destroyed and also that this
- // object gets destroyed in the
- // destruction of this class
+ ExcMessage ("You can't use subface data for cells that are "
+ "already refined. Iterate over their children "
+ "instead in these cases."));
+
+ // set new cell. auto_ptr will take
+ // care that old object gets
+ // destroyed and also that this
+ // object gets destroyed in the
+ // destruction of this class
this->maybe_invalidate_previous_present_cell (cell);
this->present_cell.reset
(new typename FEValuesBase<dim,spacedim>::template
CellIterator<typename DoFHandler<dim,spacedim>::cell_iterator> (cell));
- // this was the part of the work
- // that is dependent on the actual
- // data type of the iterator. now
- // pass on to the function doing
- // the real work.
+ // this was the part of the work
+ // that is dependent on the actual
+ // data type of the iterator. now
+ // pass on to the function doing
+ // the real work.
do_reinit (face_no, subface_no);
}
template <int dim, int spacedim>
void FESubfaceValues<dim,spacedim>::reinit (const typename hp::DoFHandler<dim,spacedim>::cell_iterator &cell,
- const unsigned int face_no,
- const unsigned int subface_no)
+ const unsigned int face_no,
+ const unsigned int subface_no)
{
- // assert that the finite elements
- // passed to the constructor and
- // used by the hp::DoFHandler used by
- // this cell, are the same
+ // assert that the finite elements
+ // passed to the constructor and
+ // used by the hp::DoFHandler used by
+ // this cell, are the same
typedef FEValuesBase<dim,spacedim> FEVB;
Assert (static_cast<const FiniteElementData<dim>&>(*this->fe) ==
- static_cast<const FiniteElementData<dim>&>(
- cell->get_dof_handler().get_fe()[cell->active_fe_index ()]),
- typename FEVB::ExcFEDontMatch());
+ static_cast<const FiniteElementData<dim>&>(
+ cell->get_dof_handler().get_fe()[cell->active_fe_index ()]),
+ typename FEVB::ExcFEDontMatch());
Assert (face_no < GeometryInfo<dim>::faces_per_cell,
- ExcIndexRange (face_no, 0, GeometryInfo<dim>::faces_per_cell));
+ ExcIndexRange (face_no, 0, GeometryInfo<dim>::faces_per_cell));
Assert (subface_no < cell->face(face_no)->number_of_children(),
- ExcIndexRange (subface_no, 0, cell->face(face_no)->number_of_children()));
+ ExcIndexRange (subface_no, 0, cell->face(face_no)->number_of_children()));
Assert (cell->has_children() == false,
- ExcMessage ("You can't use subface data for cells that are "
- "already refined. Iterate over their children "
- "instead in these cases."));
-
- // set new cell. auto_ptr will take
- // care that old object gets
- // destroyed and also that this
- // object gets destroyed in the
- // destruction of this class
+ ExcMessage ("You can't use subface data for cells that are "
+ "already refined. Iterate over their children "
+ "instead in these cases."));
+
+ // set new cell. auto_ptr will take
+ // care that old object gets
+ // destroyed and also that this
+ // object gets destroyed in the
+ // destruction of this class
this->maybe_invalidate_previous_present_cell (cell);
this->present_cell.reset
(new typename FEValuesBase<dim,spacedim>::template
CellIterator<typename hp::DoFHandler<dim,spacedim>::cell_iterator> (cell));
- // this was the part of the work
- // that is dependent on the actual
- // data type of the iterator. now
- // pass on to the function doing
- // the real work.
+ // this was the part of the work
+ // that is dependent on the actual
+ // data type of the iterator. now
+ // pass on to the function doing
+ // the real work.
do_reinit (face_no, subface_no);
}
template <int dim, int spacedim>
void FESubfaceValues<dim,spacedim>::reinit (const typename MGDoFHandler<dim,spacedim>::cell_iterator &cell,
- const unsigned int face_no,
- const unsigned int subface_no)
+ const unsigned int face_no,
+ const unsigned int subface_no)
{
typedef FEValuesBase<dim,spacedim> FEVB;
Assert (static_cast<const FiniteElementData<dim>&>(*this->fe) ==
- static_cast<const FiniteElementData<dim>&>(cell->get_dof_handler().get_fe()),
- typename FEVB::ExcFEDontMatch());
+ static_cast<const FiniteElementData<dim>&>(cell->get_dof_handler().get_fe()),
+ typename FEVB::ExcFEDontMatch());
Assert (face_no < GeometryInfo<dim>::faces_per_cell,
- ExcIndexRange (face_no, 0, GeometryInfo<dim>::faces_per_cell));
+ ExcIndexRange (face_no, 0, GeometryInfo<dim>::faces_per_cell));
Assert (subface_no < cell->face(face_no)->number_of_children(),
- ExcIndexRange (subface_no, 0, cell->face(face_no)->number_of_children()));
+ ExcIndexRange (subface_no, 0, cell->face(face_no)->number_of_children()));
Assert (cell->has_children() == false,
- ExcMessage ("You can't use subface data for cells that are "
- "already refined. Iterate over their children "
- "instead in these cases."));
-
- // set new cell. auto_ptr will take
- // care that old object gets
- // destroyed and also that this
- // object gets destroyed in the
- // destruction of this class
+ ExcMessage ("You can't use subface data for cells that are "
+ "already refined. Iterate over their children "
+ "instead in these cases."));
+
+ // set new cell. auto_ptr will take
+ // care that old object gets
+ // destroyed and also that this
+ // object gets destroyed in the
+ // destruction of this class
this->maybe_invalidate_previous_present_cell (cell);
this->present_cell.reset
(new typename FEValuesBase<dim,spacedim>::template
CellIterator<typename MGDoFHandler<dim,spacedim>::cell_iterator> (cell));
- // this was the part of the work
- // that is dependent on the actual
- // data type of the iterator. now
- // pass on to the function doing
- // the real work.
+ // this was the part of the work
+ // that is dependent on the actual
+ // data type of the iterator. now
+ // pass on to the function doing
+ // the real work.
do_reinit (face_no, subface_no);
}
template <int dim, int spacedim>
void FESubfaceValues<dim,spacedim>::reinit (const typename Triangulation<dim,spacedim>::cell_iterator &cell,
- const unsigned int face_no,
- const unsigned int subface_no)
+ const unsigned int face_no,
+ const unsigned int subface_no)
{
Assert (face_no < GeometryInfo<dim>::faces_per_cell,
- ExcIndexRange (face_no, 0, GeometryInfo<dim>::faces_per_cell));
+ ExcIndexRange (face_no, 0, GeometryInfo<dim>::faces_per_cell));
Assert (subface_no < cell->face(face_no)->n_children(),
- ExcIndexRange (subface_no, 0, cell->face(face_no)->n_children()));
+ ExcIndexRange (subface_no, 0, cell->face(face_no)->n_children()));
- // set new cell. auto_ptr will take
- // care that old object gets
- // destroyed and also that this
- // object gets destroyed in the
- // destruction of this class
+ // set new cell. auto_ptr will take
+ // care that old object gets
+ // destroyed and also that this
+ // object gets destroyed in the
+ // destruction of this class
this->maybe_invalidate_previous_present_cell (cell);
this->present_cell.reset
(new typename FEValuesBase<dim,spacedim>::TriaCellIterator (cell));
- // this was the part of the work
- // that is dependent on the actual
- // data type of the iterator. now
- // pass on to the function doing
- // the real work.
+ // this was the part of the work
+ // that is dependent on the actual
+ // data type of the iterator. now
+ // pass on to the function doing
+ // the real work.
do_reinit (face_no, subface_no);
}
template <int dim, int spacedim>
void FESubfaceValues<dim,spacedim>::do_reinit (const unsigned int face_no,
- const unsigned int subface_no)
+ const unsigned int subface_no)
{
- // first of all, set the present_face_index
- // (if available)
+ // first of all, set the present_face_index
+ // (if available)
const typename Triangulation<dim,spacedim>::cell_iterator cell=*this->present_cell;
if (!cell->face(face_no)->has_children())
- // no subfaces at all, so set
- // present_face_index to this face rather
- // than any subface
+ // no subfaces at all, so set
+ // present_face_index to this face rather
+ // than any subface
this->present_face_index=cell->face_index(face_no);
else
if (dim!=3)
this->present_face_index=cell->face(face_no)->child_index(subface_no);
else
{
- // this is the same logic we use in
- // cell->neighbor_child_on_subface(). See
- // there for an explanation of the
- // different cases
- unsigned int subface_index=numbers::invalid_unsigned_int;
- switch (cell->subface_case(face_no))
- {
- case internal::SubfaceCase<3>::case_x:
- case internal::SubfaceCase<3>::case_y:
- case internal::SubfaceCase<3>::case_xy:
- subface_index=cell->face(face_no)->child_index(subface_no);
- break;
- case internal::SubfaceCase<3>::case_x1y2y:
- case internal::SubfaceCase<3>::case_y1x2x:
- subface_index=cell->face(face_no)->child(subface_no/2)->child_index(subface_no%2);
- break;
- case internal::SubfaceCase<3>::case_x1y:
- case internal::SubfaceCase<3>::case_y1x:
- switch (subface_no)
- {
- case 0:
- case 1:
- subface_index=cell->face(face_no)->child(0)->child_index(subface_no);
- break;
- case 2:
- subface_index=cell->face(face_no)->child_index(1);
- break;
- default:
- Assert(false, ExcInternalError());
- }
- break;
- case internal::SubfaceCase<3>::case_x2y:
- case internal::SubfaceCase<3>::case_y2x:
- switch (subface_no)
- {
- case 0:
- subface_index=cell->face(face_no)->child_index(0);
- break;
- case 1:
- case 2:
- subface_index=cell->face(face_no)->child(1)->child_index(subface_no-1);
- break;
- default:
- Assert(false, ExcInternalError());
- }
- break;
- default:
- Assert(false, ExcInternalError());
- break;
- }
- Assert(subface_index!=numbers::invalid_unsigned_int,
- ExcInternalError());
- this->present_face_index=subface_index;
+ // this is the same logic we use in
+ // cell->neighbor_child_on_subface(). See
+ // there for an explanation of the
+ // different cases
+ unsigned int subface_index=numbers::invalid_unsigned_int;
+ switch (cell->subface_case(face_no))
+ {
+ case internal::SubfaceCase<3>::case_x:
+ case internal::SubfaceCase<3>::case_y:
+ case internal::SubfaceCase<3>::case_xy:
+ subface_index=cell->face(face_no)->child_index(subface_no);
+ break;
+ case internal::SubfaceCase<3>::case_x1y2y:
+ case internal::SubfaceCase<3>::case_y1x2x:
+ subface_index=cell->face(face_no)->child(subface_no/2)->child_index(subface_no%2);
+ break;
+ case internal::SubfaceCase<3>::case_x1y:
+ case internal::SubfaceCase<3>::case_y1x:
+ switch (subface_no)
+ {
+ case 0:
+ case 1:
+ subface_index=cell->face(face_no)->child(0)->child_index(subface_no);
+ break;
+ case 2:
+ subface_index=cell->face(face_no)->child_index(1);
+ break;
+ default:
+ Assert(false, ExcInternalError());
+ }
+ break;
+ case internal::SubfaceCase<3>::case_x2y:
+ case internal::SubfaceCase<3>::case_y2x:
+ switch (subface_no)
+ {
+ case 0:
+ subface_index=cell->face(face_no)->child_index(0);
+ break;
+ case 1:
+ case 2:
+ subface_index=cell->face(face_no)->child(1)->child_index(subface_no-1);
+ break;
+ default:
+ Assert(false, ExcInternalError());
+ }
+ break;
+ default:
+ Assert(false, ExcInternalError());
+ break;
+ }
+ Assert(subface_index!=numbers::invalid_unsigned_int,
+ ExcInternalError());
+ this->present_face_index=subface_index;
}
- // now ask the mapping and the finite element
- // to do the actual work
+ // now ask the mapping and the finite element
+ // to do the actual work
this->get_mapping().fill_fe_subface_values(*this->present_cell,
- face_no, subface_no,
- this->quadrature,
- *this->mapping_data,
- this->quadrature_points,
- this->JxW_values,
- this->boundary_forms,
- this->normal_vectors);
+ face_no, subface_no,
+ this->quadrature,
+ *this->mapping_data,
+ this->quadrature_points,
+ this->JxW_values,
+ this->boundary_forms,
+ this->normal_vectors);
this->get_fe().fill_fe_subface_values(this->get_mapping(),
- *this->present_cell,
- face_no, subface_no,
- this->quadrature,
- *this->mapping_data,
- *this->fe_data,
- *this);
+ *this->present_cell,
+ face_no, subface_no,
+ this->quadrature,
+ *this->mapping_data,
+ *this->fe_data,
+ *this);
this->fe_data->clear_first_cell ();
this->mapping_data->clear_first_cell ();
// $Id$
// Version: $Name$
//
-// Copyright (C) 2001, 2002, 2003, 2005, 2006, 2009, 2011 by the deal.II authors
+// Copyright (C) 2001, 2002, 2003, 2005, 2006, 2009, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
template <int dim, int spacedim>
Mapping<dim, spacedim>::InternalDataBase::InternalDataBase ():
- update_flags(update_default),
- update_once(update_default),
- update_each(update_default),
- first_cell(true)
+ update_flags(update_default),
+ update_once(update_default),
+ update_each(update_default),
+ first_cell(true)
{}
// $Id$
// Version: $Name$
//
-// Copyright (C) 2001, 2002, 2003, 2005, 2006 by the deal.II authors
+// Copyright (C) 2001, 2002, 2003, 2005, 2006, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
template <int dim, int spacedim>
MappingC1<dim,spacedim>::MappingC1 ()
- :
- MappingQ<dim,spacedim> (3)
+ :
+ MappingQ<dim,spacedim> (3)
{
Assert (dim > 1, ExcImpossibleInDim(dim));
}
template <>
void
MappingC1<1>::add_line_support_points (const Triangulation<1>::cell_iterator &,
- std::vector<Point<1> > &) const
+ std::vector<Point<1> > &) const
{
const unsigned int dim = 1;
Assert (dim > 1, ExcImpossibleInDim(dim));
template <>
void
MappingC1<2>::add_line_support_points (const Triangulation<2>::cell_iterator &cell,
- std::vector<Point<2> > &a) const
+ std::vector<Point<2> > &a) const
{
const unsigned int dim = 2;
std::vector<Point<dim> > line_points (2);
- // loop over each of the lines,
- // and if it is at the
- // boundary, then first get the
- // boundary description and
- // second compute the points on
- // it. if not at the boundary,
- // get the respective points
- // from another function
+ // loop over each of the lines,
+ // and if it is at the
+ // boundary, then first get the
+ // boundary description and
+ // second compute the points on
+ // it. if not at the boundary,
+ // get the respective points
+ // from another function
for (unsigned int line_no=0; line_no<GeometryInfo<dim>::lines_per_cell; ++line_no)
{
const Triangulation<dim>::line_iterator line = cell->line(line_no);
if (line->at_boundary())
- {
- // first get the normal
- // vectors at the two
- // vertices of this line
- // from the boundary
- // description
- const Boundary<dim> &boundary
- = line->get_triangulation().get_boundary(line->boundary_indicator());
-
- Boundary<dim>::FaceVertexNormals face_vertex_normals;
- boundary.get_normals_at_vertices (line, face_vertex_normals);
-
- // then transform them into
- // interpolation points for
- // a cubic polynomial
- //
- // for this, note that if
- // we describe the boundary
- // curve as a polynomial in
- // tangential coordinate
- // @p{t=0..1} (along the
- // line) and @p{s} in
- // normal direction, then
- // the cubic mapping is
- // such that @p{s = a*t**3
- // + b*t**2 + c*t + d}, and
- // we want to determine the
- // interpolation points at
- // @p{t=1/3} and
- // @p{t=2/3}. Since at
- // @p{t=0,1} we want a
- // vertex which is actually
- // at the boundary, we know
- // that @p{d=0} and
- // @p{a=-b-c}. As
- // side-conditions, we want
- // that the derivatives at
- // @p{t=0} and @p{t=1},
- // i.e. at the vertices
- // match those returned by
- // the boundary. We then
- // have that
- // @p{s(1/3)=1/27(2b+8c)}
- // and
- // @p{s(2/3)=4/27b+10/27c}.
- //
- // The task is then first
- // to determine the
- // coefficients from the
- // tangentials. for that,
- // first rotate the
- // tangents of @p{s(t)}
- // into the global
- // coordinate system. they
- // are @p{A (1,c)} and @p{A
- // (1,-b-2c)} with @p{A} the
- // rotation matrix, since
- // the tangentials in the
- // coordinate system
- // relative to the line are
- // @p{(1,c)} and @p{(1,-b-2c)}
- // at the two vertices,
- // respectively. We then
- // have to make sure by
- // matching @p{b,c} that
- // these tangentials are
- // orthogonal to the normals
- // returned by the boundary
- // object
- const Tensor<1,2> coordinate_vector = line->vertex(1) - line->vertex(0);
- const double h = std::sqrt(coordinate_vector * coordinate_vector);
- Tensor<1,2> coordinate_axis = coordinate_vector;
- coordinate_axis /= h;
-
- const double alpha = std::atan2(coordinate_axis[1], coordinate_axis[0]);
- const double c = -((face_vertex_normals[0][1] * std::sin(alpha)
- +face_vertex_normals[0][0] * std::cos(alpha)) /
- (face_vertex_normals[0][1] * std::cos(alpha)
- -face_vertex_normals[0][0] * std::sin(alpha)));
- const double b = ((face_vertex_normals[1][1] * std::sin(alpha)
- +face_vertex_normals[1][0] * std::cos(alpha)) /
- (face_vertex_normals[1][1] * std::cos(alpha)
- -face_vertex_normals[1][0] * std::sin(alpha)))
- -2*c;
-
-
- // next evaluate the so
- // determined cubic
- // polynomial at the points
- // 1/3 and 2/3, first in
- // unit coordinates
- const Point<2> new_unit_points[2] = { Point<2>(1./3., 1./27.*(2*b+8*c)),
- Point<2>(2./3., 4./27.*b+10./27.*c) };
- // then transform these
- // points to real
- // coordinates by rotating,
- // scaling and shifting
- for (unsigned int i=0; i<2; ++i)
- {
- Point<2> real_point (std::cos(alpha) * new_unit_points[i][0]
- - std::sin(alpha) * new_unit_points[i][1],
- std::sin(alpha) * new_unit_points[i][0]
- + std::cos(alpha) * new_unit_points[i][1]);
- real_point *= h;
- real_point += line->vertex(0);
- a.push_back (real_point);
- };
- }
+ {
+ // first get the normal
+ // vectors at the two
+ // vertices of this line
+ // from the boundary
+ // description
+ const Boundary<dim> &boundary
+ = line->get_triangulation().get_boundary(line->boundary_indicator());
+
+ Boundary<dim>::FaceVertexNormals face_vertex_normals;
+ boundary.get_normals_at_vertices (line, face_vertex_normals);
+
+ // then transform them into
+ // interpolation points for
+ // a cubic polynomial
+ //
+ // for this, note that if
+ // we describe the boundary
+ // curve as a polynomial in
+ // tangential coordinate
+ // @p{t=0..1} (along the
+ // line) and @p{s} in
+ // normal direction, then
+ // the cubic mapping is
+ // such that @p{s = a*t**3
+ // + b*t**2 + c*t + d}, and
+ // we want to determine the
+ // interpolation points at
+ // @p{t=1/3} and
+ // @p{t=2/3}. Since at
+ // @p{t=0,1} we want a
+ // vertex which is actually
+ // at the boundary, we know
+ // that @p{d=0} and
+ // @p{a=-b-c}. As
+ // side-conditions, we want
+ // that the derivatives at
+ // @p{t=0} and @p{t=1},
+ // i.e. at the vertices
+ // match those returned by
+ // the boundary. We then
+ // have that
+ // @p{s(1/3)=1/27(2b+8c)}
+ // and
+ // @p{s(2/3)=4/27b+10/27c}.
+ //
+ // The task is then first
+ // to determine the
+ // coefficients from the
+ // tangentials. for that,
+ // first rotate the
+ // tangents of @p{s(t)}
+ // into the global
+ // coordinate system. they
+ // are @p{A (1,c)} and @p{A
+ // (1,-b-2c)} with @p{A} the
+ // rotation matrix, since
+ // the tangentials in the
+ // coordinate system
+ // relative to the line are
+ // @p{(1,c)} and @p{(1,-b-2c)}
+ // at the two vertices,
+ // respectively. We then
+ // have to make sure by
+ // matching @p{b,c} that
+ // these tangentials are
+ // orthogonal to the normals
+ // returned by the boundary
+ // object
+ const Tensor<1,2> coordinate_vector = line->vertex(1) - line->vertex(0);
+ const double h = std::sqrt(coordinate_vector * coordinate_vector);
+ Tensor<1,2> coordinate_axis = coordinate_vector;
+ coordinate_axis /= h;
+
+ const double alpha = std::atan2(coordinate_axis[1], coordinate_axis[0]);
+ const double c = -((face_vertex_normals[0][1] * std::sin(alpha)
+ +face_vertex_normals[0][0] * std::cos(alpha)) /
+ (face_vertex_normals[0][1] * std::cos(alpha)
+ -face_vertex_normals[0][0] * std::sin(alpha)));
+ const double b = ((face_vertex_normals[1][1] * std::sin(alpha)
+ +face_vertex_normals[1][0] * std::cos(alpha)) /
+ (face_vertex_normals[1][1] * std::cos(alpha)
+ -face_vertex_normals[1][0] * std::sin(alpha)))
+ -2*c;
+
+
+ // next evaluate the so
+ // determined cubic
+ // polynomial at the points
+ // 1/3 and 2/3, first in
+ // unit coordinates
+ const Point<2> new_unit_points[2] = { Point<2>(1./3., 1./27.*(2*b+8*c)),
+ Point<2>(2./3., 4./27.*b+10./27.*c) };
+ // then transform these
+ // points to real
+ // coordinates by rotating,
+ // scaling and shifting
+ for (unsigned int i=0; i<2; ++i)
+ {
+ Point<2> real_point (std::cos(alpha) * new_unit_points[i][0]
+ - std::sin(alpha) * new_unit_points[i][1],
+ std::sin(alpha) * new_unit_points[i][0]
+ + std::cos(alpha) * new_unit_points[i][1]);
+ real_point *= h;
+ real_point += line->vertex(0);
+ a.push_back (real_point);
+ };
+ }
else
- // not at boundary
- {
- static const StraightBoundary<dim> straight_boundary;
- straight_boundary.get_intermediate_points_on_line (line, line_points);
- a.insert (a.end(), line_points.begin(), line_points.end());
- };
+ // not at boundary
+ {
+ static const StraightBoundary<dim> straight_boundary;
+ straight_boundary.get_intermediate_points_on_line (line, line_points);
+ a.insert (a.end(), line_points.begin(), line_points.end());
+ };
};
}
template<int dim, int spacedim>
void
MappingC1<dim,spacedim>::add_line_support_points (const typename Triangulation<dim>::cell_iterator &,
- std::vector<Point<dim> > &) const
+ std::vector<Point<dim> > &) const
{
Assert (false, ExcNotImplemented());
}
template <>
void
MappingC1<1>::add_quad_support_points (const Triangulation<1>::cell_iterator &,
- std::vector<Point<1> > &) const
+ std::vector<Point<1> > &) const
{
const unsigned int dim = 1;
Assert (dim > 2, ExcImpossibleInDim(dim));
template <>
void
MappingC1<2>::add_quad_support_points (const Triangulation<2>::cell_iterator &,
- std::vector<Point<2> > &) const
+ std::vector<Point<2> > &) const
{
const unsigned int dim = 2;
Assert (dim > 2, ExcImpossibleInDim(dim));
template<int dim, int spacedim>
void
MappingC1<dim,spacedim>::add_quad_support_points (const typename Triangulation<dim>::cell_iterator &,
- std::vector<Point<dim> > &) const
+ std::vector<Point<dim> > &) const
{
Assert (false, ExcNotImplemented());
}
// $Id$
// Version: $Name$
//
-// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 by the deal.II authors
+// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
template<int dim, int spacedim>
MappingCartesian<dim, spacedim>::InternalData::InternalData (const Quadrature<dim>& q)
- :
- quadrature_points (q.get_points ())
+ :
+ quadrature_points (q.get_points ())
{}
MappingCartesian<dim, spacedim>::InternalData::memory_consumption () const
{
return (Mapping<dim, spacedim>::InternalDataBase::memory_consumption() +
- MemoryConsumption::memory_consumption (length) +
- MemoryConsumption::memory_consumption (quadrature_points));
+ MemoryConsumption::memory_consumption (length) +
+ MemoryConsumption::memory_consumption (quadrature_points));
}
template<int dim, int spacedim>
typename Mapping<dim, spacedim>::InternalDataBase *
MappingCartesian<dim, spacedim>::get_data (const UpdateFlags update_flags,
- const Quadrature<dim> &q) const
+ const Quadrature<dim> &q) const
{
InternalData* data = new InternalData (q);
template<int dim, int spacedim>
typename Mapping<dim, spacedim>::InternalDataBase *
MappingCartesian<dim, spacedim>::get_face_data (const UpdateFlags update_flags,
- const Quadrature<dim-1>& quadrature) const
+ const Quadrature<dim-1>& quadrature) const
{
InternalData* data
= new InternalData (QProjector<dim>::project_to_all_faces(quadrature));
template<int dim, int spacedim>
typename Mapping<dim, spacedim>::InternalDataBase *
MappingCartesian<dim, spacedim>::get_subface_data (const UpdateFlags update_flags,
- const Quadrature<dim-1> &quadrature) const
+ const Quadrature<dim-1> &quadrature) const
{
InternalData* data
= new InternalData (QProjector<dim>::project_to_all_subfaces(quadrature));
template<int dim, int spacedim>
void
MappingCartesian<dim, spacedim>::compute_fill (const typename Triangulation<dim,spacedim>::cell_iterator &cell,
- const unsigned int face_no,
- const unsigned int sub_no,
- const CellSimilarity::Similarity cell_similarity,
- InternalData &data,
- std::vector<Point<dim> > &quadrature_points,
- std::vector<Point<dim> > &normal_vectors) const
+ const unsigned int face_no,
+ const unsigned int sub_no,
+ const CellSimilarity::Similarity cell_similarity,
+ InternalData &data,
+ std::vector<Point<dim> > &quadrature_points,
+ std::vector<Point<dim> > &normal_vectors) const
{
const UpdateFlags update_flags(data.current_update_flags());
// some more sanity checks
if (face_no != invalid_face_number)
{
- // Add 1 on both sides of
- // assertion to avoid compiler
- // warning about testing
- // unsigned int < 0 in 1d.
+ // Add 1 on both sides of
+ // assertion to avoid compiler
+ // warning about testing
+ // unsigned int < 0 in 1d.
Assert (face_no+1 < GeometryInfo<dim>::faces_per_cell+1,
- ExcIndexRange (face_no, 0, GeometryInfo<dim>::faces_per_cell));
-
- // We would like to check for
- // sub_no < cell->face(face_no)->n_children(),
- // but unfortunately the current
- // function is also called for
- // faces without children (see
- // tests/fe/mapping.cc). Therefore,
- // we must use following workaround
- // of two separate assertions
+ ExcIndexRange (face_no, 0, GeometryInfo<dim>::faces_per_cell));
+
+ // We would like to check for
+ // sub_no < cell->face(face_no)->n_children(),
+ // but unfortunately the current
+ // function is also called for
+ // faces without children (see
+ // tests/fe/mapping.cc). Therefore,
+ // we must use following workaround
+ // of two separate assertions
Assert ((sub_no == invalid_face_number) ||
cell->face(face_no)->has_children() ||
(sub_no+1 < GeometryInfo<dim>::max_children_per_face+1),
ExcIndexRange (sub_no, 0, cell->face(face_no)->n_children()));
}
else
- // invalid face number, so
- // subface should be invalid as
- // well
+ // invalid face number, so
+ // subface should be invalid as
+ // well
Assert (sub_no == invalid_face_number, ExcInternalError());
- // let @p{start} be the origin of a
- // local coordinate system. it is
- // chosen as the (lower) left
- // vertex
+ // let @p{start} be the origin of a
+ // local coordinate system. it is
+ // chosen as the (lower) left
+ // vertex
const Point<dim> start = cell->vertex(0);
- // Compute start point and sizes
- // along axes. Strange vertex
- // numbering makes this complicated
- // again.
+ // Compute start point and sizes
+ // along axes. Strange vertex
+ // numbering makes this complicated
+ // again.
if (cell_similarity != CellSimilarity::translation)
{
switch (dim)
- {
- case 1:
- data.length[0] = cell->vertex(1)(0) - start(0);
- break;
- case 2:
- data.length[0] = cell->vertex(1)(0) - start(0);
- data.length[1] = cell->vertex(2)(1) - start(1);
- break;
- case 3:
- data.length[0] = cell->vertex(1)(0) - start(0);
- data.length[1] = cell->vertex(2)(1) - start(1);
- data.length[2] = cell->vertex(4)(2) - start(2);
- break;
- default:
- Assert(false, ExcNotImplemented());
- }
+ {
+ case 1:
+ data.length[0] = cell->vertex(1)(0) - start(0);
+ break;
+ case 2:
+ data.length[0] = cell->vertex(1)(0) - start(0);
+ data.length[1] = cell->vertex(2)(1) - start(1);
+ break;
+ case 3:
+ data.length[0] = cell->vertex(1)(0) - start(0);
+ data.length[1] = cell->vertex(2)(1) - start(1);
+ data.length[2] = cell->vertex(4)(2) - start(2);
+ break;
+ default:
+ Assert(false, ExcNotImplemented());
+ }
}
- // transform quadrature point. this
- // is obtained simply by scaling
- // unit coordinates with lengths in
- // each direction
+ // transform quadrature point. this
+ // is obtained simply by scaling
+ // unit coordinates with lengths in
+ // each direction
if (update_flags & update_quadrature_points)
{
const typename QProjector<dim>::DataSetDescriptor offset
- = (face_no == invalid_face_number
- ?
- QProjector<dim>::DataSetDescriptor::cell()
- :
- (sub_no == invalid_face_number
- ?
- // called from FEFaceValues
- QProjector<dim>::DataSetDescriptor::face (face_no,
- cell->face_orientation(face_no),
- cell->face_flip(face_no),
- cell->face_rotation(face_no),
- quadrature_points.size())
- :
- // called from FESubfaceValues
- QProjector<dim>::DataSetDescriptor::subface (face_no, sub_no,
- cell->face_orientation(face_no),
- cell->face_flip(face_no),
- cell->face_rotation(face_no),
- quadrature_points.size(),
- cell->subface_case(face_no))
- ));
+ = (face_no == invalid_face_number
+ ?
+ QProjector<dim>::DataSetDescriptor::cell()
+ :
+ (sub_no == invalid_face_number
+ ?
+ // called from FEFaceValues
+ QProjector<dim>::DataSetDescriptor::face (face_no,
+ cell->face_orientation(face_no),
+ cell->face_flip(face_no),
+ cell->face_rotation(face_no),
+ quadrature_points.size())
+ :
+ // called from FESubfaceValues
+ QProjector<dim>::DataSetDescriptor::subface (face_no, sub_no,
+ cell->face_orientation(face_no),
+ cell->face_flip(face_no),
+ cell->face_rotation(face_no),
+ quadrature_points.size(),
+ cell->subface_case(face_no))
+ ));
for (unsigned int i=0; i<quadrature_points.size(); ++i)
- {
- quadrature_points[i] = start;
- for (unsigned int d=0; d<dim; ++d)
- quadrature_points[i](d) += data.length[d] *
- data.quadrature_points[i+offset](d);
- }
+ {
+ quadrature_points[i] = start;
+ for (unsigned int d=0; d<dim; ++d)
+ quadrature_points[i](d) += data.length[d] *
+ data.quadrature_points[i+offset](d);
+ }
}
- // compute normal vectors. since
- // cells are aligned to coordinate
- // axes, they are simply vectors
- // with exactly one entry equal to
- // 1 or -1. Furthermore, all
- // normals on a face have the same
- // value
+ // compute normal vectors. since
+ // cells are aligned to coordinate
+ // axes, they are simply vectors
+ // with exactly one entry equal to
+ // 1 or -1. Furthermore, all
+ // normals on a face have the same
+ // value
if (update_flags & update_normal_vectors)
{
Assert (face_no < GeometryInfo<dim>::faces_per_cell,
switch (dim)
{
- case 1:
- {
+ case 1:
+ {
static const Point<dim>
normals[GeometryInfo<1>::faces_per_cell]
= { Point<dim>(-1.),
normals[face_no]);
break;
}
-
+
case 2:
{
static const Point<dim>
MappingCartesian<dim, spacedim>::
fill_fe_values (const typename Triangulation<dim,spacedim>::cell_iterator& cell,
const Quadrature<dim>& q,
- typename Mapping<dim,spacedim>::InternalDataBase& mapping_data,
+ typename Mapping<dim,spacedim>::InternalDataBase& mapping_data,
std::vector<Point<spacedim> >& quadrature_points,
std::vector<double>& JxW_values,
- std::vector< DerivativeForm<1,dim,spacedim> > & jacobians,
- std::vector<DerivativeForm<2,dim,spacedim> > &jacobian_grads,
- std::vector<DerivativeForm<1,spacedim,dim> > &inverse_jacobians,
- std::vector<Point<spacedim> > &,
- CellSimilarity::Similarity& cell_similarity) const
+ std::vector< DerivativeForm<1,dim,spacedim> > & jacobians,
+ std::vector<DerivativeForm<2,dim,spacedim> > &jacobian_grads,
+ std::vector<DerivativeForm<1,spacedim,dim> > &inverse_jacobians,
+ std::vector<Point<spacedim> > &,
+ CellSimilarity::Similarity& cell_similarity) const
{
- // convert data object to internal
- // data for this class. fails with
- // an exception if that is not
- // possible
+ // convert data object to internal
+ // data for this class. fails with
+ // an exception if that is not
+ // possible
Assert (dynamic_cast<InternalData*> (&mapping_data) != 0, ExcInternalError());
InternalData &data = static_cast<InternalData&> (mapping_data);
std::vector<Point<dim> > dummy;
compute_fill (cell, invalid_face_number, invalid_face_number, cell_similarity,
- data,
- quadrature_points,
- dummy);
-
- // compute Jacobian
- // determinant. all values are
- // equal and are the product of the
- // local lengths in each coordinate
- // direction
+ data,
+ quadrature_points,
+ dummy);
+
+ // compute Jacobian
+ // determinant. all values are
+ // equal and are the product of the
+ // local lengths in each coordinate
+ // direction
if (data.current_update_flags() & (update_JxW_values | update_volume_elements))
if (cell_similarity != CellSimilarity::translation)
{
- double J = data.length[0];
- for (unsigned int d=1;d<dim;++d)
- J *= data.length[d];
- data.volume_element = J;
- if (data.current_update_flags() & update_JxW_values)
- for (unsigned int i=0; i<JxW_values.size();++i)
- JxW_values[i] = J * q.weight(i);
+ double J = data.length[0];
+ for (unsigned int d=1;d<dim;++d)
+ J *= data.length[d];
+ data.volume_element = J;
+ if (data.current_update_flags() & update_JxW_values)
+ for (unsigned int i=0; i<JxW_values.size();++i)
+ JxW_values[i] = J * q.weight(i);
}
- // "compute" Jacobian at the quadrature
- // points, which are all the same
+ // "compute" Jacobian at the quadrature
+ // points, which are all the same
if (data.current_update_flags() & update_jacobians)
if (cell_similarity != CellSimilarity::translation)
for (unsigned int i=0; i<jacobians.size();++i)
- {
- jacobians[i] = DerivativeForm<1,dim,spacedim>();
- for (unsigned int j=0; j<dim; ++j)
- jacobians[i][j][j]=data.length[j];
- }
- // "compute" the derivative of the Jacobian
- // at the quadrature points, which are all
- // zero of course
+ {
+ jacobians[i] = DerivativeForm<1,dim,spacedim>();
+ for (unsigned int j=0; j<dim; ++j)
+ jacobians[i][j][j]=data.length[j];
+ }
+ // "compute" the derivative of the Jacobian
+ // at the quadrature points, which are all
+ // zero of course
if (data.current_update_flags() & update_jacobian_grads)
if (cell_similarity != CellSimilarity::translation)
for (unsigned int i=0; i<jacobian_grads.size();++i)
- jacobian_grads[i]=DerivativeForm<2,dim,spacedim>();
- // "compute" inverse Jacobian at the
- // quadrature points, which are all
- // the same
+ jacobian_grads[i]=DerivativeForm<2,dim,spacedim>();
+ // "compute" inverse Jacobian at the
+ // quadrature points, which are all
+ // the same
if (data.current_update_flags() & update_inverse_jacobians)
if (cell_similarity != CellSimilarity::translation)
for (unsigned int i=0; i<inverse_jacobians.size();++i)
- {
- inverse_jacobians[i]=Tensor<2,dim>();
- for (unsigned int j=0; j<dim; ++j)
- inverse_jacobians[j][j]=1./data.length[j];
- }
+ {
+ inverse_jacobians[i]=Tensor<2,dim>();
+ for (unsigned int j=0; j<dim; ++j)
+ inverse_jacobians[j][j]=1./data.length[j];
+ }
}
std::vector<Tensor<1,dim> > &boundary_forms,
std::vector<Point<spacedim> > &normal_vectors) const
{
- // convert data object to internal
- // data for this class. fails with
- // an exception if that is not
- // possible
+ // convert data object to internal
+ // data for this class. fails with
+ // an exception if that is not
+ // possible
Assert (dynamic_cast<InternalData*> (&mapping_data) != 0,
- ExcInternalError());
+ ExcInternalError());
InternalData &data = static_cast<InternalData&> (mapping_data);
compute_fill (cell, face_no, invalid_face_number,
- CellSimilarity::none,
- data,
- quadrature_points,
- normal_vectors);
-
- // first compute Jacobian
- // determinant, which is simply the
- // product of the local lengths
- // since the jacobian is diagonal
+ CellSimilarity::none,
+ data,
+ quadrature_points,
+ normal_vectors);
+
+ // first compute Jacobian
+ // determinant, which is simply the
+ // product of the local lengths
+ // since the jacobian is diagonal
double J = 1.;
for (unsigned int d=0; d<dim; ++d)
if (d != GeometryInfo<dim>::unit_normal_direction[face_no])
{
J = data.length[0];
for (unsigned int d=1;d<dim;++d)
- J *= data.length[d];
+ J *= data.length[d];
data.volume_element = J;
}
}
std::vector<Tensor<1,dim> > &boundary_forms,
std::vector<Point<spacedim> > &normal_vectors) const
{
- // convert data object to internal
- // data for this class. fails with
- // an exception if that is not
- // possible
+ // convert data object to internal
+ // data for this class. fails with
+ // an exception if that is not
+ // possible
Assert (dynamic_cast<InternalData*> (&mapping_data) != 0, ExcInternalError());
InternalData &data = static_cast<InternalData&> (mapping_data);
compute_fill (cell, face_no, sub_no, CellSimilarity::none,
- data,
- quadrature_points,
- normal_vectors);
-
- // first compute Jacobian
- // determinant, which is simply the
- // product of the local lengths
- // since the jacobian is diagonal
+ data,
+ quadrature_points,
+ normal_vectors);
+
+ // first compute Jacobian
+ // determinant, which is simply the
+ // product of the local lengths
+ // since the jacobian is diagonal
double J = 1.;
for (unsigned int d=0; d<dim; ++d)
if (d != GeometryInfo<dim>::unit_normal_direction[face_no])
if (data.current_update_flags() & update_JxW_values)
{
- // Here,
- // cell->face(face_no)->n_children()
- // would be the right choice,
- // but unfortunately the
- // current function is also
- // called for faces without
- // children (see
- // tests/fe/mapping.cc). Add
- // following switch to avoid
- // diffs in tests/fe/mapping.OK
+ // Here,
+ // cell->face(face_no)->n_children()
+ // would be the right choice,
+ // but unfortunately the
+ // current function is also
+ // called for faces without
+ // children (see
+ // tests/fe/mapping.cc). Add
+ // following switch to avoid
+ // diffs in tests/fe/mapping.OK
const unsigned int n_subfaces=
- cell->face(face_no)->has_children() ?
- cell->face(face_no)->n_children() :
- GeometryInfo<dim>::max_children_per_face;
+ cell->face(face_no)->has_children() ?
+ cell->face(face_no)->n_children() :
+ GeometryInfo<dim>::max_children_per_face;
for (unsigned int i=0; i<JxW_values.size();++i)
- JxW_values[i] = J * q.weight(i) / n_subfaces;
+ JxW_values[i] = J * q.weight(i) / n_subfaces;
}
if (data.current_update_flags() & update_boundary_forms)
{
J = data.length[0];
for (unsigned int d=1;d<dim;++d)
- J *= data.length[d];
+ J *= data.length[d];
data.volume_element = J;
}
}
{
AssertDimension (input.size(), output.size());
Assert (dynamic_cast<const InternalData *>(&mapping_data) != 0,
- ExcInternalError());
+ ExcInternalError());
const InternalData &data = static_cast<const InternalData&> (mapping_data);
switch (mapping_type)
{
case mapping_covariant:
{
- Assert (data.update_flags & update_covariant_transformation,
- typename FEValuesBase<dim>::ExcAccessToUninitializedField());
+ Assert (data.update_flags & update_covariant_transformation,
+ typename FEValuesBase<dim>::ExcAccessToUninitializedField());
- for (unsigned int i=0; i<output.size(); ++i)
- for (unsigned int d=0;d<dim;++d)
- output[i][d] = input[i][d]/data.length[d];
- return;
+ for (unsigned int i=0; i<output.size(); ++i)
+ for (unsigned int d=0;d<dim;++d)
+ output[i][d] = input[i][d]/data.length[d];
+ return;
}
case mapping_contravariant:
{
- Assert (data.update_flags & update_contravariant_transformation,
- typename FEValuesBase<dim>::ExcAccessToUninitializedField());
+ Assert (data.update_flags & update_contravariant_transformation,
+ typename FEValuesBase<dim>::ExcAccessToUninitializedField());
- for (unsigned int i=0; i<output.size(); ++i)
- for (unsigned int d=0;d<dim;++d)
- output[i][d] = input[i][d]*data.length[d];
- return;
+ for (unsigned int i=0; i<output.size(); ++i)
+ for (unsigned int d=0;d<dim;++d)
+ output[i][d] = input[i][d]*data.length[d];
+ return;
}
case mapping_piola:
{
- Assert (data.update_flags & update_contravariant_transformation,
- typename FEValuesBase<dim>::ExcAccessToUninitializedField());
- Assert (data.update_flags & update_volume_elements,
- typename FEValuesBase<dim>::ExcAccessToUninitializedField());
-
- for (unsigned int i=0; i<output.size(); ++i)
- for (unsigned int d=0;d<dim;++d)
- output[i][d] = input[i][d] * data.length[d] / data.volume_element;
- return;
+ Assert (data.update_flags & update_contravariant_transformation,
+ typename FEValuesBase<dim>::ExcAccessToUninitializedField());
+ Assert (data.update_flags & update_volume_elements,
+ typename FEValuesBase<dim>::ExcAccessToUninitializedField());
+
+ for (unsigned int i=0; i<output.size(); ++i)
+ for (unsigned int d=0;d<dim;++d)
+ output[i][d] = input[i][d] * data.length[d] / data.volume_element;
+ return;
}
default:
- Assert(false, ExcNotImplemented());
+ Assert(false, ExcNotImplemented());
}
}
{
AssertDimension (input.size(), output.size());
Assert (dynamic_cast<const InternalData *>(&mapping_data) != 0,
- ExcInternalError());
+ ExcInternalError());
const InternalData &data = static_cast<const InternalData&>(mapping_data);
switch (mapping_type)
{
case mapping_covariant:
{
- Assert (data.update_flags & update_covariant_transformation,
- typename FEValuesBase<dim>::ExcAccessToUninitializedField());
-
- for (unsigned int i=0; i<output.size(); ++i)
- for (unsigned int d1=0;d1<dim;++d1)
- for (unsigned int d2=0;d2<dim;++d2)
- output[i][d1][d2] = input[i][d1][d2] / data.length[d2];
- return;
+ Assert (data.update_flags & update_covariant_transformation,
+ typename FEValuesBase<dim>::ExcAccessToUninitializedField());
+
+ for (unsigned int i=0; i<output.size(); ++i)
+ for (unsigned int d1=0;d1<dim;++d1)
+ for (unsigned int d2=0;d2<dim;++d2)
+ output[i][d1][d2] = input[i][d1][d2] / data.length[d2];
+ return;
}
case mapping_contravariant:
{
- Assert (data.update_flags & update_contravariant_transformation,
- typename FEValuesBase<dim>::ExcAccessToUninitializedField());
-
- for (unsigned int i=0; i<output.size(); ++i)
- for (unsigned int d1=0;d1<dim;++d1)
- for (unsigned int d2=0;d2<dim;++d2)
- output[i][d1][d2] = input[i][d1][d2] * data.length[d2];
- return;
+ Assert (data.update_flags & update_contravariant_transformation,
+ typename FEValuesBase<dim>::ExcAccessToUninitializedField());
+
+ for (unsigned int i=0; i<output.size(); ++i)
+ for (unsigned int d1=0;d1<dim;++d1)
+ for (unsigned int d2=0;d2<dim;++d2)
+ output[i][d1][d2] = input[i][d1][d2] * data.length[d2];
+ return;
}
case mapping_covariant_gradient:
{
- Assert (data.update_flags & update_covariant_transformation,
- typename FEValuesBase<dim>::ExcAccessToUninitializedField());
-
- for (unsigned int i=0; i<output.size(); ++i)
- for (unsigned int d1=0;d1<dim;++d1)
- for (unsigned int d2=0;d2<dim;++d2)
- output[i][d1][d2] = input[i][d1][d2] / data.length[d2] / data.length[d1];
- return;
+ Assert (data.update_flags & update_covariant_transformation,
+ typename FEValuesBase<dim>::ExcAccessToUninitializedField());
+
+ for (unsigned int i=0; i<output.size(); ++i)
+ for (unsigned int d1=0;d1<dim;++d1)
+ for (unsigned int d2=0;d2<dim;++d2)
+ output[i][d1][d2] = input[i][d1][d2] / data.length[d2] / data.length[d1];
+ return;
}
case mapping_contravariant_gradient:
{
- Assert (data.update_flags & update_contravariant_transformation,
- typename FEValuesBase<dim>::ExcAccessToUninitializedField());
-
- for (unsigned int i=0; i<output.size(); ++i)
- for (unsigned int d1=0;d1<dim;++d1)
- for (unsigned int d2=0;d2<dim;++d2)
- output[i][d1][d2] = input[i][d1][d2] * data.length[d2] / data.length[d1];
- return;
+ Assert (data.update_flags & update_contravariant_transformation,
+ typename FEValuesBase<dim>::ExcAccessToUninitializedField());
+
+ for (unsigned int i=0; i<output.size(); ++i)
+ for (unsigned int d1=0;d1<dim;++d1)
+ for (unsigned int d2=0;d2<dim;++d2)
+ output[i][d1][d2] = input[i][d1][d2] * data.length[d2] / data.length[d1];
+ return;
}
case mapping_piola:
{
- Assert (data.update_flags & update_contravariant_transformation,
- typename FEValuesBase<dim>::ExcAccessToUninitializedField());
- Assert (data.update_flags & update_volume_elements,
- typename FEValuesBase<dim>::ExcAccessToUninitializedField());
-
- for (unsigned int i=0; i<output.size(); ++i)
- for (unsigned int d1=0;d1<dim;++d1)
- for (unsigned int d2=0;d2<dim;++d2)
- output[i][d1][d2] = input[i][d1][d2] * data.length[d2]
- / data.length[d1] / data.volume_element;
- return;
+ Assert (data.update_flags & update_contravariant_transformation,
+ typename FEValuesBase<dim>::ExcAccessToUninitializedField());
+ Assert (data.update_flags & update_volume_elements,
+ typename FEValuesBase<dim>::ExcAccessToUninitializedField());
+
+ for (unsigned int i=0; i<output.size(); ++i)
+ for (unsigned int d1=0;d1<dim;++d1)
+ for (unsigned int d2=0;d2<dim;++d2)
+ output[i][d1][d2] = input[i][d1][d2] * data.length[d2]
+ / data.length[d1] / data.volume_element;
+ return;
}
default:
- Assert(false, ExcNotImplemented());
+ Assert(false, ExcNotImplemented());
}
}
AssertDimension (input.size(), output.size());
Assert (dynamic_cast<const InternalData *>(&mapping_data) != 0,
- ExcInternalError());
+ ExcInternalError());
const InternalData &data = static_cast<const InternalData&>(mapping_data);
switch (mapping_type)
{
case mapping_piola_gradient:
{
- Assert (data.update_flags & update_contravariant_transformation,
- typename FEValuesBase<dim>::ExcAccessToUninitializedField());
- Assert (data.update_flags & update_volume_elements,
- typename FEValuesBase<dim>::ExcAccessToUninitializedField());
-
- for (unsigned int i=0; i<output.size(); ++i)
- for (unsigned int d1=0;d1<dim;++d1)
- for (unsigned int d2=0;d2<dim;++d2)
- output[i][d1][d2] = input[i][d1][d2] * data.length[d2]
- / data.length[d1] / data.volume_element;
- return;
+ Assert (data.update_flags & update_contravariant_transformation,
+ typename FEValuesBase<dim>::ExcAccessToUninitializedField());
+ Assert (data.update_flags & update_volume_elements,
+ typename FEValuesBase<dim>::ExcAccessToUninitializedField());
+
+ for (unsigned int i=0; i<output.size(); ++i)
+ for (unsigned int d1=0;d1<dim;++d1)
+ for (unsigned int d2=0;d2<dim;++d2)
+ output[i][d1][d2] = input[i][d1][d2] * data.length[d2]
+ / data.length[d1] / data.volume_element;
+ return;
}
default:
- Assert(false, ExcNotImplemented());
+ Assert(false, ExcNotImplemented());
}
}
switch (dim)
{
case 1:
- length[0] = cell->vertex(1)(0) - start(0);
- break;
+ length[0] = cell->vertex(1)(0) - start(0);
+ break;
case 2:
- length[0] = cell->vertex(1)(0) - start(0);
- length[1] = cell->vertex(2)(1) - start(1);
- break;
+ length[0] = cell->vertex(1)(0) - start(0);
+ length[1] = cell->vertex(2)(1) - start(1);
+ break;
case 3:
- length[0] = cell->vertex(1)(0) - start(0);
- length[1] = cell->vertex(2)(1) - start(1);
- length[2] = cell->vertex(4)(2) - start(2);
- break;
+ length[0] = cell->vertex(1)(0) - start(0);
+ length[1] = cell->vertex(2)(1) - start(1);
+ length[2] = cell->vertex(4)(2) - start(2);
+ break;
default:
- Assert(false, ExcNotImplemented());
+ Assert(false, ExcNotImplemented());
}
Point<dim> p_real = cell->vertex(0);
switch (dim)
{
case 1:
- real(0) /= cell->vertex(1)(0) - start(0);
- break;
+ real(0) /= cell->vertex(1)(0) - start(0);
+ break;
case 2:
- real(0) /= cell->vertex(1)(0) - start(0);
- real(1) /= cell->vertex(2)(1) - start(1);
- break;
+ real(0) /= cell->vertex(1)(0) - start(0);
+ real(1) /= cell->vertex(2)(1) - start(1);
+ break;
case 3:
- real(0) /= cell->vertex(1)(0) - start(0);
- real(1) /= cell->vertex(2)(1) - start(1);
- real(2) /= cell->vertex(4)(2) - start(2);
- break;
+ real(0) /= cell->vertex(1)(0) - start(0);
+ real(1) /= cell->vertex(2)(1) - start(1);
+ real(2) /= cell->vertex(4)(2) - start(2);
+ break;
default:
- Assert(false, ExcNotImplemented());
+ Assert(false, ExcNotImplemented());
}
return real;
}
// $Id$
// Version: $Name$
//
-// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 by the deal.II authors
+// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
template<int dim, int spacedim>
MappingQ<dim,spacedim>::InternalData::InternalData (const unsigned int n_shape_functions)
- :
- MappingQ1<dim,spacedim>::InternalData(n_shape_functions),
+ :
+ MappingQ1<dim,spacedim>::InternalData(n_shape_functions),
use_mapping_q1_on_current_cell(false),
- mapping_q1_data(1 << dim)
+ mapping_q1_data(1 << dim)
{
this->is_mapping_q1_data=false;
}
MappingQ<dim,spacedim>::InternalData::memory_consumption () const
{
return (MappingQ1<dim,spacedim>::InternalData::memory_consumption () +
- MemoryConsumption::memory_consumption (unit_normals) +
- MemoryConsumption::memory_consumption (use_mapping_q1_on_current_cell) +
- MemoryConsumption::memory_consumption (mapping_q1_data));
+ MemoryConsumption::memory_consumption (unit_normals) +
+ MemoryConsumption::memory_consumption (use_mapping_q1_on_current_cell) +
+ MemoryConsumption::memory_consumption (mapping_q1_data));
}
// cells are scaled linearly. Unless codimension is equal to two
template<>
MappingQ<1>::MappingQ (const unsigned int,
- const bool /*use_mapping_q_on_all_cells*/)
- :
- degree(1),
- n_inner(0),
- n_outer(0),
- tensor_pols(0),
- n_shape_functions(2),
- renumber(0),
- use_mapping_q_on_all_cells (false),
- feq(degree)
+ const bool /*use_mapping_q_on_all_cells*/)
+ :
+ degree(1),
+ n_inner(0),
+ n_outer(0),
+ tensor_pols(0),
+ n_shape_functions(2),
+ renumber(0),
+ use_mapping_q_on_all_cells (false),
+ feq(degree)
{}
template<>
MappingQ<1>::MappingQ (const MappingQ<1> &m):
- MappingQ1<1> (),
- degree(1),
- n_inner(0),
- n_outer(0),
- tensor_pols(0),
- n_shape_functions(2),
- renumber(0),
- use_mapping_q_on_all_cells (m.use_mapping_q_on_all_cells),
- feq(degree)
+ MappingQ1<1> (),
+ degree(1),
+ n_inner(0),
+ n_outer(0),
+ tensor_pols(0),
+ n_shape_functions(2),
+ renumber(0),
+ use_mapping_q_on_all_cells (m.use_mapping_q_on_all_cells),
+ feq(degree)
{}
template<>
template<int dim, int spacedim>
MappingQ<dim,spacedim>::MappingQ (const unsigned int p,
- const bool use_mapping_q_on_all_cells)
+ const bool use_mapping_q_on_all_cells)
:
- degree(p),
- n_inner(Utilities::fixed_power<dim>(degree-1)),
- n_outer((dim==1) ? 2 :
- ((dim==2) ?
- 4+4*(degree-1) :
- 8+12*(degree-1)+6*(degree-1)*(degree-1))),
- tensor_pols(0),
- n_shape_functions(Utilities::fixed_power<dim>(degree+1)),
- renumber(FETools::
- lexicographic_to_hierarchic_numbering (
- FiniteElementData<dim> (get_dpo_vector<dim>(degree), 1,
- degree))),
- use_mapping_q_on_all_cells (use_mapping_q_on_all_cells
- || (dim != spacedim)),
- feq(degree)
+ degree(p),
+ n_inner(Utilities::fixed_power<dim>(degree-1)),
+ n_outer((dim==1) ? 2 :
+ ((dim==2) ?
+ 4+4*(degree-1) :
+ 8+12*(degree-1)+6*(degree-1)*(degree-1))),
+ tensor_pols(0),
+ n_shape_functions(Utilities::fixed_power<dim>(degree+1)),
+ renumber(FETools::
+ lexicographic_to_hierarchic_numbering (
+ FiniteElementData<dim> (get_dpo_vector<dim>(degree), 1,
+ degree))),
+ use_mapping_q_on_all_cells (use_mapping_q_on_all_cells
+ || (dim != spacedim)),
+ feq(degree)
{
- // Construct the tensor product
- // polynomials used as shape
- // functions for the Qp mapping of
- // cells at the boundary.
+ // Construct the tensor product
+ // polynomials used as shape
+ // functions for the Qp mapping of
+ // cells at the boundary.
std::vector<Polynomials::LagrangeEquidistant> v;
for (unsigned int i=0; i<=degree; ++i)
v.push_back(Polynomials::LagrangeEquidistant(degree,i));
tensor_pols = new TensorProductPolynomials<dim> (v);
Assert (n_shape_functions==tensor_pols->n(),
- ExcInternalError());
+ ExcInternalError());
Assert(n_inner+n_outer==n_shape_functions, ExcInternalError());
- // build laplace_on_quad_vector
+ // build laplace_on_quad_vector
if (degree>1)
{
if (dim >= 2)
- set_laplace_on_quad_vector(laplace_on_quad_vector);
+ set_laplace_on_quad_vector(laplace_on_quad_vector);
if (dim >= 3)
- set_laplace_on_hex_vector(laplace_on_hex_vector);
+ set_laplace_on_hex_vector(laplace_on_hex_vector);
}
}
template<int dim, int spacedim>
MappingQ<dim,spacedim>::MappingQ (const MappingQ<dim,spacedim> &mapping)
- :
- MappingQ1<dim,spacedim>(),
- degree(mapping.degree),
- n_inner(mapping.n_inner),
- n_outer(mapping.n_outer),
- tensor_pols(0),
- n_shape_functions(mapping.n_shape_functions),
- renumber(mapping.renumber),
- use_mapping_q_on_all_cells (mapping.use_mapping_q_on_all_cells),
- feq(degree)
+ :
+ MappingQ1<dim,spacedim>(),
+ degree(mapping.degree),
+ n_inner(mapping.n_inner),
+ n_outer(mapping.n_outer),
+ tensor_pols(0),
+ n_shape_functions(mapping.n_shape_functions),
+ renumber(mapping.renumber),
+ use_mapping_q_on_all_cells (mapping.use_mapping_q_on_all_cells),
+ feq(degree)
{
tensor_pols=new TensorProductPolynomials<dim> (*mapping.tensor_pols);
laplace_on_quad_vector=mapping.laplace_on_quad_vector;
template<>
void
MappingQ<1>::compute_shapes_virtual (const std::vector<Point<1> > &unit_points,
- MappingQ1<1>::InternalData &data) const
+ MappingQ1<1>::InternalData &data) const
{
MappingQ1<1>::compute_shapes_virtual(unit_points, data);
}
template<int dim, int spacedim>
void
MappingQ<dim,spacedim>::compute_shapes_virtual (const std::vector<Point<dim> > &unit_points,
- typename MappingQ1<dim,spacedim>::InternalData &data) const
+ typename MappingQ1<dim,spacedim>::InternalData &data) const
{
const unsigned int n_points=unit_points.size();
std::vector<double> values;
if (data.shape_values.size()!=0)
{
Assert(data.shape_values.size()==n_shape_functions*n_points,
- ExcInternalError());
+ ExcInternalError());
values.resize(n_shape_functions);
}
if (data.shape_derivatives.size()!=0)
{
Assert(data.shape_derivatives.size()==n_shape_functions*n_points,
- ExcInternalError());
+ ExcInternalError());
grads.resize(n_shape_functions);
}
-// // dummy variable of size 0
+// // dummy variable of size 0
std::vector<Tensor<2,dim> > grad2;
if (data.shape_second_derivatives.size()!=0)
{
Assert(data.shape_second_derivatives.size()==n_shape_functions*n_points,
- ExcInternalError());
+ ExcInternalError());
grad2.resize(n_shape_functions);
}
if (data.shape_values.size()!=0 || data.shape_derivatives.size()!=0)
for (unsigned int point=0; point<n_points; ++point)
{
- tensor_pols->compute(unit_points[point], values, grads, grad2);
+ tensor_pols->compute(unit_points[point], values, grads, grad2);
- if (data.shape_values.size()!=0)
- for (unsigned int i=0; i<n_shape_functions; ++i)
- data.shape(point,renumber[i]) = values[i];
+ if (data.shape_values.size()!=0)
+ for (unsigned int i=0; i<n_shape_functions; ++i)
+ data.shape(point,renumber[i]) = values[i];
- if (data.shape_derivatives.size()!=0)
- for (unsigned int i=0; i<n_shape_functions; ++i)
- data.derivative(point,renumber[i]) = grads[i];
+ if (data.shape_derivatives.size()!=0)
+ for (unsigned int i=0; i<n_shape_functions; ++i)
+ data.derivative(point,renumber[i]) = grads[i];
- if (data.shape_second_derivatives.size()!=0)
- for (unsigned int i=0; i<n_shape_functions; ++i)
- data.second_derivative(point,renumber[i]) = grad2[i];
+ if (data.shape_second_derivatives.size()!=0)
+ for (unsigned int i=0; i<n_shape_functions; ++i)
+ data.second_derivative(point,renumber[i]) = grad2[i];
}
}
template<int dim, int spacedim>
typename Mapping<dim,spacedim>::InternalDataBase *
MappingQ<dim,spacedim>::get_data (const UpdateFlags update_flags,
- const Quadrature<dim> &quadrature) const
+ const Quadrature<dim> &quadrature) const
{
InternalData *data = new InternalData(n_shape_functions);
this->compute_data (update_flags, quadrature,
template<int dim, int spacedim>
typename Mapping<dim,spacedim>::InternalDataBase *
MappingQ<dim,spacedim>::get_face_data (const UpdateFlags update_flags,
- const Quadrature<dim-1>& quadrature) const
+ const Quadrature<dim-1>& quadrature) const
{
InternalData *data = new InternalData(n_shape_functions);
const Quadrature<dim> q (QProjector<dim>::project_to_all_faces(quadrature));
template<int dim, int spacedim>
typename Mapping<dim,spacedim>::InternalDataBase *
MappingQ<dim,spacedim>::get_subface_data (const UpdateFlags update_flags,
- const Quadrature<dim-1>& quadrature) const
+ const Quadrature<dim-1>& quadrature) const
{
InternalData *data = new InternalData(n_shape_functions);
const Quadrature<dim> q (QProjector<dim>::project_to_all_subfaces(quadrature));
std::vector<Point<spacedim> > &normal_vectors,
CellSimilarity::Similarity &cell_similarity) const
{
- // convert data object to internal
- // data for this class. fails with
- // an exception if that is not
- // possible
+ // convert data object to internal
+ // data for this class. fails with
+ // an exception if that is not
+ // possible
Assert (dynamic_cast<InternalData*> (&mapping_data) != 0, ExcInternalError());
InternalData &data = static_cast<InternalData&> (mapping_data);
- // check whether this cell needs
- // the full mapping or can be
- // treated by a reduced Q1 mapping,
- // e.g. if the cell is in the
- // interior of the domain
+ // check whether this cell needs
+ // the full mapping or can be
+ // treated by a reduced Q1 mapping,
+ // e.g. if the cell is in the
+ // interior of the domain
data.use_mapping_q1_on_current_cell = !(use_mapping_q_on_all_cells
- || cell->has_boundary_lines());
-
- // depending on this result, use this or
- // the other data object for the
- // mapping. furthermore, we need to
- // ensure that the flag indicating
- // whether we can use some similarity has
- // to be modified - for a general
- // MappingQ, the data needs to be
- // recomputed anyway since then the
- // mapping changes the data. this needs
- // to be known also for later operations,
- // so modify the variable here. this also
- // affects the calculation of the next
- // cell -- if we use Q1 data on the next
- // cell, the data will still be invalid.
+ || cell->has_boundary_lines());
+
+ // depending on this result, use this or
+ // the other data object for the
+ // mapping. furthermore, we need to
+ // ensure that the flag indicating
+ // whether we can use some similarity has
+ // to be modified - for a general
+ // MappingQ, the data needs to be
+ // recomputed anyway since then the
+ // mapping changes the data. this needs
+ // to be known also for later operations,
+ // so modify the variable here. this also
+ // affects the calculation of the next
+ // cell -- if we use Q1 data on the next
+ // cell, the data will still be invalid.
typename MappingQ1<dim,spacedim>::InternalData *p_data=0;
if (data.use_mapping_q1_on_current_cell)
p_data=&data.mapping_q1_data;
{
p_data=&data;
if (get_degree() > 1)
- cell_similarity = CellSimilarity::invalid_next_cell;
+ cell_similarity = CellSimilarity::invalid_next_cell;
}
MappingQ1<dim,spacedim>::fill_fe_values(cell, q, *p_data,
- quadrature_points, JxW_values,
- jacobians, jacobian_grads, inverse_jacobians,
- normal_vectors, cell_similarity);
+ quadrature_points, JxW_values,
+ jacobians, jacobian_grads, inverse_jacobians,
+ normal_vectors, cell_similarity);
}
std::vector<Tensor<1,spacedim> > &exterior_forms,
std::vector<Point<spacedim> > &normal_vectors) const
{
- // convert data object to internal
- // data for this class. fails with
- // an exception if that is not
- // possible
+ // convert data object to internal
+ // data for this class. fails with
+ // an exception if that is not
+ // possible
Assert (dynamic_cast<InternalData*> (&mapping_data) != 0,
- ExcInternalError());
+ ExcInternalError());
InternalData &data = static_cast<InternalData&> (mapping_data);
- // check whether this cell needs
- // the full mapping or can be
- // treated by a reduced Q1 mapping,
- // e.g. if the cell is entirely in
- // the interior of the domain. note
- // that it is not sufficient to ask
- // whether the present _face_ is in
- // the interior, as the mapping on
- // the face depends on the mapping
- // of the cell, which in turn
- // depends on the fact whether
- // _any_ of the faces of this cell
- // is at the boundary, not only the
- // present face
+ // check whether this cell needs
+ // the full mapping or can be
+ // treated by a reduced Q1 mapping,
+ // e.g. if the cell is entirely in
+ // the interior of the domain. note
+ // that it is not sufficient to ask
+ // whether the present _face_ is in
+ // the interior, as the mapping on
+ // the face depends on the mapping
+ // of the cell, which in turn
+ // depends on the fact whether
+ // _any_ of the faces of this cell
+ // is at the boundary, not only the
+ // present face
data.use_mapping_q1_on_current_cell=!(use_mapping_q_on_all_cells
- || cell->has_boundary_lines());
+ || cell->has_boundary_lines());
- // depending on this result, use
- // this or the other data object
- // for the mapping
+ // depending on this result, use
+ // this or the other data object
+ // for the mapping
typename MappingQ1<dim,spacedim>::InternalData *p_data=0;
if (data.use_mapping_q1_on_current_cell)
p_data=&data.mapping_q1_data;
n_q_points,
QProjector<dim>::DataSetDescriptor::
face (face_no,
- cell->face_orientation(face_no),
- cell->face_flip(face_no),
- cell->face_rotation(face_no),
+ cell->face_orientation(face_no),
+ cell->face_flip(face_no),
+ cell->face_rotation(face_no),
n_q_points),
q.get_weights(),
*p_data,
template<int dim, int spacedim>
void
MappingQ<dim,spacedim>::fill_fe_subface_values (const typename Triangulation<dim,spacedim>::cell_iterator &cell,
- const unsigned int face_no,
- const unsigned int sub_no,
- const Quadrature<dim-1> &q,
- typename Mapping<dim,spacedim>::InternalDataBase &mapping_data,
- std::vector<Point<spacedim> > &quadrature_points,
- std::vector<double> &JxW_values,
- std::vector<Tensor<1,spacedim> > &exterior_forms,
- std::vector<Point<spacedim> > &normal_vectors) const
+ const unsigned int face_no,
+ const unsigned int sub_no,
+ const Quadrature<dim-1> &q,
+ typename Mapping<dim,spacedim>::InternalDataBase &mapping_data,
+ std::vector<Point<spacedim> > &quadrature_points,
+ std::vector<double> &JxW_values,
+ std::vector<Tensor<1,spacedim> > &exterior_forms,
+ std::vector<Point<spacedim> > &normal_vectors) const
{
- // convert data object to internal
- // data for this class. fails with
- // an exception if that is not
- // possible
+ // convert data object to internal
+ // data for this class. fails with
+ // an exception if that is not
+ // possible
Assert (dynamic_cast<InternalData*> (&mapping_data) != 0,
- ExcInternalError());
+ ExcInternalError());
InternalData &data = static_cast<InternalData&> (mapping_data);
- // check whether this cell needs
- // the full mapping or can be
- // treated by a reduced Q1 mapping,
- // e.g. if the cell is entirely in
- // the interior of the domain. note
- // that it is not sufficient to ask
- // whether the present _face_ is in
- // the interior, as the mapping on
- // the face depends on the mapping
- // of the cell, which in turn
- // depends on the fact whether
- // _any_ of the faces of this cell
- // is at the boundary, not only the
- // present face
+ // check whether this cell needs
+ // the full mapping or can be
+ // treated by a reduced Q1 mapping,
+ // e.g. if the cell is entirely in
+ // the interior of the domain. note
+ // that it is not sufficient to ask
+ // whether the present _face_ is in
+ // the interior, as the mapping on
+ // the face depends on the mapping
+ // of the cell, which in turn
+ // depends on the fact whether
+ // _any_ of the faces of this cell
+ // is at the boundary, not only the
+ // present face
data.use_mapping_q1_on_current_cell=!(use_mapping_q_on_all_cells
- || cell->has_boundary_lines());
+ || cell->has_boundary_lines());
- // depending on this result, use
- // this or the other data object
- // for the mapping
+ // depending on this result, use
+ // this or the other data object
+ // for the mapping
typename MappingQ1<dim,spacedim>::InternalData *p_data=0;
if (data.use_mapping_q1_on_current_cell)
p_data=&data.mapping_q1_data;
n_q_points,
QProjector<dim>::DataSetDescriptor::
subface (face_no, sub_no,
- cell->face_orientation(face_no),
- cell->face_flip(face_no),
- cell->face_rotation(face_no),
- n_q_points,
- cell->subface_case(face_no)),
+ cell->face_orientation(face_no),
+ cell->face_flip(face_no),
+ cell->face_rotation(face_no),
+ n_q_points,
+ cell->subface_case(face_no)),
q.get_weights(),
*p_data,
quadrature_points, JxW_values,
const unsigned int n_inner_2d=(degree-1)*(degree-1);
const unsigned int n_outer_2d=4+4*(degree-1);
- // first check whether we have precomputed
- // the values for some polynomial degree;
- // the sizes of arrays is
- // n_inner_2d*n_outer_2d
+ // first check whether we have precomputed
+ // the values for some polynomial degree;
+ // the sizes of arrays is
+ // n_inner_2d*n_outer_2d
double const *loqv_ptr=0;
switch (degree)
{
// right -- just in case someone
// wonders where they come from --
// WB)
- static const double loqv2[1*8]
- ={1/16., 1/16., 1/16., 1/16., 3/16., 3/16., 3/16., 3/16.};
- loqv_ptr=&loqv2[0];
+ static const double loqv2[1*8]
+ ={1/16., 1/16., 1/16., 1/16., 3/16., 3/16., 3/16., 3/16.};
+ loqv_ptr=&loqv2[0];
Assert (sizeof(loqv2)/sizeof(loqv2[0]) ==
n_inner_2d * n_outer_2d,
ExcInternalError());
- break;
+ break;
}
case 3:
{
// (same as above)
- static const double loqv3[4*12]
- ={80/1053., 1/81., 1/81., 11/1053., 25/117., 44/351.,
- 7/117., 16/351., 25/117., 44/351., 7/117., 16/351.,
- 1/81., 80/1053., 11/1053., 1/81., 7/117., 16/351.,
- 25/117., 44/351., 44/351., 25/117., 16/351., 7/117.,
- 1/81., 11/1053., 80/1053., 1/81., 44/351., 25/117.,
- 16/351., 7/117., 7/117., 16/351., 25/117., 44/351.,
- 11/1053., 1/81., 1/81., 80/1053., 16/351., 7/117.,
- 44/351., 25/117., 16/351., 7/117., 44/351., 25/117.};
+ static const double loqv3[4*12]
+ ={80/1053., 1/81., 1/81., 11/1053., 25/117., 44/351.,
+ 7/117., 16/351., 25/117., 44/351., 7/117., 16/351.,
+ 1/81., 80/1053., 11/1053., 1/81., 7/117., 16/351.,
+ 25/117., 44/351., 44/351., 25/117., 16/351., 7/117.,
+ 1/81., 11/1053., 80/1053., 1/81., 44/351., 25/117.,
+ 16/351., 7/117., 7/117., 16/351., 25/117., 44/351.,
+ 11/1053., 1/81., 1/81., 80/1053., 16/351., 7/117.,
+ 44/351., 25/117., 16/351., 7/117., 44/351., 25/117.};
Assert (sizeof(loqv3)/sizeof(loqv3[0]) ==
n_inner_2d * n_outer_2d,
ExcInternalError());
- loqv_ptr=&loqv3[0];
+ loqv_ptr=&loqv3[0];
- break;
+ break;
}
case 4:
{
- static const double loqv4[9*16]
- ={0.07405921850311571, -0.001075744628905992,
- -0.001075744628906007, 0.001914292239071463,
- 0.2231273865431892, 0.1346851306015187,
- 0.03812914216116724, 0.02913160002633252,
- 0.02200737428129396, 0.01600835564431224,
- 0.2231273865431891, 0.1346851306015187,
- 0.03812914216116723, 0.02913160002633253,
- 0.02200737428129391, 0.01600835564431222,
-
- 0.00664803151334206, 0.006648031513342719,
- 0.002873452861657458, 0.002873452861657626,
- 0.07903572682584378, 0.05969238281250031,
- 0.03619864817415824, 0.07903572682584187,
- 0.0596923828124999, 0.03619864817415815,
- 0.1527716818820237, 0.2348152760709273,
- 0.152771681882024, 0.02496269311797778,
- 0.04081948955407129, 0.02496269311797789,
-
- -0.001075744628906923, 0.07405921850311589,
- 0.001914292239071339, -0.001075744628905884,
- 0.02913160002633509, 0.02200737428129395,
- 0.01600835564431229, 0.2231273865431878,
- 0.1346851306015183, 0.0381291421611672,
- 0.03812914216116729, 0.1346851306015185,
- 0.2231273865431898, 0.01600835564431217,
- 0.02200737428129394, 0.02913160002633262,
-
- 0.006648031513342073, 0.002873452861657473,
- 0.006648031513342726, 0.002873452861657636,
- 0.1527716818820238, 0.2348152760709273,
- 0.152771681882024, 0.02496269311797779,
- 0.04081948955407131, 0.0249626931179779,
- 0.07903572682584376, 0.05969238281250026,
- 0.03619864817415824, 0.07903572682584187,
- 0.0596923828124998, 0.0361986481741581,
-
- 0.01106770833333302, 0.01106770833333336,
- 0.01106770833333337, 0.01106770833333374,
- 0.06770833333333424, 0.1035156250000011,
- 0.0677083333333344, 0.06770833333333376,
- 0.103515624999999, 0.06770833333333399,
- 0.06770833333333422, 0.1035156250000009,
- 0.06770833333333436, 0.0677083333333337,
- 0.1035156249999988, 0.0677083333333339,
-
- 0.002873452861657185, 0.006648031513342362,
- 0.002873452861657334, 0.006648031513343038,
- 0.02496269311797779, 0.04081948955407401,
- 0.02496269311797788, 0.1527716818820234,
- 0.234815276070926, 0.1527716818820237,
- 0.03619864817415819, 0.05969238281250028,
- 0.07903572682584407, 0.03619864817415804,
- 0.05969238281249986, 0.0790357268258422,
-
- -0.001075744628906913, 0.00191429223907134,
- 0.07405921850311592, -0.001075744628905865,
- 0.03812914216116729, 0.1346851306015185,
- 0.2231273865431899, 0.01600835564431217,
- 0.02200737428129396, 0.02913160002633264,
- 0.02913160002633509, 0.02200737428129391,
- 0.01600835564431228, 0.2231273865431878,
- 0.1346851306015183, 0.03812914216116718,
-
- 0.002873452861657176, 0.002873452861657321,
- 0.006648031513342374, 0.006648031513343037,
- 0.03619864817415817, 0.05969238281250032,
- 0.07903572682584409, 0.03619864817415805,
- 0.05969238281249992, 0.07903572682584221,
- 0.02496269311797776, 0.04081948955407392,
- 0.02496269311797785, 0.1527716818820233,
- 0.2348152760709258, 0.1527716818820236,
-
- 0.001914292239071237, -0.001075744628906803,
- -0.001075744628906778, 0.07405921850311617,
- 0.01600835564431228, 0.02200737428129401,
- 0.02913160002633524, 0.03812914216116726,
- 0.1346851306015182, 0.2231273865431886,
- 0.01600835564431228, 0.02200737428129397,
- 0.02913160002633523, 0.03812914216116726,
- 0.1346851306015181, 0.2231273865431886,
+ static const double loqv4[9*16]
+ ={0.07405921850311571, -0.001075744628905992,
+ -0.001075744628906007, 0.001914292239071463,
+ 0.2231273865431892, 0.1346851306015187,
+ 0.03812914216116724, 0.02913160002633252,
+ 0.02200737428129396, 0.01600835564431224,
+ 0.2231273865431891, 0.1346851306015187,
+ 0.03812914216116723, 0.02913160002633253,
+ 0.02200737428129391, 0.01600835564431222,
+
+ 0.00664803151334206, 0.006648031513342719,
+ 0.002873452861657458, 0.002873452861657626,
+ 0.07903572682584378, 0.05969238281250031,
+ 0.03619864817415824, 0.07903572682584187,
+ 0.0596923828124999, 0.03619864817415815,
+ 0.1527716818820237, 0.2348152760709273,
+ 0.152771681882024, 0.02496269311797778,
+ 0.04081948955407129, 0.02496269311797789,
+
+ -0.001075744628906923, 0.07405921850311589,
+ 0.001914292239071339, -0.001075744628905884,
+ 0.02913160002633509, 0.02200737428129395,
+ 0.01600835564431229, 0.2231273865431878,
+ 0.1346851306015183, 0.0381291421611672,
+ 0.03812914216116729, 0.1346851306015185,
+ 0.2231273865431898, 0.01600835564431217,
+ 0.02200737428129394, 0.02913160002633262,
+
+ 0.006648031513342073, 0.002873452861657473,
+ 0.006648031513342726, 0.002873452861657636,
+ 0.1527716818820238, 0.2348152760709273,
+ 0.152771681882024, 0.02496269311797779,
+ 0.04081948955407131, 0.0249626931179779,
+ 0.07903572682584376, 0.05969238281250026,
+ 0.03619864817415824, 0.07903572682584187,
+ 0.0596923828124998, 0.0361986481741581,
+
+ 0.01106770833333302, 0.01106770833333336,
+ 0.01106770833333337, 0.01106770833333374,
+ 0.06770833333333424, 0.1035156250000011,
+ 0.0677083333333344, 0.06770833333333376,
+ 0.103515624999999, 0.06770833333333399,
+ 0.06770833333333422, 0.1035156250000009,
+ 0.06770833333333436, 0.0677083333333337,
+ 0.1035156249999988, 0.0677083333333339,
+
+ 0.002873452861657185, 0.006648031513342362,
+ 0.002873452861657334, 0.006648031513343038,
+ 0.02496269311797779, 0.04081948955407401,
+ 0.02496269311797788, 0.1527716818820234,
+ 0.234815276070926, 0.1527716818820237,
+ 0.03619864817415819, 0.05969238281250028,
+ 0.07903572682584407, 0.03619864817415804,
+ 0.05969238281249986, 0.0790357268258422,
+
+ -0.001075744628906913, 0.00191429223907134,
+ 0.07405921850311592, -0.001075744628905865,
+ 0.03812914216116729, 0.1346851306015185,
+ 0.2231273865431899, 0.01600835564431217,
+ 0.02200737428129396, 0.02913160002633264,
+ 0.02913160002633509, 0.02200737428129391,
+ 0.01600835564431228, 0.2231273865431878,
+ 0.1346851306015183, 0.03812914216116718,
+
+ 0.002873452861657176, 0.002873452861657321,
+ 0.006648031513342374, 0.006648031513343037,
+ 0.03619864817415817, 0.05969238281250032,
+ 0.07903572682584409, 0.03619864817415805,
+ 0.05969238281249992, 0.07903572682584221,
+ 0.02496269311797776, 0.04081948955407392,
+ 0.02496269311797785, 0.1527716818820233,
+ 0.2348152760709258, 0.1527716818820236,
+
+ 0.001914292239071237, -0.001075744628906803,
+ -0.001075744628906778, 0.07405921850311617,
+ 0.01600835564431228, 0.02200737428129401,
+ 0.02913160002633524, 0.03812914216116726,
+ 0.1346851306015182, 0.2231273865431886,
+ 0.01600835564431228, 0.02200737428129397,
+ 0.02913160002633523, 0.03812914216116726,
+ 0.1346851306015181, 0.2231273865431886,
};
Assert (sizeof(loqv4)/sizeof(loqv4[0]) ==
n_inner_2d * n_outer_2d,
ExcInternalError());
- loqv_ptr=&loqv4[0];
+ loqv_ptr=&loqv4[0];
- break;
+ break;
}
- // no other cases implemented,
- // so simply fall through
+ // no other cases implemented,
+ // so simply fall through
default:
break;
}
if (loqv_ptr!=0)
{
- // precomputed. copy values to
- // the loqvs array
+ // precomputed. copy values to
+ // the loqvs array
loqvs.reinit(n_inner_2d, n_outer_2d);
for (unsigned int unit_point=0; unit_point<n_inner_2d; ++unit_point)
- for (unsigned int k=0; k<n_outer_2d; ++k)
- loqvs[unit_point][k]=loqv_ptr[unit_point*n_outer_2d+k];
+ for (unsigned int k=0; k<n_outer_2d; ++k)
+ loqvs[unit_point][k]=loqv_ptr[unit_point*n_outer_2d+k];
}
else
{
- // not precomputed, then do so now
+ // not precomputed, then do so now
if (dim==2)
- compute_laplace_vector(loqvs);
+ compute_laplace_vector(loqvs);
else
- // computing the Laplace vector for
- // faces is not supported in 3d at
- // present. presumably, doing so
- // would not be so hard: we would
- // only have to call the function in
- // 2d, i.e. the quad(=face) values in
- // 3d are equal to the quad(=cell)
- // values in 2d. however, that would
- // require us to link in the 2d
- // library, which is kind of awkward
- // (note that compute_laplace_vector
- // really makes use of a lot of 2d
- // stuff, such as FEValues etc). an
- // alternative would be to precompute
- // the values of this array for a
- // couple of higher mapping orders,
- // pin down their values and insert
- // them into the array above.
- Assert (false, ExcNotImplemented());
+ // computing the Laplace vector for
+ // faces is not supported in 3d at
+ // present. presumably, doing so
+ // would not be so hard: we would
+ // only have to call the function in
+ // 2d, i.e. the quad(=face) values in
+ // 3d are equal to the quad(=cell)
+ // values in 2d. however, that would
+ // require us to link in the 2d
+ // library, which is kind of awkward
+ // (note that compute_laplace_vector
+ // really makes use of a lot of 2d
+ // stuff, such as FEValues etc). an
+ // alternative would be to precompute
+ // the values of this array for a
+ // couple of higher mapping orders,
+ // pin down their values and insert
+ // them into the array above.
+ Assert (false, ExcNotImplemented());
}
- // the sum of weights of the points
- // at the outer rim should be
- // one. check this
+ // the sum of weights of the points
+ // at the outer rim should be
+ // one. check this
for (unsigned int unit_point=0; unit_point<loqvs.n_rows(); ++unit_point)
Assert(std::fabs(std::accumulate(loqvs[unit_point].begin(),
- loqvs[unit_point].end(),0.)-1)<1e-13,
- ExcInternalError());
+ loqvs[unit_point].end(),0.)-1)<1e-13,
+ ExcInternalError());
}
{
Assert(degree>1, ExcInternalError());
- // first check whether we have
- // precomputed the values for some
- // polynomial degree
+ // first check whether we have
+ // precomputed the values for some
+ // polynomial degree
double const *lohv_ptr=0;
if (degree==2)
{
static const double loqv2[26]
- ={1/128., 1/128., 1/128., 1/128., 1/128., 1/128., 1/128., 1/128.,
- 7/192., 7/192., 7/192., 7/192., 7/192., 7/192., 7/192., 7/192.,
- 7/192., 7/192., 7/192., 7/192.,
- 1/12., 1/12., 1/12., 1/12., 1/12., 1/12.};
+ ={1/128., 1/128., 1/128., 1/128., 1/128., 1/128., 1/128., 1/128.,
+ 7/192., 7/192., 7/192., 7/192., 7/192., 7/192., 7/192., 7/192.,
+ 7/192., 7/192., 7/192., 7/192.,
+ 1/12., 1/12., 1/12., 1/12., 1/12., 1/12.};
lohv_ptr=&loqv2[0];
}
if (lohv_ptr!=0)
{
- // precomputed. copy values to
- // the lohvs array
+ // precomputed. copy values to
+ // the lohvs array
lohvs.reinit(n_inner, n_outer);
for (unsigned int unit_point=0; unit_point<n_inner; ++unit_point)
- for (unsigned int k=0; k<n_outer; ++k)
- lohvs[unit_point][k]=lohv_ptr[unit_point*n_outer+k];
+ for (unsigned int k=0; k<n_outer; ++k)
+ lohvs[unit_point][k]=lohv_ptr[unit_point*n_outer+k];
}
else
- // not precomputed, then do so now
+ // not precomputed, then do so now
compute_laplace_vector(lohvs);
- // the sum of weights of the points
- // at the outer rim should be
- // one. check this
+ // the sum of weights of the points
+ // at the outer rim should be
+ // one. check this
for (unsigned int unit_point=0; unit_point<n_inner; ++unit_point)
Assert(std::fabs(std::accumulate(lohvs[unit_point].begin(),
- lohvs[unit_point].end(),0.) - 1)<1e-13,
- ExcInternalError());
+ lohvs[unit_point].end(),0.) - 1)<1e-13,
+ ExcInternalError());
}
// them are on the vertices
Assert(degree>1, ExcInternalError());
- // compute the shape
- // gradients at the quadrature
- // points on the unit cell
+ // compute the shape
+ // gradients at the quadrature
+ // points on the unit cell
const QGauss<dim> quadrature(degree+1);
const unsigned int n_q_points=quadrature.size();
quadrature_data.shape_derivatives.resize(n_shape_functions * n_q_points);
this->compute_shapes(quadrature.get_points(), quadrature_data);
- // Compute the stiffness matrix of
- // the inner dofs
+ // Compute the stiffness matrix of
+ // the inner dofs
FullMatrix<double> S(n_inner);
for (unsigned int point=0; point<n_q_points; ++point)
for (unsigned int i=0; i<n_inner; ++i)
for (unsigned int j=0; j<n_inner; ++j)
- S(i,j) += contract(quadrature_data.derivative(point, n_outer+i),
- quadrature_data.derivative(point, n_outer+j))
- * quadrature.weight(point);
+ S(i,j) += contract(quadrature_data.derivative(point, n_outer+i),
+ quadrature_data.derivative(point, n_outer+j))
+ * quadrature.weight(point);
- // Compute the components of T to be the
- // product of gradients of inner and
- // outer shape functions.
+ // Compute the components of T to be the
+ // product of gradients of inner and
+ // outer shape functions.
FullMatrix<double> T(n_inner, n_outer);
for (unsigned int point=0; point<n_q_points; ++point)
for (unsigned int i=0; i<n_inner; ++i)
for (unsigned int k=0; k<n_outer; ++k)
- T(i,k) += contract(quadrature_data.derivative(point, n_outer+i),
- quadrature_data.derivative(point, k))
- *quadrature.weight(point);
+ T(i,k) += contract(quadrature_data.derivative(point, n_outer+i),
+ quadrature_data.derivative(point, k))
+ *quadrature.weight(point);
FullMatrix<double> S_1(n_inner);
S_1.invert(S);
FullMatrix<double> S_1_T(n_inner, n_outer);
- // S:=S_1*T
+ // S:=S_1*T
S_1.mmult(S_1_T,T);
- // Resize and initialize the
- // lvs
+ // Resize and initialize the
+ // lvs
lvs.reinit (n_inner, n_outer);
for (unsigned int i=0; i<n_inner; ++i)
for (unsigned int k=0; k<n_outer; ++k)
template<int dim, int spacedim>
void
MappingQ<dim,spacedim>::apply_laplace_vector(const Table<2,double> &lvs,
- std::vector<Point<spacedim> > &a) const
+ std::vector<Point<spacedim> > &a) const
{
// check whether the data we need
// is really available. if you fail
const unsigned int n_inner_apply=lvs.n_rows();
Assert(n_inner_apply==n_inner || n_inner_apply==(degree-1)*(degree-1),
- ExcInternalError());
+ ExcInternalError());
const unsigned int n_outer_apply=lvs.n_cols();
Assert(a.size()==n_outer_apply,
- ExcDimensionMismatch(a.size(), n_outer_apply));
-
- // compute each inner point as
- // linear combination of the outer
- // points. the weights are given by
- // the lvs entries, the outer
- // points are the first (existing)
- // elements of a
+ ExcDimensionMismatch(a.size(), n_outer_apply));
+
+ // compute each inner point as
+ // linear combination of the outer
+ // points. the weights are given by
+ // the lvs entries, the outer
+ // points are the first (existing)
+ // elements of a
for (unsigned int unit_point=0; unit_point<n_inner_apply; ++unit_point)
{
Assert(lvs.n_cols()==n_outer_apply, ExcInternalError());
Point<spacedim> p;
for (unsigned int k=0; k<n_outer_apply; ++k)
- p+=lvs[unit_point][k]*a[k];
+ p+=lvs[unit_point][k]*a[k];
a.push_back(p);
}
const typename Triangulation<dim,spacedim>::cell_iterator &cell,
std::vector<Point<spacedim> > &a) const
{
- // if this is a cell for which we
- // want to compute the full
- // mapping, then get them from the
- // following function
+ // if this is a cell for which we
+ // want to compute the full
+ // mapping, then get them from the
+ // following function
if (use_mapping_q_on_all_cells || cell->has_boundary_lines())
compute_support_points_laplace(cell, a);
else
- // otherwise: use a Q1 mapping
- // for which the mapping shape
- // function support points are
- // simply the vertices of the
- // cell
+ // otherwise: use a Q1 mapping
+ // for which the mapping shape
+ // function support points are
+ // simply the vertices of the
+ // cell
{
a.resize(GeometryInfo<dim>::vertices_per_cell);
for (unsigned int i=0; i<GeometryInfo<dim>::vertices_per_cell; ++i)
- a[i] = cell->vertex(i);
+ a[i] = cell->vertex(i);
}
}
template<int dim, int spacedim>
void
MappingQ<dim,spacedim>::compute_support_points_laplace(const typename Triangulation<dim,spacedim>::cell_iterator &cell,
- std::vector<Point<spacedim> > &a) const
+ std::vector<Point<spacedim> > &a) const
{
- // in any case, we need the
- // vertices first
+ // in any case, we need the
+ // vertices first
a.resize(GeometryInfo<dim>::vertices_per_cell);
for (unsigned int i=0; i<GeometryInfo<dim>::vertices_per_cell; ++i)
a[i] = cell->vertex(i);
if (degree>1)
switch (dim)
{
- case 1:
- Assert(spacedim == 2, ExcInternalError());
- add_line_support_points(cell, a);
- break;
- case 2:
- // in 2d, add the
- // points on the four
- // bounding lines to
- // the exterior (outer)
- // points
- add_line_support_points (cell, a);
- if(dim != spacedim)
- add_quad_support_points(cell, a);
- else
- apply_laplace_vector (laplace_on_quad_vector,a);
- break;
-
- case 3:
- {
- // in 3d also add the
- // points located on
- // the boundary faces
- add_line_support_points (cell, a);
- add_quad_support_points (cell, a);
- apply_laplace_vector (laplace_on_hex_vector, a);
- break;
- }
- default:
- Assert(false, ExcNotImplemented());
- break;
+ case 1:
+ Assert(spacedim == 2, ExcInternalError());
+ add_line_support_points(cell, a);
+ break;
+ case 2:
+ // in 2d, add the
+ // points on the four
+ // bounding lines to
+ // the exterior (outer)
+ // points
+ add_line_support_points (cell, a);
+ if(dim != spacedim)
+ add_quad_support_points(cell, a);
+ else
+ apply_laplace_vector (laplace_on_quad_vector,a);
+ break;
+
+ case 3:
+ {
+ // in 3d also add the
+ // points located on
+ // the boundary faces
+ add_line_support_points (cell, a);
+ add_quad_support_points (cell, a);
+ apply_laplace_vector (laplace_on_hex_vector, a);
+ break;
+ }
+ default:
+ Assert(false, ExcNotImplemented());
+ break;
};
}
template <>
void
MappingQ<1>::add_line_support_points (const Triangulation<1>::cell_iterator &,
- std::vector<Point<1> > &) const
+ std::vector<Point<1> > &) const
{
- // there are no points on bounding
- // lines which are to be added
+ // there are no points on bounding
+ // lines which are to be added
const unsigned int dim=1;
Assert (dim > 1, ExcImpossibleInDim(dim));
}
template <>
void
MappingQ<1,2>::add_line_support_points (const Triangulation<1,2>::cell_iterator &cell,
- std::vector<Point<2> > &a) const
+ std::vector<Point<2> > &a) const
{
const unsigned int dim=1, spacedim=2;
- // Ask for the mid point, if that's
- // the only thing we need.
+ // Ask for the mid point, if that's
+ // the only thing we need.
if (degree==2)
{
const Boundary<dim,spacedim> * const boundary
- = &(cell->get_triangulation().get_boundary(cell->material_id()));
+ = &(cell->get_triangulation().get_boundary(cell->material_id()));
a.push_back(boundary->get_new_point_on_line(cell));
}
else
- // otherwise call the more
- // complicated functions and ask
- // for inner points from the
- // boundary description
+ // otherwise call the more
+ // complicated functions and ask
+ // for inner points from the
+ // boundary description
{
std::vector<Point<spacedim> > line_points (degree-1);
const Boundary<dim,spacedim> * const boundary
- = &(cell->get_triangulation().get_boundary(cell->material_id()));
+ = &(cell->get_triangulation().get_boundary(cell->material_id()));
boundary->get_intermediate_points_on_line (cell, line_points);
- // Append all points
+ // Append all points
a.insert (a.end(), line_points.begin(), line_points.end());
}
}
template<int dim, int spacedim>
void
MappingQ<dim,spacedim>::add_line_support_points (const typename Triangulation<dim,spacedim>::cell_iterator &cell,
- std::vector<Point<spacedim> > &a) const
+ std::vector<Point<spacedim> > &a) const
{
static const StraightBoundary<dim,spacedim> straight_boundary;
- // if we only need the midpoint,
- // then ask for it.
+ // if we only need the midpoint,
+ // then ask for it.
if (degree==2)
{
for (unsigned int line_no=0; line_no<GeometryInfo<dim>::lines_per_cell; ++line_no)
- {
- const typename Triangulation<dim,spacedim>::line_iterator line = cell->line(line_no);
- const Boundary<dim,spacedim> * const boundary
- = (line->at_boundary()?
- &line->get_triangulation().get_boundary(line->boundary_indicator()):
- (dim != spacedim) ?
- &line->get_triangulation().get_boundary(cell->material_id()):
- &straight_boundary);
-
- a.push_back(boundary->get_new_point_on_line(line));
- };
+ {
+ const typename Triangulation<dim,spacedim>::line_iterator line = cell->line(line_no);
+ const Boundary<dim,spacedim> * const boundary
+ = (line->at_boundary()?
+ &line->get_triangulation().get_boundary(line->boundary_indicator()):
+ (dim != spacedim) ?
+ &line->get_triangulation().get_boundary(cell->material_id()):
+ &straight_boundary);
+
+ a.push_back(boundary->get_new_point_on_line(line));
+ };
}
else
- // otherwise call the more
- // complicated functions and ask
- // for inner points from the
- // boundary description
+ // otherwise call the more
+ // complicated functions and ask
+ // for inner points from the
+ // boundary description
{
std::vector<Point<spacedim> > line_points (degree-1);
- // loop over each of the lines,
- // and if it is at the
- // boundary, then first get the
- // boundary description and
- // second compute the points on
- // it
+ // loop over each of the lines,
+ // and if it is at the
+ // boundary, then first get the
+ // boundary description and
+ // second compute the points on
+ // it
for (unsigned int line_no=0; line_no<GeometryInfo<dim>::lines_per_cell; ++line_no)
- {
- const typename Triangulation<dim,spacedim>::line_iterator line = cell->line(line_no);
-
- const Boundary<dim,spacedim> * const boundary
- = (line->at_boundary()?
- &line->get_triangulation().get_boundary(line->boundary_indicator()) :
- (dim != spacedim) ?
- &line->get_triangulation().get_boundary(cell->material_id()) :
- &straight_boundary);
-
- boundary->get_intermediate_points_on_line (line, line_points);
- if (dim==3)
- {
- // in 3D, lines might be in wrong
- // orientation. if so, reverse
- // the vector
- if (cell->line_orientation(line_no))
- a.insert (a.end(), line_points.begin(), line_points.end());
- else
- a.insert (a.end(), line_points.rbegin(), line_points.rend());
- }
- else
- // in 2D, lines always have the
- // correct orientation. simply
- // append all points
- a.insert (a.end(), line_points.begin(), line_points.end());
-
- }
+ {
+ const typename Triangulation<dim,spacedim>::line_iterator line = cell->line(line_no);
+
+ const Boundary<dim,spacedim> * const boundary
+ = (line->at_boundary()?
+ &line->get_triangulation().get_boundary(line->boundary_indicator()) :
+ (dim != spacedim) ?
+ &line->get_triangulation().get_boundary(cell->material_id()) :
+ &straight_boundary);
+
+ boundary->get_intermediate_points_on_line (line, line_points);
+ if (dim==3)
+ {
+ // in 3D, lines might be in wrong
+ // orientation. if so, reverse
+ // the vector
+ if (cell->line_orientation(line_no))
+ a.insert (a.end(), line_points.begin(), line_points.end());
+ else
+ a.insert (a.end(), line_points.rbegin(), line_points.rend());
+ }
+ else
+ // in 2D, lines always have the
+ // correct orientation. simply
+ // append all points
+ a.insert (a.end(), line_points.begin(), line_points.end());
+
+ }
}
}
std::vector<Point<3> > &a) const
{
const unsigned int faces_per_cell = GeometryInfo<3>::faces_per_cell,
- vertices_per_face = GeometryInfo<3>::vertices_per_face,
- lines_per_face = GeometryInfo<3>::lines_per_face,
- vertices_per_cell = GeometryInfo<3>::vertices_per_cell;
+ vertices_per_face = GeometryInfo<3>::vertices_per_face,
+ lines_per_face = GeometryInfo<3>::lines_per_face,
+ vertices_per_cell = GeometryInfo<3>::vertices_per_cell;
static const StraightBoundary<3> straight_boundary;
- // used if face quad at boundary or
- // entirely in the interior of the
- // domain
+ // used if face quad at boundary or
+ // entirely in the interior of the
+ // domain
std::vector<Point<3> > quad_points ((degree-1)*(degree-1));
- // used if only one line of face
- // quad is at boundary
+ // used if only one line of face
+ // quad is at boundary
std::vector<Point<3> > b(4*degree);
- // loop over all faces and collect
- // points on them
+ // loop over all faces and collect
+ // points on them
for (unsigned int face_no=0; face_no<faces_per_cell; ++face_no)
{
const Triangulation<3>::face_iterator face = cell->face(face_no);
// select the correct mappings
// for the present face
const bool face_orientation = cell->face_orientation(face_no),
- face_flip = cell->face_flip (face_no),
- face_rotation = cell->face_rotation (face_no);
+ face_flip = cell->face_flip (face_no),
+ face_rotation = cell->face_rotation (face_no);
#ifdef DEBUG
// some sanity checks up front
for (unsigned int i=0; i<vertices_per_face; ++i)
Assert(face->vertex_index(i)==cell->vertex_index(
- GeometryInfo<3>::face_to_cell_vertices(face_no, i,
- face_orientation,
- face_flip,
- face_rotation)),
- ExcInternalError());
-
- // indices of the lines that
- // bound a face are given by
- // GeometryInfo<3>::
- // face_to_cell_lines
+ GeometryInfo<3>::face_to_cell_vertices(face_no, i,
+ face_orientation,
+ face_flip,
+ face_rotation)),
+ ExcInternalError());
+
+ // indices of the lines that
+ // bound a face are given by
+ // GeometryInfo<3>::
+ // face_to_cell_lines
for (unsigned int i=0; i<lines_per_face; ++i)
Assert(face->line(i)==cell->line(GeometryInfo<3>::face_to_cell_lines(
- face_no, i, face_orientation, face_flip, face_rotation)),
- ExcInternalError());
+ face_no, i, face_orientation, face_flip, face_rotation)),
+ ExcInternalError());
#endif
- // if face at boundary, then
- // ask boundary object to
- // return intermediate points
- // on it
+ // if face at boundary, then
+ // ask boundary object to
+ // return intermediate points
+ // on it
if (face->at_boundary())
- {
- face->get_triangulation().get_boundary(face->boundary_indicator())
- .get_intermediate_points_on_quad (face, quad_points);
- // in 3D, the orientation, flip and
- // rotation of the face might not
- // match what we expect here, namely
- // the standard orientation. thus
- // reorder points accordingly. since
- // a Mapping uses the same shape
- // function as an FEQ, we can ask a
- // FEQ to do the reordering for us.
- for (unsigned int i=0; i<quad_points.size(); ++i)
- a.push_back(quad_points[feq.adjust_quad_dof_index_for_face_orientation(i,
- face_orientation,
- face_flip,
- face_rotation)]);
- }
+ {
+ face->get_triangulation().get_boundary(face->boundary_indicator())
+ .get_intermediate_points_on_quad (face, quad_points);
+ // in 3D, the orientation, flip and
+ // rotation of the face might not
+ // match what we expect here, namely
+ // the standard orientation. thus
+ // reorder points accordingly. since
+ // a Mapping uses the same shape
+ // function as an FEQ, we can ask a
+ // FEQ to do the reordering for us.
+ for (unsigned int i=0; i<quad_points.size(); ++i)
+ a.push_back(quad_points[feq.adjust_quad_dof_index_for_face_orientation(i,
+ face_orientation,
+ face_flip,
+ face_rotation)]);
+ }
else
- {
- // face is not at boundary,
- // but maybe some of its
- // lines are. count them
- unsigned int lines_at_boundary=0;
- for (unsigned int i=0; i<lines_per_face; ++i)
- if (face->line(i)->at_boundary())
- ++lines_at_boundary;
-
- Assert(lines_at_boundary<=lines_per_face, ExcInternalError());
-
- // if at least one of the
- // lines bounding this quad
- // is at the boundary, then
- // collect points
- // separately
- if (lines_at_boundary>0)
- {
- // call of function
- // apply_laplace_vector
- // increases size of b
- // about 1. There
- // resize b for the
- // case the mentioned
- // function was already
- // called.
- b.resize(4*degree);
-
- // b is of size
- // 4*degree, make sure
- // that this is the
- // right size
- Assert(b.size()==vertices_per_face+lines_per_face*(degree-1),
- ExcDimensionMismatch(b.size(),
+ {
+ // face is not at boundary,
+ // but maybe some of its
+ // lines are. count them
+ unsigned int lines_at_boundary=0;
+ for (unsigned int i=0; i<lines_per_face; ++i)
+ if (face->line(i)->at_boundary())
+ ++lines_at_boundary;
+
+ Assert(lines_at_boundary<=lines_per_face, ExcInternalError());
+
+ // if at least one of the
+ // lines bounding this quad
+ // is at the boundary, then
+ // collect points
+ // separately
+ if (lines_at_boundary>0)
+ {
+ // call of function
+ // apply_laplace_vector
+ // increases size of b
+ // about 1. There
+ // resize b for the
+ // case the mentioned
+ // function was already
+ // called.
+ b.resize(4*degree);
+
+ // b is of size
+ // 4*degree, make sure
+ // that this is the
+ // right size
+ Assert(b.size()==vertices_per_face+lines_per_face*(degree-1),
+ ExcDimensionMismatch(b.size(),
vertices_per_face+lines_per_face*(degree-1)));
- // sort the points into b. We
- // used access from the cell (not
- // from the face) to fill b, so
- // we can assume a standard face
- // orientation. Doing so, the
- // calculated points will be in
- // standard orientation as well.
+ // sort the points into b. We
+ // used access from the cell (not
+ // from the face) to fill b, so
+ // we can assume a standard face
+ // orientation. Doing so, the
+ // calculated points will be in
+ // standard orientation as well.
for (unsigned int i=0; i<vertices_per_face; ++i)
b[i]=a[GeometryInfo<3>::face_to_cell_vertices(face_no, i)];
for (unsigned int j=0; j<degree-1; ++j)
b[vertices_per_face+i*(degree-1)+j]=
a[vertices_per_cell + GeometryInfo<3>::face_to_cell_lines(
- face_no, i)*(degree-1)+j];
-
- // Now b includes the support
- // points on the quad and we can
- // apply the laplace vector
- apply_laplace_vector(laplace_on_quad_vector, b);
- Assert(b.size()==4*degree+(degree-1)*(degree-1),
- ExcDimensionMismatch(b.size(), 4*degree+(degree-1)*(degree-1)));
-
- for (unsigned int i=0; i<(degree-1)*(degree-1); ++i)
- a.push_back(b[4*degree+i]);
- }
- else
- {
- // face is entirely in
- // the interior. get
- // intermediate points
- // from a straight
- // boundary object
- straight_boundary.get_intermediate_points_on_quad (face, quad_points);
- // in 3D, the orientation, flip
- // and rotation of the face might
- // not match what we expect here,
- // namely the standard
- // orientation. thus reorder
- // points accordingly. since a
- // Mapping uses the same shape
- // function as an FEQ, we can ask
- // a FEQ to do the reordering for
- // us.
- for (unsigned int i=0; i<quad_points.size(); ++i)
- a.push_back(quad_points[feq.adjust_quad_dof_index_for_face_orientation(i,
- face_orientation,
- face_flip,
- face_rotation)]);
- }
- }
+ face_no, i)*(degree-1)+j];
+
+ // Now b includes the support
+ // points on the quad and we can
+ // apply the laplace vector
+ apply_laplace_vector(laplace_on_quad_vector, b);
+ Assert(b.size()==4*degree+(degree-1)*(degree-1),
+ ExcDimensionMismatch(b.size(), 4*degree+(degree-1)*(degree-1)));
+
+ for (unsigned int i=0; i<(degree-1)*(degree-1); ++i)
+ a.push_back(b[4*degree+i]);
+ }
+ else
+ {
+ // face is entirely in
+ // the interior. get
+ // intermediate points
+ // from a straight
+ // boundary object
+ straight_boundary.get_intermediate_points_on_quad (face, quad_points);
+ // in 3D, the orientation, flip
+ // and rotation of the face might
+ // not match what we expect here,
+ // namely the standard
+ // orientation. thus reorder
+ // points accordingly. since a
+ // Mapping uses the same shape
+ // function as an FEQ, we can ask
+ // a FEQ to do the reordering for
+ // us.
+ for (unsigned int i=0; i<quad_points.size(); ++i)
+ a.push_back(quad_points[feq.adjust_quad_dof_index_for_face_orientation(i,
+ face_orientation,
+ face_flip,
+ face_rotation)]);
+ }
+ }
}
}
const MappingType mapping_type) const
{
AssertDimension (input.size(), output.size());
- // The data object may be jsut a
- // MappingQ1::InternalData, so we
- // have to test for this first.
+ // The data object may be jsut a
+ // MappingQ1::InternalData, so we
+ // have to test for this first.
const typename MappingQ1<dim,spacedim>::InternalData *q1_data =
dynamic_cast<const typename MappingQ1<dim,spacedim>::InternalData *> (&mapping_data);
Assert(q1_data!=0, ExcInternalError());
- // If it is a genuine
- // MappingQ::InternalData, we have
- // to test further
+ // If it is a genuine
+ // MappingQ::InternalData, we have
+ // to test further
if (!q1_data->is_mapping_q1_data)
{
Assert (dynamic_cast<const InternalData *>(&mapping_data) != 0,
- ExcInternalError());
+ ExcInternalError());
const InternalData &data = static_cast<const InternalData&>(mapping_data);
- // If we only use the
- // Q1-portion, we have to
- // extract that data object
+ // If we only use the
+ // Q1-portion, we have to
+ // extract that data object
if (data.use_mapping_q1_on_current_cell)
- q1_data = &data.mapping_q1_data;
+ q1_data = &data.mapping_q1_data;
}
- // Now, q1_data should have the
- // right tensors in it and we call
- // the base classes transform
- // function
+ // Now, q1_data should have the
+ // right tensors in it and we call
+ // the base classes transform
+ // function
MappingQ1<dim,spacedim>::transform(input, output, *q1_data, mapping_type);
}
const MappingType mapping_type) const
{
AssertDimension (input.size(), output.size());
- // The data object may be jsut a
- // MappingQ1::InternalData, so we
- // have to test for this first.
+ // The data object may be jsut a
+ // MappingQ1::InternalData, so we
+ // have to test for this first.
const typename MappingQ1<dim,spacedim>::InternalData *q1_data =
dynamic_cast<const typename MappingQ1<dim,spacedim>::InternalData *> (&mapping_data);
Assert(q1_data!=0, ExcInternalError());
- // If it is a genuine
- // MappingQ::InternalData, we have
- // to test further
+ // If it is a genuine
+ // MappingQ::InternalData, we have
+ // to test further
if (!q1_data->is_mapping_q1_data)
{
Assert (dynamic_cast<const InternalData *>(&mapping_data) != 0,
- ExcInternalError());
+ ExcInternalError());
const InternalData &data = static_cast<const InternalData&>(mapping_data);
- // If we only use the
- // Q1-portion, we have to
- // extract that data object
+ // If we only use the
+ // Q1-portion, we have to
+ // extract that data object
if (data.use_mapping_q1_on_current_cell)
- q1_data = &data.mapping_q1_data;
+ q1_data = &data.mapping_q1_data;
}
- // Now, q1_data should have the
- // right tensors in it and we call
- // the base classes transform
- // function
+ // Now, q1_data should have the
+ // right tensors in it and we call
+ // the base classes transform
+ // function
MappingQ1<dim,spacedim>::transform(input, output, *q1_data, mapping_type);
}
const MappingType mapping_type) const
{
AssertDimension (input.size(), output.size());
- // The data object may be jsut a
- // MappingQ1::InternalData, so we
- // have to test for this first.
+ // The data object may be jsut a
+ // MappingQ1::InternalData, so we
+ // have to test for this first.
const typename MappingQ1<dim,spacedim>::InternalData *q1_data =
dynamic_cast<const typename MappingQ1<dim,spacedim>::InternalData *> (&mapping_data);
Assert(q1_data!=0, ExcInternalError());
- // If it is a genuine
- // MappingQ::InternalData, we have
- // to test further
+ // If it is a genuine
+ // MappingQ::InternalData, we have
+ // to test further
if (!q1_data->is_mapping_q1_data)
{
Assert (dynamic_cast<const InternalData *>(&mapping_data) != 0,
- ExcInternalError());
+ ExcInternalError());
const InternalData &data = static_cast<const InternalData&>(mapping_data);
- // If we only use the
- // Q1-portion, we have to
- // extract that data object
+ // If we only use the
+ // Q1-portion, we have to
+ // extract that data object
if (data.use_mapping_q1_on_current_cell)
- q1_data = &data.mapping_q1_data;
+ q1_data = &data.mapping_q1_data;
}
- // Now, q1_data should have the
- // right tensors in it and we call
- // the base classes transform
- // function
+ // Now, q1_data should have the
+ // right tensors in it and we call
+ // the base classes transform
+ // function
MappingQ1<dim,spacedim>::transform(input, output, *q1_data, mapping_type);
}
transform_unit_to_real_cell (const typename Triangulation<dim,spacedim>::cell_iterator &cell,
const Point<dim> &p) const
{
- // Use the get_data function to
- // create an InternalData with data
- // vectors of the right size and
- // transformation shape values
- // already computed at point p.
+ // Use the get_data function to
+ // create an InternalData with data
+ // vectors of the right size and
+ // transformation shape values
+ // already computed at point p.
const Quadrature<dim> point_quadrature(p);
std::auto_ptr<InternalData>
mdata (dynamic_cast<InternalData *> (
get_data(update_transformation_values, point_quadrature)));
mdata->use_mapping_q1_on_current_cell = !(use_mapping_q_on_all_cells ||
- cell->has_boundary_lines());
+ cell->has_boundary_lines());
typename MappingQ1<dim,spacedim>::InternalData
*p_data = (mdata->use_mapping_q1_on_current_cell ?
&*mdata);
compute_mapping_support_points(cell, p_data->mapping_support_points);
- // If this should be Q1, ignore all
- // other support points.
+ // If this should be Q1, ignore all
+ // other support points.
if(p_data->shape_values.size()<p_data->mapping_support_points.size())
p_data->mapping_support_points.resize
(GeometryInfo<dim>::vertices_per_cell);
transform_real_to_unit_cell (const typename Triangulation<dim,spacedim>::cell_iterator &cell,
const Point<spacedim> &p) const
{
- // first a Newton iteration based
- // on a Q1 mapping
+ // first a Newton iteration based
+ // on a Q1 mapping
Point<dim> p_unit = MappingQ1<dim,spacedim>::transform_real_to_unit_cell(cell, p);
// then a Newton iteration based on the
use_mapping_q_on_all_cells ||
(dim!=spacedim) )
{
-
+
const Quadrature<dim> point_quadrature(p_unit);
UpdateFlags update_flags = update_transformation_values|update_transformation_gradients;
if (spacedim>dim)
- update_flags |= update_jacobian_grads;
+ update_flags |= update_jacobian_grads;
std::auto_ptr<InternalData>
mdata (dynamic_cast<InternalData *> (
get_data(update_flags,point_quadrature)));
compute_mapping_support_points (cell, mdata->mapping_support_points);
- // If this is a q1 mapping,
- // then only use the support
- // points on the vertices.
+ // If this is a q1 mapping,
+ // then only use the support
+ // points on the vertices.
if (mdata->shape_values.size() < mdata->mapping_support_points.size())
- mdata->mapping_support_points.resize(GeometryInfo<dim>::vertices_per_cell);
+ mdata->mapping_support_points.resize(GeometryInfo<dim>::vertices_per_cell);
this->transform_real_to_unit_cell_internal(cell, p, *mdata, p_unit);
template<int dim, int spacedim>
MappingQ1<dim,spacedim>::InternalData::InternalData (const unsigned int n_shape_functions)
- :
- is_mapping_q1_data(true),
- n_shape_functions (n_shape_functions)
+ :
+ is_mapping_q1_data(true),
+ n_shape_functions (n_shape_functions)
{}
MappingQ1<dim,spacedim>::InternalData::memory_consumption () const
{
return (Mapping<dim,spacedim>::InternalDataBase::memory_consumption() +
- MemoryConsumption::memory_consumption (shape_values) +
- MemoryConsumption::memory_consumption (shape_derivatives) +
- MemoryConsumption::memory_consumption (covariant) +
- MemoryConsumption::memory_consumption (contravariant) +
- MemoryConsumption::memory_consumption (unit_tangentials) +
- MemoryConsumption::memory_consumption (aux) +
- MemoryConsumption::memory_consumption (mapping_support_points) +
- MemoryConsumption::memory_consumption (cell_of_current_support_points) +
- MemoryConsumption::memory_consumption (is_mapping_q1_data) +
- MemoryConsumption::memory_consumption (n_shape_functions));
+ MemoryConsumption::memory_consumption (shape_values) +
+ MemoryConsumption::memory_consumption (shape_derivatives) +
+ MemoryConsumption::memory_consumption (covariant) +
+ MemoryConsumption::memory_consumption (contravariant) +
+ MemoryConsumption::memory_consumption (unit_tangentials) +
+ MemoryConsumption::memory_consumption (aux) +
+ MemoryConsumption::memory_consumption (mapping_support_points) +
+ MemoryConsumption::memory_consumption (cell_of_current_support_points) +
+ MemoryConsumption::memory_consumption (is_mapping_q1_data) +
+ MemoryConsumption::memory_consumption (n_shape_functions));
}
template<int dim, int spacedim>
void
MappingQ1<dim,spacedim>::compute_shapes (const std::vector<Point<dim> > &unit_points,
- InternalData &data) const
+ InternalData &data) const
{
- // choose either the function implemented
- // in this class, or whatever a virtual
- // function call resolves to
+ // choose either the function implemented
+ // in this class, or whatever a virtual
+ // function call resolves to
if (data.is_mapping_q1_data)
MappingQ1<dim,spacedim>::compute_shapes_virtual(unit_points, data);
else
template <int spacedim>
void
compute_shapes_virtual (const unsigned int n_shape_functions,
- const std::vector<Point<1> > &unit_points,
- typename dealii::MappingQ1<1,spacedim>::InternalData& data)
+ const std::vector<Point<1> > &unit_points,
+ typename dealii::MappingQ1<1,spacedim>::InternalData& data)
{
const unsigned int n_points=unit_points.size();
for (unsigned int k = 0 ; k < n_points ; ++k)
- {
- double x = unit_points[k](0);
-
- if (data.shape_values.size()!=0)
- {
- Assert(data.shape_values.size()==n_shape_functions*n_points,
- ExcInternalError());
- data.shape(k,0) = 1.-x;
- data.shape(k,1) = x;
- }
- if (data.shape_derivatives.size()!=0)
- {
- Assert(data.shape_derivatives.size()==n_shape_functions*n_points,
- ExcInternalError());
- data.derivative(k,0)[0] = -1.;
- data.derivative(k,1)[0] = 1.;
- }
- if (data.shape_second_derivatives.size()!=0)
- {
- // the following may or may not
- // work if dim != spacedim
- Assert (spacedim == 1, ExcNotImplemented());
-
- Assert(data.shape_second_derivatives.size()==n_shape_functions*n_points,
- ExcInternalError());
- data.second_derivative(k,0)[0][0] = 0;
- data.second_derivative(k,1)[0][0] = 0;
- }
- }
+ {
+ double x = unit_points[k](0);
+
+ if (data.shape_values.size()!=0)
+ {
+ Assert(data.shape_values.size()==n_shape_functions*n_points,
+ ExcInternalError());
+ data.shape(k,0) = 1.-x;
+ data.shape(k,1) = x;
+ }
+ if (data.shape_derivatives.size()!=0)
+ {
+ Assert(data.shape_derivatives.size()==n_shape_functions*n_points,
+ ExcInternalError());
+ data.derivative(k,0)[0] = -1.;
+ data.derivative(k,1)[0] = 1.;
+ }
+ if (data.shape_second_derivatives.size()!=0)
+ {
+ // the following may or may not
+ // work if dim != spacedim
+ Assert (spacedim == 1, ExcNotImplemented());
+
+ Assert(data.shape_second_derivatives.size()==n_shape_functions*n_points,
+ ExcInternalError());
+ data.second_derivative(k,0)[0][0] = 0;
+ data.second_derivative(k,1)[0][0] = 0;
+ }
+ }
}
template <int spacedim>
void
compute_shapes_virtual (const unsigned int n_shape_functions,
- const std::vector<Point<2> > &unit_points,
- typename dealii::MappingQ1<2,spacedim>::InternalData& data)
+ const std::vector<Point<2> > &unit_points,
+ typename dealii::MappingQ1<2,spacedim>::InternalData& data)
{
const unsigned int n_points=unit_points.size();
for (unsigned int k = 0 ; k < n_points ; ++k)
- {
- double x = unit_points[k](0);
- double y = unit_points[k](1);
-
- if (data.shape_values.size()!=0)
- {
- Assert(data.shape_values.size()==n_shape_functions*n_points,
- ExcInternalError());
- data.shape(k,0) = (1.-x)*(1.-y);
- data.shape(k,1) = x*(1.-y);
- data.shape(k,2) = (1.-x)*y;
- data.shape(k,3) = x*y;
- }
- if (data.shape_derivatives.size()!=0)
- {
- Assert(data.shape_derivatives.size()==n_shape_functions*n_points,
- ExcInternalError());
- data.derivative(k,0)[0] = (y-1.);
- data.derivative(k,1)[0] = (1.-y);
- data.derivative(k,2)[0] = -y;
- data.derivative(k,3)[0] = y;
- data.derivative(k,0)[1] = (x-1.);
- data.derivative(k,1)[1] = -x;
- data.derivative(k,2)[1] = (1.-x);
- data.derivative(k,3)[1] = x;
- }
- if (data.shape_second_derivatives.size()!=0)
- {
- Assert(data.shape_second_derivatives.size()==n_shape_functions*n_points,
- ExcInternalError());
- data.second_derivative(k,0)[0][0] = 0;
- data.second_derivative(k,1)[0][0] = 0;
- data.second_derivative(k,2)[0][0] = 0;
- data.second_derivative(k,3)[0][0] = 0;
- data.second_derivative(k,0)[0][1] = 1.;
- data.second_derivative(k,1)[0][1] = -1.;
- data.second_derivative(k,2)[0][1] = -1.;
- data.second_derivative(k,3)[0][1] = 1.;
- data.second_derivative(k,0)[1][0] = 1.;
- data.second_derivative(k,1)[1][0] = -1.;
- data.second_derivative(k,2)[1][0] = -1.;
- data.second_derivative(k,3)[1][0] = 1.;
- data.second_derivative(k,0)[1][1] = 0;
- data.second_derivative(k,1)[1][1] = 0;
- data.second_derivative(k,2)[1][1] = 0;
- data.second_derivative(k,3)[1][1] = 0;
- }
- }
+ {
+ double x = unit_points[k](0);
+ double y = unit_points[k](1);
+
+ if (data.shape_values.size()!=0)
+ {
+ Assert(data.shape_values.size()==n_shape_functions*n_points,
+ ExcInternalError());
+ data.shape(k,0) = (1.-x)*(1.-y);
+ data.shape(k,1) = x*(1.-y);
+ data.shape(k,2) = (1.-x)*y;
+ data.shape(k,3) = x*y;
+ }
+ if (data.shape_derivatives.size()!=0)
+ {
+ Assert(data.shape_derivatives.size()==n_shape_functions*n_points,
+ ExcInternalError());
+ data.derivative(k,0)[0] = (y-1.);
+ data.derivative(k,1)[0] = (1.-y);
+ data.derivative(k,2)[0] = -y;
+ data.derivative(k,3)[0] = y;
+ data.derivative(k,0)[1] = (x-1.);
+ data.derivative(k,1)[1] = -x;
+ data.derivative(k,2)[1] = (1.-x);
+ data.derivative(k,3)[1] = x;
+ }
+ if (data.shape_second_derivatives.size()!=0)
+ {
+ Assert(data.shape_second_derivatives.size()==n_shape_functions*n_points,
+ ExcInternalError());
+ data.second_derivative(k,0)[0][0] = 0;
+ data.second_derivative(k,1)[0][0] = 0;
+ data.second_derivative(k,2)[0][0] = 0;
+ data.second_derivative(k,3)[0][0] = 0;
+ data.second_derivative(k,0)[0][1] = 1.;
+ data.second_derivative(k,1)[0][1] = -1.;
+ data.second_derivative(k,2)[0][1] = -1.;
+ data.second_derivative(k,3)[0][1] = 1.;
+ data.second_derivative(k,0)[1][0] = 1.;
+ data.second_derivative(k,1)[1][0] = -1.;
+ data.second_derivative(k,2)[1][0] = -1.;
+ data.second_derivative(k,3)[1][0] = 1.;
+ data.second_derivative(k,0)[1][1] = 0;
+ data.second_derivative(k,1)[1][1] = 0;
+ data.second_derivative(k,2)[1][1] = 0;
+ data.second_derivative(k,3)[1][1] = 0;
+ }
+ }
}
template <int spacedim>
void
compute_shapes_virtual (const unsigned int n_shape_functions,
- const std::vector<Point<3> > &unit_points,
- typename dealii::MappingQ1<3,spacedim>::InternalData& data)
+ const std::vector<Point<3> > &unit_points,
+ typename dealii::MappingQ1<3,spacedim>::InternalData& data)
{
const unsigned int n_points=unit_points.size();
for (unsigned int k = 0 ; k < n_points ; ++k)
- {
- double x = unit_points[k](0);
- double y = unit_points[k](1);
- double z = unit_points[k](2);
-
- if (data.shape_values.size()!=0)
- {
- Assert(data.shape_values.size()==n_shape_functions*n_points,
- ExcInternalError());
- data.shape(k,0) = (1.-x)*(1.-y)*(1.-z);
- data.shape(k,1) = x*(1.-y)*(1.-z);
- data.shape(k,2) = (1.-x)*y*(1.-z);
- data.shape(k,3) = x*y*(1.-z);
- data.shape(k,4) = (1.-x)*(1.-y)*z;
- data.shape(k,5) = x*(1.-y)*z;
- data.shape(k,6) = (1.-x)*y*z;
- data.shape(k,7) = x*y*z;
- }
- if (data.shape_derivatives.size()!=0)
- {
- Assert(data.shape_derivatives.size()==n_shape_functions*n_points,
- ExcInternalError());
- data.derivative(k,0)[0] = (y-1.)*(1.-z);
- data.derivative(k,1)[0] = (1.-y)*(1.-z);
- data.derivative(k,2)[0] = -y*(1.-z);
- data.derivative(k,3)[0] = y*(1.-z);
- data.derivative(k,4)[0] = (y-1.)*z;
- data.derivative(k,5)[0] = (1.-y)*z;
- data.derivative(k,6)[0] = -y*z;
- data.derivative(k,7)[0] = y*z;
- data.derivative(k,0)[1] = (x-1.)*(1.-z);
- data.derivative(k,1)[1] = -x*(1.-z);
- data.derivative(k,2)[1] = (1.-x)*(1.-z);
- data.derivative(k,3)[1] = x*(1.-z);
- data.derivative(k,4)[1] = (x-1.)*z;
- data.derivative(k,5)[1] = -x*z;
- data.derivative(k,6)[1] = (1.-x)*z;
- data.derivative(k,7)[1] = x*z;
- data.derivative(k,0)[2] = (x-1)*(1.-y);
- data.derivative(k,1)[2] = x*(y-1.);
- data.derivative(k,2)[2] = (x-1.)*y;
- data.derivative(k,3)[2] = -x*y;
- data.derivative(k,4)[2] = (1.-x)*(1.-y);
- data.derivative(k,5)[2] = x*(1.-y);
- data.derivative(k,6)[2] = (1.-x)*y;
- data.derivative(k,7)[2] = x*y;
- }
- if (data.shape_second_derivatives.size()!=0)
- {
- // the following may or may not
- // work if dim != spacedim
- Assert (spacedim == 3, ExcNotImplemented());
-
- Assert(data.shape_second_derivatives.size()==n_shape_functions*n_points,
- ExcInternalError());
- data.second_derivative(k,0)[0][0] = 0;
- data.second_derivative(k,1)[0][0] = 0;
- data.second_derivative(k,2)[0][0] = 0;
- data.second_derivative(k,3)[0][0] = 0;
- data.second_derivative(k,4)[0][0] = 0;
- data.second_derivative(k,5)[0][0] = 0;
- data.second_derivative(k,6)[0][0] = 0;
- data.second_derivative(k,7)[0][0] = 0;
- data.second_derivative(k,0)[1][1] = 0;
- data.second_derivative(k,1)[1][1] = 0;
- data.second_derivative(k,2)[1][1] = 0;
- data.second_derivative(k,3)[1][1] = 0;
- data.second_derivative(k,4)[1][1] = 0;
- data.second_derivative(k,5)[1][1] = 0;
- data.second_derivative(k,6)[1][1] = 0;
- data.second_derivative(k,7)[1][1] = 0;
- data.second_derivative(k,0)[2][2] = 0;
- data.second_derivative(k,1)[2][2] = 0;
- data.second_derivative(k,2)[2][2] = 0;
- data.second_derivative(k,3)[2][2] = 0;
- data.second_derivative(k,4)[2][2] = 0;
- data.second_derivative(k,5)[2][2] = 0;
- data.second_derivative(k,6)[2][2] = 0;
- data.second_derivative(k,7)[2][2] = 0;
-
- data.second_derivative(k,0)[0][1] = (1.-z);
- data.second_derivative(k,1)[0][1] = -(1.-z);
- data.second_derivative(k,2)[0][1] = -(1.-z);
- data.second_derivative(k,3)[0][1] = (1.-z);
- data.second_derivative(k,4)[0][1] = z;
- data.second_derivative(k,5)[0][1] = -z;
- data.second_derivative(k,6)[0][1] = -z;
- data.second_derivative(k,7)[0][1] = z;
- data.second_derivative(k,0)[1][0] = (1.-z);
- data.second_derivative(k,1)[1][0] = -(1.-z);
- data.second_derivative(k,2)[1][0] = -(1.-z);
- data.second_derivative(k,3)[1][0] = (1.-z);
- data.second_derivative(k,4)[1][0] = z;
- data.second_derivative(k,5)[1][0] = -z;
- data.second_derivative(k,6)[1][0] = -z;
- data.second_derivative(k,7)[1][0] = z;
-
- data.second_derivative(k,0)[0][2] = (1.-y);
- data.second_derivative(k,1)[0][2] = -(1.-y);
- data.second_derivative(k,2)[0][2] = y;
- data.second_derivative(k,3)[0][2] = -y;
- data.second_derivative(k,4)[0][2] = -(1.-y);
- data.second_derivative(k,5)[0][2] = (1.-y);
- data.second_derivative(k,6)[0][2] = -y;
- data.second_derivative(k,7)[0][2] = y;
- data.second_derivative(k,0)[2][0] = (1.-y);
- data.second_derivative(k,1)[2][0] = -(1.-y);
- data.second_derivative(k,2)[2][0] = y;
- data.second_derivative(k,3)[2][0] = -y;
- data.second_derivative(k,4)[2][0] = -(1.-y);
- data.second_derivative(k,5)[2][0] = (1.-y);
- data.second_derivative(k,6)[2][0] = -y;
- data.second_derivative(k,7)[2][0] = y;
-
- data.second_derivative(k,0)[1][2] = (1.-x);
- data.second_derivative(k,1)[1][2] = x;
- data.second_derivative(k,2)[1][2] = -(1.-x);
- data.second_derivative(k,3)[1][2] = -x;
- data.second_derivative(k,4)[1][2] = -(1.-x);
- data.second_derivative(k,5)[1][2] = -x;
- data.second_derivative(k,6)[1][2] = (1.-x);
- data.second_derivative(k,7)[1][2] = x;
- data.second_derivative(k,0)[2][1] = (1.-x);
- data.second_derivative(k,1)[2][1] = x;
- data.second_derivative(k,2)[2][1] = -(1.-x);
- data.second_derivative(k,3)[2][1] = -x;
- data.second_derivative(k,4)[2][1] = -(1.-x);
- data.second_derivative(k,5)[2][1] = -x;
- data.second_derivative(k,6)[2][1] = (1.-x);
- data.second_derivative(k,7)[2][1] = x;
- }
- }
+ {
+ double x = unit_points[k](0);
+ double y = unit_points[k](1);
+ double z = unit_points[k](2);
+
+ if (data.shape_values.size()!=0)
+ {
+ Assert(data.shape_values.size()==n_shape_functions*n_points,
+ ExcInternalError());
+ data.shape(k,0) = (1.-x)*(1.-y)*(1.-z);
+ data.shape(k,1) = x*(1.-y)*(1.-z);
+ data.shape(k,2) = (1.-x)*y*(1.-z);
+ data.shape(k,3) = x*y*(1.-z);
+ data.shape(k,4) = (1.-x)*(1.-y)*z;
+ data.shape(k,5) = x*(1.-y)*z;
+ data.shape(k,6) = (1.-x)*y*z;
+ data.shape(k,7) = x*y*z;
+ }
+ if (data.shape_derivatives.size()!=0)
+ {
+ Assert(data.shape_derivatives.size()==n_shape_functions*n_points,
+ ExcInternalError());
+ data.derivative(k,0)[0] = (y-1.)*(1.-z);
+ data.derivative(k,1)[0] = (1.-y)*(1.-z);
+ data.derivative(k,2)[0] = -y*(1.-z);
+ data.derivative(k,3)[0] = y*(1.-z);
+ data.derivative(k,4)[0] = (y-1.)*z;
+ data.derivative(k,5)[0] = (1.-y)*z;
+ data.derivative(k,6)[0] = -y*z;
+ data.derivative(k,7)[0] = y*z;
+ data.derivative(k,0)[1] = (x-1.)*(1.-z);
+ data.derivative(k,1)[1] = -x*(1.-z);
+ data.derivative(k,2)[1] = (1.-x)*(1.-z);
+ data.derivative(k,3)[1] = x*(1.-z);
+ data.derivative(k,4)[1] = (x-1.)*z;
+ data.derivative(k,5)[1] = -x*z;
+ data.derivative(k,6)[1] = (1.-x)*z;
+ data.derivative(k,7)[1] = x*z;
+ data.derivative(k,0)[2] = (x-1)*(1.-y);
+ data.derivative(k,1)[2] = x*(y-1.);
+ data.derivative(k,2)[2] = (x-1.)*y;
+ data.derivative(k,3)[2] = -x*y;
+ data.derivative(k,4)[2] = (1.-x)*(1.-y);
+ data.derivative(k,5)[2] = x*(1.-y);
+ data.derivative(k,6)[2] = (1.-x)*y;
+ data.derivative(k,7)[2] = x*y;
+ }
+ if (data.shape_second_derivatives.size()!=0)
+ {
+ // the following may or may not
+ // work if dim != spacedim
+ Assert (spacedim == 3, ExcNotImplemented());
+
+ Assert(data.shape_second_derivatives.size()==n_shape_functions*n_points,
+ ExcInternalError());
+ data.second_derivative(k,0)[0][0] = 0;
+ data.second_derivative(k,1)[0][0] = 0;
+ data.second_derivative(k,2)[0][0] = 0;
+ data.second_derivative(k,3)[0][0] = 0;
+ data.second_derivative(k,4)[0][0] = 0;
+ data.second_derivative(k,5)[0][0] = 0;
+ data.second_derivative(k,6)[0][0] = 0;
+ data.second_derivative(k,7)[0][0] = 0;
+ data.second_derivative(k,0)[1][1] = 0;
+ data.second_derivative(k,1)[1][1] = 0;
+ data.second_derivative(k,2)[1][1] = 0;
+ data.second_derivative(k,3)[1][1] = 0;
+ data.second_derivative(k,4)[1][1] = 0;
+ data.second_derivative(k,5)[1][1] = 0;
+ data.second_derivative(k,6)[1][1] = 0;
+ data.second_derivative(k,7)[1][1] = 0;
+ data.second_derivative(k,0)[2][2] = 0;
+ data.second_derivative(k,1)[2][2] = 0;
+ data.second_derivative(k,2)[2][2] = 0;
+ data.second_derivative(k,3)[2][2] = 0;
+ data.second_derivative(k,4)[2][2] = 0;
+ data.second_derivative(k,5)[2][2] = 0;
+ data.second_derivative(k,6)[2][2] = 0;
+ data.second_derivative(k,7)[2][2] = 0;
+
+ data.second_derivative(k,0)[0][1] = (1.-z);
+ data.second_derivative(k,1)[0][1] = -(1.-z);
+ data.second_derivative(k,2)[0][1] = -(1.-z);
+ data.second_derivative(k,3)[0][1] = (1.-z);
+ data.second_derivative(k,4)[0][1] = z;
+ data.second_derivative(k,5)[0][1] = -z;
+ data.second_derivative(k,6)[0][1] = -z;
+ data.second_derivative(k,7)[0][1] = z;
+ data.second_derivative(k,0)[1][0] = (1.-z);
+ data.second_derivative(k,1)[1][0] = -(1.-z);
+ data.second_derivative(k,2)[1][0] = -(1.-z);
+ data.second_derivative(k,3)[1][0] = (1.-z);
+ data.second_derivative(k,4)[1][0] = z;
+ data.second_derivative(k,5)[1][0] = -z;
+ data.second_derivative(k,6)[1][0] = -z;
+ data.second_derivative(k,7)[1][0] = z;
+
+ data.second_derivative(k,0)[0][2] = (1.-y);
+ data.second_derivative(k,1)[0][2] = -(1.-y);
+ data.second_derivative(k,2)[0][2] = y;
+ data.second_derivative(k,3)[0][2] = -y;
+ data.second_derivative(k,4)[0][2] = -(1.-y);
+ data.second_derivative(k,5)[0][2] = (1.-y);
+ data.second_derivative(k,6)[0][2] = -y;
+ data.second_derivative(k,7)[0][2] = y;
+ data.second_derivative(k,0)[2][0] = (1.-y);
+ data.second_derivative(k,1)[2][0] = -(1.-y);
+ data.second_derivative(k,2)[2][0] = y;
+ data.second_derivative(k,3)[2][0] = -y;
+ data.second_derivative(k,4)[2][0] = -(1.-y);
+ data.second_derivative(k,5)[2][0] = (1.-y);
+ data.second_derivative(k,6)[2][0] = -y;
+ data.second_derivative(k,7)[2][0] = y;
+
+ data.second_derivative(k,0)[1][2] = (1.-x);
+ data.second_derivative(k,1)[1][2] = x;
+ data.second_derivative(k,2)[1][2] = -(1.-x);
+ data.second_derivative(k,3)[1][2] = -x;
+ data.second_derivative(k,4)[1][2] = -(1.-x);
+ data.second_derivative(k,5)[1][2] = -x;
+ data.second_derivative(k,6)[1][2] = (1.-x);
+ data.second_derivative(k,7)[1][2] = x;
+ data.second_derivative(k,0)[2][1] = (1.-x);
+ data.second_derivative(k,1)[2][1] = x;
+ data.second_derivative(k,2)[2][1] = -(1.-x);
+ data.second_derivative(k,3)[2][1] = -x;
+ data.second_derivative(k,4)[2][1] = -(1.-x);
+ data.second_derivative(k,5)[2][1] = -x;
+ data.second_derivative(k,6)[2][1] = (1.-x);
+ data.second_derivative(k,7)[2][1] = x;
+ }
+ }
}
}
}
void
MappingQ1<dim, spacedim>::
compute_shapes_virtual (const std::vector<Point<dim> > &unit_points,
- InternalData& data) const
+ InternalData& data) const
{
internal::MappingQ1::
compute_shapes_virtual<spacedim> (n_shape_functions,
- unit_points, data);
+ unit_points, data);
}
MappingQ1<dim,spacedim>::update_once (const UpdateFlags in) const
{
UpdateFlags out = UpdateFlags(in & (update_transformation_values
- | update_transformation_gradients));
+ | update_transformation_gradients));
- // Shape function values
+ // Shape function values
if (in & update_quadrature_points)
out |= update_transformation_values;
- // Shape function gradients
+ // Shape function gradients
if (in & (update_covariant_transformation
- | update_contravariant_transformation
- | update_JxW_values
- | update_boundary_forms
- | update_normal_vectors
- | update_jacobians
- | update_jacobian_grads
- | update_inverse_jacobians))
+ | update_contravariant_transformation
+ | update_JxW_values
+ | update_boundary_forms
+ | update_normal_vectors
+ | update_jacobians
+ | update_jacobian_grads
+ | update_inverse_jacobians))
out |= update_transformation_gradients;
return out;
UpdateFlags
MappingQ1<dim,spacedim>::update_each (const UpdateFlags in) const
{
- // Select flags of concern for the
- // transformation.
+ // Select flags of concern for the
+ // transformation.
UpdateFlags out = UpdateFlags(in & (update_quadrature_points
- | update_covariant_transformation
- | update_contravariant_transformation
- | update_JxW_values
- | update_boundary_forms
- | update_normal_vectors
- | update_volume_elements
- | update_jacobians
- | update_jacobian_grads
- | update_inverse_jacobians));
-
- // add flags if the respective
- // quantities are necessary to
- // compute what we need. note that
- // some flags appear in both
- // conditions and in subsequents
- // set operations. this leads to
- // some circular logic. the only
- // way to treat this is to
- // iterate. since there are 4
- // if-clauses in the loop, it will
- // take at most 3 iterations to
- // converge. do them:
+ | update_covariant_transformation
+ | update_contravariant_transformation
+ | update_JxW_values
+ | update_boundary_forms
+ | update_normal_vectors
+ | update_volume_elements
+ | update_jacobians
+ | update_jacobian_grads
+ | update_inverse_jacobians));
+
+ // add flags if the respective
+ // quantities are necessary to
+ // compute what we need. note that
+ // some flags appear in both
+ // conditions and in subsequents
+ // set operations. this leads to
+ // some circular logic. the only
+ // way to treat this is to
+ // iterate. since there are 4
+ // if-clauses in the loop, it will
+ // take at most 3 iterations to
+ // converge. do them:
for (unsigned int i=0; i<4; ++i)
{
- // The following is a little incorrect:
- // If not applied on a face,
- // update_boundary_forms does not
- // make sense. On the other hand,
- // it is necessary on a
- // face. Currently,
- // update_boundary_forms is simply
- // ignored for the interior of a
- // cell.
+ // The following is a little incorrect:
+ // If not applied on a face,
+ // update_boundary_forms does not
+ // make sense. On the other hand,
+ // it is necessary on a
+ // face. Currently,
+ // update_boundary_forms is simply
+ // ignored for the interior of a
+ // cell.
if (out & (update_JxW_values
- | update_normal_vectors))
- out |= update_boundary_forms;
+ | update_normal_vectors))
+ out |= update_boundary_forms;
if (out & (update_covariant_transformation
- | update_JxW_values
- | update_jacobians
- | update_jacobian_grads
- | update_boundary_forms
- | update_normal_vectors))
- out |= update_contravariant_transformation;
+ | update_JxW_values
+ | update_jacobians
+ | update_jacobian_grads
+ | update_boundary_forms
+ | update_normal_vectors))
+ out |= update_contravariant_transformation;
if (out & (update_inverse_jacobians))
- out |= update_covariant_transformation;
-
- // The contravariant transformation
- // is a Piola transformation, which
- // requires the determinant of the
- // Jacobi matrix of the transformation.
- // Therefore these values have to be
- // updated for each cell.
+ out |= update_covariant_transformation;
+
+ // The contravariant transformation
+ // is a Piola transformation, which
+ // requires the determinant of the
+ // Jacobi matrix of the transformation.
+ // Therefore these values have to be
+ // updated for each cell.
if (out & update_contravariant_transformation)
- out |= update_JxW_values;
+ out |= update_JxW_values;
if (out & update_normal_vectors)
- out |= update_JxW_values;
+ out |= update_JxW_values;
}
return out;
template<int dim, int spacedim>
void
MappingQ1<dim,spacedim>::compute_data (const UpdateFlags update_flags,
- const Quadrature<dim> &q,
- const unsigned int n_original_q_points,
- InternalData &data) const
+ const Quadrature<dim> &q,
+ const unsigned int n_original_q_points,
+ InternalData &data) const
{
const unsigned int n_q_points = q.size();
template<int dim, int spacedim>
typename Mapping<dim,spacedim>::InternalDataBase *
MappingQ1<dim,spacedim>::get_data (const UpdateFlags update_flags,
- const Quadrature<dim>& q) const
+ const Quadrature<dim>& q) const
{
InternalData* data = new InternalData(n_shape_functions);
compute_data (update_flags, q, q.size(), *data);
template<int dim, int spacedim>
void
MappingQ1<dim,spacedim>::compute_face_data (const UpdateFlags update_flags,
- const Quadrature<dim>& q,
- const unsigned int n_original_q_points,
- InternalData& data) const
+ const Quadrature<dim>& q,
+ const unsigned int n_original_q_points,
+ InternalData& data) const
{
compute_data (update_flags, q, n_original_q_points, data);
if (dim > 1)
{
if (data.update_flags & update_boundary_forms)
- {
- data.aux.resize (dim-1, std::vector<Tensor<1,spacedim> > (n_original_q_points));
-
- // Compute tangentials to the
- // unit cell.
- const unsigned int nfaces = GeometryInfo<dim>::faces_per_cell;
- data.unit_tangentials.resize (nfaces*(dim-1),
- std::vector<Tensor<1,dim> > (n_original_q_points));
- if (dim==2)
- {
- // ensure a counterclock wise
- // orientation of tangentials
- static const int tangential_orientation[4]={-1,1,1,-1};
- for (unsigned int i=0; i<nfaces; ++i)
- {
- Tensor<1,dim> tang;
- tang[1-i/2]=tangential_orientation[i];
- std::fill (data.unit_tangentials[i].begin(),
- data.unit_tangentials[i].end(), tang);
- }
- }
- else if (dim==3)
- {
- for (unsigned int i=0; i<nfaces; ++i)
- {
- Tensor<1,dim> tang1, tang2;
-
- const unsigned int nd=
- GeometryInfo<dim>::unit_normal_direction[i];
-
- // first tangential
- // vector in direction
- // of the (nd+1)%3 axis
- // and inverted in case
- // of unit inward normal
- tang1[(nd+1)%dim]=GeometryInfo<dim>::unit_normal_orientation[i];
- // second tangential
- // vector in direction
- // of the (nd+2)%3 axis
- tang2[(nd+2)%dim]=1.;
-
- // same unit tangents
- // for all quadrature
- // points on this face
- std::fill (data.unit_tangentials[i].begin(),
- data.unit_tangentials[i].end(), tang1);
- std::fill (data.unit_tangentials[nfaces+i].begin(),
- data.unit_tangentials[nfaces+i].end(), tang2);
- }
- }
- }
+ {
+ data.aux.resize (dim-1, std::vector<Tensor<1,spacedim> > (n_original_q_points));
+
+ // Compute tangentials to the
+ // unit cell.
+ const unsigned int nfaces = GeometryInfo<dim>::faces_per_cell;
+ data.unit_tangentials.resize (nfaces*(dim-1),
+ std::vector<Tensor<1,dim> > (n_original_q_points));
+ if (dim==2)
+ {
+ // ensure a counterclock wise
+ // orientation of tangentials
+ static const int tangential_orientation[4]={-1,1,1,-1};
+ for (unsigned int i=0; i<nfaces; ++i)
+ {
+ Tensor<1,dim> tang;
+ tang[1-i/2]=tangential_orientation[i];
+ std::fill (data.unit_tangentials[i].begin(),
+ data.unit_tangentials[i].end(), tang);
+ }
+ }
+ else if (dim==3)
+ {
+ for (unsigned int i=0; i<nfaces; ++i)
+ {
+ Tensor<1,dim> tang1, tang2;
+
+ const unsigned int nd=
+ GeometryInfo<dim>::unit_normal_direction[i];
+
+ // first tangential
+ // vector in direction
+ // of the (nd+1)%3 axis
+ // and inverted in case
+ // of unit inward normal
+ tang1[(nd+1)%dim]=GeometryInfo<dim>::unit_normal_orientation[i];
+ // second tangential
+ // vector in direction
+ // of the (nd+2)%3 axis
+ tang2[(nd+2)%dim]=1.;
+
+ // same unit tangents
+ // for all quadrature
+ // points on this face
+ std::fill (data.unit_tangentials[i].begin(),
+ data.unit_tangentials[i].end(), tang1);
+ std::fill (data.unit_tangentials[nfaces+i].begin(),
+ data.unit_tangentials[nfaces+i].end(), tang2);
+ }
+ }
+ }
}
}
template<int dim, int spacedim>
typename Mapping<dim,spacedim>::InternalDataBase *
MappingQ1<dim,spacedim>::get_face_data (const UpdateFlags update_flags,
- const Quadrature<dim-1> &quadrature) const
+ const Quadrature<dim-1> &quadrature) const
{
InternalData* data = new InternalData(n_shape_functions);
compute_face_data (update_flags,
- QProjector<dim>::project_to_all_faces(quadrature),
- quadrature.size(),
- *data);
+ QProjector<dim>::project_to_all_faces(quadrature),
+ quadrature.size(),
+ *data);
return data;
}
template<int dim, int spacedim>
typename Mapping<dim,spacedim>::InternalDataBase *
MappingQ1<dim,spacedim>::get_subface_data (const UpdateFlags update_flags,
- const Quadrature<dim-1>& quadrature) const
+ const Quadrature<dim-1>& quadrature) const
{
InternalData* data = new InternalData(n_shape_functions);
compute_face_data (update_flags,
- QProjector<dim>::project_to_all_subfaces(quadrature),
- quadrature.size(),
- *data);
+ QProjector<dim>::project_to_all_subfaces(quadrature),
+ quadrature.size(),
+ *data);
return data;
}
template<int dim, int spacedim>
void
MappingQ1<dim,spacedim>::compute_fill (const typename Triangulation<dim,spacedim>::cell_iterator &cell,
- const unsigned int n_q_points,
- const DataSetDescriptor data_set,
- const CellSimilarity::Similarity cell_similarity,
- InternalData &data,
- std::vector<Point<spacedim> > &quadrature_points) const
+ const unsigned int n_q_points,
+ const DataSetDescriptor data_set,
+ const CellSimilarity::Similarity cell_similarity,
+ InternalData &data,
+ std::vector<Point<spacedim> > &quadrature_points) const
{
const UpdateFlags update_flags(data.current_update_flags());
- // if necessary, recompute the
- // support points of the
- // transformation of this cell
- // (note that we need to first
- // check the triangulation pointer,
- // since otherwise the second test
- // might trigger an exception if
- // the triangulations are not the
- // same)
+ // if necessary, recompute the
+ // support points of the
+ // transformation of this cell
+ // (note that we need to first
+ // check the triangulation pointer,
+ // since otherwise the second test
+ // might trigger an exception if
+ // the triangulations are not the
+ // same)
if ((data.mapping_support_points.size() == 0)
||
(&cell->get_triangulation() !=
AssertDimension (quadrature_points.size(), n_q_points);
for (unsigned int point=0; point<n_q_points; ++point)
- {
- const double * shape = &data.shape(point+data_set,0);
- Point<spacedim> result = (shape[0] *
- data.mapping_support_points[0]);
- for (unsigned int k=1; k<data.n_shape_functions; ++k)
- for (unsigned int i=0; i<spacedim; ++i)
- result[i] += shape[k] * data.mapping_support_points[k][i];
- quadrature_points[point] = result;
- }
+ {
+ const double * shape = &data.shape(point+data_set,0);
+ Point<spacedim> result = (shape[0] *
+ data.mapping_support_points[0]);
+ for (unsigned int k=1; k<data.n_shape_functions; ++k)
+ for (unsigned int i=0; i<spacedim; ++i)
+ result[i] += shape[k] * data.mapping_support_points[k][i];
+ quadrature_points[point] = result;
+ }
}
// then Jacobians
{
AssertDimension (data.contravariant.size(), n_q_points);
- // if the current cell is just a
- // translation of the previous one, no
- // need to recompute jacobians...
+ // if the current cell is just a
+ // translation of the previous one, no
+ // need to recompute jacobians...
if (cell_similarity != CellSimilarity::translation)
- {
- std::fill(data.contravariant.begin(), data.contravariant.end(),
- DerivativeForm<1,dim,spacedim>());
-
- Assert (data.n_shape_functions > 0, ExcInternalError());
- const Tensor<1,spacedim> *supp_pts =
- &data.mapping_support_points[0];
-
- for (unsigned int point=0; point<n_q_points; ++point)
- {
- const Tensor<1,dim> * data_derv =
- &data.derivative(point+data_set, 0);
-
- double result [spacedim][dim];
-
- // peel away part of sum to avoid zeroing the
- // entries and adding for the first time
- for (unsigned int i=0; i<spacedim; ++i)
- for (unsigned int j=0; j<dim; ++j)
- result[i][j] = data_derv[0][j] * supp_pts[0][i];
- for (unsigned int k=1; k<data.n_shape_functions; ++k)
- for (unsigned int i=0; i<spacedim; ++i)
- for (unsigned int j=0; j<dim; ++j)
- result[i][j] += data_derv[k][j] * supp_pts[k][i];
-
- // write result into contravariant data. for
- // j=dim in the case dim<spacedim, there will
- // never be any nonzero data that arrives in
- // here, so it is ok anyway because it was
- // initialized to zero at the initialization
- for (unsigned int i=0; i<spacedim; ++i)
- for (unsigned int j=0; j<dim; ++j)
- data.contravariant[point][i][j] = result[i][j];
- }
- }
+ {
+ std::fill(data.contravariant.begin(), data.contravariant.end(),
+ DerivativeForm<1,dim,spacedim>());
+
+ Assert (data.n_shape_functions > 0, ExcInternalError());
+ const Tensor<1,spacedim> *supp_pts =
+ &data.mapping_support_points[0];
+
+ for (unsigned int point=0; point<n_q_points; ++point)
+ {
+ const Tensor<1,dim> * data_derv =
+ &data.derivative(point+data_set, 0);
+
+ double result [spacedim][dim];
+
+ // peel away part of sum to avoid zeroing the
+ // entries and adding for the first time
+ for (unsigned int i=0; i<spacedim; ++i)
+ for (unsigned int j=0; j<dim; ++j)
+ result[i][j] = data_derv[0][j] * supp_pts[0][i];
+ for (unsigned int k=1; k<data.n_shape_functions; ++k)
+ for (unsigned int i=0; i<spacedim; ++i)
+ for (unsigned int j=0; j<dim; ++j)
+ result[i][j] += data_derv[k][j] * supp_pts[k][i];
+
+ // write result into contravariant data. for
+ // j=dim in the case dim<spacedim, there will
+ // never be any nonzero data that arrives in
+ // here, so it is ok anyway because it was
+ // initialized to zero at the initialization
+ for (unsigned int i=0; i<spacedim; ++i)
+ for (unsigned int j=0; j<dim; ++j)
+ data.contravariant[point][i][j] = result[i][j];
+ }
+ }
}
if (update_flags & update_covariant_transformation)
{
AssertDimension (data.covariant.size(), n_q_points);
if (cell_similarity != CellSimilarity::translation)
- for (unsigned int point=0; point<n_q_points; ++point)
- {
- data.covariant[point] = (data.contravariant[point]).covariant_form();
- }
+ for (unsigned int point=0; point<n_q_points; ++point)
+ {
+ data.covariant[point] = (data.contravariant[point]).covariant_form();
+ }
}
if (update_flags & update_volume_elements)
if (cell_similarity != CellSimilarity::translation)
for (unsigned int point=0; point<n_q_points; ++point)
- data.volume_elements[point] = data.contravariant[point].determinant();
+ data.volume_elements[point] = data.contravariant[point].determinant();
}
std::vector<Point<spacedim> > &normal_vectors,
CellSimilarity::Similarity &cell_similarity) const
{
- // ensure that the following cast
- // is really correct:
+ // ensure that the following cast
+ // is really correct:
Assert (dynamic_cast<InternalData *>(&mapping_data) != 0,
- ExcInternalError());
+ ExcInternalError());
InternalData &data = static_cast<InternalData&>(mapping_data);
const unsigned int n_q_points=q.size();
const UpdateFlags update_flags(data.current_update_flags());
const std::vector<double> &weights=q.get_weights();
- // Multiply quadrature weights by
- // Jacobian determinants or the area
- // element g=sqrt(DX^t DX) in case of
- // codim > 0
+ // Multiply quadrature weights by
+ // Jacobian determinants or the area
+ // element g=sqrt(DX^t DX) in case of
+ // codim > 0
if (update_flags & (update_normal_vectors
- | update_JxW_values))
+ | update_JxW_values))
{
AssertDimension (JxW_values.size(), n_q_points);
Assert( !(update_flags & update_normal_vectors ) ||
- (normal_vectors.size() == n_q_points),
- ExcDimensionMismatch(normal_vectors.size(), n_q_points));
+ (normal_vectors.size() == n_q_points),
+ ExcDimensionMismatch(normal_vectors.size(), n_q_points));
if (cell_similarity != CellSimilarity::translation)
- for (unsigned int point=0; point<n_q_points; ++point)
- {
-
- if (dim == spacedim)
- {
- JxW_values[point]
- = data.contravariant[point].determinant() * weights[point];
- }
- // if dim==spacedim,
- // then there is no
- // cell normal to
- // compute. since this
- // is for FEValues (and
- // not FEFaceValues),
- // there are also no
- // face normals to
- // compute
- else //codim>0 case
- {
- Tensor<1, spacedim> DX_t [dim];
- for (unsigned int i=0; i<spacedim; ++i)
- for (unsigned int j=0; j<dim; ++j)
- DX_t[j][i] = data.contravariant[point][i][j];
-
- Tensor<2, dim> G; //First fundamental form
- for (unsigned int i=0; i<dim; ++i)
- for (unsigned int j=0; j<dim; ++j)
- G[i][j] = DX_t[i] * DX_t[j];
-
- JxW_values[point]
- = sqrt(determinant(G)) * weights[point];
-
- if (cell_similarity == CellSimilarity::inverted_translation)
- {
- // we only need to flip the normal
- if (update_flags & update_normal_vectors)
- normal_vectors[point] *= -1.;
- }
- else
- {
- const unsigned int codim = spacedim-dim;
-
- if (update_flags & update_normal_vectors)
- {
- Assert( codim==1 , ExcMessage("There is no cell normal in codim 2."));
-
- if (dim==1)
- cross_product(normal_vectors[point],
- -DX_t[0]);
- else //dim == 2
- cross_product(normal_vectors[point],DX_t[0],DX_t[1]);
-
- normal_vectors[point] /= normal_vectors[point].norm();
-
- if (cell->direction_flag() == false)
- normal_vectors[point] *= -1.;
- }
-
- }
- } //codim>0 case
-
- }
+ for (unsigned int point=0; point<n_q_points; ++point)
+ {
+
+ if (dim == spacedim)
+ {
+ JxW_values[point]
+ = data.contravariant[point].determinant() * weights[point];
+ }
+ // if dim==spacedim,
+ // then there is no
+ // cell normal to
+ // compute. since this
+ // is for FEValues (and
+ // not FEFaceValues),
+ // there are also no
+ // face normals to
+ // compute
+ else //codim>0 case
+ {
+ Tensor<1, spacedim> DX_t [dim];
+ for (unsigned int i=0; i<spacedim; ++i)
+ for (unsigned int j=0; j<dim; ++j)
+ DX_t[j][i] = data.contravariant[point][i][j];
+
+ Tensor<2, dim> G; //First fundamental form
+ for (unsigned int i=0; i<dim; ++i)
+ for (unsigned int j=0; j<dim; ++j)
+ G[i][j] = DX_t[i] * DX_t[j];
+
+ JxW_values[point]
+ = sqrt(determinant(G)) * weights[point];
+
+ if (cell_similarity == CellSimilarity::inverted_translation)
+ {
+ // we only need to flip the normal
+ if (update_flags & update_normal_vectors)
+ normal_vectors[point] *= -1.;
+ }
+ else
+ {
+ const unsigned int codim = spacedim-dim;
+
+ if (update_flags & update_normal_vectors)
+ {
+ Assert( codim==1 , ExcMessage("There is no cell normal in codim 2."));
+
+ if (dim==1)
+ cross_product(normal_vectors[point],
+ -DX_t[0]);
+ else //dim == 2
+ cross_product(normal_vectors[point],DX_t[0],DX_t[1]);
+
+ normal_vectors[point] /= normal_vectors[point].norm();
+
+ if (cell->direction_flag() == false)
+ normal_vectors[point] *= -1.;
+ }
+
+ }
+ } //codim>0 case
+
+ }
}
- // copy values from InternalData to
- // vector given by reference
+ // copy values from InternalData to
+ // vector given by reference
if (update_flags & update_jacobians)
{
AssertDimension (jacobians.size(), n_q_points);
if (cell_similarity != CellSimilarity::translation)
- for (unsigned int point=0; point<n_q_points; ++point)
- jacobians[point] = data.contravariant[point];
+ for (unsigned int point=0; point<n_q_points; ++point)
+ jacobians[point] = data.contravariant[point];
}
- // calculate values of the
- // derivatives of the Jacobians. do
- // it here, since we only do it for
- // cells, not faces.
+ // calculate values of the
+ // derivatives of the Jacobians. do
+ // it here, since we only do it for
+ // cells, not faces.
if (update_flags & update_jacobian_grads)
{
AssertDimension (jacobian_grads.size(), n_q_points);
if (cell_similarity != CellSimilarity::translation)
- {
-
- std::fill(jacobian_grads.begin(),
- jacobian_grads.end(),
- DerivativeForm<2,dim,spacedim>());
-
-
- const unsigned int data_set = DataSetDescriptor::cell();
-
- for (unsigned int point=0; point<n_q_points; ++point)
- {
- const Tensor<2,dim> * second =
- &data.second_derivative(point+data_set, 0);
- double result [spacedim][dim][dim];
- for (unsigned int i=0; i<spacedim; ++i)
- for (unsigned int j=0; j<dim; ++j)
- for (unsigned int l=0; l<dim; ++l)
- result[i][j][l] = (second[0][j][l] *
- data.mapping_support_points[0][i]);
- for (unsigned int k=1; k<data.n_shape_functions; ++k)
- for (unsigned int i=0; i<spacedim; ++i)
- for (unsigned int j=0; j<dim; ++j)
- for (unsigned int l=0; l<dim; ++l)
- result[i][j][l]
- += (second[k][j][l]
- *
- data.mapping_support_points[k][i]);
-
- // never touch any data for j=dim in case
- // dim<spacedim, so it will always be zero as
- // it was initialized
- for (unsigned int i=0; i<spacedim; ++i)
- for (unsigned int j=0; j<dim; ++j)
- for (unsigned int l=0; l<dim; ++l)
- jacobian_grads[point][i][j][l] = result[i][j][l];
- }
- }
+ {
+
+ std::fill(jacobian_grads.begin(),
+ jacobian_grads.end(),
+ DerivativeForm<2,dim,spacedim>());
+
+
+ const unsigned int data_set = DataSetDescriptor::cell();
+
+ for (unsigned int point=0; point<n_q_points; ++point)
+ {
+ const Tensor<2,dim> * second =
+ &data.second_derivative(point+data_set, 0);
+ double result [spacedim][dim][dim];
+ for (unsigned int i=0; i<spacedim; ++i)
+ for (unsigned int j=0; j<dim; ++j)
+ for (unsigned int l=0; l<dim; ++l)
+ result[i][j][l] = (second[0][j][l] *
+ data.mapping_support_points[0][i]);
+ for (unsigned int k=1; k<data.n_shape_functions; ++k)
+ for (unsigned int i=0; i<spacedim; ++i)
+ for (unsigned int j=0; j<dim; ++j)
+ for (unsigned int l=0; l<dim; ++l)
+ result[i][j][l]
+ += (second[k][j][l]
+ *
+ data.mapping_support_points[k][i]);
+
+ // never touch any data for j=dim in case
+ // dim<spacedim, so it will always be zero as
+ // it was initialized
+ for (unsigned int i=0; i<spacedim; ++i)
+ for (unsigned int j=0; j<dim; ++j)
+ for (unsigned int l=0; l<dim; ++l)
+ jacobian_grads[point][i][j][l] = result[i][j][l];
+ }
+ }
}
- // copy values from InternalData to vector
- // given by reference
+ // copy values from InternalData to vector
+ // given by reference
if (update_flags & update_inverse_jacobians)
{
AssertDimension (inverse_jacobians.size(), n_q_points);
if (cell_similarity != CellSimilarity::translation)
- for (unsigned int point=0; point<n_q_points; ++point)
- inverse_jacobians[point] = data.covariant[point].transpose();
+ for (unsigned int point=0; point<n_q_points; ++point)
+ inverse_jacobians[point] = data.covariant[point].transpose();
}
}
template <int dim, int spacedim>
void
compute_fill_face (const dealii::MappingQ1<dim,spacedim> &mapping,
- const typename dealii::Triangulation<dim,spacedim>::cell_iterator &cell,
- const unsigned int face_no,
- const unsigned int subface_no,
- const unsigned int n_q_points,
- const std::vector<double> &weights,
- typename dealii::MappingQ1<dim,spacedim>::InternalData &data,
- std::vector<double> &JxW_values,
- std::vector<Tensor<1,spacedim> > &boundary_forms,
- std::vector<Point<spacedim> > &normal_vectors)
+ const typename dealii::Triangulation<dim,spacedim>::cell_iterator &cell,
+ const unsigned int face_no,
+ const unsigned int subface_no,
+ const unsigned int n_q_points,
+ const std::vector<double> &weights,
+ typename dealii::MappingQ1<dim,spacedim>::InternalData &data,
+ std::vector<double> &JxW_values,
+ std::vector<Tensor<1,spacedim> > &boundary_forms,
+ std::vector<Point<spacedim> > &normal_vectors)
{
const UpdateFlags update_flags(data.current_update_flags());
if (update_flags & update_boundary_forms)
- {
- AssertDimension (boundary_forms.size(), n_q_points);
- if (update_flags & update_normal_vectors)
- AssertDimension (normal_vectors.size(), n_q_points);
- if (update_flags & update_JxW_values)
- AssertDimension (JxW_values.size(), n_q_points);
-
- // map the unit tangentials to the
- // real cell. checking for d!=dim-1
- // eliminates compiler warnings
- // regarding unsigned expressions <
- // 0.
- for (unsigned int d=0; d!=dim-1; ++d)
- {
- Assert (face_no+GeometryInfo<dim>::faces_per_cell*d <
- data.unit_tangentials.size(),
- ExcInternalError());
- Assert (data.aux[d].size() <=
- data.unit_tangentials[face_no+GeometryInfo<dim>::faces_per_cell*d].size(),
- ExcInternalError());
-
- mapping.transform (data.unit_tangentials[face_no+GeometryInfo<dim>::faces_per_cell*d],
- data.aux[d],
- data,
- mapping_contravariant);
- }
-
- // if dim==spacedim, we can use the
- // unit tangentials to compute the
- // boundary form by simply taking
- // the cross product
- if (dim == spacedim)
- {
- for (unsigned int i=0; i<n_q_points; ++i)
- switch (dim)
- {
- case 1:
- // in 1d, we don't
- // have access to
- // any of the
- // data.aux fields
- // (because it has
- // only dim-1
- // components), but
- // we can still
- // compute the
- // boundary form
- // simply by simply
- // looking at the
- // number of the
- // face
- boundary_forms[i][0] = (face_no == 0 ?
- -1 : +1);
- break;
- case 2:
- cross_product (boundary_forms[i], data.aux[0][i]);
- break;
- case 3:
- cross_product (boundary_forms[i], data.aux[0][i], data.aux[1][i]);
- break;
- default:
- Assert(false, ExcNotImplemented());
- }
- }
- else //(dim < spacedim)
- {
- // in the codim-one case, the
- // boundary form results from
- // the cross product of all the
- // face tangential vectors and
- // the cell normal vector
- //
- // to compute the cell normal,
- // use the same method used in
- // fill_fe_values for cells
- // above
- AssertDimension (data.contravariant.size(), n_q_points);
-
- for (unsigned int point=0; point<n_q_points; ++point)
- {
- if (dim==1)
- {
- // J is a tangent vector
- boundary_forms[point] = data.contravariant[point].transpose()[0];
- boundary_forms[point] /=
- (face_no == 0 ? -1. : +1.) * boundary_forms[point].norm();
-
- }
-
- if (dim==2)
- {
- Tensor<1,spacedim> cell_normal;
- const DerivativeForm<1,spacedim,dim> DX_t =
- data.contravariant[point].transpose();
- cross_product(cell_normal,DX_t[0],DX_t[1]);
- cell_normal /= cell_normal.norm();
-
- // then compute the face
- // normal from the face
- // tangent and the cell
- // normal:
- cross_product (boundary_forms[point],
- data.aux[0][point], cell_normal);
-
- }
-
- }
- }
-
-
-
- if (update_flags & (update_normal_vectors
- | update_JxW_values))
- for (unsigned int i=0;i<boundary_forms.size();++i)
- {
- if (update_flags & update_JxW_values)
- {
- JxW_values[i] = boundary_forms[i].norm() * weights[i];
-
- if (subface_no!=deal_II_numbers::invalid_unsigned_int)
- {
- const double area_ratio=GeometryInfo<dim>::subface_ratio(
- cell->subface_case(face_no), subface_no);
- JxW_values[i] *= area_ratio;
- }
- }
-
- if (update_flags & update_normal_vectors)
- normal_vectors[i] = boundary_forms[i] / boundary_forms[i].norm();
- }
- }
+ {
+ AssertDimension (boundary_forms.size(), n_q_points);
+ if (update_flags & update_normal_vectors)
+ AssertDimension (normal_vectors.size(), n_q_points);
+ if (update_flags & update_JxW_values)
+ AssertDimension (JxW_values.size(), n_q_points);
+
+ // map the unit tangentials to the
+ // real cell. checking for d!=dim-1
+ // eliminates compiler warnings
+ // regarding unsigned expressions <
+ // 0.
+ for (unsigned int d=0; d!=dim-1; ++d)
+ {
+ Assert (face_no+GeometryInfo<dim>::faces_per_cell*d <
+ data.unit_tangentials.size(),
+ ExcInternalError());
+ Assert (data.aux[d].size() <=
+ data.unit_tangentials[face_no+GeometryInfo<dim>::faces_per_cell*d].size(),
+ ExcInternalError());
+
+ mapping.transform (data.unit_tangentials[face_no+GeometryInfo<dim>::faces_per_cell*d],
+ data.aux[d],
+ data,
+ mapping_contravariant);
+ }
+
+ // if dim==spacedim, we can use the
+ // unit tangentials to compute the
+ // boundary form by simply taking
+ // the cross product
+ if (dim == spacedim)
+ {
+ for (unsigned int i=0; i<n_q_points; ++i)
+ switch (dim)
+ {
+ case 1:
+ // in 1d, we don't
+ // have access to
+ // any of the
+ // data.aux fields
+ // (because it has
+ // only dim-1
+ // components), but
+ // we can still
+ // compute the
+ // boundary form
+ // simply by simply
+ // looking at the
+ // number of the
+ // face
+ boundary_forms[i][0] = (face_no == 0 ?
+ -1 : +1);
+ break;
+ case 2:
+ cross_product (boundary_forms[i], data.aux[0][i]);
+ break;
+ case 3:
+ cross_product (boundary_forms[i], data.aux[0][i], data.aux[1][i]);
+ break;
+ default:
+ Assert(false, ExcNotImplemented());
+ }
+ }
+ else //(dim < spacedim)
+ {
+ // in the codim-one case, the
+ // boundary form results from
+ // the cross product of all the
+ // face tangential vectors and
+ // the cell normal vector
+ //
+ // to compute the cell normal,
+ // use the same method used in
+ // fill_fe_values for cells
+ // above
+ AssertDimension (data.contravariant.size(), n_q_points);
+
+ for (unsigned int point=0; point<n_q_points; ++point)
+ {
+ if (dim==1)
+ {
+ // J is a tangent vector
+ boundary_forms[point] = data.contravariant[point].transpose()[0];
+ boundary_forms[point] /=
+ (face_no == 0 ? -1. : +1.) * boundary_forms[point].norm();
+
+ }
+
+ if (dim==2)
+ {
+ Tensor<1,spacedim> cell_normal;
+ const DerivativeForm<1,spacedim,dim> DX_t =
+ data.contravariant[point].transpose();
+ cross_product(cell_normal,DX_t[0],DX_t[1]);
+ cell_normal /= cell_normal.norm();
+
+ // then compute the face
+ // normal from the face
+ // tangent and the cell
+ // normal:
+ cross_product (boundary_forms[point],
+ data.aux[0][point], cell_normal);
+
+ }
+
+ }
+ }
+
+
+
+ if (update_flags & (update_normal_vectors
+ | update_JxW_values))
+ for (unsigned int i=0;i<boundary_forms.size();++i)
+ {
+ if (update_flags & update_JxW_values)
+ {
+ JxW_values[i] = boundary_forms[i].norm() * weights[i];
+
+ if (subface_no!=deal_II_numbers::invalid_unsigned_int)
+ {
+ const double area_ratio=GeometryInfo<dim>::subface_ratio(
+ cell->subface_case(face_no), subface_no);
+ JxW_values[i] *= area_ratio;
+ }
+ }
+
+ if (update_flags & update_normal_vectors)
+ normal_vectors[i] = boundary_forms[i] / boundary_forms[i].norm();
+ }
+ }
}
}
}
std::vector<Point<spacedim> > &normal_vectors) const
{
compute_fill (cell, n_q_points, data_set, CellSimilarity::none,
- data, quadrature_points);
+ data, quadrature_points);
internal::compute_fill_face (*this,
- cell, face_no, subface_no, n_q_points,
- weights, data,
- JxW_values, boundary_forms, normal_vectors);
+ cell, face_no, subface_no, n_q_points,
+ weights, data,
+ JxW_values, boundary_forms, normal_vectors);
}
void
MappingQ1<dim,spacedim>::
fill_fe_face_values (const typename Triangulation<dim,spacedim>::cell_iterator &cell,
- const unsigned int face_no,
- const Quadrature<dim-1> &q,
- typename Mapping<dim,spacedim>::InternalDataBase &mapping_data,
- std::vector<Point<spacedim> > &quadrature_points,
- std::vector<double> &JxW_values,
- std::vector<Tensor<1,spacedim> > &boundary_forms,
- std::vector<Point<spacedim> > &normal_vectors) const
+ const unsigned int face_no,
+ const Quadrature<dim-1> &q,
+ typename Mapping<dim,spacedim>::InternalDataBase &mapping_data,
+ std::vector<Point<spacedim> > &quadrature_points,
+ std::vector<double> &JxW_values,
+ std::vector<Tensor<1,spacedim> > &boundary_forms,
+ std::vector<Point<spacedim> > &normal_vectors) const
{
- // ensure that the following cast
- // is really correct:
+ // ensure that the following cast
+ // is really correct:
Assert (dynamic_cast<InternalData *>(&mapping_data) != 0,
- ExcInternalError());
+ ExcInternalError());
InternalData &data = static_cast<InternalData&>(mapping_data);
const unsigned int n_q_points = q.size();
compute_fill_face (cell, face_no, deal_II_numbers::invalid_unsigned_int,
- n_q_points,
- DataSetDescriptor::face (face_no,
+ n_q_points,
+ DataSetDescriptor::face (face_no,
cell->face_orientation(face_no),
cell->face_flip(face_no),
cell->face_rotation(face_no),
n_q_points),
- q.get_weights(),
- data,
- quadrature_points,
- JxW_values,
- boundary_forms,
- normal_vectors);
+ q.get_weights(),
+ data,
+ quadrature_points,
+ JxW_values,
+ boundary_forms,
+ normal_vectors);
}
void
MappingQ1<dim,spacedim>::
fill_fe_subface_values (const typename Triangulation<dim,spacedim>::cell_iterator &cell,
- const unsigned int face_no,
- const unsigned int sub_no,
- const Quadrature<dim-1> &q,
- typename Mapping<dim,spacedim>::InternalDataBase &mapping_data,
- std::vector<Point<spacedim> > &quadrature_points,
- std::vector<double> &JxW_values,
- std::vector<Tensor<1,spacedim> > &boundary_forms,
- std::vector<Point<spacedim> > &normal_vectors) const
+ const unsigned int face_no,
+ const unsigned int sub_no,
+ const Quadrature<dim-1> &q,
+ typename Mapping<dim,spacedim>::InternalDataBase &mapping_data,
+ std::vector<Point<spacedim> > &quadrature_points,
+ std::vector<double> &JxW_values,
+ std::vector<Tensor<1,spacedim> > &boundary_forms,
+ std::vector<Point<spacedim> > &normal_vectors) const
{
- // ensure that the following cast
- // is really correct:
+ // ensure that the following cast
+ // is really correct:
Assert (dynamic_cast<InternalData *>(&mapping_data) != 0,
- ExcInternalError());
+ ExcInternalError());
InternalData &data = static_cast<InternalData&>(mapping_data);
const unsigned int n_q_points = q.size();
compute_fill_face (cell, face_no, sub_no,
- n_q_points,
- DataSetDescriptor::subface (face_no, sub_no,
- cell->face_orientation(face_no),
- cell->face_flip(face_no),
- cell->face_rotation(face_no),
- n_q_points,
- cell->subface_case(face_no)),
- q.get_weights(),
- data,
- quadrature_points,
- JxW_values,
- boundary_forms,
- normal_vectors);
+ n_q_points,
+ DataSetDescriptor::subface (face_no, sub_no,
+ cell->face_orientation(face_no),
+ cell->face_flip(face_no),
+ cell->face_rotation(face_no),
+ n_q_points,
+ cell->subface_case(face_no)),
+ q.get_weights(),
+ data,
+ quadrature_points,
+ JxW_values,
+ boundary_forms,
+ normal_vectors);
}
switch (mapping_type)
{
case mapping_contravariant:
- transform_fields(input, output, mapping_data, mapping_type);
- return;
+ transform_fields(input, output, mapping_data, mapping_type);
+ return;
case mapping_piola_gradient:
case mapping_contravariant_gradient:
case mapping_covariant_gradient:
- transform_gradients(input, output, mapping_data, mapping_type);
- return;
+ transform_gradients(input, output, mapping_data, mapping_type);
+ return;
default:
- Assert(false, ExcNotImplemented());
+ Assert(false, ExcNotImplemented());
}
}
{
AssertDimension (input.size(), output.size());
Assert (dynamic_cast<const InternalData *>(&mapping_data) != 0,
- ExcInternalError());
+ ExcInternalError());
const InternalData &data = static_cast<const InternalData&>(mapping_data);
switch (mapping_type)
{
case mapping_contravariant:
{
- Assert (data.update_flags & update_contravariant_transformation,
- typename FEValuesBase<dim>::ExcAccessToUninitializedField());
+ Assert (data.update_flags & update_contravariant_transformation,
+ typename FEValuesBase<dim>::ExcAccessToUninitializedField());
- for (unsigned int i=0; i<output.size(); ++i)
- output[i] = apply_transformation(data.contravariant[i], input[i]);
+ for (unsigned int i=0; i<output.size(); ++i)
+ output[i] = apply_transformation(data.contravariant[i], input[i]);
- return;
+ return;
}
case mapping_piola:
{
- Assert (data.update_flags & update_contravariant_transformation,
- typename FEValuesBase<dim>::ExcAccessToUninitializedField());
- Assert (data.update_flags & update_volume_elements,
- typename FEValuesBase<dim>::ExcAccessToUninitializedField());
- Assert (rank==1, ExcMessage("Only for rank 1"));
- for (unsigned int i=0; i<output.size(); ++i)
- {
- output[i] = apply_transformation(data.contravariant[i], input[i]);
- output[i] /= data.volume_elements[i];
- }
- return;
+ Assert (data.update_flags & update_contravariant_transformation,
+ typename FEValuesBase<dim>::ExcAccessToUninitializedField());
+ Assert (data.update_flags & update_volume_elements,
+ typename FEValuesBase<dim>::ExcAccessToUninitializedField());
+ Assert (rank==1, ExcMessage("Only for rank 1"));
+ for (unsigned int i=0; i<output.size(); ++i)
+ {
+ output[i] = apply_transformation(data.contravariant[i], input[i]);
+ output[i] /= data.volume_elements[i];
+ }
+ return;
}
- //We still allow this operation as in the
- //reference cell Derivatives are Tensor
- //rather than DerivativeForm
+ //We still allow this operation as in the
+ //reference cell Derivatives are Tensor
+ //rather than DerivativeForm
case mapping_covariant:
{
- Assert (data.update_flags & update_contravariant_transformation,
- typename FEValuesBase<dim>::ExcAccessToUninitializedField());
+ Assert (data.update_flags & update_contravariant_transformation,
+ typename FEValuesBase<dim>::ExcAccessToUninitializedField());
- for (unsigned int i=0; i<output.size(); ++i)
- output[i] = apply_transformation(data.covariant[i], input[i]);
+ for (unsigned int i=0; i<output.size(); ++i)
+ output[i] = apply_transformation(data.covariant[i], input[i]);
- return;
+ return;
}
default:
- Assert(false, ExcNotImplemented());
+ Assert(false, ExcNotImplemented());
}
}
{
AssertDimension (input.size(), output.size());
Assert (dynamic_cast<const InternalData *>(&mapping_data) != 0,
- ExcInternalError());
+ ExcInternalError());
const InternalData &data = static_cast<const InternalData&>(mapping_data);
switch (mapping_type)
{
case mapping_contravariant_gradient:
{
- Assert (data.update_flags & update_covariant_transformation,
- typename FEValuesBase<dim>::ExcAccessToUninitializedField());
- Assert (data.update_flags & update_contravariant_transformation,
- typename FEValuesBase<dim>::ExcAccessToUninitializedField());
- Assert (rank==2, ExcMessage("Only for rank 2"));
-
- for (unsigned int i=0; i<output.size(); ++i)
- {
- DerivativeForm<1,spacedim,dim> A =
- apply_transformation(data.contravariant[i], transpose(input[i]) );
- output[i] = apply_transformation(data.covariant[i], A.transpose() );
- }
-
- return;
+ Assert (data.update_flags & update_covariant_transformation,
+ typename FEValuesBase<dim>::ExcAccessToUninitializedField());
+ Assert (data.update_flags & update_contravariant_transformation,
+ typename FEValuesBase<dim>::ExcAccessToUninitializedField());
+ Assert (rank==2, ExcMessage("Only for rank 2"));
+
+ for (unsigned int i=0; i<output.size(); ++i)
+ {
+ DerivativeForm<1,spacedim,dim> A =
+ apply_transformation(data.contravariant[i], transpose(input[i]) );
+ output[i] = apply_transformation(data.covariant[i], A.transpose() );
+ }
+
+ return;
}
case mapping_covariant_gradient:
{
- Assert (data.update_flags & update_covariant_transformation,
- typename FEValuesBase<dim>::ExcAccessToUninitializedField());
- Assert (data.update_flags & update_contravariant_transformation,
- typename FEValuesBase<dim>::ExcAccessToUninitializedField());
- Assert (rank==2, ExcMessage("Only for rank 2"));
+ Assert (data.update_flags & update_covariant_transformation,
+ typename FEValuesBase<dim>::ExcAccessToUninitializedField());
+ Assert (data.update_flags & update_contravariant_transformation,
+ typename FEValuesBase<dim>::ExcAccessToUninitializedField());
+ Assert (rank==2, ExcMessage("Only for rank 2"));
- for (unsigned int i=0; i<output.size(); ++i)
- {
- DerivativeForm<1,spacedim,dim> A =
- apply_transformation(data.covariant[i], transpose(input[i]) );
- output[i] = apply_transformation(data.covariant[i], A.transpose() );
+ for (unsigned int i=0; i<output.size(); ++i)
+ {
+ DerivativeForm<1,spacedim,dim> A =
+ apply_transformation(data.covariant[i], transpose(input[i]) );
+ output[i] = apply_transformation(data.covariant[i], A.transpose() );
- }
+ }
- return;
+ return;
}
case mapping_piola_gradient:
{
- Assert (data.update_flags & update_covariant_transformation,
- typename FEValuesBase<dim>::ExcAccessToUninitializedField());
- Assert (data.update_flags & update_contravariant_transformation,
- typename FEValuesBase<dim>::ExcAccessToUninitializedField());
- Assert (data.update_flags & update_volume_elements,
- typename FEValuesBase<dim>::ExcAccessToUninitializedField());
- Assert (rank==2, ExcMessage("Only for rank 2"));
-
- for (unsigned int i=0; i<output.size(); ++i)
- {
- DerivativeForm<1,spacedim,dim> A =
- apply_transformation(data.covariant[i], input[i] );
- Tensor<2,spacedim> T =
- apply_transformation(data.contravariant[i], A.transpose() );
-
- output[i] = transpose(T);
- output[i] /= data.volume_elements[i];
- }
-
- return;
+ Assert (data.update_flags & update_covariant_transformation,
+ typename FEValuesBase<dim>::ExcAccessToUninitializedField());
+ Assert (data.update_flags & update_contravariant_transformation,
+ typename FEValuesBase<dim>::ExcAccessToUninitializedField());
+ Assert (data.update_flags & update_volume_elements,
+ typename FEValuesBase<dim>::ExcAccessToUninitializedField());
+ Assert (rank==2, ExcMessage("Only for rank 2"));
+
+ for (unsigned int i=0; i<output.size(); ++i)
+ {
+ DerivativeForm<1,spacedim,dim> A =
+ apply_transformation(data.covariant[i], input[i] );
+ Tensor<2,spacedim> T =
+ apply_transformation(data.contravariant[i], A.transpose() );
+
+ output[i] = transpose(T);
+ output[i] /= data.volume_elements[i];
+ }
+
+ return;
}
default:
- Assert(false, ExcNotImplemented());
+ Assert(false, ExcNotImplemented());
}
}
AssertDimension (input.size(), output.size());
Assert (dynamic_cast<const InternalData *>(&mapping_data) != 0,
- ExcInternalError());
+ ExcInternalError());
const InternalData &data = static_cast<const InternalData&>(mapping_data);
switch (mapping_type)
{
case mapping_covariant:
{
- Assert (data.update_flags & update_contravariant_transformation,
- typename FEValuesBase<dim>::ExcAccessToUninitializedField());
+ Assert (data.update_flags & update_contravariant_transformation,
+ typename FEValuesBase<dim>::ExcAccessToUninitializedField());
- for (unsigned int i=0; i<output.size(); ++i)
- output[i] = apply_transformation(data.covariant[i], input[i]);
+ for (unsigned int i=0; i<output.size(); ++i)
+ output[i] = apply_transformation(data.covariant[i], input[i]);
- return;
+ return;
}
default:
- Assert(false, ExcNotImplemented());
+ Assert(false, ExcNotImplemented());
}
}
const typename Triangulation<dim,spacedim>::cell_iterator& cell,
const Point<dim>& p) const
{
- // Use the get_data function to
- // create an InternalData with data
- // vectors of the right size and
- // transformation shape values
- // already computed at point p.
+ // Use the get_data function to
+ // create an InternalData with data
+ // vectors of the right size and
+ // transformation shape values
+ // already computed at point p.
const Quadrature<dim> point_quadrature(p);
std::auto_ptr<InternalData>
mdata (dynamic_cast<InternalData *> (
get_data(update_transformation_values, point_quadrature)));
- // compute the mapping support
- // points
+ // compute the mapping support
+ // points
compute_mapping_support_points(cell, mdata->mapping_support_points);
- // Mapping support points can be
- // bigger than necessary. If this
- // is the case, force them to be
- // Q1.
+ // Mapping support points can be
+ // bigger than necessary. If this
+ // is the case, force them to be
+ // Q1.
if(mdata->mapping_support_points.size() > mdata->shape_values.size())
mdata->mapping_support_points.resize
(GeometryInfo<dim>::vertices_per_cell);
const unsigned int n_mapping_points=data.mapping_support_points.size();
AssertDimension (data.shape_values.size(), n_mapping_points);
- // use now the InternalData to
- // compute the point in real space.
+ // use now the InternalData to
+ // compute the point in real space.
Point<spacedim> p_real;
for (unsigned int i=0; i<data.mapping_support_points.size(); ++i)
p_real += data.mapping_support_points[i] * data.shape(0,i);
- /* For an explanation of the KA and Kb
- arrays see the comments in the declaration of
- transform_real_to_unit_cell_initial_guess */
+ /* For an explanation of the KA and Kb
+ arrays see the comments in the declaration of
+ transform_real_to_unit_cell_initial_guess */
namespace
{
template <int dim>
TransformR2UInitialGuess<1>::
KA[GeometryInfo<1>::vertices_per_cell][1] =
{
- {-1.000000},
- {1.000000}
+ {-1.000000},
+ {1.000000}
};
template <>
Point<dim>
MappingQ1<dim,spacedim>::
transform_real_to_unit_cell_initial_guess (const std::vector<Point<spacedim> > &vertex,
- const Point<spacedim> &p) const
+ const Point<spacedim> &p) const
{
Point<dim> p_unit;
{
- // Find the initial value for the
- // Newton iteration by a normal projection
- // to the least square plane determined by
- // the vertices of the cell
+ // Find the initial value for the
+ // Newton iteration by a normal projection
+ // to the least square plane determined by
+ // the vertices of the cell
std::vector<Point<spacedim> > a;
compute_mapping_support_points (cell,a);
Point<dim> p_unit =
transform_real_to_unit_cell_initial_guess(a,p);
- // if dim==1 there is nothing
- // else to do the initial value is the answer.
+ // if dim==1 there is nothing
+ // else to do the initial value is the answer.
if (dim>1)
{
- // Use the get_data function to
- // create an InternalData with data
- // vectors of the right size and
- // transformation shape values and
- // derivatives already computed at
- // point p_unit.
+ // Use the get_data function to
+ // create an InternalData with data
+ // vectors of the right size and
+ // transformation shape values and
+ // derivatives already computed at
+ // point p_unit.
const Quadrature<dim> point_quadrature(p_unit);
UpdateFlags update_flags = update_transformation_values| update_transformation_gradients;
if (spacedim>dim)
- update_flags |= update_jacobian_grads;
+ update_flags |= update_jacobian_grads;
std::auto_ptr<InternalData>
- mdata(dynamic_cast<InternalData *> (
- MappingQ1<dim,spacedim>::get_data(update_flags, point_quadrature)));
+ mdata(dynamic_cast<InternalData *> (
+ MappingQ1<dim,spacedim>::get_data(update_flags, point_quadrature)));
compute_mapping_support_points (cell, mdata->mapping_support_points);
- // The support points have to be at
- // least as many as there are
- // vertices.
+ // The support points have to be at
+ // least as many as there are
+ // vertices.
Assert(mdata->mapping_support_points.size() >=
- GeometryInfo<dim>::vertices_per_cell,
- ExcInternalError());
- // Ignore non vertex support points.
+ GeometryInfo<dim>::vertices_per_cell,
+ ExcInternalError());
+ // Ignore non vertex support points.
mdata->mapping_support_points.resize(GeometryInfo<dim>::vertices_per_cell);
- // perform the newton iteration.
+ // perform the newton iteration.
transform_real_to_unit_cell_internal(cell, p, *mdata, p_unit);
}
AssertDimension (points.size(), n_shapes);
- // Newton iteration to solve
- // f(x)=p(x)-p=0
- // x_{n+1}=x_n-[f'(x)]^{-1}f(x)
+ // Newton iteration to solve
+ // f(x)=p(x)-p=0
+ // x_{n+1}=x_n-[f'(x)]^{-1}f(x)
- // The start value was set to be the
- // linear approximation to the cell
+ // The start value was set to be the
+ // linear approximation to the cell
- // The shape values and derivatives
- // of the mapping at this point are
- // previously computed.
+ // The shape values and derivatives
+ // of the mapping at this point are
+ // previously computed.
- // For the <2,3> case there is a
- // template specialization.
+ // For the <2,3> case there is a
+ // template specialization.
- // f(x)
+ // f(x)
compute_shapes(std::vector<Point<dim> > (1, p_unit), mdata);
Point<spacedim> p_real(transform_unit_to_real_cell_internal(mdata));
unsigned int loop=0;
while (f.square()>eps*eps && loop++<loop_limit)
{
- // f'(x)
+ // f'(x)
Tensor<2,spacedim> df;
for (unsigned int k=0; k<mdata.n_shape_functions; ++k)
- {
- const Tensor<1,dim> &grad_transform=mdata.derivative(0,k);
- const Point<spacedim> &point=points[k];
+ {
+ const Tensor<1,dim> &grad_transform=mdata.derivative(0,k);
+ const Point<spacedim> &point=points[k];
- for (unsigned int i=0; i<spacedim; ++i)
- for (unsigned int j=0; j<dim; ++j)
- df[i][j]+=point[i]*grad_transform[j];
- }
+ for (unsigned int i=0; i<spacedim; ++i)
+ for (unsigned int j=0; j<dim; ++j)
+ df[i][j]+=point[i]*grad_transform[j];
+ }
- // Solve [f'(x)]d=f(x)
+ // Solve [f'(x)]d=f(x)
Tensor<1,spacedim> d;
Tensor<2,spacedim> df_1;
df_1 = invert(df);
contract (d, df_1, static_cast<const Tensor<1,spacedim>&>(f));
- // update of p_unit. The
- // spacedimth component of
- // transformed point is simply
- // ignored in codimension one
- // case. When this component is
- // not zero, then we are
- // projecting the point to the
- // surface or curve identified
- // by the cell.
+ // update of p_unit. The
+ // spacedimth component of
+ // transformed point is simply
+ // ignored in codimension one
+ // case. When this component is
+ // not zero, then we are
+ // projecting the point to the
+ // surface or curve identified
+ // by the cell.
for(unsigned int i=0;i<dim; ++i)
- p_unit[i] -= d[i];
+ p_unit[i] -= d[i];
- // shape values and derivatives
- // at new p_unit point
+ // shape values and derivatives
+ // at new p_unit point
compute_shapes(std::vector<Point<dim> > (1, p_unit), mdata);
- // f(x)
+ // f(x)
p_real = transform_unit_to_real_cell_internal(mdata);
f = p_real-p;
}
- // Here we check that in the last
- // execution of while the first
- // condition was already wrong,
- // meaning the residual was below
- // eps. Only if the first condition
- // failed, loop will have been
- // increased and tested, and thus
- // havereached the limit.
+ // Here we check that in the last
+ // execution of while the first
+ // condition was already wrong,
+ // meaning the residual was below
+ // eps. Only if the first condition
+ // failed, loop will have been
+ // increased and tested, and thus
+ // havereached the limit.
AssertThrow(loop<loop_limit, ExcTransformationFailed());
}
template<>
void MappingQ1<2,3>::
transform_real_to_unit_cell_internal (const Triangulation<2,3>::cell_iterator &cell,
- const Point<3> &p,
- InternalData &mdata,
- Point<2> &p_unit) const
+ const Point<3> &p,
+ InternalData &mdata,
+ Point<2> &p_unit) const
{
transform_real_to_unit_cell_internal_codim1(cell,p, mdata, p_unit);
}
template<>
void MappingQ1<1,2>::
transform_real_to_unit_cell_internal (const Triangulation<1,2>::cell_iterator &cell,
- const Point<2> &p,
- InternalData &mdata,
- Point<1> &p_unit) const
+ const Point<2> &p,
+ InternalData &mdata,
+ Point<1> &p_unit) const
{
transform_real_to_unit_cell_internal_codim1(cell,p, mdata, p_unit);
}
template<>
void MappingQ1<1,3>::
transform_real_to_unit_cell_internal (const Triangulation<1,3>::cell_iterator &/*cell*/,
- const Point<3> &/*p*/,
- InternalData &/*mdata*/,
- Point<1> &/*p_unit*/) const
+ const Point<3> &/*p*/,
+ InternalData &/*mdata*/,
+ Point<1> &/*p_unit*/) const
{
Assert(false, ExcNotImplemented());
}
Point<dim1> f;
Tensor<2,dim1> df;
- //Evaluate first and second derivatives
+ //Evaluate first and second derivatives
compute_shapes(std::vector<Point<dim1> > (1, p_unit), mdata);
for (unsigned int k=0; k<mdata.n_shape_functions; ++k)
{
const Point<spacedim1> &point_k = points[k];
for (unsigned int j=0; j<dim1; ++j)
- {
- DF[j] += grad_phi_k[j] * point_k;
- for (unsigned int l=0; l<dim1; ++l)
- D2F[j][l] += hessian_k[j][l] * point_k;
- }
+ {
+ DF[j] += grad_phi_k[j] * point_k;
+ for (unsigned int l=0; l<dim1; ++l)
+ D2F[j][l] += hessian_k[j][l] * point_k;
+ }
}
p_minus_F = p;
{
f[j] = DF[j] * p_minus_F;
for (unsigned int l=0; l<dim1; ++l)
- df[j][l] = -DF[j]*DF[l] + D2F[j][l] * p_minus_F;
+ df[j][l] = -DF[j]*DF[l] + D2F[j][l] * p_minus_F;
}
while (f.norm()>eps && loop++<loop_limit)
{
- // Solve [df(x)]d=f(x)
+ // Solve [df(x)]d=f(x)
Tensor<1,dim1> d;
Tensor<2,dim1> df_1;
p_unit -= d;
for (unsigned int j=0; j<dim1; ++j)
- {
- DF[j].clear();
- for (unsigned int l=0; l<dim1; ++l)
- D2F[j][l].clear();
- }
+ {
+ DF[j].clear();
+ for (unsigned int l=0; l<dim1; ++l)
+ D2F[j][l].clear();
+ }
compute_shapes(std::vector<Point<dim1> > (1, p_unit), mdata);
for (unsigned int k=0; k<mdata.n_shape_functions; ++k)
- {
- const Tensor<1,dim1> &grad_phi_k = mdata.derivative(0,k);
- const Tensor<2,dim1> &hessian_k = mdata.second_derivative(0,k);
- const Point<spacedim1> &point_k = points[k];
-
- for (unsigned int j=0; j<dim1; ++j)
- {
- DF[j] += grad_phi_k[j] * point_k;
- for (unsigned int l=0; l<dim1; ++l)
- D2F[j][l] += hessian_k[j][l] * point_k;
- }
- }
+ {
+ const Tensor<1,dim1> &grad_phi_k = mdata.derivative(0,k);
+ const Tensor<2,dim1> &hessian_k = mdata.second_derivative(0,k);
+ const Point<spacedim1> &point_k = points[k];
+
+ for (unsigned int j=0; j<dim1; ++j)
+ {
+ DF[j] += grad_phi_k[j] * point_k;
+ for (unsigned int l=0; l<dim1; ++l)
+ D2F[j][l] += hessian_k[j][l] * point_k;
+ }
+ }
p_minus_F = p;
p_minus_F -= transform_unit_to_real_cell_internal(mdata);
for (unsigned int j=0; j<dim1; ++j)
- {
- f[j] = DF[j] * p_minus_F;
- for (unsigned int l=0; l<dim1; ++l)
- df[j][l] = -DF[j]*DF[l] + D2F[j][l] * p_minus_F;
- }
+ {
+ f[j] = DF[j] * p_minus_F;
+ for (unsigned int l=0; l<dim1; ++l)
+ df[j][l] = -DF[j]*DF[l] + D2F[j][l] * p_minus_F;
+ }
}
- // Here we check that in the last
- // execution of while the first
- // condition was already wrong,
- // meaning the residual was below
- // eps. Only if the first condition
- // failed, loop will have been
- // increased and tested, and thus
- // havereached the limit.
+ // Here we check that in the last
+ // execution of while the first
+ // condition was already wrong,
+ // meaning the residual was below
+ // eps. Only if the first condition
+ // failed, loop will have been
+ // increased and tested, and thus
+ // havereached the limit.
AssertThrow(loop<loop_limit, ExcTransformationFailed());
// $Id$
// Version: $Name$
//
-// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2009, 2010 by the deal.II authors
+// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2009, 2010, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
template <int dim, class EulerVectorType, int spacedim>
MappingQ1Eulerian<dim, EulerVectorType, spacedim>::
MappingQ1Eulerian (const EulerVectorType &euler_transform_vectors,
- const DoFHandler<dim,spacedim> &shiftmap_dof_handler)
+ const DoFHandler<dim,spacedim> &shiftmap_dof_handler)
:
- euler_transform_vectors(&euler_transform_vectors),
- shiftmap_dof_handler(&shiftmap_dof_handler)
+ euler_transform_vectors(&euler_transform_vectors),
+ shiftmap_dof_handler(&shiftmap_dof_handler)
{}
void
MappingQ1Eulerian<dim, EulerVectorType, spacedim>::
compute_mapping_support_points(const typename Triangulation<dim,spacedim>::cell_iterator &cell,
- std::vector<Point<spacedim> > &a) const
+ std::vector<Point<spacedim> > &a) const
{
- // The assertions can not be in the
- // constructor, since this would
- // require to call
- // dof_handler.distribute_dofs(fe)
- // *before* the mapping object is
- // constructed, which is not
- // necessarily what we want.
+ // The assertions can not be in the
+ // constructor, since this would
+ // require to call
+ // dof_handler.distribute_dofs(fe)
+ // *before* the mapping object is
+ // constructed, which is not
+ // necessarily what we want.
//TODO: Only one of these two assertions should be relevant
AssertDimension (spacedim, shiftmap_dof_handler->get_fe().n_dofs_per_vertex());
AssertDimension (shiftmap_dof_handler->n_dofs(), euler_transform_vectors->size());
- // cast the
- // Triangulation<dim>::cell_iterator
- // into a
- // DoFHandler<dim>::cell_iterator
- // which is necessary for access to
- // DoFCellAccessor::get_dof_values()
+ // cast the
+ // Triangulation<dim>::cell_iterator
+ // into a
+ // DoFHandler<dim>::cell_iterator
+ // which is necessary for access to
+ // DoFCellAccessor::get_dof_values()
typename DoFHandler<dim,spacedim>::cell_iterator
dof_cell (const_cast<Triangulation<dim,spacedim> *> (&(cell->get_triangulation())),
- cell->level(),
- cell->index(),
- shiftmap_dof_handler);
+ cell->level(),
+ cell->index(),
+ shiftmap_dof_handler);
- // We require the cell to be active
- // since we can only then get nodal
- // values for the shifts
+ // We require the cell to be active
+ // since we can only then get nodal
+ // values for the shifts
Assert (dof_cell->active() == true, ExcInactiveCell());
- // for Q1 elements, the number of
- // support points should equal the
- // number of vertices
+ // for Q1 elements, the number of
+ // support points should equal the
+ // number of vertices
a.resize(GeometryInfo<dim>::vertices_per_cell);
- // now get the values of the shift
- // vectors at the vertices
+ // now get the values of the shift
+ // vectors at the vertices
Vector<double> mapping_values (shiftmap_dof_handler->get_fe().dofs_per_cell);
dof_cell->get_dof_values (*euler_transform_vectors, mapping_values);
{
Point<spacedim> shift_vector;
- // pick out the value of the
- // shift vector at the present
- // vertex. since vertex dofs
- // are always numbered first,
- // we can access them easily
+ // pick out the value of the
+ // shift vector at the present
+ // vertex. since vertex dofs
+ // are always numbered first,
+ // we can access them easily
for (unsigned int j=0; j<spacedim; ++j)
- shift_vector[j] = mapping_values(i*spacedim+j);
+ shift_vector[j] = mapping_values(i*spacedim+j);
- // compute new support point by
- // old (reference) value and
- // added shift
+ // compute new support point by
+ // old (reference) value and
+ // added shift
a[i] = cell->vertex(i) + shift_vector;
}
}
std::vector<Point<spacedim> > &normal_vectors,
CellSimilarity::Similarity &cell_similarity) const
{
- // disable any previously detected
- // similarity and then enter the
- // respective function of the base class.
+ // disable any previously detected
+ // similarity and then enter the
+ // respective function of the base class.
cell_similarity = CellSimilarity::invalid_next_cell;
MappingQ1<dim,spacedim>::fill_fe_values (cell, q, mapping_data,
- quadrature_points, JxW_values, jacobians,
- jacobian_grads, inverse_jacobians,
- normal_vectors, cell_similarity);
+ quadrature_points, JxW_values, jacobians,
+ jacobian_grads, inverse_jacobians,
+ normal_vectors, cell_similarity);
}
// $Id$
// Version: $Name$
//
-// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2008, 2009, 2010 by the deal.II authors
+// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2008, 2009, 2010, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
template <int dim, class EulerVectorType, int spacedim>
MappingQEulerian<dim, EulerVectorType, spacedim>::
MappingQEulerian (const unsigned int degree,
- const EulerVectorType &euler_vector,
- const DoFHandler<dim,spacedim> &euler_dof_handler)
- :
- MappingQ<dim,spacedim>(degree, true),
- euler_vector(&euler_vector),
- euler_dof_handler(&euler_dof_handler),
- support_quadrature(degree),
- fe_values(euler_dof_handler.get_fe(),
- support_quadrature,
- update_values | update_q_points)
+ const EulerVectorType &euler_vector,
+ const DoFHandler<dim,spacedim> &euler_dof_handler)
+ :
+ MappingQ<dim,spacedim>(degree, true),
+ euler_vector(&euler_vector),
+ euler_dof_handler(&euler_dof_handler),
+ support_quadrature(degree),
+ fe_values(euler_dof_handler.get_fe(),
+ support_quadrature,
+ update_values | update_q_points)
{ }
MappingQEulerian<dim, EulerVectorType, spacedim>::clone () const
{
return new MappingQEulerian<dim,EulerVectorType,spacedim>(this->get_degree(),
- *euler_vector,
- *euler_dof_handler);
+ *euler_vector,
+ *euler_dof_handler);
}
MappingQEulerian<dim,EulerVectorType,spacedim>::
SupportQuadrature::
SupportQuadrature (const unsigned int map_degree)
- :
- Quadrature<dim>(Utilities::fixed_power<dim>(map_degree+1))
+ :
+ Quadrature<dim>(Utilities::fixed_power<dim>(map_degree+1))
{
- // first we determine the support points
- // on the unit cell in lexicographic order.
- // for this purpose we can use an interated
- // trapezoidal quadrature rule.
+ // first we determine the support points
+ // on the unit cell in lexicographic order.
+ // for this purpose we can use an interated
+ // trapezoidal quadrature rule.
const QTrapez<1> q1d;
const QIterated<dim> q_iterated(q1d,map_degree);
const unsigned int n_q_points = q_iterated.size();
- // we then need to define a renumbering
- // vector that allows us to go from a
- // lexicographic numbering scheme to a hierarchic
- // one. this fragment is taking almost verbatim
- // from the MappingQ class.
+ // we then need to define a renumbering
+ // vector that allows us to go from a
+ // lexicographic numbering scheme to a hierarchic
+ // one. this fragment is taking almost verbatim
+ // from the MappingQ class.
std::vector<unsigned int> renumber(n_q_points);
std::vector<unsigned int> dpo(dim+1, 1U);
FETools::lexicographic_to_hierarchic_numbering (
FiniteElementData<dim> (dpo, 1, map_degree), renumber);
- // finally we assign the quadrature points in the
- // required order.
+ // finally we assign the quadrature points in the
+ // required order.
for(unsigned int q=0; q<n_q_points; ++q)
this->quadrature_points[renumber[q]] = q_iterated.point(q);
std::vector<Point<spacedim> > &a) const
{
- // first, basic assertion
- // with respect to vector size,
+ // first, basic assertion
+ // with respect to vector size,
const unsigned int n_dofs = euler_dof_handler->n_dofs();
const unsigned int vector_size = euler_vector->size();
AssertDimension(vector_size,n_dofs);
- // we then transform our tria iterator
- // into a dof iterator so we can
- // access data not associated with
- // triangulations
+ // we then transform our tria iterator
+ // into a dof iterator so we can
+ // access data not associated with
+ // triangulations
typename DoFHandler<dim,spacedim>::cell_iterator dof_cell
(const_cast<Triangulation<dim,spacedim> *> (&(cell->get_triangulation())),
Assert (dof_cell->active() == true, ExcInactiveCell());
- // our quadrature rule is chosen
- // so that each quadrature point
- // corresponds to a support point
- // in the undeformed configuration.
- // we can then query the given
- // displacement field at these points
- // to determine the shift vector that
- // maps the support points to the
- // deformed configuration.
-
- // we assume that the given field contains
- // dim displacement components, but
- // that there may be other solution
- // components as well (e.g. pressures).
- // this class therefore assumes that the
- // first dim components represent the
- // actual shift vector we need, and simply
- // ignores any components after that.
- // this implies that the user should order
- // components appropriately, or create a
- // separate dof handler for the displacements.
+ // our quadrature rule is chosen
+ // so that each quadrature point
+ // corresponds to a support point
+ // in the undeformed configuration.
+ // we can then query the given
+ // displacement field at these points
+ // to determine the shift vector that
+ // maps the support points to the
+ // deformed configuration.
+
+ // we assume that the given field contains
+ // dim displacement components, but
+ // that there may be other solution
+ // components as well (e.g. pressures).
+ // this class therefore assumes that the
+ // first dim components represent the
+ // actual shift vector we need, and simply
+ // ignores any components after that.
+ // this implies that the user should order
+ // components appropriately, or create a
+ // separate dof handler for the displacements.
const unsigned int n_support_pts = support_quadrature.size();
const unsigned int n_components = euler_dof_handler->get_fe().n_components();
std::vector<Vector<double> > shift_vector(n_support_pts,Vector<double>(n_components));
- // fill shift vector for each
- // support point using an fe_values
- // object. make sure that the
- // fe_values variable isn't used
- // simulatenously from different
- // threads
+ // fill shift vector for each
+ // support point using an fe_values
+ // object. make sure that the
+ // fe_values variable isn't used
+ // simulatenously from different
+ // threads
Threads::ThreadMutex::ScopedLock lock(fe_values_mutex);
fe_values.reinit(dof_cell);
fe_values.get_function_values(*euler_vector, shift_vector);
- // and finally compute the positions of the
- // support points in the deformed
- // configuration.
+ // and finally compute the positions of the
+ // support points in the deformed
+ // configuration.
a.resize(n_support_pts);
for(unsigned int q=0; q<n_support_pts; ++q)
{
a[q] = fe_values.quadrature_point(q);
for(unsigned int d=0; d<spacedim; ++d)
- a[q](d) += shift_vector[q](d);
+ a[q](d) += shift_vector[q](d);
}
}
std::vector<Point<spacedim> > &normal_vectors,
CellSimilarity::Similarity &cell_similarity) const
{
- // disable any previously detected
- // similarity and hand on to the respective
- // function of the base class.
+ // disable any previously detected
+ // similarity and hand on to the respective
+ // function of the base class.
cell_similarity = CellSimilarity::invalid_next_cell;
MappingQ<dim,spacedim>::fill_fe_values (cell, q, mapping_data,
- quadrature_points, JxW_values, jacobians,
- jacobian_grads, inverse_jacobians,
- normal_vectors, cell_similarity);
+ quadrature_points, JxW_values, jacobians,
+ jacobian_grads, inverse_jacobians,
+ normal_vectors, cell_similarity);
}
namespace
{
- // Corner points of the cube [-1,1]^3
+ // Corner points of the cube [-1,1]^3
const Point<3> hexahedron[8] =
{
- Point<3>(-1,-1,-1),
- Point<3>(+1,-1,-1),
- Point<3>(-1,+1,-1),
- Point<3>(+1,+1,-1),
- Point<3>(-1,-1,+1),
- Point<3>(+1,-1,+1),
- Point<3>(-1,+1,+1),
- Point<3>(+1,+1,+1)
+ Point<3>(-1,-1,-1),
+ Point<3>(+1,-1,-1),
+ Point<3>(-1,+1,-1),
+ Point<3>(+1,+1,-1),
+ Point<3>(-1,-1,+1),
+ Point<3>(+1,-1,+1),
+ Point<3>(-1,+1,+1),
+ Point<3>(+1,+1,+1)
};
- // Octahedron inscribed in the cube
- // [-1,1]^3
+ // Octahedron inscribed in the cube
+ // [-1,1]^3
const Point<3> octahedron[6] =
{
- Point<3>(-1, 0, 0),
- Point<3>( 1, 0, 0),
- Point<3>( 0,-1, 0),
- Point<3>( 0, 1, 0),
- Point<3>( 0, 0,-1),
- Point<3>( 0, 0, 1)
+ Point<3>(-1, 0, 0),
+ Point<3>( 1, 0, 0),
+ Point<3>( 0,-1, 0),
+ Point<3>( 0, 1, 0),
+ Point<3>( 0, 0,-1),
+ Point<3>( 0, 0, 1)
};
}
template <int dim, int spacedim>
void
GridGenerator::hyper_rectangle (Triangulation<dim,spacedim> &tria,
- const Point<spacedim> &p_1,
- const Point<spacedim> &p_2,
- const bool colorize)
+ const Point<spacedim> &p_1,
+ const Point<spacedim> &p_2,
+ const bool colorize)
{
- // First, normalize input such that
- // p1 is lower in all coordinate directions.
+ // First, normalize input such that
+ // p1 is lower in all coordinate directions.
Point<spacedim> p1(p_1);
Point<spacedim> p2(p_2);
switch (dim)
{
case 1:
- vertices[0] = p1;
- vertices[1] = p2;
- break;
+ vertices[0] = p1;
+ vertices[1] = p2;
+ break;
case 2:
- vertices[0] = vertices[1] = p1;
- vertices[2] = vertices[3] = p2;
+ vertices[0] = vertices[1] = p1;
+ vertices[2] = vertices[3] = p2;
- vertices[1](0) = p2(0);
- vertices[2](0) = p1(0);
- break;
+ vertices[1](0) = p2(0);
+ vertices[2](0) = p1(0);
+ break;
case 3:
- vertices[0] = vertices[1] = vertices[2] = vertices[3] = p1;
- vertices[4] = vertices[5] = vertices[6] = vertices[7] = p2;
+ vertices[0] = vertices[1] = vertices[2] = vertices[3] = p1;
+ vertices[4] = vertices[5] = vertices[6] = vertices[7] = p2;
- vertices[1](0) = p2(0);
- vertices[2](1) = p2(1);
- vertices[3](0) = p2(0);
- vertices[3](1) = p2(1);
+ vertices[1](0) = p2(0);
+ vertices[2](1) = p2(1);
+ vertices[3](0) = p2(0);
+ vertices[3](1) = p2(1);
- vertices[4](0) = p1(0);
- vertices[4](1) = p1(1);
- vertices[5](1) = p1(1);
- vertices[6](0) = p1(0);
+ vertices[4](0) = p1(0);
+ vertices[4](1) = p1(1);
+ vertices[5](1) = p1(1);
+ vertices[6](0) = p1(0);
- break;
+ break;
default:
- Assert (false, ExcNotImplemented ());
+ Assert (false, ExcNotImplemented ());
}
- // Prepare cell data
+ // Prepare cell data
std::vector<CellData<dim> > cells (1);
for (unsigned int i=0;i<GeometryInfo<dim>::vertices_per_cell;++i)
cells[0].vertices[i] = i;
tria.create_triangulation (vertices, cells, SubCellData());
- // Assign boundary indicators
+ // Assign boundary indicators
if (colorize)
colorize_hyper_rectangle (tria);
}
void
GridGenerator::colorize_hyper_rectangle (Triangulation<dim,spacedim> &tria)
{
- // there is nothing to do in 1d
+ // there is nothing to do in 1d
if (dim > 1)
{
- // there is only one cell, so
- // simple task
+ // there is only one cell, so
+ // simple task
const typename Triangulation<dim,spacedim>::cell_iterator
- cell = tria.begin();
+ cell = tria.begin();
for (unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell; ++f)
- cell->face(f)->set_boundary_indicator (f);
+ cell->face(f)->set_boundary_indicator (f);
}
}
template <int dim, int spacedim>
void GridGenerator::hyper_cube (Triangulation<dim,spacedim> &tria,
- const double left,
- const double right)
+ const double left,
+ const double right)
{
Assert (left < right,
- ExcMessage ("Invalid left-to-right bounds of hypercube"));
+ ExcMessage ("Invalid left-to-right bounds of hypercube"));
Point<spacedim> p1;
Point<spacedim> p2;
for (unsigned int i=0; i<n_cells; ++i)
for (unsigned int j=0; j<4; ++j)
{
- vertices[4*i+j][0]=R*std::cos(i*alpha_step)+r*std::cos(i*beta_step+j*numbers::PI/2.0)*std::cos(i*alpha_step);
- vertices[4*i+j][1]=R*std::sin(i*alpha_step)+r*std::cos(i*beta_step+j*numbers::PI/2.0)*std::sin(i*alpha_step);
- vertices[4*i+j][2]=r*std::sin(i*beta_step+j*numbers::PI/2.0);
+ vertices[4*i+j][0]=R*std::cos(i*alpha_step)+r*std::cos(i*beta_step+j*numbers::PI/2.0)*std::cos(i*alpha_step);
+ vertices[4*i+j][1]=R*std::sin(i*alpha_step)+r*std::cos(i*beta_step+j*numbers::PI/2.0)*std::sin(i*alpha_step);
+ vertices[4*i+j][2]=r*std::sin(i*beta_step+j*numbers::PI/2.0);
}
unsigned int offset=0;
for (unsigned int i=0; i<n_cells; ++i)
{
for (unsigned int j=0; j<2; ++j)
- {
- cells[i].vertices[0+4*j]=offset+0+4*j;
- cells[i].vertices[1+4*j]=offset+3+4*j;
- cells[i].vertices[2+4*j]=offset+2+4*j;
- cells[i].vertices[3+4*j]=offset+1+4*j;
- }
+ {
+ cells[i].vertices[0+4*j]=offset+0+4*j;
+ cells[i].vertices[1+4*j]=offset+3+4*j;
+ cells[i].vertices[2+4*j]=offset+2+4*j;
+ cells[i].vertices[3+4*j]=offset+1+4*j;
+ }
offset+=4;
cells[i].material_id=0;
}
- // now correct the last four vertices
+ // now correct the last four vertices
cells[n_cells-1].vertices[4]=(0+n_rotations)%4;
cells[n_cells-1].vertices[5]=(3+n_rotations)%4;
cells[n_cells-1].vertices[6]=(2+n_rotations)%4;
void
GridGenerator::torus (Triangulation<2,3>& tria,
- const double R,
- const double r)
+ const double R,
+ const double r)
{
Assert (R>r, ExcMessage("Outer radius must be greater than inner radius."));
vertices[15]=Point<spacedim>(0,r,-R);
std::vector<CellData<dim> > cells (16);
- //Right Hand Orientation
+ //Right Hand Orientation
cells[0].vertices[0] = 0;
cells[0].vertices[1] = 4;
cells[0].vertices[2] = 7;
cells[15].vertices[3] = 14;
cells[15].material_id = 0;
- // Must call this to be able to create a
- // correct triangulation in dealii, read
- // GridReordering<> doc
+ // Must call this to be able to create a
+ // correct triangulation in dealii, read
+ // GridReordering<> doc
GridReordering<dim,spacedim>::reorder_cells (cells);
tria.create_triangulation_compatibility (vertices, cells, SubCellData());
}
vertices[1] = corners[0];
vertices[2] = corners[1];
vertices[3] = vertices[1] + vertices[2];
- // Prepare cell data
+ // Prepare cell data
std::vector<CellData<2> > cells (1);
for (unsigned int i=0;i<GeometryInfo<2>::vertices_per_cell;++i)
cells[0].vertices[i] = i;
tria.create_triangulation (vertices, cells, SubCellData());
- // Assign boundary indicators
+ // Assign boundary indicators
if (colorize)
colorize_hyper_rectangle (tria);
}
{
Assert (repetitions >= 1, ExcInvalidRepetitions(repetitions));
Assert (left < right,
- ExcMessage ("Invalid left-to-right bounds of hypercube"));
+ ExcMessage ("Invalid left-to-right bounds of hypercube"));
// first generate the necessary
// points
}
// next create the cells
- // Prepare cell data
+ // Prepare cell data
std::vector<CellData<dim> > cells;
- // Define these as abbreviations
- // for the step sizes below. The
- // number of points in a single
- // direction is repetitions+1
+ // Define these as abbreviations
+ // for the step sizes below. The
+ // number of points in a single
+ // direction is repetitions+1
const unsigned int dy = repetitions+1;
const unsigned int dz = dy*dy;
switch (dim)
{
case 1:
- cells.resize (repetitions);
- for (unsigned int x=0; x<repetitions; ++x)
- {
- cells[x].vertices[0] = x;
- cells[x].vertices[1] = x+1;
- cells[x].material_id = 0;
- }
- break;
+ cells.resize (repetitions);
+ for (unsigned int x=0; x<repetitions; ++x)
+ {
+ cells[x].vertices[0] = x;
+ cells[x].vertices[1] = x+1;
+ cells[x].material_id = 0;
+ }
+ break;
case 2:
- cells.resize (repetitions*repetitions);
- for (unsigned int y=0; y<repetitions; ++y)
- for (unsigned int x=0; x<repetitions; ++x)
- {
- const unsigned int c = x +y*repetitions;
- cells[c].vertices[0] = x +y*dy;
- cells[c].vertices[1] = x+1+y*dy;
- cells[c].vertices[2] = x +(y+1)*dy;
- cells[c].vertices[3] = x+1+(y+1)*dy;
- cells[c].material_id = 0;
- }
- break;
+ cells.resize (repetitions*repetitions);
+ for (unsigned int y=0; y<repetitions; ++y)
+ for (unsigned int x=0; x<repetitions; ++x)
+ {
+ const unsigned int c = x +y*repetitions;
+ cells[c].vertices[0] = x +y*dy;
+ cells[c].vertices[1] = x+1+y*dy;
+ cells[c].vertices[2] = x +(y+1)*dy;
+ cells[c].vertices[3] = x+1+(y+1)*dy;
+ cells[c].material_id = 0;
+ }
+ break;
case 3:
- cells.resize (repetitions*repetitions*repetitions);
- for (unsigned int z=0; z<repetitions; ++z)
- for (unsigned int y=0; y<repetitions; ++y)
- for (unsigned int x=0; x<repetitions; ++x)
- {
- const unsigned int c = x+y*repetitions
- +z*repetitions*repetitions;
- cells[c].vertices[0] = x +y*dy +z*dz;
- cells[c].vertices[1] = x+1+y*dy +z*dz;
- cells[c].vertices[2] = x +(y+1)*dy+z*dz;
- cells[c].vertices[3] = x+1+(y+1)*dy+z*dz;
- cells[c].vertices[4] = x +y*dy +(z+1)*dz;
- cells[c].vertices[5] = x+1+y*dy +(z+1)*dz;
- cells[c].vertices[6] = x +(y+1)*dy+(z+1)*dz;
- cells[c].vertices[7] = x+1+(y+1)*dy+(z+1)*dz;
- cells[c].material_id = 0;
- }
- break;
+ cells.resize (repetitions*repetitions*repetitions);
+ for (unsigned int z=0; z<repetitions; ++z)
+ for (unsigned int y=0; y<repetitions; ++y)
+ for (unsigned int x=0; x<repetitions; ++x)
+ {
+ const unsigned int c = x+y*repetitions
+ +z*repetitions*repetitions;
+ cells[c].vertices[0] = x +y*dy +z*dz;
+ cells[c].vertices[1] = x+1+y*dy +z*dz;
+ cells[c].vertices[2] = x +(y+1)*dy+z*dz;
+ cells[c].vertices[3] = x+1+(y+1)*dy+z*dz;
+ cells[c].vertices[4] = x +y*dy +(z+1)*dz;
+ cells[c].vertices[5] = x+1+y*dy +(z+1)*dz;
+ cells[c].vertices[6] = x +(y+1)*dy+(z+1)*dz;
+ cells[c].vertices[7] = x+1+(y+1)*dy+(z+1)*dz;
+ cells[c].material_id = 0;
+ }
+ break;
default:
// should be trivial to
const Point<dim> &p_2,
const bool colorize)
{
- // contributed by Joerg R. Weimar
- // (j.weimar@jweimar.de) 2003
+ // contributed by Joerg R. Weimar
+ // (j.weimar@jweimar.de) 2003
Assert(repetitions.size() == dim,
- ExcInvalidRepetitionsDimension(dim));
- // First, normalize input such that
- // p1 is lower in all coordinate
- // directions.
+ ExcInvalidRepetitionsDimension(dim));
+ // First, normalize input such that
+ // p1 is lower in all coordinate
+ // directions.
Point<dim> p1(p_1);
Point<dim> p2(p_2);
if (p1(i) > p2(i))
std::swap (p1(i), p2(i));
- // then check that all repetitions
- // are >= 1, and calculate deltas
- // convert repetitions from double
- // to int by taking the ceiling.
+ // then check that all repetitions
+ // are >= 1, and calculate deltas
+ // convert repetitions from double
+ // to int by taking the ceiling.
Point<dim> delta;
for (unsigned int i=0; i<dim; ++i)
}
// next create the cells
- // Prepare cell data
+ // Prepare cell data
std::vector<CellData<dim> > cells;
switch (dim)
{
if (colorize)
{
- // to colorize, run through all
- // faces of all cells and set
- // boundary indicator to the
- // correct value if it was 0.
-
- // use a large epsilon to
- // compare numbers to avoid
- // roundoff problems.
+ // to colorize, run through all
+ // faces of all cells and set
+ // boundary indicator to the
+ // correct value if it was 0.
+
+ // use a large epsilon to
+ // compare numbers to avoid
+ // roundoff problems.
const double epsilon
= 0.01 * *std::min_element (&delta[0], &delta[0]+dim);
Assert (epsilon > 0,
- ExcMessage ("The distance between corner points must be positive."))
+ ExcMessage ("The distance between corner points must be positive."))
// actual code is external since
// 1-D is different from 2/3D.
const Point<dim> &p_2,
const bool colorize)
{
- // contributed by Joerg R. Weimar
- // (j.weimar@jweimar.de) 2003
- // modified by Yaqi Wang 2006
+ // contributed by Joerg R. Weimar
+ // (j.weimar@jweimar.de) 2003
+ // modified by Yaqi Wang 2006
Assert(step_sz.size() == dim,
- ExcInvalidRepetitionsDimension(dim));
+ ExcInvalidRepetitionsDimension(dim));
- // First, normalize input such that
- // p1 is lower in all coordinate
- // directions.
+ // First, normalize input such that
+ // p1 is lower in all coordinate
+ // directions.
// and check the consistency of
// step sizes, i.e. that they all
for (unsigned int i=0;i<dim;++i)
{
if (p1(i) > p2(i))
- {
- std::swap (p1(i), p2(i));
- std::reverse (step_sizes[i].begin(), step_sizes[i].end());
- }
+ {
+ std::swap (p1(i), p2(i));
+ std::reverse (step_sizes[i].begin(), step_sizes[i].end());
+ }
double x = 0;
for (unsigned int j=0; j<step_sizes.at(i).size(); j++)
- x += step_sizes[i][j];
+ x += step_sizes[i][j];
Assert(std::fabs(x - (p2(i)-p1(i))) <= 1e-12*std::fabs(x),
- ExcInvalidRepetitions (i) );
+ ExcInvalidRepetitions (i) );
}
{
case 1:
{
- double x=0;
- for (unsigned int i=0; ; ++i)
- {
- points.push_back (Point<dim> (p1[0]+x));
-
- // form partial sums. in
- // the last run through
- // avoid accessing
- // non-existent values
- // and exit early instead
- if (i == step_sizes[0].size())
- break;
-
- x += step_sizes[0][i];
- }
- break;
+ double x=0;
+ for (unsigned int i=0; ; ++i)
+ {
+ points.push_back (Point<dim> (p1[0]+x));
+
+ // form partial sums. in
+ // the last run through
+ // avoid accessing
+ // non-existent values
+ // and exit early instead
+ if (i == step_sizes[0].size())
+ break;
+
+ x += step_sizes[0][i];
+ }
+ break;
}
case 2:
{
- double y=0;
- for (unsigned int j=0; ; ++j)
- {
- double x=0;
- for (unsigned int i=0; ; ++i)
- {
- points.push_back (Point<dim> (p1[0]+x,
- p1[1]+y));
- if (i == step_sizes[0].size())
- break;
-
- x += step_sizes[0][i];
- }
-
- if (j == step_sizes[1].size())
- break;
-
- y += step_sizes[1][j];
- }
- break;
+ double y=0;
+ for (unsigned int j=0; ; ++j)
+ {
+ double x=0;
+ for (unsigned int i=0; ; ++i)
+ {
+ points.push_back (Point<dim> (p1[0]+x,
+ p1[1]+y));
+ if (i == step_sizes[0].size())
+ break;
+
+ x += step_sizes[0][i];
+ }
+
+ if (j == step_sizes[1].size())
+ break;
+
+ y += step_sizes[1][j];
+ }
+ break;
}
case 3:
{
- double z=0;
- for (unsigned int k=0; ; ++k)
- {
- double y=0;
- for (unsigned int j=0; ; ++j)
- {
- double x=0;
- for (unsigned int i=0; ; ++i)
- {
- points.push_back (Point<dim> (p1[0]+x,
- p1[1]+y,
- p1[2]+z));
- if (i == step_sizes[0].size())
- break;
-
- x += step_sizes[0][i];
- }
-
- if (j == step_sizes[1].size())
- break;
-
- y += step_sizes[1][j];
- }
-
- if (k == step_sizes[2].size())
- break;
-
- z += step_sizes[2][k];
- }
- break;
+ double z=0;
+ for (unsigned int k=0; ; ++k)
+ {
+ double y=0;
+ for (unsigned int j=0; ; ++j)
+ {
+ double x=0;
+ for (unsigned int i=0; ; ++i)
+ {
+ points.push_back (Point<dim> (p1[0]+x,
+ p1[1]+y,
+ p1[2]+z));
+ if (i == step_sizes[0].size())
+ break;
+
+ x += step_sizes[0][i];
+ }
+
+ if (j == step_sizes[1].size())
+ break;
+
+ y += step_sizes[1][j];
+ }
+
+ if (k == step_sizes[2].size())
+ break;
+
+ z += step_sizes[2][k];
+ }
+ break;
}
default:
}
// next create the cells
- // Prepare cell data
+ // Prepare cell data
std::vector<CellData<dim> > cells;
switch (dim)
{
if (colorize)
{
- // to colorize, run through all
- // faces of all cells and set
- // boundary indicator to the
- // correct value if it was 0.
-
- // use a large epsilon to
- // compare numbers to avoid
- // roundoff problems.
+ // to colorize, run through all
+ // faces of all cells and set
+ // boundary indicator to the
+ // correct value if it was 0.
+
+ // use a large epsilon to
+ // compare numbers to avoid
+ // roundoff problems.
double min_size = *std::min_element (step_sizes[0].begin(),
- step_sizes[0].end());
+ step_sizes[0].end());
for (unsigned int i=1; i<dim; ++i)
- min_size = std::min (min_size,
- *std::min_element (step_sizes[i].begin(),
- step_sizes[i].end()));
+ min_size = std::min (min_size,
+ *std::min_element (step_sizes[i].begin(),
+ step_sizes[i].end()));
const double epsilon = 0.01 * min_size;
// actual code is external since
const Table<1,types::material_id_t>& material_id,
const bool colorize)
{
- // contributed by Yaqi Wang 2006
+ // contributed by Yaqi Wang 2006
Assert(spacing.size() == 1,
- ExcInvalidRepetitionsDimension(1));
+ ExcInvalidRepetitionsDimension(1));
const unsigned int n_cells = material_id.size(0);
Assert(spacing[0].size() == n_cells,
- ExcInvalidRepetitionsDimension(1));
+ ExcInvalidRepetitionsDimension(1));
double delta = std::numeric_limits<double>::max();
for (unsigned int i=0; i<n_cells; i++) {
for (unsigned int x=0; x<n_cells; ++x)
if (material_id[x] != types::invalid_material_id)
{
- cells[id].vertices[0] = x;
- cells[id].vertices[1] = x+1;
- cells[id].material_id = material_id[x];
- id++;
+ cells[id].vertices[0] = x;
+ cells[id].vertices[1] = x+1;
+ cells[id].material_id = material_id[x];
+ id++;
}
// create triangulation
SubCellData t;
const Table<2,types::material_id_t>& material_id,
const bool colorize)
{
- // contributed by Yaqi Wang 2006
+ // contributed by Yaqi Wang 2006
Assert(spacing.size() == 2,
- ExcInvalidRepetitionsDimension(2));
+ ExcInvalidRepetitionsDimension(2));
std::vector<unsigned int> repetitions(2);
unsigned int n_cells = 1;
repetitions[i] = spacing[i].size();
n_cells *= repetitions[i];
for (unsigned int j=0; j<repetitions[i]; j++)
- {
- Assert (spacing[i][j] >= 0, ExcInvalidRepetitions(-1));
- delta = std::min (delta, spacing[i][j]);
- }
+ {
+ Assert (spacing[i][j] >= 0, ExcInvalidRepetitions(-1));
+ delta = std::min (delta, spacing[i][j]);
+ }
Assert(material_id.size(i) == repetitions[i],
- ExcInvalidRepetitionsDimension(i));
+ ExcInvalidRepetitionsDimension(i));
}
// generate the necessary points
{
double ax = p[0];
for (unsigned int x=0; x<=repetitions[0]; ++x)
- {
- points.push_back (Point<2> (ax,ay));
- if (x<repetitions[0])
- ax += spacing[0][x];
- }
+ {
+ points.push_back (Point<2> (ax,ay));
+ if (x<repetitions[0])
+ ax += spacing[0][x];
+ }
if (y<repetitions[1])
- ay += spacing[1][y];
+ ay += spacing[1][y];
}
// create the cells
for (unsigned int i=0; i<material_id.size(0); i++)
for (unsigned int j=0; j<material_id.size(1); j++)
if (material_id[i][j] != types::invalid_material_id)
- n_val_cells++;
+ n_val_cells++;
std::vector<CellData<2> > cells(n_val_cells);
unsigned int id = 0;
for (unsigned int y=0; y<repetitions[1]; ++y)
for (unsigned int x=0; x<repetitions[0]; ++x)
if (material_id[x][y]!=types::invalid_material_id)
- {
- cells[id].vertices[0] = y*(repetitions[0]+1)+x;
- cells[id].vertices[1] = y*(repetitions[0]+1)+x+1;
- cells[id].vertices[2] = (y+1)*(repetitions[0]+1)+x;
- cells[id].vertices[3] = (y+1)*(repetitions[0]+1)+x+1;
- cells[id].material_id = material_id[x][y];
- id++;
- }
+ {
+ cells[id].vertices[0] = y*(repetitions[0]+1)+x;
+ cells[id].vertices[1] = y*(repetitions[0]+1)+x+1;
+ cells[id].vertices[2] = (y+1)*(repetitions[0]+1)+x;
+ cells[id].vertices[3] = (y+1)*(repetitions[0]+1)+x+1;
+ cells[id].material_id = material_id[x][y];
+ id++;
+ }
// create triangulation
SubCellData t;
{
double eps = 0.01 * delta;
Triangulation<2>::cell_iterator cell = tria.begin_raw(),
- endc = tria.end();
+ endc = tria.end();
for (; cell !=endc; ++cell)
- {
- Point<2> cell_center = cell->center();
- for(unsigned int f=0; f<GeometryInfo<2>::faces_per_cell; ++f)
- if (cell->face(f)->boundary_indicator() == 0)
- {
- Point<2> face_center = cell->face(f)->center();
- for (unsigned int i=0; i<2; ++i)
- {
- if (face_center[i]<cell_center[i]-eps)
- cell->face(f)->set_boundary_indicator(i*2);
- if (face_center[i]>cell_center[i]+eps)
- cell->face(f)->set_boundary_indicator(i*2+1);
- }
- }
- }
+ {
+ Point<2> cell_center = cell->center();
+ for(unsigned int f=0; f<GeometryInfo<2>::faces_per_cell; ++f)
+ if (cell->face(f)->boundary_indicator() == 0)
+ {
+ Point<2> face_center = cell->face(f)->center();
+ for (unsigned int i=0; i<2; ++i)
+ {
+ if (face_center[i]<cell_center[i]-eps)
+ cell->face(f)->set_boundary_indicator(i*2);
+ if (face_center[i]>cell_center[i]+eps)
+ cell->face(f)->set_boundary_indicator(i*2+1);
+ }
+ }
+ }
}
}
const Table<3,types::material_id_t>& material_id,
const bool colorize)
{
- // contributed by Yaqi Wang 2006
+ // contributed by Yaqi Wang 2006
const unsigned int dim = 3;
Assert(spacing.size() == dim,
- ExcInvalidRepetitionsDimension(dim));
+ ExcInvalidRepetitionsDimension(dim));
std::vector<unsigned int> repetitions(dim);
unsigned int n_cells = 1;
repetitions[i] = spacing[i].size();
n_cells *= repetitions[i];
for (unsigned int j=0; j<repetitions[i]; j++)
- {
- Assert (spacing[i][j] >= 0, ExcInvalidRepetitions(-1));
- delta = std::min (delta, spacing[i][j]);
- }
+ {
+ Assert (spacing[i][j] >= 0, ExcInvalidRepetitions(-1));
+ delta = std::min (delta, spacing[i][j]);
+ }
Assert(material_id.size(i) == repetitions[i],
- ExcInvalidRepetitionsDimension(i));
+ ExcInvalidRepetitionsDimension(i));
}
// generate the necessary points
{
double ay = p[1];
for (unsigned int y=0; y<=repetitions[1]; ++y)
- {
- double ax = p[0];
- for (unsigned int x=0; x<=repetitions[0]; ++x)
- {
- points.push_back (Point<dim> (ax,ay,az));
- if (x<repetitions[0])
- ax += spacing[0][x];
- }
- if (y<repetitions[1])
- ay += spacing[1][y];
- }
+ {
+ double ax = p[0];
+ for (unsigned int x=0; x<=repetitions[0]; ++x)
+ {
+ points.push_back (Point<dim> (ax,ay,az));
+ if (x<repetitions[0])
+ ax += spacing[0][x];
+ }
+ if (y<repetitions[1])
+ ay += spacing[1][y];
+ }
if (z<repetitions[2])
- az += spacing[2][z];
+ az += spacing[2][z];
}
// create the cells
for (unsigned int i=0; i<material_id.size(0); i++)
for (unsigned int j=0; j<material_id.size(1); j++)
for (unsigned int k=0; k<material_id.size(2); k++)
- if (material_id[i][j][k]!=types::invalid_material_id)
- n_val_cells++;
+ if (material_id[i][j][k]!=types::invalid_material_id)
+ n_val_cells++;
std::vector<CellData<dim> > cells(n_val_cells);
unsigned int id = 0;
for (unsigned int z=0; z<repetitions[2]; ++z)
for (unsigned int y=0; y<repetitions[1]; ++y)
for (unsigned int x=0; x<repetitions[0]; ++x)
- if (material_id[x][y][z]!=types::invalid_material_id)
- {
- cells[id].vertices[0] = z*n_xy + y*n_x + x;
- cells[id].vertices[1] = z*n_xy + y*n_x + x+1;
- cells[id].vertices[2] = z*n_xy + (y+1)*n_x + x;
- cells[id].vertices[3] = z*n_xy + (y+1)*n_x + x+1;
- cells[id].vertices[4] = (z+1)*n_xy + y*n_x + x;
- cells[id].vertices[5] = (z+1)*n_xy + y*n_x + x+1;
- cells[id].vertices[6] = (z+1)*n_xy + (y+1)*n_x + x;
- cells[id].vertices[7] = (z+1)*n_xy + (y+1)*n_x + x+1;
- cells[id].material_id = material_id[x][y][z];
- id++;
- }
-
- // create triangulation
+ if (material_id[x][y][z]!=types::invalid_material_id)
+ {
+ cells[id].vertices[0] = z*n_xy + y*n_x + x;
+ cells[id].vertices[1] = z*n_xy + y*n_x + x+1;
+ cells[id].vertices[2] = z*n_xy + (y+1)*n_x + x;
+ cells[id].vertices[3] = z*n_xy + (y+1)*n_x + x+1;
+ cells[id].vertices[4] = (z+1)*n_xy + y*n_x + x;
+ cells[id].vertices[5] = (z+1)*n_xy + y*n_x + x+1;
+ cells[id].vertices[6] = (z+1)*n_xy + (y+1)*n_x + x;
+ cells[id].vertices[7] = (z+1)*n_xy + (y+1)*n_x + x+1;
+ cells[id].material_id = material_id[x][y][z];
+ id++;
+ }
+
+ // create triangulation
SubCellData t;
GridTools::delete_unused_vertices (points, cells, t);
{
double eps = 0.01 * delta;
Triangulation<dim>::cell_iterator cell = tria.begin_raw(),
- endc = tria.end();
+ endc = tria.end();
for (; cell !=endc; ++cell)
- {
- Point<dim> cell_center = cell->center();
- for(unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell; ++f)
- if (cell->face(f)->boundary_indicator() == 0)
- {
- Point<dim> face_center = cell->face(f)->center();
- for (unsigned int i=0; i<dim; ++i)
- {
- if (face_center[i]<cell_center[i]-eps)
- cell->face(f)->set_boundary_indicator(i*2);
- if (face_center[i]>cell_center[i]+eps)
- cell->face(f)->set_boundary_indicator(i*2+1);
- }
- }
- }
+ {
+ Point<dim> cell_center = cell->center();
+ for(unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell; ++f)
+ if (cell->face(f)->boundary_indicator() == 0)
+ {
+ Point<dim> face_center = cell->face(f)->center();
+ for (unsigned int i=0; i<dim; ++i)
+ {
+ if (face_center[i]<cell_center[i]-eps)
+ cell->face(f)->set_boundary_indicator(i*2);
+ if (face_center[i]>cell_center[i]+eps)
+ cell->face(f)->set_boundary_indicator(i*2+1);
+ }
+ }
+ }
}
}
cell != tria.end(); ++cell)
if (cell->center()(0) > 0)
cell->set_material_id(1);
- // boundary indicators are set to
- // 0 (left) and 1 (right) by default.
+ // boundary indicators are set to
+ // 0 (left) and 1 (right) by default.
}
template <int dim>
void
GridGenerator::colorize_subdivided_hyper_rectangle (Triangulation<dim> &tria,
- const Point<dim> &p1,
- const Point<dim> &p2,
- const double epsilon)
+ const Point<dim> &p1,
+ const Point<dim> &p2,
+ const double epsilon)
{
- // run through all faces and check
- // if one of their center coordinates matches
- // one of the corner points. Comparisons
- // are made using an epsilon which
- // should be smaller than the smallest cell
- // diameter.
+ // run through all faces and check
+ // if one of their center coordinates matches
+ // one of the corner points. Comparisons
+ // are made using an epsilon which
+ // should be smaller than the smallest cell
+ // diameter.
typename Triangulation<dim>::raw_face_iterator face = tria.begin_raw_face(),
- endface = tria.end_face();
+ endface = tria.end_face();
for (; face!=endface; ++face)
{
if (face->boundary_indicator() == 0)
- {
- const Point<dim> center (face->center());
- if (std::abs(center(0)-p1[0]) < epsilon)
- face->set_boundary_indicator(0);
- else if (std::abs(center(0) - p2[0]) < epsilon)
- face->set_boundary_indicator(1);
- else if (dim > 1 && std::abs(center(1) - p1[1]) < epsilon)
- face->set_boundary_indicator(2);
- else if (dim > 1 && std::abs(center(1) - p2[1]) < epsilon)
- face->set_boundary_indicator(3);
- else if (dim > 2 && std::abs(center(2) - p1[2]) < epsilon)
- face->set_boundary_indicator(4);
- else if (dim > 2 && std::abs(center(2) - p2[2]) < epsilon)
- face->set_boundary_indicator(5);
- else
- // triangulation says it
- // is on the boundary,
- // but we could not find
- // on which boundary.
- Assert (false, ExcInternalError());
-
- }
+ {
+ const Point<dim> center (face->center());
+ if (std::abs(center(0)-p1[0]) < epsilon)
+ face->set_boundary_indicator(0);
+ else if (std::abs(center(0) - p2[0]) < epsilon)
+ face->set_boundary_indicator(1);
+ else if (dim > 1 && std::abs(center(1) - p1[1]) < epsilon)
+ face->set_boundary_indicator(2);
+ else if (dim > 1 && std::abs(center(1) - p2[1]) < epsilon)
+ face->set_boundary_indicator(3);
+ else if (dim > 2 && std::abs(center(2) - p1[2]) < epsilon)
+ face->set_boundary_indicator(4);
+ else if (dim > 2 && std::abs(center(2) - p2[2]) < epsilon)
+ face->set_boundary_indicator(5);
+ else
+ // triangulation says it
+ // is on the boundary,
+ // but we could not find
+ // on which boundary.
+ Assert (false, ExcInternalError());
+
+ }
}
for (typename Triangulation<dim>::cell_iterator cell = tria.begin();
cell != tria.end(); ++cell)
{
char id = 0;
for (unsigned int d=0;d<dim;++d)
- if (cell->center()(d) > 0) id += 1 << d;
+ if (cell->center()(d) > 0) id += 1 << d;
cell->set_material_id(id);
}
}
template <>
void GridGenerator::hyper_cube_slit (Triangulation<1> &,
- const double,
- const double,
- const bool)
+ const double,
+ const double,
+ const bool)
{
Assert (false, ExcNotImplemented());
}
template <>
void GridGenerator::enclosed_hyper_cube (Triangulation<1>&,
- const double,
- const double,
- const double,
- const bool)
+ const double,
+ const double,
+ const double,
+ const bool)
{
Assert (false, ExcNotImplemented());
}
template <>
void GridGenerator::hyper_L (Triangulation<1> &,
- const double,
- const double)
+ const double,
+ const double)
{
Assert (false, ExcNotImplemented());
}
template <>
void GridGenerator::hyper_ball (Triangulation<1> &,
- const Point<1> &,
- const double)
+ const Point<1> &,
+ const double)
{
Assert (false, ExcNotImplemented());
}
template <>
void GridGenerator::cylinder (Triangulation<1> &,
- const double,
- const double)
+ const double,
+ const double)
{
Assert (false, ExcNotImplemented());
}
template <>
void GridGenerator::truncated_cone (Triangulation<1> &,
- const double,
- const double,
- const double)
+ const double,
+ const double,
+ const double)
{
Assert (false, ExcNotImplemented());
}
template <>
void GridGenerator::hyper_shell (Triangulation<1> &,
- const Point<1> &,
- const double,
- const double,
- const unsigned int,
- const bool)
+ const Point<1> &,
+ const double,
+ const double,
+ const unsigned int,
+ const bool)
{
Assert (false, ExcNotImplemented());
}
template <>
void GridGenerator::colorize_hyper_shell (Triangulation<1> &,
- const Point<1> &,
- const double,
- const double)
+ const Point<1> &,
+ const double,
+ const double)
{
Assert (false, ExcNotImplemented());
}
template <>
void
GridGenerator::half_hyper_ball (Triangulation<1>&,
- const Point<1>&,
- const double)
+ const Point<1>&,
+ const double)
{
Assert (false, ExcNotImplemented());
}
template <>
void
GridGenerator::half_hyper_shell (Triangulation<1>&,
- const Point<1>&,
- const double,
- const double,
- const unsigned int,
- const bool)
+ const Point<1>&,
+ const double,
+ const double,
+ const unsigned int,
+ const bool)
{
Assert (false, ExcNotImplemented());
}
template <>
void GridGenerator::quarter_hyper_shell (Triangulation<1>&,
- const Point<1>&,
- const double,
- const double,
- const unsigned int,
- const bool)
+ const Point<1>&,
+ const double,
+ const double,
+ const unsigned int,
+ const bool)
{
Assert (false, ExcNotImplemented());
}
template <>
void GridGenerator::enclosed_hyper_cube (Triangulation<2> &tria,
- const double left,
- const double right,
- const double thickness,
- const bool colorize)
+ const double left,
+ const double right,
+ const double thickness,
+ const bool colorize)
{
Assert(left<right,
- ExcMessage ("Invalid left-to-right bounds of enclosed hypercube"));
+ ExcMessage ("Invalid left-to-right bounds of enclosed hypercube"));
std::vector<Point<2> > vertices(16);
double coords[4];
vertices[k++] = Point<2>(coords[i1], coords[i0]);
const types::material_id_t materials[9] = { 5, 4, 6,
- 1, 0, 2,
- 9, 8,10
+ 1, 0, 2,
+ 9, 8,10
};
std::vector<CellData<2> > cells(9);
for (unsigned int i0=0;i0<3;++i0)
for (unsigned int i1=0;i1<3;++i1)
{
- cells[k].vertices[0] = i1+4*i0;
- cells[k].vertices[1] = i1+4*i0+1;
- cells[k].vertices[2] = i1+4*i0+4;
- cells[k].vertices[3] = i1+4*i0+5;
- if (colorize)
- cells[k].material_id = materials[k];
- ++k;
+ cells[k].vertices[0] = i1+4*i0;
+ cells[k].vertices[1] = i1+4*i0+1;
+ cells[k].vertices[2] = i1+4*i0+4;
+ cells[k].vertices[3] = i1+4*i0+5;
+ if (colorize)
+ cells[k].material_id = materials[k];
+ ++k;
}
tria.create_triangulation (vertices,
- cells,
- SubCellData()); // no boundary information
+ cells,
+ SubCellData()); // no boundary information
}
template <>
void
GridGenerator::hyper_cube_slit (Triangulation<2> &tria,
- const double left,
- const double right,
- const bool colorize)
+ const double left,
+ const double right,
+ const bool colorize)
{
const double rl2=(right+left)/2;
const Point<2> vertices[10] = { Point<2>(left, left ),
- Point<2>(rl2, left ),
- Point<2>(rl2, rl2 ),
- Point<2>(left, rl2 ),
- Point<2>(right,left ),
- Point<2>(right,rl2 ),
- Point<2>(rl2, right),
- Point<2>(left, right),
- Point<2>(right,right),
- Point<2>(rl2, left ) };
+ Point<2>(rl2, left ),
+ Point<2>(rl2, rl2 ),
+ Point<2>(left, rl2 ),
+ Point<2>(right,left ),
+ Point<2>(right,rl2 ),
+ Point<2>(rl2, right),
+ Point<2>(left, right),
+ Point<2>(right,right),
+ Point<2>(rl2, left ) };
const int cell_vertices[4][4] = { { 0,1,3,2 },
- { 9,4,2,5 },
- { 3,2,7,6 },
- { 2,5,6,8 } };
+ { 9,4,2,5 },
+ { 3,2,7,6 },
+ { 2,5,6,8 } };
std::vector<CellData<2> > cells (4, CellData<2>());
for (unsigned int i=0; i<4; ++i)
{
for (unsigned int j=0; j<4; ++j)
- cells[i].vertices[j] = cell_vertices[i][j];
+ cells[i].vertices[j] = cell_vertices[i][j];
cells[i].material_id = 0;
};
tria.create_triangulation (
template <>
void GridGenerator::truncated_cone (Triangulation<2> &triangulation,
- const double radius_0,
- const double radius_1,
- const double half_length)
+ const double radius_0,
+ const double radius_1,
+ const double half_length)
{
Point<2> vertices_tmp[4];
template <>
void
GridGenerator::hyper_L (Triangulation<2> &tria,
- const double a,
- const double b)
+ const double a,
+ const double b)
{
const Point<2> vertices[8] = { Point<2> (a,a),
- Point<2> ((a+b)/2,a),
- Point<2> (b,a),
- Point<2> (a,(a+b)/2),
- Point<2> ((a+b)/2,(a+b)/2),
- Point<2> (b,(a+b)/2),
- Point<2> (a,b),
- Point<2> ((a+b)/2,b) };
+ Point<2> ((a+b)/2,a),
+ Point<2> (b,a),
+ Point<2> (a,(a+b)/2),
+ Point<2> ((a+b)/2,(a+b)/2),
+ Point<2> (b,(a+b)/2),
+ Point<2> (a,b),
+ Point<2> ((a+b)/2,b) };
const int cell_vertices[3][4] = {{0, 1, 3, 4},
- {1, 2, 4, 5},
- {3, 4, 6, 7}};
+ {1, 2, 4, 5},
+ {3, 4, 6, 7}};
std::vector<CellData<2> > cells (3, CellData<2>());
for (unsigned int i=0; i<3; ++i)
{
for (unsigned int j=0; j<4; ++j)
- cells[i].vertices[j] = cell_vertices[i][j];
+ cells[i].vertices[j] = cell_vertices[i][j];
cells[i].material_id = 0;
};
template <>
void
GridGenerator::hyper_ball (Triangulation<2> &tria,
- const Point<2> &p,
- const double radius)
+ const Point<2> &p,
+ const double radius)
{
- // equilibrate cell sizes at
- // transition from the inner part
- // to the radial cells
+ // equilibrate cell sizes at
+ // transition from the inner part
+ // to the radial cells
const double a = 1./(1+std::sqrt(2.0));
const Point<2> vertices[8] = { p+Point<2>(-1,-1)*(radius/std::sqrt(2.0)),
- p+Point<2>(+1,-1)*(radius/std::sqrt(2.0)),
- p+Point<2>(-1,-1)*(radius/std::sqrt(2.0)*a),
- p+Point<2>(+1,-1)*(radius/std::sqrt(2.0)*a),
- p+Point<2>(-1,+1)*(radius/std::sqrt(2.0)*a),
- p+Point<2>(+1,+1)*(radius/std::sqrt(2.0)*a),
- p+Point<2>(-1,+1)*(radius/std::sqrt(2.0)),
- p+Point<2>(+1,+1)*(radius/std::sqrt(2.0)) };
+ p+Point<2>(+1,-1)*(radius/std::sqrt(2.0)),
+ p+Point<2>(-1,-1)*(radius/std::sqrt(2.0)*a),
+ p+Point<2>(+1,-1)*(radius/std::sqrt(2.0)*a),
+ p+Point<2>(-1,+1)*(radius/std::sqrt(2.0)*a),
+ p+Point<2>(+1,+1)*(radius/std::sqrt(2.0)*a),
+ p+Point<2>(-1,+1)*(radius/std::sqrt(2.0)),
+ p+Point<2>(+1,+1)*(radius/std::sqrt(2.0)) };
const int cell_vertices[5][4] = {{0, 1, 2, 3},
- {0, 2, 6, 4},
- {2, 3, 4, 5},
- {1, 7, 3, 5},
- {6, 4, 7, 5}};
+ {0, 2, 6, 4},
+ {2, 3, 4, 5},
+ {1, 7, 3, 5},
+ {6, 4, 7, 5}};
std::vector<CellData<2> > cells (5, CellData<2>());
for (unsigned int i=0; i<5; ++i)
{
for (unsigned int j=0; j<4; ++j)
- cells[i].vertices[j] = cell_vertices[i][j];
+ cells[i].vertices[j] = cell_vertices[i][j];
cells[i].material_id = 0;
};
Triangulation<2>& tria,
const Point<2>&, const double, const double)
{
- // Inspite of receiving geometrical
- // data, we do this only based on
- // topology.
+ // Inspite of receiving geometrical
+ // data, we do this only based on
+ // topology.
- // For the mesh based on cube,
- // this is highly irregular
+ // For the mesh based on cube,
+ // this is highly irregular
for (Triangulation<2>::cell_iterator cell = tria.begin();
cell != tria.end(); ++cell)
{
template <>
void GridGenerator::hyper_shell (Triangulation<2> &tria,
- const Point<2> ¢er,
- const double inner_radius,
- const double outer_radius,
- const unsigned int n_cells,
- const bool colorize)
+ const Point<2> ¢er,
+ const double inner_radius,
+ const double outer_radius,
+ const unsigned int n_cells,
+ const bool colorize)
{
Assert ((inner_radius > 0) && (inner_radius < outer_radius),
- ExcInvalidRadii ());
+ ExcInvalidRadii ());
const double pi = numbers::PI;
- // determine the number of cells
- // for the grid. if not provided by
- // the user determine it such that
- // the length of each cell on the
- // median (in the middle between
- // the two circles) is equal to its
- // radial extent (which is the
- // difference between the two
- // radii)
+ // determine the number of cells
+ // for the grid. if not provided by
+ // the user determine it such that
+ // the length of each cell on the
+ // median (in the middle between
+ // the two circles) is equal to its
+ // radial extent (which is the
+ // difference between the two
+ // radii)
const unsigned int N = (n_cells == 0 ?
- static_cast<unsigned int>
- (std::ceil((2*pi* (outer_radius + inner_radius)/2) /
- (outer_radius - inner_radius))) :
- n_cells);
-
- // set up N vertices on the
- // outer and N vertices on
- // the inner circle. the
- // first N ones are on the
- // outer one, and all are
- // numbered counter-clockwise
+ static_cast<unsigned int>
+ (std::ceil((2*pi* (outer_radius + inner_radius)/2) /
+ (outer_radius - inner_radius))) :
+ n_cells);
+
+ // set up N vertices on the
+ // outer and N vertices on
+ // the inner circle. the
+ // first N ones are on the
+ // outer one, and all are
+ // numbered counter-clockwise
std::vector<Point<2> > vertices(2*N);
for (unsigned int i=0; i<N; ++i)
{
vertices[i] = Point<2>( std::cos(2*pi * i/N),
- std::sin(2*pi * i/N)) * outer_radius;
+ std::sin(2*pi * i/N)) * outer_radius;
vertices[i+N] = vertices[i] * (inner_radius/outer_radius);
vertices[i] += center;
template <>
void
GridGenerator::cylinder (Triangulation<2> &tria,
- const double radius,
- const double half_length)
+ const double radius,
+ const double half_length)
{
Point<2> p1 (-half_length, -radius);
Point<2> p2 (half_length, radius);
while (f != end)
{
switch (f->boundary_indicator())
- {
- case 0:
- f->set_boundary_indicator(1);
- break;
- case 1:
- f->set_boundary_indicator(2);
- break;
- default:
- f->set_boundary_indicator(0);
- break;
- }
+ {
+ case 0:
+ f->set_boundary_indicator(1);
+ break;
+ case 1:
+ f->set_boundary_indicator(2);
+ break;
+ default:
+ f->set_boundary_indicator(0);
+ break;
+ }
++f;
}
}
template <>
void
GridGenerator::half_hyper_ball (Triangulation<2> &tria,
- const Point<2> &p,
- const double radius)
+ const Point<2> &p,
+ const double radius)
{
- // equilibrate cell sizes at
- // transition from the inner part
- // to the radial cells
+ // equilibrate cell sizes at
+ // transition from the inner part
+ // to the radial cells
const double a = 1./(1+std::sqrt(2.0));
const Point<2> vertices[8] = { p+Point<2>(0,-1)*radius,
- p+Point<2>(+1,-1)*(radius/std::sqrt(2.0)),
- p+Point<2>(0,-1)*(radius/std::sqrt(2.0)*a),
- p+Point<2>(+1,-1)*(radius/std::sqrt(2.0)*a),
- p+Point<2>(0,+1)*(radius/std::sqrt(2.0)*a),
- p+Point<2>(+1,+1)*(radius/std::sqrt(2.0)*a),
- p+Point<2>(0,+1)*radius,
- p+Point<2>(+1,+1)*(radius/std::sqrt(2.0)) };
+ p+Point<2>(+1,-1)*(radius/std::sqrt(2.0)),
+ p+Point<2>(0,-1)*(radius/std::sqrt(2.0)*a),
+ p+Point<2>(+1,-1)*(radius/std::sqrt(2.0)*a),
+ p+Point<2>(0,+1)*(radius/std::sqrt(2.0)*a),
+ p+Point<2>(+1,+1)*(radius/std::sqrt(2.0)*a),
+ p+Point<2>(0,+1)*radius,
+ p+Point<2>(+1,+1)*(radius/std::sqrt(2.0)) };
const int cell_vertices[5][4] = {{0, 1, 2, 3},
- {2, 3, 4, 5},
- {1, 7, 3, 5},
- {6, 4, 7, 5}};
+ {2, 3, 4, 5},
+ {1, 7, 3, 5},
+ {6, 4, 7, 5}};
std::vector<CellData<2> > cells (4, CellData<2>());
for (unsigned int i=0; i<4; ++i)
{
for (unsigned int j=0; j<4; ++j)
- cells[i].vertices[j] = cell_vertices[i][j];
+ cells[i].vertices[j] = cell_vertices[i][j];
cells[i].material_id = 0;
};
while (cell != end)
{
- for (unsigned int i=0;i<GeometryInfo<2>::faces_per_cell;++i)
- {
- if (cell->face(i)->boundary_indicator() == types::internal_face_boundary_id)
- continue;
-
- // If x is zero, then this is part of the plane
- if (cell->face(i)->center()(0) < p(0)+1.e-5)
- cell->face(i)->set_boundary_indicator(1);
- }
- ++cell;
+ for (unsigned int i=0;i<GeometryInfo<2>::faces_per_cell;++i)
+ {
+ if (cell->face(i)->boundary_indicator() == types::internal_face_boundary_id)
+ continue;
+
+ // If x is zero, then this is part of the plane
+ if (cell->face(i)->center()(0) < p(0)+1.e-5)
+ cell->face(i)->set_boundary_indicator(1);
+ }
+ ++cell;
}
}
template <>
void
GridGenerator::half_hyper_shell (Triangulation<2> &tria,
- const Point<2> ¢er,
- const double inner_radius,
- const double outer_radius,
- const unsigned int n_cells,
- const bool colorize)
+ const Point<2> ¢er,
+ const double inner_radius,
+ const double outer_radius,
+ const unsigned int n_cells,
+ const bool colorize)
{
Assert ((inner_radius > 0) && (inner_radius < outer_radius),
- ExcInvalidRadii ());
+ ExcInvalidRadii ());
const double pi = numbers::PI;
- // determine the number of cells
- // for the grid. if not provided by
- // the user determine it such that
- // the length of each cell on the
- // median (in the middle between
- // the two circles) is equal to its
- // radial extent (which is the
- // difference between the two
- // radii)
+ // determine the number of cells
+ // for the grid. if not provided by
+ // the user determine it such that
+ // the length of each cell on the
+ // median (in the middle between
+ // the two circles) is equal to its
+ // radial extent (which is the
+ // difference between the two
+ // radii)
const unsigned int N = (n_cells == 0 ?
- static_cast<unsigned int>
- (std::ceil((pi* (outer_radius + inner_radius)/2) /
- (outer_radius - inner_radius))) :
- n_cells);
-
- // set up N+1 vertices on the
- // outer and N+1 vertices on
- // the inner circle. the
- // first N+1 ones are on the
- // outer one, and all are
- // numbered counter-clockwise
+ static_cast<unsigned int>
+ (std::ceil((pi* (outer_radius + inner_radius)/2) /
+ (outer_radius - inner_radius))) :
+ n_cells);
+
+ // set up N+1 vertices on the
+ // outer and N+1 vertices on
+ // the inner circle. the
+ // first N+1 ones are on the
+ // outer one, and all are
+ // numbered counter-clockwise
std::vector<Point<2> > vertices(2*(N+1));
for (unsigned int i=0; i<=N; ++i)
{
- // enforce that the x-coordinates
- // of the first and last point of
- // each half-circle are exactly
- // zero (contrary to what we may
- // compute using the imprecise
- // value of pi)
+ // enforce that the x-coordinates
+ // of the first and last point of
+ // each half-circle are exactly
+ // zero (contrary to what we may
+ // compute using the imprecise
+ // value of pi)
vertices[i] = Point<2>( ( (i==0) || (i==N) ?
- 0 :
- std::cos(pi * i/N - pi/2) ),
- std::sin(pi * i/N - pi/2)) * outer_radius;
+ 0 :
+ std::cos(pi * i/N - pi/2) ),
+ std::sin(pi * i/N - pi/2)) * outer_radius;
vertices[i+N+1] = vertices[i] * (inner_radius/outer_radius);
vertices[i] += center;
Triangulation<2>::cell_iterator cell = tria.begin();
for (;cell!=tria.end();++cell)
{
- cell->face(2)->set_boundary_indicator(1);
+ cell->face(2)->set_boundary_indicator(1);
}
tria.begin()->face(0)->set_boundary_indicator(3);
template <>
void GridGenerator::quarter_hyper_shell (Triangulation<2> &tria,
- const Point<2> ¢er,
- const double inner_radius,
- const double outer_radius,
- const unsigned int n_cells,
- const bool colorize)
+ const Point<2> ¢er,
+ const double inner_radius,
+ const double outer_radius,
+ const unsigned int n_cells,
+ const bool colorize)
{
Assert ((inner_radius > 0) && (inner_radius < outer_radius),
- ExcInvalidRadii ());
+ ExcInvalidRadii ());
const double pi = numbers::PI;
- // determine the number of cells
- // for the grid. if not provided by
- // the user determine it such that
- // the length of each cell on the
- // median (in the middle between
- // the two circles) is equal to its
- // radial extent (which is the
- // difference between the two
- // radii)
+ // determine the number of cells
+ // for the grid. if not provided by
+ // the user determine it such that
+ // the length of each cell on the
+ // median (in the middle between
+ // the two circles) is equal to its
+ // radial extent (which is the
+ // difference between the two
+ // radii)
const unsigned int N = (n_cells == 0 ?
- static_cast<unsigned int>
- (std::ceil((pi* (outer_radius + inner_radius)/4) /
- (outer_radius - inner_radius))) :
- n_cells);
-
- // set up N+1 vertices on the
- // outer and N+1 vertices on
- // the inner circle. the
- // first N+1 ones are on the
- // outer one, and all are
- // numbered counter-clockwise
+ static_cast<unsigned int>
+ (std::ceil((pi* (outer_radius + inner_radius)/4) /
+ (outer_radius - inner_radius))) :
+ n_cells);
+
+ // set up N+1 vertices on the
+ // outer and N+1 vertices on
+ // the inner circle. the
+ // first N+1 ones are on the
+ // outer one, and all are
+ // numbered counter-clockwise
std::vector<Point<2> > vertices(2*(N+1));
for (unsigned int i=0; i<=N; ++i)
{
- // enforce that the x-coordinates
- // of the last point is exactly
- // zero (contrary to what we may
- // compute using the imprecise
- // value of pi)
+ // enforce that the x-coordinates
+ // of the last point is exactly
+ // zero (contrary to what we may
+ // compute using the imprecise
+ // value of pi)
vertices[i] = Point<2>( ( (i==N) ?
- 0 :
- std::cos(pi * i/N/2) ),
- std::sin(pi * i/N/2)) * outer_radius;
+ 0 :
+ std::cos(pi * i/N/2) ),
+ std::sin(pi * i/N/2)) * outer_radius;
vertices[i+N+1] = vertices[i] * (inner_radius/outer_radius);
vertices[i] += center;
Triangulation<2>::cell_iterator cell = tria.begin();
for (;cell!=tria.end();++cell)
{
- cell->face(2)->set_boundary_indicator(1);
+ cell->face(2)->set_boundary_indicator(1);
}
tria.begin()->face(0)->set_boundary_indicator(3);
// Implementation for 3D only
template <>
void GridGenerator::hyper_cube_slit (Triangulation<3>& tria,
- const double left,
- const double right,
- const bool colorize)
+ const double left,
+ const double right,
+ const bool colorize)
{
const double rl2=(right+left)/2;
const double len = (right-left)/2.;
const Point<3> vertices[20] = {
- Point<3>(left, left , -len/2.),
- Point<3>(rl2, left , -len/2.),
- Point<3>(rl2, rl2 , -len/2.),
- Point<3>(left, rl2 , -len/2.),
- Point<3>(right,left , -len/2.),
- Point<3>(right,rl2 , -len/2.),
- Point<3>(rl2, right, -len/2.),
- Point<3>(left, right, -len/2.),
- Point<3>(right,right, -len/2.),
- Point<3>(rl2, left , -len/2.),
- Point<3>(left, left , len/2.),
- Point<3>(rl2, left , len/2.),
- Point<3>(rl2, rl2 , len/2.),
- Point<3>(left, rl2 , len/2.),
- Point<3>(right,left , len/2.),
- Point<3>(right,rl2 , len/2.),
- Point<3>(rl2, right, len/2.),
- Point<3>(left, right, len/2.),
- Point<3>(right,right, len/2.),
- Point<3>(rl2, left , len/2.)
+ Point<3>(left, left , -len/2.),
+ Point<3>(rl2, left , -len/2.),
+ Point<3>(rl2, rl2 , -len/2.),
+ Point<3>(left, rl2 , -len/2.),
+ Point<3>(right,left , -len/2.),
+ Point<3>(right,rl2 , -len/2.),
+ Point<3>(rl2, right, -len/2.),
+ Point<3>(left, right, -len/2.),
+ Point<3>(right,right, -len/2.),
+ Point<3>(rl2, left , -len/2.),
+ Point<3>(left, left , len/2.),
+ Point<3>(rl2, left , len/2.),
+ Point<3>(rl2, rl2 , len/2.),
+ Point<3>(left, rl2 , len/2.),
+ Point<3>(right,left , len/2.),
+ Point<3>(right,rl2 , len/2.),
+ Point<3>(rl2, right, len/2.),
+ Point<3>(left, right, len/2.),
+ Point<3>(right,right, len/2.),
+ Point<3>(rl2, left , len/2.)
};
const int cell_vertices[4][8] = { { 0,1,3,2, 10, 11, 13, 12 },
- { 9,4,2,5, 19,14, 12, 15 },
- { 3,2,7,6,13,12,17,16 },
- { 2,5,6,8,12,15,16,18 } };
+ { 9,4,2,5, 19,14, 12, 15 },
+ { 3,2,7,6,13,12,17,16 },
+ { 2,5,6,8,12,15,16,18 } };
std::vector<CellData<3> > cells (4, CellData<3>());
for (unsigned int i=0; i<4; ++i)
{
for (unsigned int j=0; j<8; ++j)
- cells[i].vertices[j] = cell_vertices[i][j];
+ cells[i].vertices[j] = cell_vertices[i][j];
cells[i].material_id = 0;
};
tria.create_triangulation (
// Implementation for 3D only
template <>
void GridGenerator::enclosed_hyper_cube (Triangulation<3> &tria,
- const double left,
- const double right,
- const double thickness,
- const bool colorize)
+ const double left,
+ const double right,
+ const double thickness,
+ const bool colorize)
{
Assert(left<right,
- ExcMessage ("Invalid left-to-right bounds of enclosed hypercube"));
+ ExcMessage ("Invalid left-to-right bounds of enclosed hypercube"));
std::vector<Point<3> > vertices(64);
double coords[4];
for (unsigned int z=0;z<4;++z)
for (unsigned int y=0;y<4;++y)
for (unsigned int x=0;x<4;++x)
- vertices[k++] = Point<3>(coords[x], coords[y], coords[z]);
+ vertices[k++] = Point<3>(coords[x], coords[y], coords[z]);
const types::material_id_t materials[27] = {
- 21,20,22,
- 17,16,18,
- 25,24,26,
- 5 , 4, 6,
- 1 , 0, 2,
- 9 , 8,10,
- 37,36,38,
- 33,32,34,
- 41,40,42
+ 21,20,22,
+ 17,16,18,
+ 25,24,26,
+ 5 , 4, 6,
+ 1 , 0, 2,
+ 9 , 8,10,
+ 37,36,38,
+ 33,32,34,
+ 41,40,42
};
std::vector<CellData<3> > cells(27);
for (unsigned int z=0;z<3;++z)
for (unsigned int y=0;y<3;++y)
for (unsigned int x=0;x<3;++x)
- {
- cells[k].vertices[0] = x+4*y+16*z;
- cells[k].vertices[1] = x+4*y+16*z+1;
- cells[k].vertices[2] = x+4*y+16*z+4;
- cells[k].vertices[3] = x+4*y+16*z+5;
- cells[k].vertices[4] = x+4*y+16*z+16;
- cells[k].vertices[5] = x+4*y+16*z+17;
- cells[k].vertices[6] = x+4*y+16*z+20;
- cells[k].vertices[7] = x+4*y+16*z+21;
- if (colorize)
- cells[k].material_id = materials[k];
- ++k;
- }
+ {
+ cells[k].vertices[0] = x+4*y+16*z;
+ cells[k].vertices[1] = x+4*y+16*z+1;
+ cells[k].vertices[2] = x+4*y+16*z+4;
+ cells[k].vertices[3] = x+4*y+16*z+5;
+ cells[k].vertices[4] = x+4*y+16*z+16;
+ cells[k].vertices[5] = x+4*y+16*z+17;
+ cells[k].vertices[6] = x+4*y+16*z+20;
+ cells[k].vertices[7] = x+4*y+16*z+21;
+ if (colorize)
+ cells[k].material_id = materials[k];
+ ++k;
+ }
tria.create_triangulation (
vertices,
cells,
template <>
void GridGenerator::truncated_cone (Triangulation<3> &triangulation,
- const double radius_0,
- const double radius_1,
- const double half_length)
+ const double radius_0,
+ const double radius_1,
+ const double half_length)
{
- // Determine number of cells and vertices
+ // Determine number of cells and vertices
const unsigned int
n_cells = static_cast<unsigned int>(std::floor (half_length /
- std::max (radius_0,
- radius_1) +
- 0.5));
+ std::max (radius_0,
+ radius_1) +
+ 0.5));
const unsigned int n_vertices = 4 * (n_cells + 1);
std::vector<Point<3> > vertices_tmp(n_vertices);
}
const std::vector<Point<3> > vertices (vertices_tmp.begin(),
- vertices_tmp.end());
+ vertices_tmp.end());
Table<2,unsigned int> cell_vertices(n_cells,GeometryInfo<3>::vertices_per_cell);
for (unsigned int i = 0; i < n_cells; ++i)
cell->face (4)->set_boundary_indicator (1);
for (unsigned int i = 0; i < 4; ++i)
- cell->line (i)->set_boundary_indicator (0);
+ cell->line (i)->set_boundary_indicator (0);
}
if (cell->vertex (4) (0) == half_length) {
cell->face (5)->set_boundary_indicator (2);
for (unsigned int i = 4; i < 8; ++i)
- cell->line (i)->set_boundary_indicator (0);
+ cell->line (i)->set_boundary_indicator (0);
}
for (unsigned int i = 0; i < 4; ++i)
template <>
void
GridGenerator::hyper_L (Triangulation<3> &tria,
- const double a,
- const double b)
+ const double a,
+ const double b)
{
- // we slice out the top back right
- // part of the cube
+ // we slice out the top back right
+ // part of the cube
const Point<3> vertices[26]
= {
- // front face of the big cube
- Point<3> (a, a,a),
- Point<3> ((a+b)/2,a,a),
- Point<3> (b, a,a),
- Point<3> (a, a,(a+b)/2),
- Point<3> ((a+b)/2,a,(a+b)/2),
- Point<3> (b, a,(a+b)/2),
- Point<3> (a, a,b),
- Point<3> ((a+b)/2,a,b),
- Point<3> (b, a,b),
- // middle face of the big cube
- Point<3> (a, (a+b)/2,a),
- Point<3> ((a+b)/2,(a+b)/2,a),
- Point<3> (b, (a+b)/2,a),
- Point<3> (a, (a+b)/2,(a+b)/2),
- Point<3> ((a+b)/2,(a+b)/2,(a+b)/2),
- Point<3> (b, (a+b)/2,(a+b)/2),
- Point<3> (a, (a+b)/2,b),
- Point<3> ((a+b)/2,(a+b)/2,b),
- Point<3> (b, (a+b)/2,b),
- // back face of the big cube
- // last (top right) point is missing
- Point<3> (a, b,a),
- Point<3> ((a+b)/2,b,a),
- Point<3> (b, b,a),
- Point<3> (a, b,(a+b)/2),
- Point<3> ((a+b)/2,b,(a+b)/2),
- Point<3> (b, b,(a+b)/2),
- Point<3> (a, b,b),
- Point<3> ((a+b)/2,b,b)
+ // front face of the big cube
+ Point<3> (a, a,a),
+ Point<3> ((a+b)/2,a,a),
+ Point<3> (b, a,a),
+ Point<3> (a, a,(a+b)/2),
+ Point<3> ((a+b)/2,a,(a+b)/2),
+ Point<3> (b, a,(a+b)/2),
+ Point<3> (a, a,b),
+ Point<3> ((a+b)/2,a,b),
+ Point<3> (b, a,b),
+ // middle face of the big cube
+ Point<3> (a, (a+b)/2,a),
+ Point<3> ((a+b)/2,(a+b)/2,a),
+ Point<3> (b, (a+b)/2,a),
+ Point<3> (a, (a+b)/2,(a+b)/2),
+ Point<3> ((a+b)/2,(a+b)/2,(a+b)/2),
+ Point<3> (b, (a+b)/2,(a+b)/2),
+ Point<3> (a, (a+b)/2,b),
+ Point<3> ((a+b)/2,(a+b)/2,b),
+ Point<3> (b, (a+b)/2,b),
+ // back face of the big cube
+ // last (top right) point is missing
+ Point<3> (a, b,a),
+ Point<3> ((a+b)/2,b,a),
+ Point<3> (b, b,a),
+ Point<3> (a, b,(a+b)/2),
+ Point<3> ((a+b)/2,b,(a+b)/2),
+ Point<3> (b, b,(a+b)/2),
+ Point<3> (a, b,b),
+ Point<3> ((a+b)/2,b,b)
};
const int cell_vertices[7][8] = {{0, 1, 9, 10, 3, 4, 12, 13},
- {1, 2, 10, 11, 4, 5, 13, 14},
- {3, 4, 12, 13, 6, 7, 15, 16},
- {4, 5, 13, 14, 7, 8, 16, 17},
- {9, 10, 18, 19, 12, 13, 21, 22},
- {10, 11, 19, 20, 13, 14, 22, 23},
- {12, 13, 21, 22, 15, 16, 24, 25}};
+ {1, 2, 10, 11, 4, 5, 13, 14},
+ {3, 4, 12, 13, 6, 7, 15, 16},
+ {4, 5, 13, 14, 7, 8, 16, 17},
+ {9, 10, 18, 19, 12, 13, 21, 22},
+ {10, 11, 19, 20, 13, 14, 22, 23},
+ {12, 13, 21, 22, 15, 16, 24, 25}};
std::vector<CellData<3> > cells (7, CellData<3>());
for (unsigned int i=0; i<7; ++i)
{
for (unsigned int j=0; j<8; ++j)
- cells[i].vertices[j] = cell_vertices[i][j];
+ cells[i].vertices[j] = cell_vertices[i][j];
cells[i].material_id = 0;
};
template <>
void
GridGenerator::hyper_ball (Triangulation<3> &tria,
- const Point<3> &p,
- const double radius)
+ const Point<3> &p,
+ const double radius)
{
const double a = 1./(1+std::sqrt(3.0)); // equilibrate cell sizes at transition
- // from the inner part to the radial
- // cells
+ // from the inner part to the radial
+ // cells
const unsigned int n_vertices = 16;
const Point<3> vertices[n_vertices]
= {
- // first the vertices of the inner
- // cell
- p+Point<3>(-1,-1,-1)*(radius/std::sqrt(3.0)*a),
- p+Point<3>(+1,-1,-1)*(radius/std::sqrt(3.0)*a),
- p+Point<3>(+1,-1,+1)*(radius/std::sqrt(3.0)*a),
- p+Point<3>(-1,-1,+1)*(radius/std::sqrt(3.0)*a),
- p+Point<3>(-1,+1,-1)*(radius/std::sqrt(3.0)*a),
- p+Point<3>(+1,+1,-1)*(radius/std::sqrt(3.0)*a),
- p+Point<3>(+1,+1,+1)*(radius/std::sqrt(3.0)*a),
- p+Point<3>(-1,+1,+1)*(radius/std::sqrt(3.0)*a),
- // now the eight vertices at
- // the outer sphere
- p+Point<3>(-1,-1,-1)*(radius/std::sqrt(3.0)),
- p+Point<3>(+1,-1,-1)*(radius/std::sqrt(3.0)),
- p+Point<3>(+1,-1,+1)*(radius/std::sqrt(3.0)),
- p+Point<3>(-1,-1,+1)*(radius/std::sqrt(3.0)),
- p+Point<3>(-1,+1,-1)*(radius/std::sqrt(3.0)),
- p+Point<3>(+1,+1,-1)*(radius/std::sqrt(3.0)),
- p+Point<3>(+1,+1,+1)*(radius/std::sqrt(3.0)),
- p+Point<3>(-1,+1,+1)*(radius/std::sqrt(3.0)),
+ // first the vertices of the inner
+ // cell
+ p+Point<3>(-1,-1,-1)*(radius/std::sqrt(3.0)*a),
+ p+Point<3>(+1,-1,-1)*(radius/std::sqrt(3.0)*a),
+ p+Point<3>(+1,-1,+1)*(radius/std::sqrt(3.0)*a),
+ p+Point<3>(-1,-1,+1)*(radius/std::sqrt(3.0)*a),
+ p+Point<3>(-1,+1,-1)*(radius/std::sqrt(3.0)*a),
+ p+Point<3>(+1,+1,-1)*(radius/std::sqrt(3.0)*a),
+ p+Point<3>(+1,+1,+1)*(radius/std::sqrt(3.0)*a),
+ p+Point<3>(-1,+1,+1)*(radius/std::sqrt(3.0)*a),
+ // now the eight vertices at
+ // the outer sphere
+ p+Point<3>(-1,-1,-1)*(radius/std::sqrt(3.0)),
+ p+Point<3>(+1,-1,-1)*(radius/std::sqrt(3.0)),
+ p+Point<3>(+1,-1,+1)*(radius/std::sqrt(3.0)),
+ p+Point<3>(-1,-1,+1)*(radius/std::sqrt(3.0)),
+ p+Point<3>(-1,+1,-1)*(radius/std::sqrt(3.0)),
+ p+Point<3>(+1,+1,-1)*(radius/std::sqrt(3.0)),
+ p+Point<3>(+1,+1,+1)*(radius/std::sqrt(3.0)),
+ p+Point<3>(-1,+1,+1)*(radius/std::sqrt(3.0)),
};
- // one needs to draw the seven cubes to
- // understand what's going on here
+ // one needs to draw the seven cubes to
+ // understand what's going on here
const unsigned int n_cells = 7;
const int cell_vertices[n_cells][8] = {{0, 1, 4, 5, 3, 2, 7, 6}, // center
- {8, 9, 12, 13, 0, 1, 4, 5}, // bottom
- {9, 13, 1, 5, 10, 14, 2, 6}, // right
- {11, 10, 3, 2, 15, 14, 7, 6}, // top
- {8, 0, 12, 4, 11, 3, 15, 7}, // left
- {8, 9, 0, 1, 11, 10, 3, 2}, // front
- {12, 4, 13, 5, 15, 7, 14, 6}}; // back
+ {8, 9, 12, 13, 0, 1, 4, 5}, // bottom
+ {9, 13, 1, 5, 10, 14, 2, 6}, // right
+ {11, 10, 3, 2, 15, 14, 7, 6}, // top
+ {8, 0, 12, 4, 11, 3, 15, 7}, // left
+ {8, 9, 0, 1, 11, 10, 3, 2}, // front
+ {12, 4, 13, 5, 15, 7, 14, 6}}; // back
std::vector<CellData<3> > cells (n_cells, CellData<3>());
for (unsigned int i=0; i<n_cells; ++i)
{
for (unsigned int j=0; j<GeometryInfo<3>::vertices_per_cell; ++j)
- cells[i].vertices[j] = cell_vertices[i][j];
+ cells[i].vertices[j] = cell_vertices[i][j];
cells[i].material_id = 0;
};
template <>
void
GridGenerator::cylinder (Triangulation<3> &tria,
- const double radius,
- const double half_length)
+ const double radius,
+ const double half_length)
{
- // Copy the base from hyper_ball<3>
- // and transform it to yz
+ // Copy the base from hyper_ball<3>
+ // and transform it to yz
const double d = radius/std::sqrt(2.0);
const double a = d/(1+std::sqrt(2.0));
Point<3> vertices[24] = {
- Point<3>(-d, -half_length,-d),
- Point<3>( d, -half_length,-d),
- Point<3>(-a, -half_length,-a),
- Point<3>( a, -half_length,-a),
- Point<3>(-a, -half_length, a),
- Point<3>( a, -half_length, a),
- Point<3>(-d, -half_length, d),
- Point<3>( d, -half_length, d),
- Point<3>(-d, 0,-d),
- Point<3>( d, 0,-d),
- Point<3>(-a, 0,-a),
- Point<3>( a, 0,-a),
- Point<3>(-a, 0, a),
- Point<3>( a, 0, a),
- Point<3>(-d, 0, d),
- Point<3>( d, 0, d),
- Point<3>(-d, half_length,-d),
- Point<3>( d, half_length,-d),
- Point<3>(-a, half_length,-a),
- Point<3>( a, half_length,-a),
- Point<3>(-a, half_length, a),
- Point<3>( a, half_length, a),
- Point<3>(-d, half_length, d),
- Point<3>( d, half_length, d),
+ Point<3>(-d, -half_length,-d),
+ Point<3>( d, -half_length,-d),
+ Point<3>(-a, -half_length,-a),
+ Point<3>( a, -half_length,-a),
+ Point<3>(-a, -half_length, a),
+ Point<3>( a, -half_length, a),
+ Point<3>(-d, -half_length, d),
+ Point<3>( d, -half_length, d),
+ Point<3>(-d, 0,-d),
+ Point<3>( d, 0,-d),
+ Point<3>(-a, 0,-a),
+ Point<3>( a, 0,-a),
+ Point<3>(-a, 0, a),
+ Point<3>( a, 0, a),
+ Point<3>(-d, 0, d),
+ Point<3>( d, 0, d),
+ Point<3>(-d, half_length,-d),
+ Point<3>( d, half_length,-d),
+ Point<3>(-a, half_length,-a),
+ Point<3>( a, half_length,-a),
+ Point<3>(-a, half_length, a),
+ Point<3>( a, half_length, a),
+ Point<3>(-d, half_length, d),
+ Point<3>( d, half_length, d),
};
- // Turn cylinder such that y->x
+ // Turn cylinder such that y->x
for (unsigned int i=0;i<24;++i)
{
const double h = vertices[i](1);
}
int cell_vertices[10][8] = {
- {0, 1, 8, 9, 2, 3, 10, 11},
- {0, 2, 8, 10, 6, 4, 14, 12},
- {2, 3, 10, 11, 4, 5, 12, 13},
- {1, 7, 9, 15, 3, 5, 11, 13},
- {6, 4, 14, 12, 7, 5, 15, 13}
+ {0, 1, 8, 9, 2, 3, 10, 11},
+ {0, 2, 8, 10, 6, 4, 14, 12},
+ {2, 3, 10, 11, 4, 5, 12, 13},
+ {1, 7, 9, 15, 3, 5, 11, 13},
+ {6, 4, 14, 12, 7, 5, 15, 13}
};
for (unsigned int i=0;i<5;++i)
for (unsigned int j=0;j<8;++j)
for (unsigned int i=0; i<10; ++i)
{
for (unsigned int j=0; j<8; ++j)
- cells[i].vertices[j] = cell_vertices[i][j];
+ cells[i].vertices[j] = cell_vertices[i][j];
cells[i].material_id = 0;
};
cells,
SubCellData()); // no boundary information
- // set boundary indicators for the
- // faces at the ends to 1 and 2,
- // respectively. note that we also
- // have to deal with those lines
- // that are purely in the interior
- // of the ends. we determine wether
- // an edge is purely in the
- // interior if one of its vertices
- // is at coordinates '+-a' as set
- // above
+ // set boundary indicators for the
+ // faces at the ends to 1 and 2,
+ // respectively. note that we also
+ // have to deal with those lines
+ // that are purely in the interior
+ // of the ends. we determine wether
+ // an edge is purely in the
+ // interior if one of its vertices
+ // is at coordinates '+-a' as set
+ // above
Triangulation<3>::cell_iterator cell = tria.begin();
Triangulation<3>::cell_iterator end = tria.end();
for (; cell != end; ++cell)
for (unsigned int i=0; i<GeometryInfo<3>::faces_per_cell; ++i)
if (cell->at_boundary(i))
- {
- if (cell->face(i)->center()(0) > half_length-1.e-5)
- {
- cell->face(i)->set_boundary_indicator(2);
-
- for (unsigned int e=0; e<GeometryInfo<3>::lines_per_face; ++e)
- if ((std::fabs(cell->face(i)->line(e)->vertex(0)[1]) == a) ||
- (std::fabs(cell->face(i)->line(e)->vertex(0)[2]) == a) ||
- (std::fabs(cell->face(i)->line(e)->vertex(1)[1]) == a) ||
- (std::fabs(cell->face(i)->line(e)->vertex(1)[2]) == a))
- cell->face(i)->line(e)->set_boundary_indicator(2);
- }
- else if (cell->face(i)->center()(0) < -half_length+1.e-5)
- {
- cell->face(i)->set_boundary_indicator(1);
-
- for (unsigned int e=0; e<GeometryInfo<3>::lines_per_face; ++e)
- if ((std::fabs(cell->face(i)->line(e)->vertex(0)[1]) == a) ||
- (std::fabs(cell->face(i)->line(e)->vertex(0)[2]) == a) ||
- (std::fabs(cell->face(i)->line(e)->vertex(1)[1]) == a) ||
- (std::fabs(cell->face(i)->line(e)->vertex(1)[2]) == a))
- cell->face(i)->line(e)->set_boundary_indicator(1);
- }
- }
+ {
+ if (cell->face(i)->center()(0) > half_length-1.e-5)
+ {
+ cell->face(i)->set_boundary_indicator(2);
+
+ for (unsigned int e=0; e<GeometryInfo<3>::lines_per_face; ++e)
+ if ((std::fabs(cell->face(i)->line(e)->vertex(0)[1]) == a) ||
+ (std::fabs(cell->face(i)->line(e)->vertex(0)[2]) == a) ||
+ (std::fabs(cell->face(i)->line(e)->vertex(1)[1]) == a) ||
+ (std::fabs(cell->face(i)->line(e)->vertex(1)[2]) == a))
+ cell->face(i)->line(e)->set_boundary_indicator(2);
+ }
+ else if (cell->face(i)->center()(0) < -half_length+1.e-5)
+ {
+ cell->face(i)->set_boundary_indicator(1);
+
+ for (unsigned int e=0; e<GeometryInfo<3>::lines_per_face; ++e)
+ if ((std::fabs(cell->face(i)->line(e)->vertex(0)[1]) == a) ||
+ (std::fabs(cell->face(i)->line(e)->vertex(0)[2]) == a) ||
+ (std::fabs(cell->face(i)->line(e)->vertex(1)[1]) == a) ||
+ (std::fabs(cell->face(i)->line(e)->vertex(1)[2]) == a))
+ cell->face(i)->line(e)->set_boundary_indicator(1);
+ }
+ }
}
template <>
void
GridGenerator::half_hyper_ball (Triangulation<3>& tria,
- const Point<3>& center,
- const double radius)
+ const Point<3>& center,
+ const double radius)
{
// These are for the two lower squares
const double d = radius/std::sqrt(2.0);
const double hc = radius*std::sqrt(3.0)/2.0;
Point<3> vertices[16] = {
- center+Point<3>( 0, d, -d),
- center+Point<3>( 0, -d, -d),
- center+Point<3>( 0, a, -a),
- center+Point<3>( 0, -a, -a),
- center+Point<3>( 0, a, a),
- center+Point<3>( 0, -a, a),
- center+Point<3>( 0, d, d),
- center+Point<3>( 0, -d, d),
-
- center+Point<3>(hc, c, -c),
- center+Point<3>(hc, -c, -c),
- center+Point<3>(hb, b, -b),
- center+Point<3>(hb, -b, -b),
- center+Point<3>(hb, b, b),
- center+Point<3>(hb, -b, b),
- center+Point<3>(hc, c, c),
- center+Point<3>(hc, -c, c),
+ center+Point<3>( 0, d, -d),
+ center+Point<3>( 0, -d, -d),
+ center+Point<3>( 0, a, -a),
+ center+Point<3>( 0, -a, -a),
+ center+Point<3>( 0, a, a),
+ center+Point<3>( 0, -a, a),
+ center+Point<3>( 0, d, d),
+ center+Point<3>( 0, -d, d),
+
+ center+Point<3>(hc, c, -c),
+ center+Point<3>(hc, -c, -c),
+ center+Point<3>(hb, b, -b),
+ center+Point<3>(hb, -b, -b),
+ center+Point<3>(hb, b, b),
+ center+Point<3>(hb, -b, b),
+ center+Point<3>(hc, c, c),
+ center+Point<3>(hc, -c, c),
};
int cell_vertices[6][8] = {
- {0, 1, 8, 9, 2, 3, 10, 11},
- {0, 2, 8, 10, 6, 4, 14, 12},
- {2, 3, 10, 11, 4, 5, 12, 13},
- {1, 7, 9, 15, 3, 5, 11, 13},
- {6, 4, 14, 12, 7, 5, 15, 13},
- {8, 10, 9, 11, 14, 12, 15, 13}
+ {0, 1, 8, 9, 2, 3, 10, 11},
+ {0, 2, 8, 10, 6, 4, 14, 12},
+ {2, 3, 10, 11, 4, 5, 12, 13},
+ {1, 7, 9, 15, 3, 5, 11, 13},
+ {6, 4, 14, 12, 7, 5, 15, 13},
+ {8, 10, 9, 11, 14, 12, 15, 13}
};
std::vector<CellData<3> > cells (6, CellData<3>());
for (unsigned int i=0; i<6; ++i)
{
- for (unsigned int j=0; j<8; ++j)
- cells[i].vertices[j] = cell_vertices[i][j];
- cells[i].material_id = 0;
+ for (unsigned int j=0; j<8; ++j)
+ cells[i].vertices[j] = cell_vertices[i][j];
+ cells[i].material_id = 0;
};
tria.create_triangulation (
- std::vector<Point<3> >(&vertices[0], &vertices[16]),
- cells,
- SubCellData()); // no boundary information
+ std::vector<Point<3> >(&vertices[0], &vertices[16]),
+ cells,
+ SubCellData()); // no boundary information
Triangulation<3>::cell_iterator cell = tria.begin();
Triangulation<3>::cell_iterator end = tria.end();
while (cell != end)
{
- for (unsigned int i=0;i<GeometryInfo<3>::faces_per_cell;++i)
- {
- if (!cell->at_boundary(i))
- continue;
-
- // If the center is on the plane x=0, this is a planar
- // element
- if (cell->face(i)->center()(0) < center(0)+1.e-5) {
- cell->face(i)->set_boundary_indicator(1);
- for (unsigned int j=0;j<GeometryInfo<3>::lines_per_face;++j)
- cell->face(i)->line(j)->set_boundary_indicator(1);
- }
- }
- // With this loop we restore back the indicator of the outer lines
- for (unsigned int i=0;i<GeometryInfo<3>::faces_per_cell;++i)
- {
- if (!cell->at_boundary(i))
- continue;
-
- // If the center is not on the plane x=0, this is a curvilinear
- // element
- if (cell->face(i)->center()(0) > center(0)+1.e-5) {
- for (unsigned int j=0;j<GeometryInfo<3>::lines_per_face;++j)
- cell->face(i)->line(j)->set_boundary_indicator(0);
- }
- }
- ++cell;
+ for (unsigned int i=0;i<GeometryInfo<3>::faces_per_cell;++i)
+ {
+ if (!cell->at_boundary(i))
+ continue;
+
+ // If the center is on the plane x=0, this is a planar
+ // element
+ if (cell->face(i)->center()(0) < center(0)+1.e-5) {
+ cell->face(i)->set_boundary_indicator(1);
+ for (unsigned int j=0;j<GeometryInfo<3>::lines_per_face;++j)
+ cell->face(i)->line(j)->set_boundary_indicator(1);
+ }
+ }
+ // With this loop we restore back the indicator of the outer lines
+ for (unsigned int i=0;i<GeometryInfo<3>::faces_per_cell;++i)
+ {
+ if (!cell->at_boundary(i))
+ continue;
+
+ // If the center is not on the plane x=0, this is a curvilinear
+ // element
+ if (cell->face(i)->center()(0) > center(0)+1.e-5) {
+ for (unsigned int j=0;j<GeometryInfo<3>::lines_per_face;++j)
+ cell->face(i)->line(j)->set_boundary_indicator(0);
+ }
+ }
+ ++cell;
}
}
void
GridGenerator::
colorize_hyper_shell (Triangulation<3>& tria,
- const Point<3>&,
- const double,
- const double)
+ const Point<3>&,
+ const double,
+ const double)
{
- // the following uses a good amount
- // of knowledge about the
- // orientation of cells. this is
- // probably not good style...
+ // the following uses a good amount
+ // of knowledge about the
+ // orientation of cells. this is
+ // probably not good style...
if (tria.n_cells() == 6)
{
Triangulation<3>::cell_iterator cell = tria.begin();
}
else if (tria.n_cells() == 12)
{
- // again use some internal
- // knowledge
+ // again use some internal
+ // knowledge
for (Triangulation<3>::cell_iterator cell = tria.begin();
- cell != tria.end(); ++cell)
- {
- Assert (cell->face(5)->at_boundary(), ExcInternalError());
- cell->face(5)->set_boundary_indicator(1);
- }
+ cell != tria.end(); ++cell)
+ {
+ Assert (cell->face(5)->at_boundary(), ExcInternalError());
+ cell->face(5)->set_boundary_indicator(1);
+ }
}
else if (tria.n_cells() == 96)
{
- // the 96-cell hypershell is
- // based on a once refined
- // 12-cell mesh. consequently,
- // since the outer faces all
- // are face_no==5 above, so
- // they are here (unless they
- // are in the interior). Use
- // this to assign boundary
- // indicators, but also make
- // sure that we encounter
- // exactly 48 such faces
+ // the 96-cell hypershell is
+ // based on a once refined
+ // 12-cell mesh. consequently,
+ // since the outer faces all
+ // are face_no==5 above, so
+ // they are here (unless they
+ // are in the interior). Use
+ // this to assign boundary
+ // indicators, but also make
+ // sure that we encounter
+ // exactly 48 such faces
unsigned int count = 0;
for (Triangulation<3>::cell_iterator cell = tria.begin();
- cell != tria.end(); ++cell)
- if (cell->face(5)->at_boundary())
- {
- cell->face(5)->set_boundary_indicator(1);
- ++count;
- }
+ cell != tria.end(); ++cell)
+ if (cell->face(5)->at_boundary())
+ {
+ cell->face(5)->set_boundary_indicator(1);
+ ++count;
+ }
Assert (count == 48, ExcInternalError());
}
else
template <>
void
GridGenerator::hyper_shell (Triangulation<3>& tria,
- const Point<3>& p,
- const double inner_radius,
- const double outer_radius,
- const unsigned int n,
- const bool colorize)
+ const Point<3>& p,
+ const double inner_radius,
+ const double outer_radius,
+ const unsigned int n,
+ const bool colorize)
{
Assert ((inner_radius > 0) && (inner_radius < outer_radius),
- ExcInvalidRadii ());
+ ExcInvalidRadii ());
const double irad = inner_radius/std::sqrt(3.0);
const double orad = outer_radius/std::sqrt(3.0);
std::vector<Point<3> > vertices;
std::vector<CellData<3> > cells;
- // Start with the shell bounded by
- // two nested cubes
+ // Start with the shell bounded by
+ // two nested cubes
if (n == 6)
{
for (unsigned int i=0;i<8;++i)
- vertices.push_back(p+hexahedron[i]*irad);
+ vertices.push_back(p+hexahedron[i]*irad);
for (unsigned int i=0;i<8;++i)
- vertices.push_back(p+hexahedron[i]*orad);
+ vertices.push_back(p+hexahedron[i]*orad);
const unsigned int n_cells = 6;
const int cell_vertices[n_cells][8] =
- {{8, 9, 10, 11, 0, 1, 2, 3}, // bottom
- {9, 11, 1, 3, 13, 15, 5, 7}, // right
- {12, 13, 4, 5, 14, 15, 6, 7}, // top
- {8, 0, 10, 2, 12, 4, 14, 6}, // left
- {8, 9, 0, 1, 12, 13, 4, 5}, // front
- {10, 2, 11, 3, 14, 6, 15, 7}}; // back
+ {{8, 9, 10, 11, 0, 1, 2, 3}, // bottom
+ {9, 11, 1, 3, 13, 15, 5, 7}, // right
+ {12, 13, 4, 5, 14, 15, 6, 7}, // top
+ {8, 0, 10, 2, 12, 4, 14, 6}, // left
+ {8, 9, 0, 1, 12, 13, 4, 5}, // front
+ {10, 2, 11, 3, 14, 6, 15, 7}}; // back
cells.resize(n_cells, CellData<3>());
for (unsigned int i=0; i<n_cells; ++i)
- {
- for (unsigned int j=0; j<GeometryInfo<3>::vertices_per_cell; ++j)
- cells[i].vertices[j] = cell_vertices[i][j];
- cells[i].material_id = 0;
- }
+ {
+ for (unsigned int j=0; j<GeometryInfo<3>::vertices_per_cell; ++j)
+ cells[i].vertices[j] = cell_vertices[i][j];
+ cells[i].material_id = 0;
+ }
tria.create_triangulation (vertices, cells, SubCellData());
}
- // A more regular subdivision can
- // be obtained by two nested
- // rhombic dodecahedra
+ // A more regular subdivision can
+ // be obtained by two nested
+ // rhombic dodecahedra
else if (n == 12)
{
for (unsigned int i=0;i<8;++i)
- vertices.push_back(p+hexahedron[i]*irad);
+ vertices.push_back(p+hexahedron[i]*irad);
for (unsigned int i=0;i<6;++i)
- vertices.push_back(p+octahedron[i]*inner_radius);
+ vertices.push_back(p+octahedron[i]*inner_radius);
for (unsigned int i=0;i<8;++i)
- vertices.push_back(p+hexahedron[i]*orad);
+ vertices.push_back(p+hexahedron[i]*orad);
for (unsigned int i=0;i<6;++i)
- vertices.push_back(p+octahedron[i]*outer_radius);
+ vertices.push_back(p+octahedron[i]*outer_radius);
const unsigned int n_cells = 12;
const unsigned int rhombi[n_cells][4] =
- {{ 10, 4, 0, 8},
- { 4, 13, 8, 6},
- { 10, 5, 4, 13},
- { 1, 9, 10, 5},
- { 9, 7, 5, 13},
- { 7, 11, 13, 6},
- { 9, 3, 7, 11},
- { 1, 12, 9, 3},
- { 12, 2, 3, 11},
- { 2, 8, 11, 6},
- { 12, 0, 2, 8},
- { 1, 10, 12, 0}};
+ {{ 10, 4, 0, 8},
+ { 4, 13, 8, 6},
+ { 10, 5, 4, 13},
+ { 1, 9, 10, 5},
+ { 9, 7, 5, 13},
+ { 7, 11, 13, 6},
+ { 9, 3, 7, 11},
+ { 1, 12, 9, 3},
+ { 12, 2, 3, 11},
+ { 2, 8, 11, 6},
+ { 12, 0, 2, 8},
+ { 1, 10, 12, 0}};
cells.resize(n_cells, CellData<3>());
for (unsigned int i=0; i<n_cells; ++i)
- {
- for (unsigned int j=0; j<4; ++j)
- {
- cells[i].vertices[j ] = rhombi[i][j];
- cells[i].vertices[j+4] = rhombi[i][j] + 14;
- }
- cells[i].material_id = 0;
- }
+ {
+ for (unsigned int j=0; j<4; ++j)
+ {
+ cells[i].vertices[j ] = rhombi[i][j];
+ cells[i].vertices[j+4] = rhombi[i][j] + 14;
+ }
+ cells[i].material_id = 0;
+ }
tria.create_triangulation (vertices, cells, SubCellData());
}
else if (n == 96)
{
- // create a triangulation based on the
- // 12-cell one where we refine the mesh
- // once and then re-arrange all
- // interior nodes so that the mesh is
- // the least distorted
+ // create a triangulation based on the
+ // 12-cell one where we refine the mesh
+ // once and then re-arrange all
+ // interior nodes so that the mesh is
+ // the least distorted
HyperShellBoundary<3> boundary (p);
Triangulation<3> tmp;
GridGenerator::hyper_shell (tmp, p, inner_radius, outer_radius, 12);
tmp.set_boundary(1, boundary);
tmp.refine_global (1);
- // let's determine the distance at
- // which the interior nodes should be
- // from the center. let's say we
- // measure distances in multiples of
- // outer_radius and call
- // r=inner_radius.
- //
- // then note
- // that we now have 48 faces on the
- // inner and 48 on the outer sphere,
- // each with an area of approximately
- // 4*pi/48*r^2 and 4*pi/48, for
- // a face edge length of approximately
- // sqrt(pi/12)*r and sqrt(pi/12)
- //
- // let's say we put the interior nodes
- // at a distance rho, then a measure of
- // deformation for the inner cells
- // would be
- // di=max(sqrt(pi/12)*r/(rho-r),
- // (rho-r)/sqrt(pi/12)/r)
- // and for the outer cells
- // do=max(sqrt(pi/12)/(1-rho),
- // (1-rho)/sqrt(pi/12))
- //
- // we now seek a rho so that the
- // deformation of cells on the inside
- // and outside is equal. there are in
- // principle four possibilities for one
- // of the branches of do== one of the
- // branches of di, though not all of
- // them satisfy do==di, of
- // course. however, we are not
- // interested in cases where the inner
- // cell is long and skinny and the
- // outer one tall -- yes, they have the
- // same aspect ratio, but in different
- // space directions.
- //
- // so it only boils down to the
- // following two possibilities: the
- // first branch of each max(.,.)
- // functions are equal, or the second
- // one are. on the other hand, since
- // they two branches are reciprocals of
- // each other, if one pair of branches
- // is equal, so is the other
- //
- // this yields the following equation
- // for rho:
- // sqrt(pi/12)*r/(rho-r)
- // == sqrt(pi/12)/(1-rho)
- // with solution rho=2r/(1+r)
+ // let's determine the distance at
+ // which the interior nodes should be
+ // from the center. let's say we
+ // measure distances in multiples of
+ // outer_radius and call
+ // r=inner_radius.
+ //
+ // then note
+ // that we now have 48 faces on the
+ // inner and 48 on the outer sphere,
+ // each with an area of approximately
+ // 4*pi/48*r^2 and 4*pi/48, for
+ // a face edge length of approximately
+ // sqrt(pi/12)*r and sqrt(pi/12)
+ //
+ // let's say we put the interior nodes
+ // at a distance rho, then a measure of
+ // deformation for the inner cells
+ // would be
+ // di=max(sqrt(pi/12)*r/(rho-r),
+ // (rho-r)/sqrt(pi/12)/r)
+ // and for the outer cells
+ // do=max(sqrt(pi/12)/(1-rho),
+ // (1-rho)/sqrt(pi/12))
+ //
+ // we now seek a rho so that the
+ // deformation of cells on the inside
+ // and outside is equal. there are in
+ // principle four possibilities for one
+ // of the branches of do== one of the
+ // branches of di, though not all of
+ // them satisfy do==di, of
+ // course. however, we are not
+ // interested in cases where the inner
+ // cell is long and skinny and the
+ // outer one tall -- yes, they have the
+ // same aspect ratio, but in different
+ // space directions.
+ //
+ // so it only boils down to the
+ // following two possibilities: the
+ // first branch of each max(.,.)
+ // functions are equal, or the second
+ // one are. on the other hand, since
+ // they two branches are reciprocals of
+ // each other, if one pair of branches
+ // is equal, so is the other
+ //
+ // this yields the following equation
+ // for rho:
+ // sqrt(pi/12)*r/(rho-r)
+ // == sqrt(pi/12)/(1-rho)
+ // with solution rho=2r/(1+r)
const double r = inner_radius / outer_radius;
const double rho = 2*r/(1+r);
- // then this is the distance of the
- // interior nodes from the center:
+ // then this is the distance of the
+ // interior nodes from the center:
const double middle_radius = rho * outer_radius;
- // mark vertices we've already moved or
- // that we want to ignore: we don't
- // want to move vertices at the inner
- // or outer boundaries
+ // mark vertices we've already moved or
+ // that we want to ignore: we don't
+ // want to move vertices at the inner
+ // or outer boundaries
std::vector<bool> vertex_already_treated (tmp.n_vertices(), false);
for (Triangulation<3>::active_cell_iterator cell = tmp.begin_active();
- cell != tmp.end(); ++cell)
- for (unsigned int f=0; f<GeometryInfo<3>::faces_per_cell; ++f)
- if (cell->at_boundary(f))
- for (unsigned int v=0; v<GeometryInfo<3>::vertices_per_face; ++v)
- vertex_already_treated[cell->face(f)->vertex_index(v)] = true;
+ cell != tmp.end(); ++cell)
+ for (unsigned int f=0; f<GeometryInfo<3>::faces_per_cell; ++f)
+ if (cell->at_boundary(f))
+ for (unsigned int v=0; v<GeometryInfo<3>::vertices_per_face; ++v)
+ vertex_already_treated[cell->face(f)->vertex_index(v)] = true;
- // now move the remaining vertices
+ // now move the remaining vertices
for (Triangulation<3>::active_cell_iterator cell = tmp.begin_active();
- cell != tmp.end(); ++cell)
- for (unsigned int v=0; v<GeometryInfo<3>::vertices_per_cell; ++v)
- if (vertex_already_treated[cell->vertex_index(v)] == false)
- {
- // this is a new interior
- // vertex. mesh refinement may
- // have placed it at a number
- // of places in radial
- // direction and oftentimes not
- // in a particularly good
- // one. move it to halfway
- // between inner and outer
- // sphere
- const Point<3> old_distance = cell->vertex(v) - p;
- const double old_radius = cell->vertex(v).distance(p);
- cell->vertex(v) = p + old_distance * (middle_radius / old_radius);
-
- vertex_already_treated[cell->vertex_index(v)] = true;
- }
-
- // now copy the resulting level 1 cells
- // into the new triangulation,
+ cell != tmp.end(); ++cell)
+ for (unsigned int v=0; v<GeometryInfo<3>::vertices_per_cell; ++v)
+ if (vertex_already_treated[cell->vertex_index(v)] == false)
+ {
+ // this is a new interior
+ // vertex. mesh refinement may
+ // have placed it at a number
+ // of places in radial
+ // direction and oftentimes not
+ // in a particularly good
+ // one. move it to halfway
+ // between inner and outer
+ // sphere
+ const Point<3> old_distance = cell->vertex(v) - p;
+ const double old_radius = cell->vertex(v).distance(p);
+ cell->vertex(v) = p + old_distance * (middle_radius / old_radius);
+
+ vertex_already_treated[cell->vertex_index(v)] = true;
+ }
+
+ // now copy the resulting level 1 cells
+ // into the new triangulation,
cells.resize(tmp.n_active_cells(), CellData<3>());
unsigned int index = 0;
for (Triangulation<3>::active_cell_iterator cell = tmp.begin_active();
- cell != tmp.end(); ++cell, ++index)
- {
- for (unsigned int v=0; v<GeometryInfo<3>::vertices_per_cell; ++v)
- cells[index].vertices[v] = cell->vertex_index(v);
- cells[index].material_id = 0;
- }
+ cell != tmp.end(); ++cell, ++index)
+ {
+ for (unsigned int v=0; v<GeometryInfo<3>::vertices_per_cell; ++v)
+ cells[index].vertices[v] = cell->vertex_index(v);
+ cells[index].material_id = 0;
+ }
tria.create_triangulation (tmp.get_vertices(), cells, SubCellData());
}
template <>
void
GridGenerator::half_hyper_shell (Triangulation<3>& tria,
- const Point<3>& center,
- const double inner_radius,
- const double outer_radius,
- const unsigned int n,
- const bool colorize)
+ const Point<3>& center,
+ const double inner_radius,
+ const double outer_radius,
+ const unsigned int n,
+ const bool colorize)
{
Assert ((inner_radius > 0) && (inner_radius < outer_radius),
- ExcInvalidRadii ());
+ ExcInvalidRadii ());
Assert(colorize == false, ExcNotImplemented());
if (n <= 5)
const double hc = outer_radius*std::sqrt(3.0)/2.0;
Point<3> vertices[16] = {
- center+Point<3>( 0, d, -d),
- center+Point<3>( 0, -d, -d),
- center+Point<3>( 0, a, -a),
- center+Point<3>( 0, -a, -a),
- center+Point<3>( 0, a, a),
- center+Point<3>( 0, -a, a),
- center+Point<3>( 0, d, d),
- center+Point<3>( 0, -d, d),
-
- center+Point<3>(hc, c, -c),
- center+Point<3>(hc, -c, -c),
- center+Point<3>(hb, b, -b),
- center+Point<3>(hb, -b, -b),
- center+Point<3>(hb, b, b),
- center+Point<3>(hb, -b, b),
- center+Point<3>(hc, c, c),
- center+Point<3>(hc, -c, c),
+ center+Point<3>( 0, d, -d),
+ center+Point<3>( 0, -d, -d),
+ center+Point<3>( 0, a, -a),
+ center+Point<3>( 0, -a, -a),
+ center+Point<3>( 0, a, a),
+ center+Point<3>( 0, -a, a),
+ center+Point<3>( 0, d, d),
+ center+Point<3>( 0, -d, d),
+
+ center+Point<3>(hc, c, -c),
+ center+Point<3>(hc, -c, -c),
+ center+Point<3>(hb, b, -b),
+ center+Point<3>(hb, -b, -b),
+ center+Point<3>(hb, b, b),
+ center+Point<3>(hb, -b, b),
+ center+Point<3>(hc, c, c),
+ center+Point<3>(hc, -c, c),
};
int cell_vertices[5][8] = {
- {0, 1, 8, 9, 2, 3, 10, 11},
- {0, 2, 8, 10, 6, 4, 14, 12},
- {1, 7, 9, 15, 3, 5, 11, 13},
- {6, 4, 14, 12, 7, 5, 15, 13},
- {8, 10, 9, 11, 14, 12, 15, 13}
+ {0, 1, 8, 9, 2, 3, 10, 11},
+ {0, 2, 8, 10, 6, 4, 14, 12},
+ {1, 7, 9, 15, 3, 5, 11, 13},
+ {6, 4, 14, 12, 7, 5, 15, 13},
+ {8, 10, 9, 11, 14, 12, 15, 13}
};
std::vector<CellData<3> > cells (5, CellData<3>());
for (unsigned int i=0; i<5; ++i)
- {
- for (unsigned int j=0; j<8; ++j)
- cells[i].vertices[j] = cell_vertices[i][j];
- cells[i].material_id = 0;
- };
+ {
+ for (unsigned int j=0; j<8; ++j)
+ cells[i].vertices[j] = cell_vertices[i][j];
+ cells[i].material_id = 0;
+ };
tria.create_triangulation (
- std::vector<Point<3> >(&vertices[0], &vertices[16]),
- cells,
- SubCellData()); // no boundary information
+ std::vector<Point<3> >(&vertices[0], &vertices[16]),
+ cells,
+ SubCellData()); // no boundary information
}
else
{
std::vector<Point<3> > vertices;
vertices.push_back (center+Point<3>( 0, inner_radius, 0)); //0
- vertices.push_back (center+Point<3>( a, a, 0)); //1
- vertices.push_back (center+Point<3>( b, b, 0)); //2
- vertices.push_back (center+Point<3>( 0, outer_radius, 0)); //3
- vertices.push_back (center+Point<3>( 0, a , a)); //4
- vertices.push_back (center+Point<3>( c, c , h)); //5
- vertices.push_back (center+Point<3>( d, d , e)); //6
- vertices.push_back (center+Point<3>( 0, b , b)); //7
- vertices.push_back (center+Point<3>( inner_radius, 0 , 0)); //8
- vertices.push_back (center+Point<3>( outer_radius, 0 , 0)); //9
- vertices.push_back (center+Point<3>( a, 0 , a)); //10
- vertices.push_back (center+Point<3>( b, 0 , b)); //11
- vertices.push_back (center+Point<3>( 0, 0 , inner_radius)); //12
- vertices.push_back (center+Point<3>( 0, 0 , outer_radius)); //13
+ vertices.push_back (center+Point<3>( a, a, 0)); //1
+ vertices.push_back (center+Point<3>( b, b, 0)); //2
+ vertices.push_back (center+Point<3>( 0, outer_radius, 0)); //3
+ vertices.push_back (center+Point<3>( 0, a , a)); //4
+ vertices.push_back (center+Point<3>( c, c , h)); //5
+ vertices.push_back (center+Point<3>( d, d , e)); //6
+ vertices.push_back (center+Point<3>( 0, b , b)); //7
+ vertices.push_back (center+Point<3>( inner_radius, 0 , 0)); //8
+ vertices.push_back (center+Point<3>( outer_radius, 0 , 0)); //9
+ vertices.push_back (center+Point<3>( a, 0 , a)); //10
+ vertices.push_back (center+Point<3>( b, 0 , b)); //11
+ vertices.push_back (center+Point<3>( 0, 0 , inner_radius)); //12
+ vertices.push_back (center+Point<3>( 0, 0 , outer_radius)); //13
const int cell_vertices[3][8] = {
{0, 1, 3, 2, 4, 5, 7, 6},
const unsigned int n_axial_cells)
{
Assert ((inner_radius > 0) && (inner_radius < outer_radius),
- ExcInvalidRadii ());
+ ExcInvalidRadii ());
const double pi = numbers::PI;
- // determine the number of cells
- // for the grid. if not provided by
- // the user determine it such that
- // the length of each cell on the
- // median (in the middle between
- // the two circles) is equal to its
- // radial extent (which is the
- // difference between the two
- // radii)
+ // determine the number of cells
+ // for the grid. if not provided by
+ // the user determine it such that
+ // the length of each cell on the
+ // median (in the middle between
+ // the two circles) is equal to its
+ // radial extent (which is the
+ // difference between the two
+ // radii)
const unsigned int N_r = (n_radial_cells == 0 ?
static_cast<unsigned int>
(std::ceil((2*pi* (outer_radius + inner_radius)/2) /
(2*pi*(outer_radius + inner_radius)/2/N_r))) :
n_axial_cells);
- // set up N vertices on the
- // outer and N vertices on
- // the inner circle. the
- // first N ones are on the
- // outer one, and all are
- // numbered counter-clockwise
+ // set up N vertices on the
+ // outer and N vertices on
+ // the inner circle. the
+ // first N ones are on the
+ // outer one, and all are
+ // numbered counter-clockwise
std::vector<Point<2> > vertices_2d(2*N_r);
for (unsigned int i=0; i<N_r; ++i)
{
void
GridGenerator::
merge_triangulations (const Triangulation<dim, spacedim> &triangulation_1,
- const Triangulation<dim, spacedim> &triangulation_2,
- Triangulation<dim, spacedim> &result)
+ const Triangulation<dim, spacedim> &triangulation_2,
+ Triangulation<dim, spacedim> &result)
{
Assert (triangulation_1.n_levels() == 1,
- ExcMessage ("The input triangulations must be coarse meshes."));
+ ExcMessage ("The input triangulations must be coarse meshes."));
Assert (triangulation_2.n_levels() == 1,
- ExcMessage ("The input triangulations must be coarse meshes."));
+ ExcMessage ("The input triangulations must be coarse meshes."));
// get the union of the set of vertices
std::vector<Point<spacedim> > vertices = triangulation_1.get_vertices();
vertices.insert (vertices.end(),
- triangulation_2.get_vertices().begin(),
- triangulation_2.get_vertices().end());
+ triangulation_2.get_vertices().begin(),
+ triangulation_2.get_vertices().end());
// now form the union of the set of cells
std::vector<CellData<dim> > cells;
// this is not necessary here as this is an internal only function.
inline
void GridGenerator::laplace_solve (const SparseMatrix<double> &S,
- const std::map<unsigned int,double> &m,
- Vector<double> &u)
+ const std::map<unsigned int,double> &m,
+ Vector<double> &u)
{
const unsigned int n_dofs=S.n();
FilteredMatrix<Vector<double> > SF (S);
// Implementation for 1D only
template <>
void GridGenerator::laplace_transformation (Triangulation<1> &,
- const std::map<unsigned int,Point<1> > &)
+ const std::map<unsigned int,Point<1> > &)
{
Assert(false, ExcNotImplemented());
}
// Implementation for dimensions except 1
template <int dim>
void GridGenerator::laplace_transformation (Triangulation<dim> &tria,
- const std::map<unsigned int,Point<dim> > &new_points)
+ const std::map<unsigned int,Point<dim> > &new_points)
{
- // first provide everything that is
- // needed for solving a Laplace
- // equation.
+ // first provide everything that is
+ // needed for solving a Laplace
+ // equation.
MappingQ1<dim> mapping_q1;
FE_Q<dim> q1(1);
DoFHandler<dim> dof_handler(tria);
dof_handler.distribute_dofs(q1);
SparsityPattern sparsity_pattern (dof_handler.n_dofs (), dof_handler.n_dofs (),
- dof_handler.max_couplings_between_dofs());
+ dof_handler.max_couplings_between_dofs());
DoFTools::make_sparsity_pattern (dof_handler, sparsity_pattern);
sparsity_pattern.compress ();
MatrixCreator::create_laplace_matrix(mapping_q1, dof_handler, quadrature, S);
- // set up the boundary values for
- // the laplace problem
+ // set up the boundary values for
+ // the laplace problem
std::vector<std::map<unsigned int,double> > m(dim);
typename std::map<unsigned int,Point<dim> >::const_iterator map_iter;
typename std::map<unsigned int,Point<dim> >::const_iterator map_end=new_points.end();
- // fill these maps using the data
- // given by new_points
+ // fill these maps using the data
+ // given by new_points
typename DoFHandler<dim>::cell_iterator cell=dof_handler.begin_active(),
- endc=dof_handler.end();
+ endc=dof_handler.end();
typename DoFHandler<dim>::face_iterator face;
for (; cell!=endc; ++cell)
{
if (cell->at_boundary())
- for (unsigned int face_no=0; face_no<GeometryInfo<dim>::faces_per_cell; ++face_no)
- {
- face=cell->face(face_no);
- if (face->at_boundary())
- for (unsigned int vertex_no=0;
- vertex_no<GeometryInfo<dim>::vertices_per_face; ++vertex_no)
- {
- const unsigned int vertex_index=face->vertex_index(vertex_no);
- map_iter=new_points.find(vertex_index);
-
- if (map_iter!=map_end)
- for (unsigned int i=0; i<dim; ++i)
- m[i].insert(std::pair<unsigned int,double> (
- face->vertex_dof_index(vertex_no, 0), map_iter->second(i)));
- }
- }
+ for (unsigned int face_no=0; face_no<GeometryInfo<dim>::faces_per_cell; ++face_no)
+ {
+ face=cell->face(face_no);
+ if (face->at_boundary())
+ for (unsigned int vertex_no=0;
+ vertex_no<GeometryInfo<dim>::vertices_per_face; ++vertex_no)
+ {
+ const unsigned int vertex_index=face->vertex_index(vertex_no);
+ map_iter=new_points.find(vertex_index);
+
+ if (map_iter!=map_end)
+ for (unsigned int i=0; i<dim; ++i)
+ m[i].insert(std::pair<unsigned int,double> (
+ face->vertex_dof_index(vertex_no, 0), map_iter->second(i)));
+ }
+ }
}
- // solve the dim problems with
- // different right hand sides.
+ // solve the dim problems with
+ // different right hand sides.
Vector<double> us[dim];
for (unsigned int i=0; i<dim; ++i)
us[i].reinit (dof_handler.n_dofs());
- // solve linear systems in parallel
+ // solve linear systems in parallel
Threads::TaskGroup<> tasks;
for (unsigned int i=0; i<dim; ++i)
tasks += Threads::new_task (&GridGenerator::laplace_solve,
- S, m[i], us[i]);
+ S, m[i], us[i]);
tasks.join_all ();
- // change the coordinates of the
- // points of the triangulation
- // according to the computed values
+ // change the coordinates of the
+ // points of the triangulation
+ // according to the computed values
for (cell=dof_handler.begin_active(); cell!=endc; ++cell)
for (unsigned int vertex_no=0;
- vertex_no<GeometryInfo<dim>::vertices_per_cell; ++vertex_no)
+ vertex_no<GeometryInfo<dim>::vertices_per_cell; ++vertex_no)
{
- Point<dim> &v=cell->vertex(vertex_no);
- const unsigned int dof_index=cell->vertex_dof_index(vertex_no, 0);
- for (unsigned int i=0; i<dim; ++i)
- v(i)=us[i](dof_index);
+ Point<dim> &v=cell->vertex(vertex_no);
+ const unsigned int dof_index=cell->vertex_dof_index(vertex_no, 0);
+ for (unsigned int i=0; i<dim; ++i)
+ v(i)=us[i](dof_index);
}
}
template <>
void GridGenerator::hyper_cube_with_cylindrical_hole (Triangulation<1> &,
- const double,
- const double,
- const double,
- const unsigned int,
- bool){
+ const double,
+ const double,
+ const double,
+ const unsigned int,
+ bool){
Assert(false, ExcNotImplemented());
}
template <>
void
GridGenerator::hyper_cube_with_cylindrical_hole (Triangulation<2> &triangulation,
- const double inner_radius,
- const double outer_radius,
- const double, // width,
- const unsigned int, // width_repetition,
- bool colorize)
+ const double inner_radius,
+ const double outer_radius,
+ const double, // width,
+ const unsigned int, // width_repetition,
+ bool colorize)
{
const int dim = 2;
Assert(inner_radius < outer_radius,
- ExcMessage("outer_radius has to be bigger than inner_radius."));
+ ExcMessage("outer_radius has to be bigger than inner_radius."));
Point<dim> center;
// We create an hyper_shell in two dimensions, and then we modify it.
GridGenerator::hyper_shell (triangulation,
- center, inner_radius, outer_radius,
+ center, inner_radius, outer_radius,
8);
Triangulation<dim>::active_cell_iterator
cell = triangulation.begin_active(),
for(; cell != endc; ++cell) {
for(unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell; ++f)
if(cell->face(f)->at_boundary()) {
- for(unsigned int v=0; v < GeometryInfo<dim>::vertices_per_face; ++v) {
- unsigned int vv = cell->face(f)->vertex_index(v);
- if(treated_vertices[vv] == false) {
- treated_vertices[vv] = true;
- switch(vv) {
- case 1:
- cell->face(f)->vertex(v) = center+Point<dim>(outer_radius,outer_radius);
- break;
- case 3:
- cell->face(f)->vertex(v) = center+Point<dim>(-outer_radius,outer_radius);
- break;
- case 5:
- cell->face(f)->vertex(v) = center+Point<dim>(-outer_radius,-outer_radius);
- break;
- case 7:
- cell->face(f)->vertex(v) = center+Point<dim>(outer_radius,-outer_radius);
- default:
- break;
- }
- }
- }
+ for(unsigned int v=0; v < GeometryInfo<dim>::vertices_per_face; ++v) {
+ unsigned int vv = cell->face(f)->vertex_index(v);
+ if(treated_vertices[vv] == false) {
+ treated_vertices[vv] = true;
+ switch(vv) {
+ case 1:
+ cell->face(f)->vertex(v) = center+Point<dim>(outer_radius,outer_radius);
+ break;
+ case 3:
+ cell->face(f)->vertex(v) = center+Point<dim>(-outer_radius,outer_radius);
+ break;
+ case 5:
+ cell->face(f)->vertex(v) = center+Point<dim>(-outer_radius,-outer_radius);
+ break;
+ case 7:
+ cell->face(f)->vertex(v) = center+Point<dim>(outer_radius,-outer_radius);
+ default:
+ break;
+ }
+ }
+ }
}
}
double eps = 1e-3 * outer_radius;
for(; cell != endc; ++cell) {
for(unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell; ++f)
if(cell->face(f)->at_boundary()) {
- double dx = cell->face(f)->center()(0) - center(0);
- double dy = cell->face(f)->center()(1) - center(1);
- if(colorize) {
- if(std::abs(dx + outer_radius) < eps)
- cell->face(f)->set_boundary_indicator(0);
- else if(std::abs(dx - outer_radius) < eps)
- cell->face(f)->set_boundary_indicator(1);
- else if(std::abs(dy + outer_radius) < eps)
- cell->face(f)->set_boundary_indicator(2);
- else if(std::abs(dy - outer_radius) < eps)
- cell->face(f)->set_boundary_indicator(3);
- else
- cell->face(f)->set_boundary_indicator(4);
- } else {
- double d = (cell->face(f)->center() - center).norm();
- if(d-inner_radius < 0)
- cell->face(f)->set_boundary_indicator(1);
- else
- cell->face(f)->set_boundary_indicator(0);
- }
+ double dx = cell->face(f)->center()(0) - center(0);
+ double dy = cell->face(f)->center()(1) - center(1);
+ if(colorize) {
+ if(std::abs(dx + outer_radius) < eps)
+ cell->face(f)->set_boundary_indicator(0);
+ else if(std::abs(dx - outer_radius) < eps)
+ cell->face(f)->set_boundary_indicator(1);
+ else if(std::abs(dy + outer_radius) < eps)
+ cell->face(f)->set_boundary_indicator(2);
+ else if(std::abs(dy - outer_radius) < eps)
+ cell->face(f)->set_boundary_indicator(3);
+ else
+ cell->face(f)->set_boundary_indicator(4);
+ } else {
+ double d = (cell->face(f)->center() - center).norm();
+ if(d-inner_radius < 0)
+ cell->face(f)->set_boundary_indicator(1);
+ else
+ cell->face(f)->set_boundary_indicator(0);
+ }
}
}
}
template <>
void GridGenerator::hyper_cube_with_cylindrical_hole(Triangulation<3> &triangulation,
- const double inner_radius,
- const double outer_radius,
- const double L,
- const unsigned int Nz,
- bool colorize)
+ const double inner_radius,
+ const double outer_radius,
+ const double L,
+ const unsigned int Nz,
+ bool colorize)
{
const int dim = 3;
Assert(inner_radius < outer_radius,
- ExcMessage("outer_radius has to be bigger than inner_radius."));
+ ExcMessage("outer_radius has to be bigger than inner_radius."));
Assert(L > 0,
- ExcMessage("Must give positive extension L"));
+ ExcMessage("Must give positive extension L"));
Assert(Nz >= 1, ExcLowerRange(1, Nz));
GridGenerator::cylinder_shell (triangulation,
- L, inner_radius, outer_radius,
- 8,
- Nz);
+ L, inner_radius, outer_radius,
+ 8,
+ Nz);
Triangulation<dim>::active_cell_iterator
cell = triangulation.begin_active(),
for(; cell != endc; ++cell) {
for(unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell; ++f)
if(cell->face(f)->at_boundary()) {
- for(unsigned int v=0; v < GeometryInfo<dim>::vertices_per_face; ++v) {
- unsigned int vv = cell->face(f)->vertex_index(v);
- if(treated_vertices[vv] == false) {
- treated_vertices[vv] = true;
- for(unsigned int i=0; i<=Nz; ++i) {
- double d = ((double) i)*L/((double) Nz);
- switch(vv-i*16) {
- case 1:
- cell->face(f)->vertex(v) = Point<dim>(outer_radius,outer_radius,d);
- break;
- case 3:
- cell->face(f)->vertex(v) = Point<dim>(-outer_radius,outer_radius,d);
- break;
- case 5:
- cell->face(f)->vertex(v) = Point<dim>(-outer_radius,-outer_radius,d);
- break;
- case 7:
- cell->face(f)->vertex(v) = Point<dim>(outer_radius,-outer_radius,d);
- break;
- default:
- break;
- }
- }
- }
- }
+ for(unsigned int v=0; v < GeometryInfo<dim>::vertices_per_face; ++v) {
+ unsigned int vv = cell->face(f)->vertex_index(v);
+ if(treated_vertices[vv] == false) {
+ treated_vertices[vv] = true;
+ for(unsigned int i=0; i<=Nz; ++i) {
+ double d = ((double) i)*L/((double) Nz);
+ switch(vv-i*16) {
+ case 1:
+ cell->face(f)->vertex(v) = Point<dim>(outer_radius,outer_radius,d);
+ break;
+ case 3:
+ cell->face(f)->vertex(v) = Point<dim>(-outer_radius,outer_radius,d);
+ break;
+ case 5:
+ cell->face(f)->vertex(v) = Point<dim>(-outer_radius,-outer_radius,d);
+ break;
+ case 7:
+ cell->face(f)->vertex(v) = Point<dim>(outer_radius,-outer_radius,d);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ }
}
}
double eps = 1e-3 * outer_radius;
for(; cell != endc; ++cell) {
for(unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell; ++f)
if(cell->face(f)->at_boundary()) {
- double dx = cell->face(f)->center()(0);
- double dy = cell->face(f)->center()(1);
- double dz = cell->face(f)->center()(2);
-
- if(colorize) {
- if(std::abs(dx + outer_radius) < eps)
- cell->face(f)->set_boundary_indicator(0);
-
- else if(std::abs(dx - outer_radius) < eps)
- cell->face(f)->set_boundary_indicator(1);
-
- else if(std::abs(dy + outer_radius) < eps)
- cell->face(f)->set_boundary_indicator(2);
-
- else if(std::abs(dy - outer_radius) < eps)
- cell->face(f)->set_boundary_indicator(3);
-
- else if(std::abs(dz) < eps)
- cell->face(f)->set_boundary_indicator(4);
-
- else if(std::abs(dz - L) < eps)
- cell->face(f)->set_boundary_indicator(5);
-
- else {
- cell->face(f)->set_boundary_indicator(6);
- for(unsigned int l=0; l<GeometryInfo<dim>::lines_per_face; ++l)
- cell->face(f)->line(l)->set_boundary_indicator(6);
- }
-
- } else {
- Point<dim> c = cell->face(f)->center();
- c(2) = 0;
- double d = c.norm();
- if(d-inner_radius < 0) {
- cell->face(f)->set_boundary_indicator(1);
- for(unsigned int l=0; l<GeometryInfo<dim>::lines_per_face; ++l)
- cell->face(f)->line(l)->set_boundary_indicator(1);
- } else
- cell->face(f)->set_boundary_indicator(0);
- }
+ double dx = cell->face(f)->center()(0);
+ double dy = cell->face(f)->center()(1);
+ double dz = cell->face(f)->center()(2);
+
+ if(colorize) {
+ if(std::abs(dx + outer_radius) < eps)
+ cell->face(f)->set_boundary_indicator(0);
+
+ else if(std::abs(dx - outer_radius) < eps)
+ cell->face(f)->set_boundary_indicator(1);
+
+ else if(std::abs(dy + outer_radius) < eps)
+ cell->face(f)->set_boundary_indicator(2);
+
+ else if(std::abs(dy - outer_radius) < eps)
+ cell->face(f)->set_boundary_indicator(3);
+
+ else if(std::abs(dz) < eps)
+ cell->face(f)->set_boundary_indicator(4);
+
+ else if(std::abs(dz - L) < eps)
+ cell->face(f)->set_boundary_indicator(5);
+
+ else {
+ cell->face(f)->set_boundary_indicator(6);
+ for(unsigned int l=0; l<GeometryInfo<dim>::lines_per_face; ++l)
+ cell->face(f)->line(l)->set_boundary_indicator(6);
+ }
+
+ } else {
+ Point<dim> c = cell->face(f)->center();
+ c(2) = 0;
+ double d = c.norm();
+ if(d-inner_radius < 0) {
+ cell->face(f)->set_boundary_indicator(1);
+ for(unsigned int l=0; l<GeometryInfo<dim>::lines_per_face; ++l)
+ cell->face(f)->line(l)->set_boundary_indicator(1);
+ } else
+ cell->face(f)->set_boundary_indicator(0);
+ }
}
}
}
// $Id$
// Version: $Name$
//
-// Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 by the deal.II authors
+// Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
template <int dim, int spacedim>
GridIn<dim, spacedim>::GridIn () :
- tria(0, typeid(*this).name()), default_format(ucd)
+ tria(0, typeid(*this).name()), default_format(ucd)
{}
Assert (tria != 0, ExcNoTriangulationSelected());
AssertThrow (in, ExcIO());
- // skip comments at start of file
+ // skip comments at start of file
skip_comment_lines (in, '#');
>> dummy; // model data
AssertThrow (in, ExcIO());
- // set up array of vertices
+ // set up array of vertices
std::vector<Point<spacedim> > vertices (n_vertices);
- // set up mapping between numbering
- // in ucd-file (key) and in the
- // vertices vector
+ // set up mapping between numbering
+ // in ucd-file (key) and in the
+ // vertices vector
std::map<int,int> vertex_indices;
for (unsigned int vertex=0; vertex<n_vertices; ++vertex)
int vertex_number;
double x[3];
- // read vertex
+ // read vertex
AssertThrow (in, ExcIO());
in >> vertex_number
- >> x[0] >> x[1] >> x[2];
+ >> x[0] >> x[1] >> x[2];
- // store vertex
+ // store vertex
for (unsigned int d=0; d<spacedim; ++d)
- vertices[vertex](d) = x[d];
- // store mapping; note that
- // vertices_indices[i] is automatically
- // created upon first usage
+ vertices[vertex](d) = x[d];
+ // store mapping; note that
+ // vertices_indices[i] is automatically
+ // created upon first usage
vertex_indices[vertex_number] = vertex;
};
- // set up array of cells
+ // set up array of cells
std::vector<CellData<dim> > cells;
SubCellData subcelldata;
for (unsigned int cell=0; cell<n_cells; ++cell)
{
- // note that since in the input
- // file we found the number of
- // cells at the top, there
- // should still be input here,
- // so check this:
+ // note that since in the input
+ // file we found the number of
+ // cells at the top, there
+ // should still be input here,
+ // so check this:
AssertThrow (in, ExcIO());
std::string cell_type;
unsigned int material_id;
in >> dummy // cell number
- >> material_id;
+ >> material_id;
in >> cell_type;
if (((cell_type == "line") && (dim == 1)) ||
- ((cell_type == "quad") && (dim == 2)) ||
- ((cell_type == "hex" ) && (dim == 3)))
- // found a cell
- {
- // allocate and read indices
- cells.push_back (CellData<dim>());
- for (unsigned int i=0; i<GeometryInfo<dim>::vertices_per_cell; ++i)
- in >> cells.back().vertices[i];
-
- // to make sure that the cast wont fail
+ ((cell_type == "quad") && (dim == 2)) ||
+ ((cell_type == "hex" ) && (dim == 3)))
+ // found a cell
+ {
+ // allocate and read indices
+ cells.push_back (CellData<dim>());
+ for (unsigned int i=0; i<GeometryInfo<dim>::vertices_per_cell; ++i)
+ in >> cells.back().vertices[i];
+
+ // to make sure that the cast wont fail
Assert(material_id<= std::numeric_limits<types::material_id_t>::max(),
ExcIndexRange(material_id,0,std::numeric_limits<types::material_id_t>::max()));
// we use only material_ids in the range from 0 to types::invalid_material_id-1
Assert(material_id < types::invalid_material_id,
ExcIndexRange(material_id,0,types::invalid_material_id));
- cells.back().material_id = static_cast<types::material_id_t>(material_id);
-
- // transform from ucd to
- // consecutive numbering
- for (unsigned int i=0; i<GeometryInfo<dim>::vertices_per_cell; ++i)
- if (vertex_indices.find (cells.back().vertices[i]) != vertex_indices.end())
- // vertex with this index exists
- cells.back().vertices[i] = vertex_indices[cells.back().vertices[i]];
- else
- {
- // no such vertex index
- AssertThrow (false, ExcInvalidVertexIndex(cell, cells.back().vertices[i]));
- cells.back().vertices[i] = numbers::invalid_unsigned_int;
- };
- }
+ cells.back().material_id = static_cast<types::material_id_t>(material_id);
+
+ // transform from ucd to
+ // consecutive numbering
+ for (unsigned int i=0; i<GeometryInfo<dim>::vertices_per_cell; ++i)
+ if (vertex_indices.find (cells.back().vertices[i]) != vertex_indices.end())
+ // vertex with this index exists
+ cells.back().vertices[i] = vertex_indices[cells.back().vertices[i]];
+ else
+ {
+ // no such vertex index
+ AssertThrow (false, ExcInvalidVertexIndex(cell, cells.back().vertices[i]));
+ cells.back().vertices[i] = numbers::invalid_unsigned_int;
+ };
+ }
else
- if ((cell_type == "line") && ((dim == 2) || (dim == 3)))
- // boundary info
- {
- subcelldata.boundary_lines.push_back (CellData<1>());
- in >> subcelldata.boundary_lines.back().vertices[0]
- >> subcelldata.boundary_lines.back().vertices[1];
-
- // to make sure that the cast wont fail
- Assert(material_id<= std::numeric_limits<types::boundary_id_t>::max(),
- ExcIndexRange(material_id,0,std::numeric_limits<types::boundary_id_t>::max()));
- // we use only boundary_ids in the range from 0 to types::internal_face_boundary_id-1
- Assert(material_id < types::internal_face_boundary_id,
- ExcIndexRange(material_id,0,types::internal_face_boundary_id));
-
- subcelldata.boundary_lines.back().boundary_id
- = static_cast<types::boundary_id_t>(material_id);
-
- // transform from ucd to
- // consecutive numbering
- for (unsigned int i=0; i<2; ++i)
- if (vertex_indices.find (subcelldata.boundary_lines.back().vertices[i]) !=
- vertex_indices.end())
- // vertex with this index exists
- subcelldata.boundary_lines.back().vertices[i]
- = vertex_indices[subcelldata.boundary_lines.back().vertices[i]];
- else
- {
- // no such vertex index
- AssertThrow (false,
- ExcInvalidVertexIndex(cell,
- subcelldata.boundary_lines.back().vertices[i]));
- subcelldata.boundary_lines.back().vertices[i]
- = numbers::invalid_unsigned_int;
- };
- }
- else
- if ((cell_type == "quad") && (dim == 3))
- // boundary info
- {
- subcelldata.boundary_quads.push_back (CellData<2>());
- in >> subcelldata.boundary_quads.back().vertices[0]
- >> subcelldata.boundary_quads.back().vertices[1]
- >> subcelldata.boundary_quads.back().vertices[2]
- >> subcelldata.boundary_quads.back().vertices[3];
-
- // to make sure that the cast wont fail
- Assert(material_id<= std::numeric_limits<types::boundary_id_t>::max(),
- ExcIndexRange(material_id,0,std::numeric_limits<types::boundary_id_t>::max()));
- // we use only boundary_ids in the range from 0 to types::internal_face_boundary_id-1
- Assert(material_id < types::internal_face_boundary_id,
- ExcIndexRange(material_id,0,types::internal_face_boundary_id));
-
- subcelldata.boundary_quads.back().boundary_id
- = static_cast<types::boundary_id_t>(material_id);
-
- // transform from ucd to
- // consecutive numbering
- for (unsigned int i=0; i<4; ++i)
- if (vertex_indices.find (subcelldata.boundary_quads.back().vertices[i]) !=
- vertex_indices.end())
- // vertex with this index exists
- subcelldata.boundary_quads.back().vertices[i]
- = vertex_indices[subcelldata.boundary_quads.back().vertices[i]];
- else
- {
- // no such vertex index
- Assert (false,
- ExcInvalidVertexIndex(cell,
- subcelldata.boundary_quads.back().vertices[i]));
- subcelldata.boundary_quads.back().vertices[i] =
- numbers::invalid_unsigned_int;
- };
-
- }
- else
- // cannot read this
- AssertThrow (false, ExcUnknownIdentifier(cell_type));
+ if ((cell_type == "line") && ((dim == 2) || (dim == 3)))
+ // boundary info
+ {
+ subcelldata.boundary_lines.push_back (CellData<1>());
+ in >> subcelldata.boundary_lines.back().vertices[0]
+ >> subcelldata.boundary_lines.back().vertices[1];
+
+ // to make sure that the cast wont fail
+ Assert(material_id<= std::numeric_limits<types::boundary_id_t>::max(),
+ ExcIndexRange(material_id,0,std::numeric_limits<types::boundary_id_t>::max()));
+ // we use only boundary_ids in the range from 0 to types::internal_face_boundary_id-1
+ Assert(material_id < types::internal_face_boundary_id,
+ ExcIndexRange(material_id,0,types::internal_face_boundary_id));
+
+ subcelldata.boundary_lines.back().boundary_id
+ = static_cast<types::boundary_id_t>(material_id);
+
+ // transform from ucd to
+ // consecutive numbering
+ for (unsigned int i=0; i<2; ++i)
+ if (vertex_indices.find (subcelldata.boundary_lines.back().vertices[i]) !=
+ vertex_indices.end())
+ // vertex with this index exists
+ subcelldata.boundary_lines.back().vertices[i]
+ = vertex_indices[subcelldata.boundary_lines.back().vertices[i]];
+ else
+ {
+ // no such vertex index
+ AssertThrow (false,
+ ExcInvalidVertexIndex(cell,
+ subcelldata.boundary_lines.back().vertices[i]));
+ subcelldata.boundary_lines.back().vertices[i]
+ = numbers::invalid_unsigned_int;
+ };
+ }
+ else
+ if ((cell_type == "quad") && (dim == 3))
+ // boundary info
+ {
+ subcelldata.boundary_quads.push_back (CellData<2>());
+ in >> subcelldata.boundary_quads.back().vertices[0]
+ >> subcelldata.boundary_quads.back().vertices[1]
+ >> subcelldata.boundary_quads.back().vertices[2]
+ >> subcelldata.boundary_quads.back().vertices[3];
+
+ // to make sure that the cast wont fail
+ Assert(material_id<= std::numeric_limits<types::boundary_id_t>::max(),
+ ExcIndexRange(material_id,0,std::numeric_limits<types::boundary_id_t>::max()));
+ // we use only boundary_ids in the range from 0 to types::internal_face_boundary_id-1
+ Assert(material_id < types::internal_face_boundary_id,
+ ExcIndexRange(material_id,0,types::internal_face_boundary_id));
+
+ subcelldata.boundary_quads.back().boundary_id
+ = static_cast<types::boundary_id_t>(material_id);
+
+ // transform from ucd to
+ // consecutive numbering
+ for (unsigned int i=0; i<4; ++i)
+ if (vertex_indices.find (subcelldata.boundary_quads.back().vertices[i]) !=
+ vertex_indices.end())
+ // vertex with this index exists
+ subcelldata.boundary_quads.back().vertices[i]
+ = vertex_indices[subcelldata.boundary_quads.back().vertices[i]];
+ else
+ {
+ // no such vertex index
+ Assert (false,
+ ExcInvalidVertexIndex(cell,
+ subcelldata.boundary_quads.back().vertices[i]));
+ subcelldata.boundary_quads.back().vertices[i] =
+ numbers::invalid_unsigned_int;
+ };
+
+ }
+ else
+ // cannot read this
+ AssertThrow (false, ExcUnknownIdentifier(cell_type));
};
- // check that no forbidden arrays are used
+ // check that no forbidden arrays are used
Assert (subcelldata.check_consistency(dim), ExcInternalError());
AssertThrow (in, ExcIO());
- // do some clean-up on vertices...
+ // do some clean-up on vertices...
GridTools::delete_unused_vertices (vertices, cells, subcelldata);
- // ... and cells
+ // ... and cells
if(dim==spacedim)
GridReordering<dim,spacedim>::invert_all_cells_of_negative_grid (vertices, cells);
GridReordering<dim,spacedim>::reorder_cells (cells);
AssertThrow (in, ExcIO());
- // skip comments at start of file
+ // skip comments at start of file
skip_comment_lines (in, '#');
- // first read in identifier string
+ // first read in identifier string
std::string line;
getline (in, line);
AssertThrow (line=="MeshVersionFormatted 0",
- ExcInvalidDBMESHInput(line));
+ ExcInvalidDBMESHInput(line));
skip_empty_lines (in);
- // next read dimension
+ // next read dimension
getline (in, line);
AssertThrow (line=="Dimension", ExcInvalidDBMESHInput(line));
unsigned int dimension;
AssertThrow (dimension == dim, ExcDBMESHWrongDimension(dimension));
skip_empty_lines (in);
- // now there are a lot of fields of
- // which we don't know the exact
- // meaning and which are far from
- // being properly documented in the
- // manual. we skip everything until
- // we find a comment line with the
- // string "# END". at some point in
- // the future, someone may have the
- // knowledge to parse and interpret
- // the other fields in between as
- // well...
+ // now there are a lot of fields of
+ // which we don't know the exact
+ // meaning and which are far from
+ // being properly documented in the
+ // manual. we skip everything until
+ // we find a comment line with the
+ // string "# END". at some point in
+ // the future, someone may have the
+ // knowledge to parse and interpret
+ // the other fields in between as
+ // well...
while (getline(in,line), line.find("# END")==std::string::npos)
;
skip_empty_lines (in);
- // now read vertices
+ // now read vertices
getline (in, line);
AssertThrow (line=="Vertices", ExcInvalidDBMESHInput(line));
std::vector<Point<spacedim> > vertices (n_vertices);
for (unsigned int vertex=0; vertex<n_vertices; ++vertex)
{
- // read vertex coordinates
+ // read vertex coordinates
for (unsigned int d=0; d<dim; ++d)
- in >> vertices[vertex][d];
- // read Ref phi_i, whatever that may be
+ in >> vertices[vertex][d];
+ // read Ref phi_i, whatever that may be
in >> dummy;
};
AssertThrow (in, ExcInvalidDBMeshFormat());
skip_empty_lines(in);
- // read edges. we ignore them at
- // present, so just read them and
- // discard the input
+ // read edges. we ignore them at
+ // present, so just read them and
+ // discard the input
getline (in, line);
AssertThrow (line=="Edges", ExcInvalidDBMESHInput(line));
in >> n_edges;
for (unsigned int edge=0; edge<n_edges; ++edge)
{
- // read vertex indices
+ // read vertex indices
in >> dummy >> dummy;
- // read Ref phi_i, whatever that may be
+ // read Ref phi_i, whatever that may be
in >> dummy;
};
AssertThrow (in, ExcInvalidDBMeshFormat());
- // read cracked edges (whatever
- // that may be). we ignore them at
- // present, so just read them and
- // discard the input
+ // read cracked edges (whatever
+ // that may be). we ignore them at
+ // present, so just read them and
+ // discard the input
getline (in, line);
AssertThrow (line=="CrackedEdges", ExcInvalidDBMESHInput(line));
in >> n_edges;
for (unsigned int edge=0; edge<n_edges; ++edge)
{
- // read vertex indices
+ // read vertex indices
in >> dummy >> dummy;
- // read Ref phi_i, whatever that may be
+ // read Ref phi_i, whatever that may be
in >> dummy;
};
AssertThrow (in, ExcInvalidDBMeshFormat());
skip_empty_lines(in);
- // now read cells.
- // set up array of cells
+ // now read cells.
+ // set up array of cells
getline (in, line);
AssertThrow (line=="Quadrilaterals", ExcInvalidDBMESHInput(line));
in >> n_cells;
for (unsigned int cell=0; cell<n_cells; ++cell)
{
- // read in vertex numbers. they
- // are 1-based, so subtract one
+ // read in vertex numbers. they
+ // are 1-based, so subtract one
cells.push_back (CellData<dim>());
for (unsigned int i=0; i<GeometryInfo<dim>::vertices_per_cell; ++i)
- {
- in >> cells.back().vertices[i];
+ {
+ in >> cells.back().vertices[i];
- AssertThrow ((cells.back().vertices[i] >= 1)
- &&
- (static_cast<unsigned int>(cells.back().vertices[i]) <= vertices.size()),
- ExcInvalidVertexIndex(cell, cells.back().vertices[i]));
+ AssertThrow ((cells.back().vertices[i] >= 1)
+ &&
+ (static_cast<unsigned int>(cells.back().vertices[i]) <= vertices.size()),
+ ExcInvalidVertexIndex(cell, cells.back().vertices[i]));
- --cells.back().vertices[i];
- };
+ --cells.back().vertices[i];
+ };
- // read and discard Ref phi_i
+ // read and discard Ref phi_i
in >> dummy;
};
AssertThrow (in, ExcInvalidDBMeshFormat());
skip_empty_lines(in);
- // then there are again a whole lot
- // of fields of which I have no
- // clue what they mean. skip them
- // all and leave the interpretation
- // to other implementors...
+ // then there are again a whole lot
+ // of fields of which I have no
+ // clue what they mean. skip them
+ // all and leave the interpretation
+ // to other implementors...
while (getline(in,line), ((line.find("End")==std::string::npos) && (in)))
;
- // ok, so we are not at the end of
- // the file, that's it, mostly
+ // ok, so we are not at the end of
+ // the file, that's it, mostly
- // check that no forbidden arrays are used
+ // check that no forbidden arrays are used
Assert (subcelldata.check_consistency(dim), ExcInternalError());
AssertThrow (in, ExcIO());
- // do some clean-up on vertices...
+ // do some clean-up on vertices...
GridTools::delete_unused_vertices (vertices, cells, subcelldata);
- // ...and cells
+ // ...and cells
GridReordering<dim,spacedim>::invert_all_cells_of_negative_grid (vertices, cells);
GridReordering<dim,spacedim>::reorder_cells (cells);
tria->create_triangulation_compatibility (vertices, cells, subcelldata);
AssertThrow (in, ExcIO());
std::string line;
- // skip comments at start of file
+ // skip comments at start of file
getline (in, line);
unsigned int n_vertices;
unsigned int n_cells;
- // read cells, throw away rest of line
+ // read cells, throw away rest of line
in >> n_cells;
getline (in, line);
in >> n_vertices;
getline (in, line);
- // ignore following 8 lines
+ // ignore following 8 lines
for (unsigned int i=0; i<8; ++i)
getline (in, line);
- // set up array of cells
+ // set up array of cells
std::vector<CellData<2> > cells (n_cells);
SubCellData subcelldata;
for (unsigned int cell=0; cell<n_cells; ++cell)
{
- // note that since in the input
- // file we found the number of
- // cells at the top, there
- // should still be input here,
- // so check this:
+ // note that since in the input
+ // file we found the number of
+ // cells at the top, there
+ // should still be input here,
+ // so check this:
AssertThrow (in, ExcIO());
Assert (GeometryInfo<2>::vertices_per_cell == 4,
- ExcInternalError());
+ ExcInternalError());
for (unsigned int i=0; i<4; ++i)
- in >> cells[cell].vertices[i];
+ in >> cells[cell].vertices[i];
};
- // set up array of vertices
+ // set up array of vertices
std::vector<Point<2> > vertices (n_vertices);
for (unsigned int vertex=0; vertex<n_vertices; ++vertex)
{
double x[3];
- // read vertex
+ // read vertex
in >> x[0] >> x[1] >> x[2];
- // store vertex
+ // store vertex
for (unsigned int d=0; d<2; ++d)
- vertices[vertex](d) = x[d];
+ vertices[vertex](d) = x[d];
};
AssertThrow (in, ExcIO());
- // do some clean-up on vertices...
+ // do some clean-up on vertices...
GridTools::delete_unused_vertices (vertices, cells, subcelldata);
- // ... and cells
+ // ... and cells
GridReordering<2>::invert_all_cells_of_negative_grid (vertices, cells);
GridReordering<2>::reorder_cells (cells);
tria->create_triangulation_compatibility (vertices, cells, subcelldata);
static const unsigned int xda_to_dealII_map[] = {0,1,5,4,3,2,6,7};
std::string line;
- // skip comments at start of file
+ // skip comments at start of file
getline (in, line);
unsigned int n_vertices;
unsigned int n_cells;
- // read cells, throw away rest of line
+ // read cells, throw away rest of line
in >> n_cells;
getline (in, line);
in >> n_vertices;
getline (in, line);
- // ignore following 8 lines
+ // ignore following 8 lines
for (unsigned int i=0; i<8; ++i)
getline (in, line);
- // set up array of cells
+ // set up array of cells
std::vector<CellData<3> > cells (n_cells);
SubCellData subcelldata;
for (unsigned int cell=0; cell<n_cells; ++cell)
{
- // note that since in the input
- // file we found the number of
- // cells at the top, there
- // should still be input here,
- // so check this:
+ // note that since in the input
+ // file we found the number of
+ // cells at the top, there
+ // should still be input here,
+ // so check this:
AssertThrow (in, ExcIO());
Assert(GeometryInfo<3>::vertices_per_cell == 8,
- ExcInternalError());
+ ExcInternalError());
unsigned int xda_ordered_nodes[8];
for (unsigned int i=0; i<8; ++i)
- in >> xda_ordered_nodes[i];
+ in >> xda_ordered_nodes[i];
for (unsigned int i=0; i<8; i++)
- cells[cell].vertices[i] = xda_ordered_nodes[xda_to_dealII_map[i]];
+ cells[cell].vertices[i] = xda_ordered_nodes[xda_to_dealII_map[i]];
};
- // set up array of vertices
+ // set up array of vertices
std::vector<Point<3> > vertices (n_vertices);
for (unsigned int vertex=0; vertex<n_vertices; ++vertex)
{
double x[3];
- // read vertex
+ // read vertex
in >> x[0] >> x[1] >> x[2];
- // store vertex
+ // store vertex
for (unsigned int d=0; d<3; ++d)
- vertices[vertex](d) = x[d];
+ vertices[vertex](d) = x[d];
};
AssertThrow (in, ExcIO());
- // do some clean-up on vertices...
+ // do some clean-up on vertices...
GridTools::delete_unused_vertices (vertices, cells, subcelldata);
- // ... and cells
+ // ... and cells
GridReordering<3>::invert_all_cells_of_negative_grid (vertices, cells);
GridReordering<3>::reorder_cells (cells);
tria->create_triangulation_compatibility (vertices, cells, subcelldata);
in >> line;
- // first determine file format
+ // first determine file format
unsigned int gmsh_file_format = 0;
if (line == "$NOD")
gmsh_file_format = 1;
else
AssertThrow (false, ExcInvalidGMSHInput(line));
- // if file format is 2 or greater
- // then we also have to read the
- // rest of the header
+ // if file format is 2 or greater
+ // then we also have to read the
+ // rest of the header
if (gmsh_file_format == 2)
{
double version;
in >> version >> file_type >> data_size;
Assert ( (version >= 2.0) &&
- (version <= 2.2), ExcNotImplemented());
+ (version <= 2.2), ExcNotImplemented());
Assert (file_type == 0, ExcNotImplemented());
Assert (data_size == sizeof(double), ExcNotImplemented());
- // read the end of the header
- // and the first line of the
- // nodes description to synch
- // ourselves with the format 1
- // handling above
+ // read the end of the header
+ // and the first line of the
+ // nodes description to synch
+ // ourselves with the format 1
+ // handling above
in >> line;
AssertThrow (line == "$EndMeshFormat",
- ExcInvalidGMSHInput(line));
+ ExcInvalidGMSHInput(line));
in >> line;
- // if the next block is of kind
- // $PhysicalNames, ignore it
+ // if the next block is of kind
+ // $PhysicalNames, ignore it
if (line == "$PhysicalNames")
- {
- do
- {
- in >> line;
- }
- while (line != "$EndPhysicalNames");
- in >> line;
- }
-
- // but the next thing should,
- // in any case, be the list of
- // nodes:
+ {
+ do
+ {
+ in >> line;
+ }
+ while (line != "$EndPhysicalNames");
+ in >> line;
+ }
+
+ // but the next thing should,
+ // in any case, be the list of
+ // nodes:
AssertThrow (line == "$Nodes",
- ExcInvalidGMSHInput(line));
+ ExcInvalidGMSHInput(line));
}
- // now read the nodes list
+ // now read the nodes list
in >> n_vertices;
std::vector<Point<spacedim> > vertices (n_vertices);
- // set up mapping between numbering
- // in msh-file (nod) and in the
- // vertices vector
+ // set up mapping between numbering
+ // in msh-file (nod) and in the
+ // vertices vector
std::map<int,int> vertex_indices;
for (unsigned int vertex=0; vertex<n_vertices; ++vertex)
int vertex_number;
double x[3];
- // read vertex
+ // read vertex
in >> vertex_number
- >> x[0] >> x[1] >> x[2];
+ >> x[0] >> x[1] >> x[2];
for (unsigned int d=0; d<spacedim; ++d)
- vertices[vertex](d) = x[d];
- // store mapping
+ vertices[vertex](d) = x[d];
+ // store mapping
vertex_indices[vertex_number] = vertex;
}
- // Assert we reached the end of the block
+ // Assert we reached the end of the block
in >> line;
static const std::string end_nodes_marker[] = {"$ENDNOD", "$EndNodes" };
AssertThrow (line==end_nodes_marker[gmsh_file_format-1],
- ExcInvalidGMSHInput(line));
+ ExcInvalidGMSHInput(line));
- // Now read in next bit
+ // Now read in next bit
in >> line;
static const std::string begin_elements_marker[] = {"$ELM", "$Elements" };
AssertThrow (line==begin_elements_marker[gmsh_file_format-1],
- ExcInvalidGMSHInput(line));
+ ExcInvalidGMSHInput(line));
in >> n_cells;
- // set up array of cells
+ // set up array of cells
std::vector<CellData<dim> > cells;
SubCellData subcelldata;
for (unsigned int cell=0; cell<n_cells; ++cell)
{
- // note that since in the input
- // file we found the number of
- // cells at the top, there
- // should still be input here,
- // so check this:
+ // note that since in the input
+ // file we found the number of
+ // cells at the top, there
+ // should still be input here,
+ // so check this:
AssertThrow (in, ExcIO());
unsigned int cell_type;
*/
in >> dummy // ELM-NUMBER
- >> cell_type; // ELM-TYPE
+ >> cell_type; // ELM-TYPE
switch (gmsh_file_format)
- {
- case 1:
- {
- in >> material_id // REG-PHYS
- >> dummy // reg_elm
- >> nod_num;
- break;
- }
-
- case 2:
- {
- // read the tags; ignore
- // all but the first one
- unsigned int n_tags;
- in >> n_tags;
- if (n_tags > 0)
- in >> material_id;
- else
- material_id = 0;
-
- for (unsigned int i=1; i<n_tags; ++i)
- in >> dummy;
-
- nod_num = GeometryInfo<dim>::vertices_per_cell;
-
- break;
- }
-
- default:
- AssertThrow (false, ExcNotImplemented());
- }
+ {
+ case 1:
+ {
+ in >> material_id // REG-PHYS
+ >> dummy // reg_elm
+ >> nod_num;
+ break;
+ }
+
+ case 2:
+ {
+ // read the tags; ignore
+ // all but the first one
+ unsigned int n_tags;
+ in >> n_tags;
+ if (n_tags > 0)
+ in >> material_id;
+ else
+ material_id = 0;
+
+ for (unsigned int i=1; i<n_tags; ++i)
+ in >> dummy;
+
+ nod_num = GeometryInfo<dim>::vertices_per_cell;
+
+ break;
+ }
+
+ default:
+ AssertThrow (false, ExcNotImplemented());
+ }
/* `ELM-TYPE'
- defines the geometrical type of the N-th element:
- `1'
- Line (2 nodes, 1 edge).
+ defines the geometrical type of the N-th element:
+ `1'
+ Line (2 nodes, 1 edge).
- `3'
- Quadrangle (4 nodes, 4 edges).
+ `3'
+ Quadrangle (4 nodes, 4 edges).
- `5'
- Hexahedron (8 nodes, 12 edges, 6 faces).
+ `5'
+ Hexahedron (8 nodes, 12 edges, 6 faces).
- `15'
- Point (1 node).
+ `15'
+ Point (1 node).
*/
if (((cell_type == 1) && (dim == 1)) ||
- ((cell_type == 3) && (dim == 2)) ||
- ((cell_type == 5) && (dim == 3)))
- // found a cell
- {
- AssertThrow (nod_num == GeometryInfo<dim>::vertices_per_cell,
- ExcMessage ("Number of nodes does not coincide with the "
- "number required for this object"));
-
- // allocate and read indices
- cells.push_back (CellData<dim>());
- for (unsigned int i=0; i<GeometryInfo<dim>::vertices_per_cell; ++i)
- in >> cells.back().vertices[i];
+ ((cell_type == 3) && (dim == 2)) ||
+ ((cell_type == 5) && (dim == 3)))
+ // found a cell
+ {
+ AssertThrow (nod_num == GeometryInfo<dim>::vertices_per_cell,
+ ExcMessage ("Number of nodes does not coincide with the "
+ "number required for this object"));
+
+ // allocate and read indices
+ cells.push_back (CellData<dim>());
+ for (unsigned int i=0; i<GeometryInfo<dim>::vertices_per_cell; ++i)
+ in >> cells.back().vertices[i];
// to make sure that the cast wont fail
Assert(material_id<= std::numeric_limits<types::material_id_t>::max(),
Assert(material_id < types::invalid_material_id,
ExcIndexRange(material_id,0,types::invalid_material_id));
- cells.back().material_id = static_cast<types::material_id_t>(material_id);
+ cells.back().material_id = static_cast<types::material_id_t>(material_id);
- // transform from ucd to
- // consecutive numbering
- for (unsigned int i=0; i<GeometryInfo<dim>::vertices_per_cell; ++i)
- {
- AssertThrow (vertex_indices.find (cells.back().vertices[i]) !=
- vertex_indices.end(),
- ExcInvalidVertexIndex(cell, cells.back().vertices[i]));
+ // transform from ucd to
+ // consecutive numbering
+ for (unsigned int i=0; i<GeometryInfo<dim>::vertices_per_cell; ++i)
+ {
+ AssertThrow (vertex_indices.find (cells.back().vertices[i]) !=
+ vertex_indices.end(),
+ ExcInvalidVertexIndex(cell, cells.back().vertices[i]));
- // vertex with this index exists
- cells.back().vertices[i] = vertex_indices[cells.back().vertices[i]];
- }
- }
+ // vertex with this index exists
+ cells.back().vertices[i] = vertex_indices[cells.back().vertices[i]];
+ }
+ }
else
- if ((cell_type == 1) && ((dim == 2) || (dim == 3)))
- // boundary info
- {
- subcelldata.boundary_lines.push_back (CellData<1>());
- in >> subcelldata.boundary_lines.back().vertices[0]
- >> subcelldata.boundary_lines.back().vertices[1];
+ if ((cell_type == 1) && ((dim == 2) || (dim == 3)))
+ // boundary info
+ {
+ subcelldata.boundary_lines.push_back (CellData<1>());
+ in >> subcelldata.boundary_lines.back().vertices[0]
+ >> subcelldata.boundary_lines.back().vertices[1];
// to make sure that the cast wont fail
Assert(material_id<= std::numeric_limits<types::boundary_id_t>::max(),
Assert(material_id < types::internal_face_boundary_id,
ExcIndexRange(material_id,0,types::internal_face_boundary_id));
- subcelldata.boundary_lines.back().boundary_id
- = static_cast<types::boundary_id_t>(material_id);
-
- // transform from ucd to
- // consecutive numbering
- for (unsigned int i=0; i<2; ++i)
- if (vertex_indices.find (subcelldata.boundary_lines.back().vertices[i]) !=
- vertex_indices.end())
- // vertex with this index exists
- subcelldata.boundary_lines.back().vertices[i]
- = vertex_indices[subcelldata.boundary_lines.back().vertices[i]];
- else
- {
- // no such vertex index
- AssertThrow (false,
- ExcInvalidVertexIndex(cell,
- subcelldata.boundary_lines.back().vertices[i]));
- subcelldata.boundary_lines.back().vertices[i] =
- numbers::invalid_unsigned_int;
- };
- }
- else
- if ((cell_type == 3) && (dim == 3))
- // boundary info
- {
- subcelldata.boundary_quads.push_back (CellData<2>());
- in >> subcelldata.boundary_quads.back().vertices[0]
- >> subcelldata.boundary_quads.back().vertices[1]
- >> subcelldata.boundary_quads.back().vertices[2]
- >> subcelldata.boundary_quads.back().vertices[3];
-
- // to make sure that the cast wont fail
- Assert(material_id<= std::numeric_limits<types::boundary_id_t>::max(),
- ExcIndexRange(material_id,0,std::numeric_limits<types::boundary_id_t>::max()));
- // we use only boundary_ids in the range from 0 to types::internal_face_boundary_id-1
- Assert(material_id < types::internal_face_boundary_id,
- ExcIndexRange(material_id,0,types::internal_face_boundary_id));
-
- subcelldata.boundary_quads.back().boundary_id
- = static_cast<types::boundary_id_t>(material_id);
-
- // transform from gmsh to
- // consecutive numbering
- for (unsigned int i=0; i<4; ++i)
- if (vertex_indices.find (subcelldata.boundary_quads.back().vertices[i]) !=
- vertex_indices.end())
- // vertex with this index exists
- subcelldata.boundary_quads.back().vertices[i]
- = vertex_indices[subcelldata.boundary_quads.back().vertices[i]];
- else
- {
- // no such vertex index
- Assert (false,
- ExcInvalidVertexIndex(cell,
- subcelldata.boundary_quads.back().vertices[i]));
- subcelldata.boundary_quads.back().vertices[i] =
- numbers::invalid_unsigned_int;
- };
-
- }
- else
- if (cell_type == 15)
- {
- // Ignore vertices
- // but read the
- // number of nodes
- // given
- switch (gmsh_file_format)
- {
- case 1:
- {
- for (unsigned int i=0; i<nod_num; ++i)
- in >> dummy;
- break;
- }
- case 2:
- {
- in >> dummy;
- break;
- }
- }
- }
- else
- // cannot read this
- AssertThrow (false, ExcGmshUnsupportedGeometry(cell_type));
+ subcelldata.boundary_lines.back().boundary_id
+ = static_cast<types::boundary_id_t>(material_id);
+
+ // transform from ucd to
+ // consecutive numbering
+ for (unsigned int i=0; i<2; ++i)
+ if (vertex_indices.find (subcelldata.boundary_lines.back().vertices[i]) !=
+ vertex_indices.end())
+ // vertex with this index exists
+ subcelldata.boundary_lines.back().vertices[i]
+ = vertex_indices[subcelldata.boundary_lines.back().vertices[i]];
+ else
+ {
+ // no such vertex index
+ AssertThrow (false,
+ ExcInvalidVertexIndex(cell,
+ subcelldata.boundary_lines.back().vertices[i]));
+ subcelldata.boundary_lines.back().vertices[i] =
+ numbers::invalid_unsigned_int;
+ };
+ }
+ else
+ if ((cell_type == 3) && (dim == 3))
+ // boundary info
+ {
+ subcelldata.boundary_quads.push_back (CellData<2>());
+ in >> subcelldata.boundary_quads.back().vertices[0]
+ >> subcelldata.boundary_quads.back().vertices[1]
+ >> subcelldata.boundary_quads.back().vertices[2]
+ >> subcelldata.boundary_quads.back().vertices[3];
+
+ // to make sure that the cast wont fail
+ Assert(material_id<= std::numeric_limits<types::boundary_id_t>::max(),
+ ExcIndexRange(material_id,0,std::numeric_limits<types::boundary_id_t>::max()));
+ // we use only boundary_ids in the range from 0 to types::internal_face_boundary_id-1
+ Assert(material_id < types::internal_face_boundary_id,
+ ExcIndexRange(material_id,0,types::internal_face_boundary_id));
+
+ subcelldata.boundary_quads.back().boundary_id
+ = static_cast<types::boundary_id_t>(material_id);
+
+ // transform from gmsh to
+ // consecutive numbering
+ for (unsigned int i=0; i<4; ++i)
+ if (vertex_indices.find (subcelldata.boundary_quads.back().vertices[i]) !=
+ vertex_indices.end())
+ // vertex with this index exists
+ subcelldata.boundary_quads.back().vertices[i]
+ = vertex_indices[subcelldata.boundary_quads.back().vertices[i]];
+ else
+ {
+ // no such vertex index
+ Assert (false,
+ ExcInvalidVertexIndex(cell,
+ subcelldata.boundary_quads.back().vertices[i]));
+ subcelldata.boundary_quads.back().vertices[i] =
+ numbers::invalid_unsigned_int;
+ };
+
+ }
+ else
+ if (cell_type == 15)
+ {
+ // Ignore vertices
+ // but read the
+ // number of nodes
+ // given
+ switch (gmsh_file_format)
+ {
+ case 1:
+ {
+ for (unsigned int i=0; i<nod_num; ++i)
+ in >> dummy;
+ break;
+ }
+ case 2:
+ {
+ in >> dummy;
+ break;
+ }
+ }
+ }
+ else
+ // cannot read this
+ AssertThrow (false, ExcGmshUnsupportedGeometry(cell_type));
};
- // Assert we reached the end of the block
+ // Assert we reached the end of the block
in >> line;
static const std::string end_elements_marker[] = {"$ENDELM", "$EndElements" };
AssertThrow (line==end_elements_marker[gmsh_file_format-1],
- ExcInvalidGMSHInput(line));
+ ExcInvalidGMSHInput(line));
- // check that no forbidden arrays are used
+ // check that no forbidden arrays are used
Assert (subcelldata.check_consistency(dim), ExcInternalError());
AssertThrow (in, ExcIO());
- // check that we actually read some
- // cells.
+ // check that we actually read some
+ // cells.
AssertThrow(cells.size() > 0, ExcGmshNoCellInformation());
- // do some clean-up on
- // vertices...
+ // do some clean-up on
+ // vertices...
GridTools::delete_unused_vertices (vertices, cells, subcelldata);
- // ... and cells
+ // ... and cells
if(dim==spacedim)
GridReordering<dim,spacedim>::invert_all_cells_of_negative_grid (vertices, cells);
GridReordering<dim,spacedim>::reorder_cells (cells);
void GridIn<2>::read_netcdf (const std::string &filename)
{
#ifndef HAVE_LIBNETCDF
- // do something with unused
- // filename
+ // do something with unused
+ // filename
filename.c_str();
AssertThrow(false, ExcNeedsNetCDF());
#else
const unsigned int spacedim=2;
const bool output=false;
Assert (tria != 0, ExcNoTriangulationSelected());
- // this function assumes the TAU
- // grid format.
- //
- // This format stores 2d grids as
- // 3d grids. In particular, a 2d
- // grid of n_cells quadrilaterals
- // in the y=0 plane is duplicated
- // to y=1 to build n_cells
- // hexaeders. The surface
- // quadrilaterals of this 3d grid
- // are marked with boundary
- // marker. In the following we read
- // in all data required, find the
- // boundary marker associated with
- // the plane y=0, and extract the
- // corresponding 2d data to build a
- // Triangulation<2>.
-
- // In the following, we assume that
- // the 2d grid lies in the x-z
- // plane (y=0). I.e. we choose:
- // point[coord]=0, with coord=1
+ // this function assumes the TAU
+ // grid format.
+ //
+ // This format stores 2d grids as
+ // 3d grids. In particular, a 2d
+ // grid of n_cells quadrilaterals
+ // in the y=0 plane is duplicated
+ // to y=1 to build n_cells
+ // hexaeders. The surface
+ // quadrilaterals of this 3d grid
+ // are marked with boundary
+ // marker. In the following we read
+ // in all data required, find the
+ // boundary marker associated with
+ // the plane y=0, and extract the
+ // corresponding 2d data to build a
+ // Triangulation<2>.
+
+ // In the following, we assume that
+ // the 2d grid lies in the x-z
+ // plane (y=0). I.e. we choose:
+ // point[coord]=0, with coord=1
const unsigned int coord=1;
- // Also x-y-z (0-1-2) point
- // coordinates will be transformed
- // to x-y (x2d-y2d) coordinates.
- // With coord=1 as above, we have
- // x-z (0-2) -> (x2d-y2d)
+ // Also x-y-z (0-1-2) point
+ // coordinates will be transformed
+ // to x-y (x2d-y2d) coordinates.
+ // With coord=1 as above, we have
+ // x-z (0-2) -> (x2d-y2d)
const unsigned int x2d=0;
const unsigned int y2d=2;
- // For the case, the 2d grid lies
- // in x-y or y-z plane instead, the
- // following code must be extended
- // to find the right value for
- // coord, and setting x2d and y2d
- // accordingly.
-
- // First, open the file
+ // For the case, the 2d grid lies
+ // in x-y or y-z plane instead, the
+ // following code must be extended
+ // to find the right value for
+ // coord, and setting x2d and y2d
+ // accordingly.
+
+ // First, open the file
NcFile nc (filename.c_str());
AssertThrow(nc.is_valid(), ExcIO());
- // then read n_cells
+ // then read n_cells
NcDim *elements_dim=nc.get_dim("no_of_elements");
AssertThrow(elements_dim->is_valid(), ExcIO());
const unsigned int n_cells=elements_dim->size();
- // then we read
- // int marker(no_of_markers)
+ // then we read
+ // int marker(no_of_markers)
NcDim *marker_dim=nc.get_dim("no_of_markers");
AssertThrow(marker_dim->is_valid(), ExcIO());
const unsigned int n_markers=marker_dim->size();
marker_var->get_dim(0)->size())==n_markers, ExcIO());
std::vector<int> marker(n_markers);
- // use &* to convert
- // vector<int>::iterator to int *
+ // use &* to convert
+ // vector<int>::iterator to int *
marker_var->get(&*marker.begin(), n_markers);
if (output)
std::cout << "n_cell=" << n_cells << std::endl;
std::cout << "marker: ";
for (unsigned int i=0; i<n_markers; ++i)
- std::cout << marker[i] << " ";
+ std::cout << marker[i] << " ";
std::cout << std::endl;
}
- // next we read
- // int boundarymarker_of_surfaces(
- // no_of_surfaceelements)
+ // next we read
+ // int boundarymarker_of_surfaces(
+ // no_of_surfaceelements)
NcDim *bquads_dim=nc.get_dim("no_of_surfacequadrilaterals");
AssertThrow(bquads_dim->is_valid(), ExcIO());
const unsigned int n_bquads=bquads_dim->size();
std::vector<int> bmarker(n_bquads);
bmarker_var->get(&*bmarker.begin(), n_bquads);
- // for each marker count the
- // number of boundary quads
- // which carry this marker
+ // for each marker count the
+ // number of boundary quads
+ // which carry this marker
std::map<int, unsigned int> n_bquads_per_bmarker;
for (unsigned int i=0; i<n_markers; ++i)
{
- // the markers should all be
- // different
+ // the markers should all be
+ // different
AssertThrow(n_bquads_per_bmarker.find(marker[i])==
- n_bquads_per_bmarker.end(), ExcIO());
+ n_bquads_per_bmarker.end(), ExcIO());
n_bquads_per_bmarker[marker[i]]=
- count(bmarker.begin(), bmarker.end(), marker[i]);
+ count(bmarker.begin(), bmarker.end(), marker[i]);
}
- // Note: the n_bquads_per_bmarker
- // map could be used to find the
- // right coord by finding the
- // marker0 such that
- // a/ n_bquads_per_bmarker[marker0]==n_cells
- // b/ point[coord]==0,
- // Condition a/ would hold for at
- // least two markers, marker0 and
- // marker1, whereas b/ would hold
- // for marker0 only. For marker1 we
- // then had point[coord]=constant
- // with e.g. constant=1 or -1
+ // Note: the n_bquads_per_bmarker
+ // map could be used to find the
+ // right coord by finding the
+ // marker0 such that
+ // a/ n_bquads_per_bmarker[marker0]==n_cells
+ // b/ point[coord]==0,
+ // Condition a/ would hold for at
+ // least two markers, marker0 and
+ // marker1, whereas b/ would hold
+ // for marker0 only. For marker1 we
+ // then had point[coord]=constant
+ // with e.g. constant=1 or -1
if (output)
{
std::cout << "n_bquads_per_bmarker: " << std::endl;
std::map<int, unsigned int>::const_iterator
- iter=n_bquads_per_bmarker.begin();
+ iter=n_bquads_per_bmarker.begin();
for (; iter!=n_bquads_per_bmarker.end(); ++iter)
- std::cout << " n_bquads_per_bmarker[" << iter->first
- << "]=" << iter->second << std::endl;
+ std::cout << " n_bquads_per_bmarker[" << iter->first
+ << "]=" << iter->second << std::endl;
}
- // next we read
- // int points_of_surfacequadrilaterals(
- // no_of_surfacequadrilaterals,
- // points_per_surfacequadrilateral)
+ // next we read
+ // int points_of_surfacequadrilaterals(
+ // no_of_surfacequadrilaterals,
+ // points_per_surfacequadrilateral)
NcDim *quad_vertices_dim=nc.get_dim("points_per_surfacequadrilateral");
AssertThrow(quad_vertices_dim->is_valid(), ExcIO());
const unsigned int vertices_per_quad=quad_vertices_dim->size();
{
std::cout << "vertex_indices:" << std::endl;
for (unsigned int i=0, v=0; i<n_bquads; ++i)
- {
- for (unsigned int j=0; j<vertices_per_quad; ++j)
- std::cout << vertex_indices[v++] << " ";
- std::cout << std::endl;
- }
+ {
+ for (unsigned int j=0; j<vertices_per_quad; ++j)
+ std::cout << vertex_indices[v++] << " ";
+ std::cout << std::endl;
+ }
}
- // next we read
- // double points_xc(no_of_points)
- // double points_yc(no_of_points)
- // double points_zc(no_of_points)
+ // next we read
+ // double points_xc(no_of_points)
+ // double points_yc(no_of_points)
+ // double points_zc(no_of_points)
NcDim *vertices_dim=nc.get_dim("no_of_points");
AssertThrow(vertices_dim->is_valid(), ExcIO());
const unsigned int n_vertices=vertices_dim->size();
AssertThrow(points_yc->num_dims()==1, ExcIO());
AssertThrow(points_zc->num_dims()==1, ExcIO());
AssertThrow(points_yc->get_dim(0)->size()==
- static_cast<int>(n_vertices), ExcIO());
+ static_cast<int>(n_vertices), ExcIO());
AssertThrow(points_zc->get_dim(0)->size()==
- static_cast<int>(n_vertices), ExcIO());
+ static_cast<int>(n_vertices), ExcIO());
AssertThrow(points_xc->get_dim(0)->size()==
- static_cast<int>(n_vertices), ExcIO());
+ static_cast<int>(n_vertices), ExcIO());
std::vector<std::vector<double> > point_values(
3, std::vector<double> (n_vertices));
points_xc->get(&*point_values[0].begin(), n_vertices);
points_yc->get(&*point_values[1].begin(), n_vertices);
points_zc->get(&*point_values[2].begin(), n_vertices);
- // and fill the vertices
+ // and fill the vertices
std::vector<Point<spacedim> > vertices (n_vertices);
for (unsigned int i=0; i<n_vertices; ++i)
{
vertices[i](1)=point_values[y2d][i];
}
- // For all boundary quads in the
- // point[coord]=0 plane add the
- // bmarker to zero_plane_markers
+ // For all boundary quads in the
+ // point[coord]=0 plane add the
+ // bmarker to zero_plane_markers
std::map<int, bool> zero_plane_markers;
for (unsigned int quad=0; quad<n_bquads; ++quad)
{
bool zero_plane=true;
for (unsigned int i=0; i<vertices_per_quad; ++i)
- if (point_values[coord][vertex_indices[quad*vertices_per_quad+i]]!=0)
- {
- zero_plane=false;
- break;
- }
+ if (point_values[coord][vertex_indices[quad*vertices_per_quad+i]]!=0)
+ {
+ zero_plane=false;
+ break;
+ }
if (zero_plane)
- zero_plane_markers[bmarker[quad]]=true;
+ zero_plane_markers[bmarker[quad]]=true;
}
unsigned int sum_of_zero_plane_cells=0;
for (std::map<int, bool>::const_iterator iter=zero_plane_markers.begin();
{
sum_of_zero_plane_cells+=n_bquads_per_bmarker[iter->first];
if (output)
- std::cout << "bmarker=" << iter->first << std::endl;
+ std::cout << "bmarker=" << iter->first << std::endl;
}
AssertThrow(sum_of_zero_plane_cells==n_cells, ExcIO());
- // fill cells with all quads
- // associated with
- // zero_plane_markers
+ // fill cells with all quads
+ // associated with
+ // zero_plane_markers
std::vector<CellData<dim> > cells(n_cells);
for (unsigned int quad=0, cell=0; quad<n_bquads; ++quad)
{
bool zero_plane=false;
for (std::map<int, bool>::const_iterator iter=zero_plane_markers.begin();
- iter != zero_plane_markers.end(); ++iter)
- if (bmarker[quad]==iter->first)
- {
- zero_plane=true;
- break;
- }
+ iter != zero_plane_markers.end(); ++iter)
+ if (bmarker[quad]==iter->first)
+ {
+ zero_plane=true;
+ break;
+ }
if (zero_plane)
- {
- for (unsigned int i=0; i<vertices_per_quad; ++i)
- {
- Assert(point_values[coord][vertex_indices[
- quad*vertices_per_quad+i]]==0, ExcNotImplemented());
- cells[cell].vertices[i]=vertex_indices[quad*vertices_per_quad+i];
- }
- ++cell;
- }
+ {
+ for (unsigned int i=0; i<vertices_per_quad; ++i)
+ {
+ Assert(point_values[coord][vertex_indices[
+ quad*vertices_per_quad+i]]==0, ExcNotImplemented());
+ cells[cell].vertices[i]=vertex_indices[quad*vertices_per_quad+i];
+ }
+ ++cell;
+ }
}
SubCellData subcelldata;
const unsigned int spacedim=3;
const bool output=false;
Assert (tria != 0, ExcNoTriangulationSelected());
- // this function assumes the TAU
- // grid format.
+ // this function assumes the TAU
+ // grid format.
- // First, open the file
+ // First, open the file
NcFile nc (filename.c_str());
AssertThrow(nc.is_valid(), ExcIO());
- // then read n_cells
+ // then read n_cells
NcDim *elements_dim=nc.get_dim("no_of_elements");
AssertThrow(elements_dim->is_valid(), ExcIO());
const unsigned int n_cells=elements_dim->size();
if (output)
std::cout << "n_cell=" << n_cells << std::endl;
- // and n_hexes
+ // and n_hexes
NcDim *hexes_dim=nc.get_dim("no_of_hexaeders");
AssertThrow(hexes_dim->is_valid(), ExcIO());
const unsigned int n_hexes=hexes_dim->size();
AssertThrow(n_hexes==n_cells,
- ExcMessage("deal.II can handle purely hexaedral grids, only."));
+ ExcMessage("deal.II can handle purely hexaedral grids, only."));
- // next we read
- // int points_of_hexaeders(
- // no_of_hexaeders,
- // points_per_hexaeder)
+ // next we read
+ // int points_of_hexaeders(
+ // no_of_hexaeders,
+ // points_per_hexaeder)
NcDim *hex_vertices_dim=nc.get_dim("points_per_hexaeder");
AssertThrow(hex_vertices_dim->is_valid(), ExcIO());
const unsigned int vertices_per_hex=hex_vertices_dim->size();
vertex_indices_var->get_dim(1)->size())==vertices_per_hex, ExcIO());
std::vector<int> vertex_indices(n_cells*vertices_per_hex);
- // use &* to convert
- // vector<int>::iterator to int *
+ // use &* to convert
+ // vector<int>::iterator to int *
vertex_indices_var->get(&*vertex_indices.begin(), n_cells, vertices_per_hex);
for (unsigned int i=0; i<vertex_indices.size(); ++i)
{
std::cout << "vertex_indices:" << std::endl;
for (unsigned int cell=0, v=0; cell<n_cells; ++cell)
- {
- for (unsigned int i=0; i<vertices_per_hex; ++i)
- std::cout << vertex_indices[v++] << " ";
- std::cout << std::endl;
- }
+ {
+ for (unsigned int i=0; i<vertices_per_hex; ++i)
+ std::cout << vertex_indices[v++] << " ";
+ std::cout << std::endl;
+ }
}
- // next we read
- // double points_xc(no_of_points)
- // double points_yc(no_of_points)
- // double points_zc(no_of_points)
+ // next we read
+ // double points_xc(no_of_points)
+ // double points_yc(no_of_points)
+ // double points_zc(no_of_points)
NcDim *vertices_dim=nc.get_dim("no_of_points");
AssertThrow(vertices_dim->is_valid(), ExcIO());
const unsigned int n_vertices=vertices_dim->size();
AssertThrow(points_yc->num_dims()==1, ExcIO());
AssertThrow(points_zc->num_dims()==1, ExcIO());
AssertThrow(points_yc->get_dim(0)->size()==
- static_cast<int>(n_vertices), ExcIO());
+ static_cast<int>(n_vertices), ExcIO());
AssertThrow(points_zc->get_dim(0)->size()==
- static_cast<int>(n_vertices), ExcIO());
+ static_cast<int>(n_vertices), ExcIO());
AssertThrow(points_xc->get_dim(0)->size()==
- static_cast<int>(n_vertices), ExcIO());
+ static_cast<int>(n_vertices), ExcIO());
std::vector<std::vector<double> > point_values(
3, std::vector<double> (n_vertices));
- // we switch y and z
+ // we switch y and z
const bool switch_y_z=false;
points_xc->get(&*point_values[0].begin(), n_vertices);
if (switch_y_z)
points_zc->get(&*point_values[2].begin(), n_vertices);
}
- // and fill the vertices
+ // and fill the vertices
std::vector<Point<spacedim> > vertices (n_vertices);
for (unsigned int i=0; i<n_vertices; ++i)
{
vertices[i](2)=point_values[2][i];
}
- // and cells
+ // and cells
std::vector<CellData<dim> > cells(n_cells);
for (unsigned int cell=0; cell<n_cells; ++cell)
for (unsigned int i=0; i<vertices_per_hex; ++i)
cells[cell].vertices[i]=vertex_indices[cell*vertices_per_hex+i];
- // for setting up the SubCellData
- // we read the vertex indices of
- // the boundary quadrilaterals and
- // their boundary markers
+ // for setting up the SubCellData
+ // we read the vertex indices of
+ // the boundary quadrilaterals and
+ // their boundary markers
- // first we read
- // int points_of_surfacequadrilaterals(
- // no_of_surfacequadrilaterals,
- // points_per_surfacequadrilateral)
+ // first we read
+ // int points_of_surfacequadrilaterals(
+ // no_of_surfacequadrilaterals,
+ // points_per_surfacequadrilateral)
NcDim *quad_vertices_dim=nc.get_dim("points_per_surfacequadrilateral");
AssertThrow(quad_vertices_dim->is_valid(), ExcIO());
const unsigned int vertices_per_quad=quad_vertices_dim->size();
AssertThrow(bvertex_indices_var->num_dims()==2, ExcIO());
const unsigned int n_bquads=bvertex_indices_var->get_dim(0)->size();
AssertThrow(static_cast<unsigned int>(
- bvertex_indices_var->get_dim(1)->size())==
- GeometryInfo<dim>::vertices_per_face, ExcIO());
+ bvertex_indices_var->get_dim(1)->size())==
+ GeometryInfo<dim>::vertices_per_face, ExcIO());
std::vector<int> bvertex_indices(n_bquads*vertices_per_quad);
bvertex_indices_var->get(&*bvertex_indices.begin(), n_bquads, vertices_per_quad);
{
std::cout << "bquads: ";
for (unsigned int i=0; i<n_bquads; ++i)
- {
- for (unsigned int v=0; v<GeometryInfo<dim>::vertices_per_face; ++v)
- std::cout << bvertex_indices[
- i*GeometryInfo<dim>::vertices_per_face+v] << " ";
- std::cout << std::endl;
- }
+ {
+ for (unsigned int v=0; v<GeometryInfo<dim>::vertices_per_face; ++v)
+ std::cout << bvertex_indices[
+ i*GeometryInfo<dim>::vertices_per_face+v] << " ";
+ std::cout << std::endl;
+ }
}
- // next we read
- // int boundarymarker_of_surfaces(
- // no_of_surfaceelements)
+ // next we read
+ // int boundarymarker_of_surfaces(
+ // no_of_surfaceelements)
NcDim *bquads_dim=nc.get_dim("no_of_surfacequadrilaterals");
AssertThrow(bquads_dim->is_valid(), ExcIO());
AssertThrow(static_cast<unsigned int>(
- bquads_dim->size())==n_bquads, ExcIO());
+ bquads_dim->size())==n_bquads, ExcIO());
NcVar *bmarker_var=nc.get_var("boundarymarker_of_surfaces");
AssertThrow(bmarker_var->is_valid(), ExcIO());
std::vector<int> bmarker(n_bquads);
bmarker_var->get(&*bmarker.begin(), n_bquads);
- // we only handle boundary
- // indicators that fit into an
- // types::boundary_id_t. Also, we don't
- // take types::internal_face_boundary_id
+ // we only handle boundary
+ // indicators that fit into an
+ // types::boundary_id_t. Also, we don't
+ // take types::internal_face_boundary_id
// as it denotes an internal face
for (unsigned int i=0; i<bmarker.size(); ++i)
Assert(0<=bmarker[i] && bmarker[i]<types::internal_face_boundary_id, ExcIO());
- // finally we setup the boundary
- // information
+ // finally we setup the boundary
+ // information
SubCellData subcelldata;
subcelldata.boundary_quads.resize(n_bquads);
for (unsigned int i=0; i<n_bquads; ++i)
{
for (unsigned int v=0; v<GeometryInfo<dim>::vertices_per_face; ++v)
- subcelldata.boundary_quads[i].vertices[v]=bvertex_indices[
- i*GeometryInfo<dim>::vertices_per_face+v];
+ subcelldata.boundary_quads[i].vertices[v]=bvertex_indices[
+ i*GeometryInfo<dim>::vertices_per_face+v];
subcelldata.boundary_quads[i].boundary_id
= static_cast<types::boundary_id_t>(bmarker[i]);
}
template <int dim, int spacedim>
void GridIn<dim, spacedim>::parse_tecplot_header(std::string &header,
- std::vector<unsigned int> &tecplot2deal,
- unsigned int &n_vars,
- unsigned int &n_vertices,
- unsigned int &n_cells,
- std::vector<unsigned int> &IJK,
- bool &structured,
- bool &blocked)
+ std::vector<unsigned int> &tecplot2deal,
+ unsigned int &n_vars,
+ unsigned int &n_vertices,
+ unsigned int &n_cells,
+ std::vector<unsigned int> &IJK,
+ bool &structured,
+ bool &blocked)
{
Assert(tecplot2deal.size()==dim, ExcInternalError());
Assert(IJK.size()==dim, ExcInternalError());
- // initialize the output variables
+ // initialize the output variables
n_vars=0;
n_vertices=0;
n_cells=0;
switch(dim)
{
case 3:
- IJK[2]=0;
+ IJK[2]=0;
case 2:
- IJK[1]=0;
+ IJK[1]=0;
case 1:
- IJK[0]=0;
+ IJK[0]=0;
}
structured=true;
blocked=false;
- // convert the string to upper case
+ // convert the string to upper case
std::transform(header.begin(),header.end(),header.begin(),::toupper);
- // replace all tabs, commas, newlines by
- // whitespaces
+ // replace all tabs, commas, newlines by
+ // whitespaces
std::replace(header.begin(),header.end(),'\t',' ');
std::replace(header.begin(),header.end(),',',' ');
std::replace(header.begin(),header.end(),'\n',' ');
- // now remove whitespace in front of and
- // after '='
+ // now remove whitespace in front of and
+ // after '='
std::string::size_type pos=header.find("=");
while(pos!=static_cast<std::string::size_type>(std::string::npos))
header.erase(pos+1,1);
else if (header[pos-1]==' ')
{
- header.erase(pos-1,1);
- --pos;
+ header.erase(pos-1,1);
+ --pos;
}
else
pos=header.find("=",++pos);
- // split the string into individual entries
+ // split the string into individual entries
std::vector<std::string> entries=Utilities::break_text_into_lines(header,1,' ');
- // now go through the list and try to extract
+ // now go through the list and try to extract
for (unsigned int i=0; i<entries.size(); ++i)
{
if (Utilities::match_at_string_start(entries[i],"VARIABLES=\""))
- {
- ++n_vars;
- // we assume, that the first variable
- // is x or no coordinate at all (not y or z)
- if (Utilities::match_at_string_start(entries[i],"VARIABLES=\"X\""))
- {
- tecplot2deal[0]=0;
- }
- ++i;
- while(entries[i][0]=='"')
- {
- if (entries[i]=="\"X\"")
- tecplot2deal[0]=n_vars;
- else if (entries[i]=="\"Y\"")
- {
- // we assume, that y contains
- // zero data in 1d, so do
- // nothing
- if (dim>1)
- tecplot2deal[1]=n_vars;
- }
- else if (entries[i]=="\"Z\"")
- {
- // we assume, that z contains
- // zero data in 1d and 2d, so
- // do nothing
- if (dim>2)
- tecplot2deal[2]=n_vars;
- }
- ++n_vars;
- ++i;
- }
- // set i back, so that the next
- // string is treated correctly
- --i;
-
- AssertThrow(n_vars>=dim,
- ExcMessage("Tecplot file must contain at least one variable for each dimension"));
- for (unsigned int i=1; i<dim; ++i)
- AssertThrow(tecplot2deal[i]>0,
- ExcMessage("Tecplot file must contain at least one variable for each dimension."));
- }
+ {
+ ++n_vars;
+ // we assume, that the first variable
+ // is x or no coordinate at all (not y or z)
+ if (Utilities::match_at_string_start(entries[i],"VARIABLES=\"X\""))
+ {
+ tecplot2deal[0]=0;
+ }
+ ++i;
+ while(entries[i][0]=='"')
+ {
+ if (entries[i]=="\"X\"")
+ tecplot2deal[0]=n_vars;
+ else if (entries[i]=="\"Y\"")
+ {
+ // we assume, that y contains
+ // zero data in 1d, so do
+ // nothing
+ if (dim>1)
+ tecplot2deal[1]=n_vars;
+ }
+ else if (entries[i]=="\"Z\"")
+ {
+ // we assume, that z contains
+ // zero data in 1d and 2d, so
+ // do nothing
+ if (dim>2)
+ tecplot2deal[2]=n_vars;
+ }
+ ++n_vars;
+ ++i;
+ }
+ // set i back, so that the next
+ // string is treated correctly
+ --i;
+
+ AssertThrow(n_vars>=dim,
+ ExcMessage("Tecplot file must contain at least one variable for each dimension"));
+ for (unsigned int i=1; i<dim; ++i)
+ AssertThrow(tecplot2deal[i]>0,
+ ExcMessage("Tecplot file must contain at least one variable for each dimension."));
+ }
else if (Utilities::match_at_string_start(entries[i],"ZONETYPE=ORDERED"))
- structured=true;
+ structured=true;
else if (Utilities::match_at_string_start(entries[i],"ZONETYPE=FELINESEG") && dim==1)
- structured=false;
+ structured=false;
else if (Utilities::match_at_string_start(entries[i],"ZONETYPE=FEQUADRILATERAL") && dim==2)
- structured=false;
+ structured=false;
else if (Utilities::match_at_string_start(entries[i],"ZONETYPE=FEBRICK") && dim==3)
- structured=false;
+ structured=false;
else if (Utilities::match_at_string_start(entries[i],"ZONETYPE="))
- // unsupported ZONETYPE
- {
- AssertThrow(false,ExcMessage("The tecplot file contains an unsupported ZONETYPE."));
- }
+ // unsupported ZONETYPE
+ {
+ AssertThrow(false,ExcMessage("The tecplot file contains an unsupported ZONETYPE."));
+ }
else if (Utilities::match_at_string_start(entries[i],"DATAPACKING=POINT"))
- blocked=false;
+ blocked=false;
else if (Utilities::match_at_string_start(entries[i],"DATAPACKING=BLOCK"))
- blocked=true;
+ blocked=true;
else if (Utilities::match_at_string_start(entries[i],"F=POINT"))
- {
- structured=true;
- blocked=false;
- }
+ {
+ structured=true;
+ blocked=false;
+ }
else if (Utilities::match_at_string_start(entries[i],"F=BLOCK"))
- {
- structured=true;
- blocked=true;
- }
+ {
+ structured=true;
+ blocked=true;
+ }
else if (Utilities::match_at_string_start(entries[i],"F=FEPOINT"))
- {
- structured=false;
- blocked=false;
- }
+ {
+ structured=false;
+ blocked=false;
+ }
else if (Utilities::match_at_string_start(entries[i],"F=FEBLOCK"))
- {
- structured=false;
- blocked=true;
- }
+ {
+ structured=false;
+ blocked=true;
+ }
else if (Utilities::match_at_string_start(entries[i],"ET=QUADRILATERAL") && dim==2)
- structured=false;
+ structured=false;
else if (Utilities::match_at_string_start(entries[i],"ET=BRICK") && dim==3)
- structured=false;
+ structured=false;
else if (Utilities::match_at_string_start(entries[i],"ET="))
- // unsupported ElementType
- {
- AssertThrow(false,ExcMessage("The tecplot file contains an unsupported ElementType."));
- }
+ // unsupported ElementType
+ {
+ AssertThrow(false,ExcMessage("The tecplot file contains an unsupported ElementType."));
+ }
else if (Utilities::match_at_string_start(entries[i],"I="))
- IJK[0]=Utilities::get_integer_at_position(entries[i],2).first;
+ IJK[0]=Utilities::get_integer_at_position(entries[i],2).first;
else if (Utilities::match_at_string_start(entries[i],"J="))
- {
- IJK[1]=Utilities::get_integer_at_position(entries[i],2).first;
- AssertThrow(dim>1 || IJK[1]==1,
- ExcMessage("Parameter 'J=' found in tecplot, although this is only possible for dimensions greater than 1."));
- }
+ {
+ IJK[1]=Utilities::get_integer_at_position(entries[i],2).first;
+ AssertThrow(dim>1 || IJK[1]==1,
+ ExcMessage("Parameter 'J=' found in tecplot, although this is only possible for dimensions greater than 1."));
+ }
else if (Utilities::match_at_string_start(entries[i],"K="))
- {
- IJK[2]=Utilities::get_integer_at_position(entries[i],2).first;
- AssertThrow(dim>2 || IJK[2]==1,
- ExcMessage("Parameter 'K=' found in tecplot, although this is only possible for dimensions greater than 2."));
- }
+ {
+ IJK[2]=Utilities::get_integer_at_position(entries[i],2).first;
+ AssertThrow(dim>2 || IJK[2]==1,
+ ExcMessage("Parameter 'K=' found in tecplot, although this is only possible for dimensions greater than 2."));
+ }
else if (Utilities::match_at_string_start(entries[i],"N="))
- n_vertices=Utilities::get_integer_at_position(entries[i],2).first;
+ n_vertices=Utilities::get_integer_at_position(entries[i],2).first;
else if (Utilities::match_at_string_start(entries[i],"E="))
- n_cells=Utilities::get_integer_at_position(entries[i],2).first;
+ n_cells=Utilities::get_integer_at_position(entries[i],2).first;
}
- // now we have read all the fields we are
- // interested in. do some checks and
- // calculate the variables
+ // now we have read all the fields we are
+ // interested in. do some checks and
+ // calculate the variables
if (structured)
{
n_vertices=1;
n_cells=1;
for (unsigned int d=0; d<dim; ++d)
- {
- AssertThrow(IJK[d]>0,
- ExcMessage("Tecplot file does not contain a complete and consistent set of parameters"));
- n_vertices*=IJK[d];
- n_cells*=(IJK[d]-1);
- }
+ {
+ AssertThrow(IJK[d]>0,
+ ExcMessage("Tecplot file does not contain a complete and consistent set of parameters"));
+ n_vertices*=IJK[d];
+ n_cells*=(IJK[d]-1);
+ }
}
else
{
AssertThrow(n_vertices>0,
- ExcMessage("Tecplot file does not contain a complete and consistent set of parameters"));
+ ExcMessage("Tecplot file does not contain a complete and consistent set of parameters"));
if (n_cells==0)
- // this means an error, although
- // tecplot itself accepts entries like
- // 'J=20' instead of 'E=20'. therefore,
- // take the max of IJK
- n_cells=*std::max_element(IJK.begin(),IJK.end());
+ // this means an error, although
+ // tecplot itself accepts entries like
+ // 'J=20' instead of 'E=20'. therefore,
+ // take the max of IJK
+ n_cells=*std::max_element(IJK.begin(),IJK.end());
AssertThrow(n_cells>0,
- ExcMessage("Tecplot file does not contain a complete and consistent set of parameters"));
+ ExcMessage("Tecplot file does not contain a complete and consistent set of parameters"));
}
}
Assert (tria != 0, ExcNoTriangulationSelected());
AssertThrow (in, ExcIO());
- // skip comments at start of file
+ // skip comments at start of file
skip_comment_lines (in, '#');
- // some strings for parsing the header
+ // some strings for parsing the header
std::string line, header;
- // first, concatenate all header lines
- // create a searchstring with almost all
- // letters. exclude e and E from the letters
- // to search, as they might appear in
- // exponential notation
+ // first, concatenate all header lines
+ // create a searchstring with almost all
+ // letters. exclude e and E from the letters
+ // to search, as they might appear in
+ // exponential notation
std::string letters ="abcdfghijklmnopqrstuvwxyzABCDFGHIJKLMNOPQRSTUVWXYZ";
getline(in,line);
getline(in,line);
}
- // now create some variables holding
- // important information on the mesh, get
- // this information from the header string
+ // now create some variables holding
+ // important information on the mesh, get
+ // this information from the header string
std::vector<unsigned int> tecplot2deal(dim);
std::vector<unsigned int> IJK(dim);
unsigned int n_vars,
blocked;
parse_tecplot_header(header,
- tecplot2deal,n_vars,n_vertices,n_cells,IJK,
- structured,blocked);
-
- // reserve space for vertices. note, that in
- // tecplot vertices are ordered beginning
- // with 1, whereas in deal all indices start
- // with 0. in order not to use -1 for all the
- // connectivity information, a 0th vertex
- // (unused) is inserted at the origin.
+ tecplot2deal,n_vars,n_vertices,n_cells,IJK,
+ structured,blocked);
+
+ // reserve space for vertices. note, that in
+ // tecplot vertices are ordered beginning
+ // with 1, whereas in deal all indices start
+ // with 0. in order not to use -1 for all the
+ // connectivity information, a 0th vertex
+ // (unused) is inserted at the origin.
std::vector<Point<spacedim> > vertices(n_vertices+1);
vertices[0]=Point<spacedim>();
- // reserve space for cells
+ // reserve space for cells
std::vector<CellData<dim> > cells(n_cells);
SubCellData subcelldata;
if (blocked)
{
- // blocked data format. first we get all
- // the values of the first variable for
- // all points, after that we get all
- // values for the second variable and so
- // on.
-
- // dummy variable to read in all the info
- // we do not want to use
+ // blocked data format. first we get all
+ // the values of the first variable for
+ // all points, after that we get all
+ // values for the second variable and so
+ // on.
+
+ // dummy variable to read in all the info
+ // we do not want to use
double dummy;
- // which is the first index to read in
- // the loop (see below)
+ // which is the first index to read in
+ // the loop (see below)
unsigned int next_index=0;
- // note, that we have already read the
- // first line containing the first variable
+ // note, that we have already read the
+ // first line containing the first variable
if (tecplot2deal[0]==0)
- {
- // we need the information in this
- // line, so extract it
- std::vector<std::string> first_var=Utilities::break_text_into_lines(line,1);
- char *endptr;
- for (unsigned int i=1; i<first_var.size()+1; ++i)
- vertices[i](0) = std::strtod (first_var[i-1].c_str(), &endptr);
-
- // if there are many points, the data
- // for this var might continue in the
- // next line(s)
- for (unsigned int j=first_var.size()+1; j<n_vertices+1; ++j)
- in>>vertices[j](next_index);
- // now we got all values of the first
- // variable, so increase the counter
- next_index=1;
- }
-
- // main loop over all variables
+ {
+ // we need the information in this
+ // line, so extract it
+ std::vector<std::string> first_var=Utilities::break_text_into_lines(line,1);
+ char *endptr;
+ for (unsigned int i=1; i<first_var.size()+1; ++i)
+ vertices[i](0) = std::strtod (first_var[i-1].c_str(), &endptr);
+
+ // if there are many points, the data
+ // for this var might continue in the
+ // next line(s)
+ for (unsigned int j=first_var.size()+1; j<n_vertices+1; ++j)
+ in>>vertices[j](next_index);
+ // now we got all values of the first
+ // variable, so increase the counter
+ next_index=1;
+ }
+
+ // main loop over all variables
for (unsigned int i=1; i<n_vars; ++i)
- {
- // if we read all the important
- // variables and do not want to
- // read further, because we are
- // using a structured grid, we can
- // stop here (and skip, for
- // example, a whole lot of solution
- // variables)
- if (next_index==dim && structured)
- break;
-
- if ((next_index<dim) && (i==tecplot2deal[next_index]))
- {
- // we need this line, read it in
- for (unsigned int j=1; j<n_vertices+1; ++j)
- in>>vertices[j](next_index);
- ++next_index;
- }
- else
- {
- // we do not need this line, read
- // it in and discard it
- for (unsigned int j=1; j<n_vertices+1; ++j)
- in>>dummy;
- }
- }
+ {
+ // if we read all the important
+ // variables and do not want to
+ // read further, because we are
+ // using a structured grid, we can
+ // stop here (and skip, for
+ // example, a whole lot of solution
+ // variables)
+ if (next_index==dim && structured)
+ break;
+
+ if ((next_index<dim) && (i==tecplot2deal[next_index]))
+ {
+ // we need this line, read it in
+ for (unsigned int j=1; j<n_vertices+1; ++j)
+ in>>vertices[j](next_index);
+ ++next_index;
+ }
+ else
+ {
+ // we do not need this line, read
+ // it in and discard it
+ for (unsigned int j=1; j<n_vertices+1; ++j)
+ in>>dummy;
+ }
+ }
Assert(next_index==dim, ExcInternalError());
}
else
{
- // the data is not blocked, so we get all
- // the variables for one point, then the
- // next and so on. create a vector to
- // hold these components
+ // the data is not blocked, so we get all
+ // the variables for one point, then the
+ // next and so on. create a vector to
+ // hold these components
std::vector<double> vars(n_vars);
- // now fill the first vertex. note, that we
- // have already read the first line
- // containing the first vertex
+ // now fill the first vertex. note, that we
+ // have already read the first line
+ // containing the first vertex
std::vector<std::string> first_vertex=Utilities::break_text_into_lines(line,1);
char *endptr;
for (unsigned int d=0; d<dim; ++d)
- vertices[1](d) = std::strtod (first_vertex[tecplot2deal[d]].c_str(), &endptr);
+ vertices[1](d) = std::strtod (first_vertex[tecplot2deal[d]].c_str(), &endptr);
- // read the remaining vertices from the
- // list
+ // read the remaining vertices from the
+ // list
for (unsigned int v=2; v<n_vertices+1; ++v)
- {
- for (unsigned int i=0; i<n_vars; ++i)
- in>>vars[i];
- // fill the vertex
- // coordinates. respect the position
- // of coordinates in the list of
- // variables
- for (unsigned int i=0; i<dim; ++i)
- vertices[v](i)=vars[tecplot2deal[i]];
- }
+ {
+ for (unsigned int i=0; i<n_vars; ++i)
+ in>>vars[i];
+ // fill the vertex
+ // coordinates. respect the position
+ // of coordinates in the list of
+ // variables
+ for (unsigned int i=0; i<dim; ++i)
+ vertices[v](i)=vars[tecplot2deal[i]];
+ }
}
if (structured)
{
- // this is the part of the code that only
- // works in 2d
+ // this is the part of the code that only
+ // works in 2d
unsigned int I=IJK[0],
- J=IJK[1];
+ J=IJK[1];
unsigned int cell=0;
// set up array of cells
for (unsigned int j=0; j<J-1; ++j)
- for (unsigned int i=1; i<I; ++i)
- {
- cells[cell].vertices[0]=i+ j *I;
- cells[cell].vertices[1]=i+1+j *I;
- cells[cell].vertices[2]=i+1+(j+1)*I;
- cells[cell].vertices[3]=i +(j+1)*I;
- ++cell;
- }
+ for (unsigned int i=1; i<I; ++i)
+ {
+ cells[cell].vertices[0]=i+ j *I;
+ cells[cell].vertices[1]=i+1+j *I;
+ cells[cell].vertices[2]=i+1+(j+1)*I;
+ cells[cell].vertices[3]=i +(j+1)*I;
+ ++cell;
+ }
Assert(cell=n_cells, ExcInternalError());
std::vector<unsigned int> boundary_vertices(2*I+2*J-4);
unsigned int k=0;
for (unsigned int i=1;i<I+1;++i)
- {
- boundary_vertices[k]=i;
- ++k;
- boundary_vertices[k]=i+(J-1)*I;
- ++k;
- }
+ {
+ boundary_vertices[k]=i;
+ ++k;
+ boundary_vertices[k]=i+(J-1)*I;
+ ++k;
+ }
for (unsigned int j=1;j<J-1;++j)
- {
- boundary_vertices[k]=1+j*I;
- ++k;
- boundary_vertices[k]=I+j*I;
- ++k;
- }
+ {
+ boundary_vertices[k]=1+j*I;
+ ++k;
+ boundary_vertices[k]=I+j*I;
+ ++k;
+ }
Assert(k==boundary_vertices.size(), ExcInternalError());
- // delete the duplicated vertices at the
- // boundary, which occur, e.g. in c-type
- // or o-type grids around a body
- // (airfoil). this automatically deletes
- // unused vertices as well.
+ // delete the duplicated vertices at the
+ // boundary, which occur, e.g. in c-type
+ // or o-type grids around a body
+ // (airfoil). this automatically deletes
+ // unused vertices as well.
GridTools::delete_duplicated_vertices(vertices,cells,subcelldata,boundary_vertices);
}
else
{
- // set up array of cells, unstructured
- // mode, so the connectivity is
- // explicitly given
+ // set up array of cells, unstructured
+ // mode, so the connectivity is
+ // explicitly given
for (unsigned int i=0; i<n_cells; ++i)
- {
- // note that since in the input file
- // we found the number of cells at
- // the top, there should still be
- // input here, so check this:
- AssertThrow (in, ExcIO());
-
- // get the connectivity from the
- // input file. the vertices are
- // ordered like in the ucd format
- for (unsigned int j=0; j<GeometryInfo<dim>::vertices_per_cell; ++j)
- in>>cells[i].vertices[j];
- }
- // do some clean-up on vertices
+ {
+ // note that since in the input file
+ // we found the number of cells at
+ // the top, there should still be
+ // input here, so check this:
+ AssertThrow (in, ExcIO());
+
+ // get the connectivity from the
+ // input file. the vertices are
+ // ordered like in the ucd format
+ for (unsigned int j=0; j<GeometryInfo<dim>::vertices_per_cell; ++j)
+ in>>cells[i].vertices[j];
+ }
+ // do some clean-up on vertices
GridTools::delete_unused_vertices (vertices, cells, subcelldata);
}
- // check that no forbidden arrays are
- // used. as we do not read in any
- // subcelldata, nothing should happen here.
+ // check that no forbidden arrays are
+ // used. as we do not read in any
+ // subcelldata, nothing should happen here.
Assert (subcelldata.check_consistency(dim), ExcInternalError());
AssertThrow (in, ExcIO());
- // do some cleanup on cells
+ // do some cleanup on cells
GridReordering<dim,spacedim>::invert_all_cells_of_negative_grid (vertices, cells);
GridReordering<dim,spacedim>::reorder_cells (cells);
tria->create_triangulation_compatibility (vertices, cells, subcelldata);
std::string line;
while (in)
{
- // get line
+ // get line
getline (in, line);
- // check if this is a line that
- // consists only of spaces, and
- // if not put the whole thing
- // back and return
+ // check if this is a line that
+ // consists only of spaces, and
+ // if not put the whole thing
+ // back and return
if (std::find_if (line.begin(), line.end(),
- std::bind2nd (std::not_equal_to<char>(),' '))
- != line.end())
- {
- in.putback ('\n');
- for (int i=line.length()-1; i>=0; --i)
- in.putback (line[i]);
- return;
- }
-
- // else: go on with next line
+ std::bind2nd (std::not_equal_to<char>(),' '))
+ != line.end())
+ {
+ in.putback ('\n');
+ for (int i=line.length()-1; i>=0; --i)
+ in.putback (line[i]);
+ return;
+ }
+
+ // else: go on with next line
}
}
template <int dim, int spacedim>
void GridIn<dim, spacedim>::skip_comment_lines (std::istream &in,
- const char comment_start)
+ const char comment_start)
{
char c;
- // loop over the following comment
- // lines
+ // loop over the following comment
+ // lines
while ((c=in.get()) == comment_start)
- // loop over the characters after
- // the comment starter
+ // loop over the characters after
+ // the comment starter
while (in.get() != '\n')
;
- // put back first character of
- // first non-comment line
+ // put back first character of
+ // first non-comment line
in.putback (c);
// at last: skip additional empty lines, if present
template <int dim, int spacedim>
void GridIn<dim, spacedim>::debug_output_grid (const std::vector<CellData<dim> > &/*cells*/,
- const std::vector<Point<spacedim> > &/*vertices*/,
- std::ostream &/*out*/)
+ const std::vector<Point<spacedim> > &/*vertices*/,
+ std::ostream &/*out*/)
{
Assert (false, ExcNotImplemented());
}
template <>
void
GridIn<2>::debug_output_grid (const std::vector<CellData<2> > &cells,
- const std::vector<Point<2> > &vertices,
- std::ostream &out)
+ const std::vector<Point<2> > &vertices,
+ std::ostream &out)
{
double min_x = vertices[cells[0].vertices[0]](0),
- max_x = vertices[cells[0].vertices[0]](0),
- min_y = vertices[cells[0].vertices[0]](1),
- max_y = vertices[cells[0].vertices[0]](1);
+ max_x = vertices[cells[0].vertices[0]](0),
+ min_y = vertices[cells[0].vertices[0]](1),
+ max_y = vertices[cells[0].vertices[0]](1);
for (unsigned int i=0; i<cells.size(); ++i)
{
for (unsigned int v=0; v<4; ++v)
- {
- const Point<2> &p = vertices[cells[i].vertices[v]];
-
- if (p(0) < min_x)
- min_x = p(0);
- if (p(0) > max_x)
- max_x = p(0);
- if (p(1) < min_y)
- min_y = p(1);
- if (p(1) > max_y)
- max_y = p(1);
- };
+ {
+ const Point<2> &p = vertices[cells[i].vertices[v]];
+
+ if (p(0) < min_x)
+ min_x = p(0);
+ if (p(0) > max_x)
+ max_x = p(0);
+ if (p(1) < min_y)
+ min_y = p(1);
+ if (p(1) > max_y)
+ max_y = p(1);
+ };
out << "# cell " << i << std::endl;
Point<2> center;
for (unsigned int f=0; f<4; ++f)
- center += vertices[cells[i].vertices[f]];
+ center += vertices[cells[i].vertices[f]];
center /= 4;
out << "set label \"" << i << "\" at "
- << center(0) << ',' << center(1)
- << " center"
- << std::endl;
+ << center(0) << ',' << center(1)
+ << " center"
+ << std::endl;
- // first two line right direction
+ // first two line right direction
for (unsigned int f=0; f<2; ++f)
- out << "set arrow from "
- << vertices[cells[i].vertices[f]](0) << ','
- << vertices[cells[i].vertices[f]](1)
- << " to "
- << vertices[cells[i].vertices[(f+1)%4]](0) << ','
- << vertices[cells[i].vertices[(f+1)%4]](1)
- << std::endl;
- // other two lines reverse direction
+ out << "set arrow from "
+ << vertices[cells[i].vertices[f]](0) << ','
+ << vertices[cells[i].vertices[f]](1)
+ << " to "
+ << vertices[cells[i].vertices[(f+1)%4]](0) << ','
+ << vertices[cells[i].vertices[(f+1)%4]](1)
+ << std::endl;
+ // other two lines reverse direction
for (unsigned int f=2; f<4; ++f)
- out << "set arrow from "
- << vertices[cells[i].vertices[(f+1)%4]](0) << ','
- << vertices[cells[i].vertices[(f+1)%4]](1)
- << " to "
- << vertices[cells[i].vertices[f]](0) << ','
- << vertices[cells[i].vertices[f]](1)
- << std::endl;
+ out << "set arrow from "
+ << vertices[cells[i].vertices[(f+1)%4]](0) << ','
+ << vertices[cells[i].vertices[(f+1)%4]](1)
+ << " to "
+ << vertices[cells[i].vertices[f]](0) << ','
+ << vertices[cells[i].vertices[f]](1)
+ << std::endl;
out << std::endl;
};
template <>
void
GridIn<3>::debug_output_grid (const std::vector<CellData<3> > &cells,
- const std::vector<Point<3> > &vertices,
- std::ostream &out)
+ const std::vector<Point<3> > &vertices,
+ std::ostream &out)
{
for (unsigned int cell=0; cell<cells.size(); ++cell)
{
- // line 0
+ // line 0
out << vertices[cells[cell].vertices[0]]
- << std::endl
- << vertices[cells[cell].vertices[1]]
- << std::endl << std::endl << std::endl;
- // line 1
+ << std::endl
+ << vertices[cells[cell].vertices[1]]
+ << std::endl << std::endl << std::endl;
+ // line 1
out << vertices[cells[cell].vertices[1]]
- << std::endl
- << vertices[cells[cell].vertices[2]]
- << std::endl << std::endl << std::endl;
- // line 2
+ << std::endl
+ << vertices[cells[cell].vertices[2]]
+ << std::endl << std::endl << std::endl;
+ // line 2
out << vertices[cells[cell].vertices[3]]
- << std::endl
- << vertices[cells[cell].vertices[2]]
- << std::endl << std::endl << std::endl;
- // line 3
+ << std::endl
+ << vertices[cells[cell].vertices[2]]
+ << std::endl << std::endl << std::endl;
+ // line 3
out << vertices[cells[cell].vertices[0]]
- << std::endl
- << vertices[cells[cell].vertices[3]]
- << std::endl << std::endl << std::endl;
- // line 4
+ << std::endl
+ << vertices[cells[cell].vertices[3]]
+ << std::endl << std::endl << std::endl;
+ // line 4
out << vertices[cells[cell].vertices[4]]
- << std::endl
- << vertices[cells[cell].vertices[5]]
- << std::endl << std::endl << std::endl;
- // line 5
+ << std::endl
+ << vertices[cells[cell].vertices[5]]
+ << std::endl << std::endl << std::endl;
+ // line 5
out << vertices[cells[cell].vertices[5]]
- << std::endl
- << vertices[cells[cell].vertices[6]]
- << std::endl << std::endl << std::endl;
- // line 6
+ << std::endl
+ << vertices[cells[cell].vertices[6]]
+ << std::endl << std::endl << std::endl;
+ // line 6
out << vertices[cells[cell].vertices[7]]
- << std::endl
- << vertices[cells[cell].vertices[6]]
- << std::endl << std::endl << std::endl;
- // line 7
+ << std::endl
+ << vertices[cells[cell].vertices[6]]
+ << std::endl << std::endl << std::endl;
+ // line 7
out << vertices[cells[cell].vertices[4]]
- << std::endl
- << vertices[cells[cell].vertices[7]]
- << std::endl << std::endl << std::endl;
- // line 8
+ << std::endl
+ << vertices[cells[cell].vertices[7]]
+ << std::endl << std::endl << std::endl;
+ // line 8
out << vertices[cells[cell].vertices[0]]
- << std::endl
- << vertices[cells[cell].vertices[4]]
- << std::endl << std::endl << std::endl;
- // line 9
+ << std::endl
+ << vertices[cells[cell].vertices[4]]
+ << std::endl << std::endl << std::endl;
+ // line 9
out << vertices[cells[cell].vertices[1]]
- << std::endl
- << vertices[cells[cell].vertices[5]]
- << std::endl << std::endl << std::endl;
- // line 10
+ << std::endl
+ << vertices[cells[cell].vertices[5]]
+ << std::endl << std::endl << std::endl;
+ // line 10
out << vertices[cells[cell].vertices[2]]
- << std::endl
- << vertices[cells[cell].vertices[6]]
- << std::endl << std::endl << std::endl;
- // line 11
+ << std::endl
+ << vertices[cells[cell].vertices[6]]
+ << std::endl << std::endl << std::endl;
+ // line 11
out << vertices[cells[cell].vertices[3]]
- << std::endl
- << vertices[cells[cell].vertices[7]]
- << std::endl << std::endl << std::endl;
+ << std::endl
+ << vertices[cells[cell].vertices[7]]
+ << std::endl << std::endl << std::endl;
};
}
template <int dim, int spacedim>
void GridIn<dim, spacedim>::read (const std::string& filename,
- Format format)
+ Format format)
{
- // Search file class for meshes
+ // Search file class for meshes
PathSearch search("MESH");
std::string name;
- // Open the file and remember its name
+ // Open the file and remember its name
if (format == Default)
name = search.find(filename);
else
const std::string::size_type slashpos = name.find_last_of('/');
const std::string::size_type dotpos = name.find_last_of('.');
if (dotpos < name.length()
- && (dotpos > slashpos || slashpos == std::string::npos))
- {
- std::string ext = name.substr(dotpos+1);
- format = parse_format(ext);
- }
+ && (dotpos > slashpos || slashpos == std::string::npos))
+ {
+ std::string ext = name.substr(dotpos+1);
+ format = parse_format(ext);
+ }
}
if (format == netcdf)
read_netcdf(filename);
template <int dim, int spacedim>
void GridIn<dim, spacedim>::read (std::istream& in,
- Format format)
+ Format format)
{
if (format == Default)
format = default_format;
switch (format)
{
case dbmesh:
- read_dbmesh (in);
- return;
+ read_dbmesh (in);
+ return;
case msh:
- read_msh (in);
- return;
+ read_msh (in);
+ return;
case ucd:
- read_ucd (in);
- return;
+ read_ucd (in);
+ return;
case xda:
- read_xda (in);
- return;
+ read_xda (in);
+ return;
case netcdf:
- Assert(false, ExcMessage("There is no read_netcdf(istream &) function. "
- "Use the read(_netcdf)(string &filename) "
- "functions, instead."));
- return;
+ Assert(false, ExcMessage("There is no read_netcdf(istream &) function. "
+ "Use the read(_netcdf)(string &filename) "
+ "functions, instead."));
+ return;
case tecplot:
- read_tecplot (in);
- return;
+ read_tecplot (in);
+ return;
case Default:
- break;
+ break;
}
Assert (false, ExcInternalError());
}
case dbmesh:
return ".dbmesh";
case msh:
- return ".msh";
+ return ".msh";
case ucd:
- return ".inp";
+ return ".inp";
case xda:
- return ".xda";
+ return ".xda";
case netcdf:
- return ".nc";
+ return ".nc";
case tecplot:
- return ".dat";
+ return ".dat";
default:
- Assert (false, ExcNotImplemented());
- return ".unknown_format";
+ Assert (false, ExcNotImplemented());
+ return ".unknown_format";
}
}
return tecplot;
if (format_name == "plt")
- // Actually, this is the extension for the
- // tecplot binary format, which we do not
- // support right now. However, some people
- // tend to create tecplot ascii files with
- // the extension 'plt' instead of
- // 'dat'. Thus, include this extension
- // here. If it actually is a binary file,
- // the read_tecplot() function will fail
- // and throw an exception, anyway.
+ // Actually, this is the extension for the
+ // tecplot binary format, which we do not
+ // support right now. However, some people
+ // tend to create tecplot ascii files with
+ // the extension 'plt' instead of
+ // 'dat'. Thus, include this extension
+ // here. If it actually is a binary file,
+ // the read_tecplot() function will fail
+ // and throw an exception, anyway.
return tecplot;
AssertThrow (false, ExcInvalidState ());
- // return something weird
+ // return something weird
return Format(Default);
}
// $Id$
// Version: $Name$
//
-// Copyright (C) 1999, 2000, 2001, 2002, 2003, 2005, 2006, 2008, 2010, 2011 by the deal.II authors
+// Copyright (C) 1999, 2000, 2001, 2002, 2003, 2005, 2006, 2008, 2010, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
namespace GridOutFlags
{
DX::DX (const bool write_cells,
- const bool write_faces,
- const bool write_diameter,
- const bool write_measure,
- const bool write_all_faces) :
+ const bool write_faces,
+ const bool write_diameter,
+ const bool write_measure,
+ const bool write_all_faces) :
write_cells (write_cells),
write_faces (write_faces),
write_diameter (write_diameter),
void DX::declare_parameters (ParameterHandler& param)
{
param.declare_entry("Write cells", "true", Patterns::Bool(),
- "Write the mesh connectivity as DX grid cells");
+ "Write the mesh connectivity as DX grid cells");
param.declare_entry("Write faces", "false", Patterns::Bool(),
- "Write faces of cells. These may be boundary faces "
- "or all faces between mesh cells, according to "
- "\"Write all faces\"");
+ "Write faces of cells. These may be boundary faces "
+ "or all faces between mesh cells, according to "
+ "\"Write all faces\"");
param.declare_entry("Write diameter", "false", Patterns::Bool(),
- "If cells are written, additionally write their"
- " diameter as data for visualization");
+ "If cells are written, additionally write their"
+ " diameter as data for visualization");
param.declare_entry("Write measure", "false", Patterns::Bool(),
- "Write the volume of each cell as data");
+ "Write the volume of each cell as data");
param.declare_entry("Write all faces", "true", Patterns::Bool(),
- "Write all faces, not only boundary");
+ "Write all faces, not only boundary");
}
void DX::parse_parameters (ParameterHandler& param)
Msh::Msh (const bool write_faces,
- const bool write_lines) :
+ const bool write_lines) :
write_faces (write_faces),
write_lines (write_lines)
{}
Ucd::Ucd (const bool write_preamble,
- const bool write_faces,
- const bool write_lines) :
- write_preamble (write_preamble),
- write_faces (write_faces),
- write_lines (write_lines)
+ const bool write_faces,
+ const bool write_lines) :
+ write_preamble (write_preamble),
+ write_faces (write_faces),
+ write_lines (write_lines)
{}
Gnuplot::Gnuplot (const bool write_cell_numbers,
- const unsigned int n_boundary_face_points,
- const bool curved_inner_cells) :
- write_cell_numbers (write_cell_numbers),
- n_boundary_face_points(n_boundary_face_points),
- curved_inner_cells(curved_inner_cells)
+ const unsigned int n_boundary_face_points,
+ const bool curved_inner_cells) :
+ write_cell_numbers (write_cell_numbers),
+ n_boundary_face_points(n_boundary_face_points),
+ curved_inner_cells(curved_inner_cells)
{}
EpsFlagsBase::EpsFlagsBase (const SizeType size_type,
- const unsigned int size,
- const double line_width,
- const bool color_lines_on_user_flag,
- const unsigned int n_boundary_face_points,
- const bool color_lines_level) :
- size_type (size_type),
- size (size),
- line_width (line_width),
- color_lines_on_user_flag(color_lines_on_user_flag),
- n_boundary_face_points(n_boundary_face_points),
- color_lines_level(color_lines_level)
+ const unsigned int size,
+ const double line_width,
+ const bool color_lines_on_user_flag,
+ const unsigned int n_boundary_face_points,
+ const bool color_lines_level) :
+ size_type (size_type),
+ size (size),
+ line_width (line_width),
+ color_lines_on_user_flag(color_lines_on_user_flag),
+ n_boundary_face_points(n_boundary_face_points),
+ color_lines_level(color_lines_level)
{}
void EpsFlagsBase::declare_parameters (ParameterHandler& param)
{
param.declare_entry("Size by", "width",
- Patterns::Selection("width|height"),
- "Depending on this parameter, either the"
- "width or height "
- "of the eps is scaled to \"Size\"");
+ Patterns::Selection("width|height"),
+ "Depending on this parameter, either the"
+ "width or height "
+ "of the eps is scaled to \"Size\"");
param.declare_entry("Size", "300", Patterns::Integer(),
- "Size of the output in points");
+ "Size of the output in points");
param.declare_entry("Line width", "0.5", Patterns::Double(),
- "Width of the lines drawn in points");
+ "Width of the lines drawn in points");
param.declare_entry("Color by flag", "false", Patterns::Bool(),
- "Draw lines with user flag set in different color");
+ "Draw lines with user flag set in different color");
param.declare_entry("Boundary points", "2", Patterns::Integer(),
- "Number of points on boundary edges. "
- "Increase this beyond 2 to see curved boundaries.");
+ "Number of points on boundary edges. "
+ "Increase this beyond 2 to see curved boundaries.");
param.declare_entry("Color by level", "false", Patterns::Bool(),
- "Draw different colors according to grid level.");
+ "Draw different colors according to grid level.");
}
Eps<1>::Eps (const SizeType size_type,
- const unsigned int size,
- const double line_width,
- const bool color_lines_on_user_flag,
- const unsigned int n_boundary_face_points)
- :
- EpsFlagsBase(size_type, size, line_width,
- color_lines_on_user_flag,
- n_boundary_face_points)
+ const unsigned int size,
+ const double line_width,
+ const bool color_lines_on_user_flag,
+ const unsigned int n_boundary_face_points)
+ :
+ EpsFlagsBase(size_type, size, line_width,
+ color_lines_on_user_flag,
+ n_boundary_face_points)
{}
Eps<2>::Eps (const SizeType size_type,
- const unsigned int size,
- const double line_width,
- const bool color_lines_on_user_flag,
- const unsigned int n_boundary_face_points,
- const bool write_cell_numbers,
- const bool write_cell_number_level,
- const bool write_vertex_numbers,
- const bool color_lines_level
+ const unsigned int size,
+ const double line_width,
+ const bool color_lines_on_user_flag,
+ const unsigned int n_boundary_face_points,
+ const bool write_cell_numbers,
+ const bool write_cell_number_level,
+ const bool write_vertex_numbers,
+ const bool color_lines_level
)
- :
- EpsFlagsBase(size_type, size, line_width,
- color_lines_on_user_flag,
- n_boundary_face_points,
- color_lines_level),
- write_cell_numbers (write_cell_numbers),
- write_cell_number_level (write_cell_number_level),
- write_vertex_numbers (write_vertex_numbers)
+ :
+ EpsFlagsBase(size_type, size, line_width,
+ color_lines_on_user_flag,
+ n_boundary_face_points,
+ color_lines_level),
+ write_cell_numbers (write_cell_numbers),
+ write_cell_number_level (write_cell_number_level),
+ write_vertex_numbers (write_vertex_numbers)
{}
void Eps<2>::declare_parameters (ParameterHandler& param)
{
param.declare_entry("Cell number", "false", Patterns::Bool(),
- "(2D only) Write cell numbers"
- " into the centers of cells");
+ "(2D only) Write cell numbers"
+ " into the centers of cells");
param.declare_entry("Level number", "false", Patterns::Bool(),
- "(2D only) if \"Cell number\" is true, write"
- "numbers in the form level.number");
+ "(2D only) if \"Cell number\" is true, write"
+ "numbers in the form level.number");
param.declare_entry("Vertex number", "false", Patterns::Bool(),
- "Write numbers for each vertex");
+ "Write numbers for each vertex");
}
Eps<3>::Eps (const SizeType size_type,
- const unsigned int size,
- const double line_width,
- const bool color_lines_on_user_flag,
- const unsigned int n_boundary_face_points,
- const double azimut_angle,
- const double turn_angle)
- :
- EpsFlagsBase(size_type, size, line_width,
- color_lines_on_user_flag,
- n_boundary_face_points),
- azimut_angle (azimut_angle),
- turn_angle (turn_angle)
+ const unsigned int size,
+ const double line_width,
+ const bool color_lines_on_user_flag,
+ const unsigned int n_boundary_face_points,
+ const double azimut_angle,
+ const double turn_angle)
+ :
+ EpsFlagsBase(size_type, size, line_width,
+ color_lines_on_user_flag,
+ n_boundary_face_points),
+ azimut_angle (azimut_angle),
+ turn_angle (turn_angle)
{}
void Eps<3>::declare_parameters (ParameterHandler& param)
{
param.declare_entry("Azimuth", "30", Patterns::Double(),
- "Azimuth of the viw point, that is, the angle "
- "in the plane from the x-axis.");
+ "Azimuth of the viw point, that is, the angle "
+ "in the plane from the x-axis.");
param.declare_entry("Elevation", "30", Patterns::Double(),
- "Elevation of the view point above the xy-plane.");
+ "Elevation of the view point above the xy-plane.");
}
XFig::XFig ()
- :
+ :
draw_boundary(true),
level_color(false),
level_depth(true),
GridOut::GridOut ()
- :
- default_format (none)
+ :
+ default_format (none)
{}
switch (output_format)
{
case none:
- return "";
+ return "";
case dx:
return ".dx";
case gnuplot:
- return ".gnuplot";
+ return ".gnuplot";
case ucd:
- return ".inp";
+ return ".inp";
case eps:
- return ".eps";
+ return ".eps";
case xfig:
- return ".fig";
+ return ".fig";
case msh:
- return ".msh";
+ return ".msh";
default:
- Assert (false, ExcNotImplemented());
- return "";
+ Assert (false, ExcNotImplemented());
+ return "";
};
}
return msh;
AssertThrow (false, ExcInvalidState ());
- // return something weird
+ // return something weird
return OutputFormat(-1);
}
GridOut::declare_parameters(ParameterHandler& param)
{
param.declare_entry("Format", "none",
- Patterns::Selection(get_output_format_names()));
+ Patterns::Selection(get_output_format_names()));
param.enter_subsection("DX");
GridOutFlags::DX::declare_parameters(param);
GridOut::memory_consumption () const
{
return (sizeof(dx_flags) +
- sizeof(msh_flags) +
- sizeof(ucd_flags) +
- sizeof(gnuplot_flags) +
- sizeof(eps_flags_1) +
- sizeof(eps_flags_2) +
- sizeof(eps_flags_3) +
- sizeof(xfig_flags));
+ sizeof(msh_flags) +
+ sizeof(ucd_flags) +
+ sizeof(gnuplot_flags) +
+ sizeof(eps_flags_1) +
+ sizeof(eps_flags_2) +
+ sizeof(eps_flags_3) +
+ sizeof(xfig_flags));
}
template <>
void GridOut::write_dx (const Triangulation<1> &,
- std::ostream &) const
+ std::ostream &) const
{
Assert (false, ExcNotImplemented());
}
template <int dim>
void GridOut::write_dx (const Triangulation<dim> &tria,
- std::ostream &out) const
+ std::ostream &out) const
{
//TODO:[GK] allow for boundary faces only
Assert(dx_flags.write_all_faces, ExcNotImplemented());
AssertThrow (out, ExcIO());
- // Copied and adapted from write_ucd
+ // Copied and adapted from write_ucd
const std::vector<Point<dim> > &vertices = tria.get_vertices();
const std::vector<bool> &vertex_used = tria.get_used_vertices();
const unsigned int n_vertices = tria.n_used_vertices();
- // vertices are implicitly numbered from 0 to
- // n_vertices-1. we have to renumber the
- // vertices, because otherwise we would end
- // up with wrong results, if there are unused
- // vertices
+ // vertices are implicitly numbered from 0 to
+ // n_vertices-1. we have to renumber the
+ // vertices, because otherwise we would end
+ // up with wrong results, if there are unused
+ // vertices
std::vector<unsigned int> renumber(vertices.size());
- // fill this vector with new vertex numbers
- // ranging from 0 to n_vertices-1
+ // fill this vector with new vertex numbers
+ // ranging from 0 to n_vertices-1
unsigned int new_number=0;
for (unsigned int i=0; i<vertices.size(); ++i)
if (vertex_used[i])
const typename Triangulation<dim>::active_cell_iterator endc=tria.end();
- // write the vertices
+ // write the vertices
out << "object \"vertices\" class array type float rank 1 shape " << dim
<< " items " << n_vertices << " data follows"
<< '\n';
for (unsigned int i=0; i<vertices.size(); ++i)
if (vertex_used[i])
{
- out << '\t' << vertices[i] << '\n';
+ out << '\t' << vertices[i] << '\n';
};
- // write cells or faces
+ // write cells or faces
const bool write_cells = dx_flags.write_cells;
const bool write_faces = (dim>1) ? dx_flags.write_faces : false;
const unsigned int n_cells = tria.n_active_cells();
const unsigned int n_faces = tria.n_active_cells()
- * GeometryInfo<dim>::faces_per_cell;
+ * GeometryInfo<dim>::faces_per_cell;
const unsigned int n_vertices_per_cell = GeometryInfo<dim>::vertices_per_cell;
const unsigned int n_vertices_per_face = GeometryInfo<dim>::vertices_per_face;
if (write_cells)
{
out << "object \"cells\" class array type int rank 1 shape "
- << n_vertices_per_cell
- << " items " << n_cells << " data follows" << '\n';
+ << n_vertices_per_cell
+ << " items " << n_cells << " data follows" << '\n';
for (cell = tria.begin_active(); cell != endc; ++cell)
- {
- for (unsigned int v=0; v<GeometryInfo<dim>::vertices_per_cell; ++v)
- out << '\t' << renumber[cell->vertex_index(GeometryInfo<dim>::dx_to_deal[v])];
- out << '\n';
- }
+ {
+ for (unsigned int v=0; v<GeometryInfo<dim>::vertices_per_cell; ++v)
+ out << '\t' << renumber[cell->vertex_index(GeometryInfo<dim>::dx_to_deal[v])];
+ out << '\n';
+ }
out << "attribute \"element type\" string \"";
if (dim==1) out << "lines";
if (dim==2) out << "quads";
if (dim==3) out << "cubes";
out << "\"" << '\n'
- << "attribute \"ref\" string \"positions\"" << '\n' << '\n';
+ << "attribute \"ref\" string \"positions\"" << '\n' << '\n';
- // Additional cell information
+ // Additional cell information
out << "object \"material\" class array type int rank 0 items "
- << n_cells << " data follows" << '\n';
+ << n_cells << " data follows" << '\n';
for (cell = tria.begin_active(); cell != endc; ++cell)
- out << ' ' << (unsigned int)cell->material_id();
+ out << ' ' << (unsigned int)cell->material_id();
out << '\n'
- << "attribute \"dep\" string \"connections\"" << '\n' << '\n';
+ << "attribute \"dep\" string \"connections\"" << '\n' << '\n';
out << "object \"level\" class array type int rank 0 items "
- << n_cells << " data follows" << '\n';
+ << n_cells << " data follows" << '\n';
for (cell = tria.begin_active(); cell != endc; ++cell)
- out << ' ' << cell->level();
+ out << ' ' << cell->level();
out << '\n'
- << "attribute \"dep\" string \"connections\"" << '\n' << '\n';
+ << "attribute \"dep\" string \"connections\"" << '\n' << '\n';
if (dx_flags.write_measure)
- {
- out << "object \"measure\" class array type float rank 0 items "
- << n_cells << " data follows" << '\n';
- for (cell = tria.begin_active(); cell != endc; ++cell)
- out << '\t' << cell->measure();
- out << '\n'
- << "attribute \"dep\" string \"connections\"" << '\n' << '\n';
- }
+ {
+ out << "object \"measure\" class array type float rank 0 items "
+ << n_cells << " data follows" << '\n';
+ for (cell = tria.begin_active(); cell != endc; ++cell)
+ out << '\t' << cell->measure();
+ out << '\n'
+ << "attribute \"dep\" string \"connections\"" << '\n' << '\n';
+ }
if (dx_flags.write_diameter)
- {
- out << "object \"diameter\" class array type float rank 0 items "
- << n_cells << " data follows" << '\n';
- for (cell = tria.begin_active(); cell != endc; ++cell)
- out << '\t' << cell->diameter();
- out << '\n'
- << "attribute \"dep\" string \"connections\"" << '\n' << '\n';
- }
+ {
+ out << "object \"diameter\" class array type float rank 0 items "
+ << n_cells << " data follows" << '\n';
+ for (cell = tria.begin_active(); cell != endc; ++cell)
+ out << '\t' << cell->diameter();
+ out << '\n'
+ << "attribute \"dep\" string \"connections\"" << '\n' << '\n';
+ }
}
if (write_faces)
{
out << "object \"faces\" class array type int rank 1 shape "
- << n_vertices_per_face
- << " items " << n_faces << " data follows"
- << '\n';
+ << n_vertices_per_face
+ << " items " << n_faces << " data follows"
+ << '\n';
for (cell = tria.begin_active(); cell != endc; ++cell)
- {
- for (unsigned int f=0;f<GeometryInfo<dim>::faces_per_cell;++f)
- {
- typename Triangulation<dim>::face_iterator face = cell->face(f);
-
- for (unsigned int v=0; v<GeometryInfo<dim>::vertices_per_face; ++v)
- out << '\t' << renumber[face->vertex_index(GeometryInfo<dim-1>::dx_to_deal[v])];
- out << '\n';
- }
- }
+ {
+ for (unsigned int f=0;f<GeometryInfo<dim>::faces_per_cell;++f)
+ {
+ typename Triangulation<dim>::face_iterator face = cell->face(f);
+
+ for (unsigned int v=0; v<GeometryInfo<dim>::vertices_per_face; ++v)
+ out << '\t' << renumber[face->vertex_index(GeometryInfo<dim-1>::dx_to_deal[v])];
+ out << '\n';
+ }
+ }
out << "attribute \"element type\" string \"";
if (dim==2) out << "lines";
if (dim==3) out << "quads";
out << "\"" << '\n'
- << "attribute \"ref\" string \"positions\"" << '\n' << '\n';
+ << "attribute \"ref\" string \"positions\"" << '\n' << '\n';
- // Additional face information
+ // Additional face information
out << "object \"boundary\" class array type int rank 0 items "
- << n_faces << " data follows" << '\n';
+ << n_faces << " data follows" << '\n';
for (cell = tria.begin_active(); cell != endc; ++cell)
- {
- // Little trick to get -1
- // for the interior
- for (unsigned int f=0;f<GeometryInfo<dim>::faces_per_cell;++f)
- out << ' ' << (int)(signed char)cell->face(f)->boundary_indicator();
- out << '\n';
- }
+ {
+ // Little trick to get -1
+ // for the interior
+ for (unsigned int f=0;f<GeometryInfo<dim>::faces_per_cell;++f)
+ out << ' ' << (int)(signed char)cell->face(f)->boundary_indicator();
+ out << '\n';
+ }
out << "attribute \"dep\" string \"connections\"" << '\n' << '\n';
if (dx_flags.write_measure)
- {
- out << "object \"face measure\" class array type float rank 0 items "
- << n_faces << " data follows" << '\n';
- for (cell = tria.begin_active(); cell != endc; ++cell)
- {
- for (unsigned int f=0;f<GeometryInfo<dim>::faces_per_cell;++f)
- out << ' ' << cell->face(f)->measure();
- out << '\n';
- }
- out << "attribute \"dep\" string \"connections\"" << '\n' << '\n';
- }
+ {
+ out << "object \"face measure\" class array type float rank 0 items "
+ << n_faces << " data follows" << '\n';
+ for (cell = tria.begin_active(); cell != endc; ++cell)
+ {
+ for (unsigned int f=0;f<GeometryInfo<dim>::faces_per_cell;++f)
+ out << ' ' << cell->face(f)->measure();
+ out << '\n';
+ }
+ out << "attribute \"dep\" string \"connections\"" << '\n' << '\n';
+ }
if (dx_flags.write_diameter)
- {
- out << "object \"face diameter\" class array type float rank 0 items "
- << n_faces << " data follows" << '\n';
- for (cell = tria.begin_active(); cell != endc; ++cell)
- {
- for (unsigned int f=0;f<GeometryInfo<dim>::faces_per_cell;++f)
- out << ' ' << cell->face(f)->diameter();
- out << '\n';
- }
- out << "attribute \"dep\" string \"connections\"" << '\n' << '\n';
- }
+ {
+ out << "object \"face diameter\" class array type float rank 0 items "
+ << n_faces << " data follows" << '\n';
+ for (cell = tria.begin_active(); cell != endc; ++cell)
+ {
+ for (unsigned int f=0;f<GeometryInfo<dim>::faces_per_cell;++f)
+ out << ' ' << cell->face(f)->diameter();
+ out << '\n';
+ }
+ out << "attribute \"dep\" string \"connections\"" << '\n' << '\n';
+ }
}
- // Write additional face information
+ // Write additional face information
if (write_faces)
{
{
}
- // The wrapper
+ // The wrapper
out << "object \"deal data\" class field" << '\n'
<< "component \"positions\" value \"vertices\"" << '\n'
<< "component \"connections\" value \"cells\"" << '\n';
if (write_cells)
{
out << "object \"cell data\" class field" << '\n'
- << "component \"positions\" value \"vertices\"" << '\n'
- << "component \"connections\" value \"cells\"" << '\n';
+ << "component \"positions\" value \"vertices\"" << '\n'
+ << "component \"connections\" value \"cells\"" << '\n';
out << "component \"material\" value \"material\"" << '\n';
out << "component \"level\" value \"level\"" << '\n';
if (dx_flags.write_measure)
- out << "component \"measure\" value \"measure\"" << '\n';
+ out << "component \"measure\" value \"measure\"" << '\n';
if (dx_flags.write_diameter)
- out << "component \"diameter\" value \"diameter\"" << '\n';
+ out << "component \"diameter\" value \"diameter\"" << '\n';
}
if (write_faces)
{
out << "object \"face data\" class field" << '\n'
- << "component \"positions\" value \"vertices\"" << '\n'
- << "component \"connections\" value \"faces\"" << '\n';
+ << "component \"positions\" value \"vertices\"" << '\n'
+ << "component \"connections\" value \"faces\"" << '\n';
out << "component \"boundary\" value \"boundary\"" << '\n';
if (dx_flags.write_measure)
- out << "component \"measure\" value \"face measure\"" << '\n';
+ out << "component \"measure\" value \"face measure\"" << '\n';
if (dx_flags.write_diameter)
- out << "component \"diameter\" value \"face diameter\"" << '\n';
+ out << "component \"diameter\" value \"face diameter\"" << '\n';
}
out << '\n'
out << "member \"faces\" value \"face data\"" << '\n';
out << "end" << '\n';
- // make sure everything now gets to
- // disk
+ // make sure everything now gets to
+ // disk
out.flush ();
AssertThrow (out, ExcIO());
template <int dim, int spacedim>
void GridOut::write_msh (const Triangulation<dim, spacedim> &tria,
- std::ostream &out) const
+ std::ostream &out) const
{
AssertThrow (out, ExcIO());
- // get the positions of the
- // vertices and whether they are
- // used.
+ // get the positions of the
+ // vertices and whether they are
+ // used.
const std::vector<Point<spacedim> > &vertices = tria.get_vertices();
const std::vector<bool> &vertex_used = tria.get_used_vertices();
typename Triangulation<dim,spacedim>::active_cell_iterator cell=tria.begin_active();
const typename Triangulation<dim,spacedim>::active_cell_iterator endc=tria.end();
- // Write Header
- // The file format is:
- /*
-
-
- $NOD
- number-of-nodes
- node-number x-coord y-coord z-coord
- ...
- $ENDNOD
- $ELM
- number-of-elements
- elm-number elm-type reg-phys reg-elem number-of-nodes node-number-list
- ...
- $ENDELM
- */
+ // Write Header
+ // The file format is:
+ /*
+
+
+ $NOD
+ number-of-nodes
+ node-number x-coord y-coord z-coord
+ ...
+ $ENDNOD
+ $ELM
+ number-of-elements
+ elm-number elm-type reg-phys reg-elem number-of-nodes node-number-list
+ ...
+ $ENDELM
+ */
out << "$NOD" << std::endl
<< n_vertices << std::endl;
- // actually write the vertices.
- // note that we shall number them
- // with first index 1 instead of 0
+ // actually write the vertices.
+ // note that we shall number them
+ // with first index 1 instead of 0
for (unsigned int i=0; i<vertices.size(); ++i)
if (vertex_used[i])
{
- out << i+1 // vertex index
- << " "
- << vertices[i];
- for (unsigned int d=spacedim+1; d<=3; ++d)
- out << " 0"; // fill with zeroes
- out << std::endl;
+ out << i+1 // vertex index
+ << " "
+ << vertices[i];
+ for (unsigned int d=spacedim+1; d<=3; ++d)
+ out << " 0"; // fill with zeroes
+ out << std::endl;
};
- // Write cells preamble
+ // Write cells preamble
out << "$ENDNOD" << std::endl
<< "$ELM" << std::endl
<< tria.n_active_cells() + ( (msh_flags.write_faces ?
- n_boundary_faces(tria) :0 ) +
- ( msh_flags.write_lines ?
- n_boundary_lines(tria) : 0 ) ) << std::endl;
-
- /*
- elm-type
- defines the geometrical type of the n-th element:
- 1
- Line (2 nodes).
- 2
- Triangle (3 nodes).
- 3
- Quadrangle (4 nodes).
- 4
- Tetrahedron (4 nodes).
- 5
- Hexahedron (8 nodes).
- 6
- Prism (6 nodes).
- 7
- Pyramid (5 nodes).
- 8
- Second order line (3 nodes: 2 associated with the vertices and 1 with the edge).
- 9
- Second order triangle (6 nodes: 3 associated with the vertices and 3 with the edges).
- 10
- Second order quadrangle (9 nodes: 4 associated with the vertices, 4 with the edges and 1 with the face).
- 11
- Second order tetrahedron (10 nodes: 4 associated with the vertices and 6 with the edges).
- 12
- Second order hexahedron (27 nodes: 8 associated with the vertices, 12 with the edges, 6 with the faces and 1 with the volume).
- 13
- Second order prism (18 nodes: 6 associated with the vertices, 9 with the edges and 3 with the quadrangular faces).
- 14
- Second order pyramid (14 nodes: 5 associated with the vertices, 8 with the edges and 1 with the quadrangular face).
- 15
- Point (1 node).
- */
+ n_boundary_faces(tria) :0 ) +
+ ( msh_flags.write_lines ?
+ n_boundary_lines(tria) : 0 ) ) << std::endl;
+
+ /*
+ elm-type
+ defines the geometrical type of the n-th element:
+ 1
+ Line (2 nodes).
+ 2
+ Triangle (3 nodes).
+ 3
+ Quadrangle (4 nodes).
+ 4
+ Tetrahedron (4 nodes).
+ 5
+ Hexahedron (8 nodes).
+ 6
+ Prism (6 nodes).
+ 7
+ Pyramid (5 nodes).
+ 8
+ Second order line (3 nodes: 2 associated with the vertices and 1 with the edge).
+ 9
+ Second order triangle (6 nodes: 3 associated with the vertices and 3 with the edges).
+ 10
+ Second order quadrangle (9 nodes: 4 associated with the vertices, 4 with the edges and 1 with the face).
+ 11
+ Second order tetrahedron (10 nodes: 4 associated with the vertices and 6 with the edges).
+ 12
+ Second order hexahedron (27 nodes: 8 associated with the vertices, 12 with the edges, 6 with the faces and 1 with the volume).
+ 13
+ Second order prism (18 nodes: 6 associated with the vertices, 9 with the edges and 3 with the quadrangular faces).
+ 14
+ Second order pyramid (14 nodes: 5 associated with the vertices, 8 with the edges and 1 with the quadrangular face).
+ 15
+ Point (1 node).
+ */
unsigned int elm_type;
switch(dim) {
case 1:
- elm_type = 1;
- break;
+ elm_type = 1;
+ break;
case 2:
- elm_type = 3;
- break;
+ elm_type = 3;
+ break;
case 3:
- elm_type = 5;
- break;
+ elm_type = 5;
+ break;
default:
- Assert(false, ExcNotImplemented());
+ Assert(false, ExcNotImplemented());
}
- // write cells. Enumerate cells
- // consecutively, starting with 1
+ // write cells. Enumerate cells
+ // consecutively, starting with 1
unsigned int cell_index=1;
for (cell=tria.begin_active();
cell!=endc; ++cell, ++cell_index)
{
out << cell_index << ' ' << elm_type << ' '
- << static_cast<unsigned int>(cell->material_id()) << ' '
- << cell->subdomain_id() << ' '
- << GeometryInfo<dim>::vertices_per_cell << ' ';
+ << static_cast<unsigned int>(cell->material_id()) << ' '
+ << cell->subdomain_id() << ' '
+ << GeometryInfo<dim>::vertices_per_cell << ' ';
- // Vertex numbering follows UCD conventions.
+ // Vertex numbering follows UCD conventions.
for (unsigned int vertex=0; vertex<GeometryInfo<dim>::vertices_per_cell;
- ++vertex)
- out << cell->vertex_index(GeometryInfo<dim>::ucd_to_deal[vertex])+1 << ' ';
+ ++vertex)
+ out << cell->vertex_index(GeometryInfo<dim>::ucd_to_deal[vertex])+1 << ' ';
out << std::endl;
};
- // write faces and lines with
- // non-zero boundary indicator
+ // write faces and lines with
+ // non-zero boundary indicator
if (msh_flags.write_faces)
write_msh_faces (tria, cell_index, out);
if (msh_flags.write_lines)
out << "$ENDELM" << std::endl;
- // make sure everything now gets to
- // disk
+ // make sure everything now gets to
+ // disk
out.flush ();
AssertThrow (out, ExcIO());
template <int dim, int spacedim>
void GridOut::write_ucd (const Triangulation<dim,spacedim> &tria,
- std::ostream &out) const
+ std::ostream &out) const
{
AssertThrow (out, ExcIO());
- // get the positions of the
- // vertices and whether they are
- // used.
+ // get the positions of the
+ // vertices and whether they are
+ // used.
const std::vector<Point<spacedim> > &vertices = tria.get_vertices();
const std::vector<bool> &vertex_used = tria.get_used_vertices();
typename Triangulation<dim,spacedim>::active_cell_iterator cell=tria.begin_active();
const typename Triangulation<dim,spacedim>::active_cell_iterator endc=tria.end();
- // write preamble
+ // write preamble
if (ucd_flags.write_preamble)
{
- // block this to have local
- // variables destroyed after
- // use
+ // block this to have local
+ // variables destroyed after
+ // use
std::time_t time1= std::time (0);
std::tm *time = std::localtime(&time1);
out << "# This file was generated by the deal.II library." << '\n'
- << "# Date = "
- << time->tm_year+1900 << "/"
- << time->tm_mon+1 << "/"
- << time->tm_mday << '\n'
- << "# Time = "
- << time->tm_hour << ":"
- << std::setw(2) << time->tm_min << ":"
- << std::setw(2) << time->tm_sec << '\n'
- << "#" << '\n'
- << "# For a description of the UCD format see the AVS Developer's guide."
- << '\n'
- << "#" << '\n';
+ << "# Date = "
+ << time->tm_year+1900 << "/"
+ << time->tm_mon+1 << "/"
+ << time->tm_mday << '\n'
+ << "# Time = "
+ << time->tm_hour << ":"
+ << std::setw(2) << time->tm_min << ":"
+ << std::setw(2) << time->tm_sec << '\n'
+ << "#" << '\n'
+ << "# For a description of the UCD format see the AVS Developer's guide."
+ << '\n'
+ << "#" << '\n';
};
- // start with ucd data
+ // start with ucd data
out << n_vertices << ' '
<< tria.n_active_cells() + ( (ucd_flags.write_faces ?
- n_boundary_faces(tria) : 0) +
- (ucd_flags.write_lines ?
- n_boundary_lines(tria) : 0) )
+ n_boundary_faces(tria) : 0) +
+ (ucd_flags.write_lines ?
+ n_boundary_lines(tria) : 0) )
<< " 0 0 0" // no data
<< '\n';
- // actually write the vertices.
- // note that we shall number them
- // with first index 1 instead of 0
+ // actually write the vertices.
+ // note that we shall number them
+ // with first index 1 instead of 0
for (unsigned int i=0; i<vertices.size(); ++i)
if (vertex_used[i])
{
- out << i+1 // vertex index
- << " "
- << vertices[i];
- for (unsigned int d=spacedim+1; d<=3; ++d)
- out << " 0"; // fill with zeroes
- out << '\n';
+ out << i+1 // vertex index
+ << " "
+ << vertices[i];
+ for (unsigned int d=spacedim+1; d<=3; ++d)
+ out << " 0"; // fill with zeroes
+ out << '\n';
};
- // write cells. Enumerate cells
- // consecutively, starting with 1
+ // write cells. Enumerate cells
+ // consecutively, starting with 1
unsigned int cell_index=1;
for (cell=tria.begin_active();
cell!=endc; ++cell, ++cell_index)
{
out << cell_index << ' '
- << static_cast<unsigned int>(cell->material_id())
- << ' ';
+ << static_cast<unsigned int>(cell->material_id())
+ << ' ';
switch (dim)
- {
- case 1: out << "line "; break;
- case 2: out << "quad "; break;
- case 3: out << "hex "; break;
- default:
- Assert (false, ExcNotImplemented());
- };
-
- // it follows a list of the
- // vertices of each cell. in 1d
- // this is simply a list of the
- // two vertices, in 2d its counter
- // clockwise, as usual in this
- // library. in 3d, the same applies
- // (special thanks to AVS for
- // numbering their vertices in a
- // way compatible to deal.II!)
- //
- // technical reference:
- // AVS Developer's Guide, Release 4,
- // May, 1992, p. E6
- //
- // note: vertex numbers are 1-base
+ {
+ case 1: out << "line "; break;
+ case 2: out << "quad "; break;
+ case 3: out << "hex "; break;
+ default:
+ Assert (false, ExcNotImplemented());
+ };
+
+ // it follows a list of the
+ // vertices of each cell. in 1d
+ // this is simply a list of the
+ // two vertices, in 2d its counter
+ // clockwise, as usual in this
+ // library. in 3d, the same applies
+ // (special thanks to AVS for
+ // numbering their vertices in a
+ // way compatible to deal.II!)
+ //
+ // technical reference:
+ // AVS Developer's Guide, Release 4,
+ // May, 1992, p. E6
+ //
+ // note: vertex numbers are 1-base
for (unsigned int vertex=0; vertex<GeometryInfo<dim>::vertices_per_cell;
- ++vertex)
- out << cell->vertex_index(GeometryInfo<dim>::ucd_to_deal[vertex])+1 << ' ';
+ ++vertex)
+ out << cell->vertex_index(GeometryInfo<dim>::ucd_to_deal[vertex])+1 << ' ';
out << '\n';
};
- // write faces and lines with
- // non-zero boundary indicator
+ // write faces and lines with
+ // non-zero boundary indicator
if (ucd_flags.write_faces)
write_ucd_faces (tria, cell_index, out);
if (ucd_flags.write_lines)
write_ucd_lines (tria, cell_index, out);
- // make sure everything now gets to
- // disk
+ // make sure everything now gets to
+ // disk
out.flush ();
AssertThrow (out, ExcIO());
const unsigned int nf = GeometryInfo<dim>::faces_per_cell;
const unsigned int nvf = GeometryInfo<dim>::vertices_per_face;
- // The following text was copied
- // from an existing XFig file.
+ // The following text was copied
+ // from an existing XFig file.
out << "#FIG 3.2\nLandscape\nCenter\nInches" << '\n'
<< "A4\n100.00\nSingle" << '\n'
- // Background is transparent
+ // Background is transparent
<< "-3" << '\n'
<< "# generated by deal.II GridOut class" << '\n'
<< "# reduce first number to scale up image" << '\n'
<< "1200 2" << '\n';
- // We write all cells and cells on
- // coarser levels are behind cells
- // on finer levels. Level 0
- // corresponds to a depth of 900,
- // each level subtracting 1
+ // We write all cells and cells on
+ // coarser levels are behind cells
+ // on finer levels. Level 0
+ // corresponds to a depth of 900,
+ // each level subtracting 1
Triangulation<dim>::cell_iterator cell = tria.begin();
const Triangulation<dim>::cell_iterator end = tria.end();
for (;cell != end; ++cell)
{
- // If depth is not encoded, write finest level only
+ // If depth is not encoded, write finest level only
if (!xfig_flags.level_depth && !cell->active())
- continue;
- // Code for polygon
+ continue;
+ // Code for polygon
out << "2 3 "
- << xfig_flags.line_style << ' '
- << xfig_flags.line_thickness
- // with black line
- << " 0 ";
- // Fill color
+ << xfig_flags.line_style << ' '
+ << xfig_flags.line_thickness
+ // with black line
+ << " 0 ";
+ // Fill color
if (xfig_flags.level_color)
- out << cell->level() + 8;
+ out << cell->level() + 8;
else
- out << cell->material_id() + 1;
- // Depth, unused, fill
+ out << cell->material_id() + 1;
+ // Depth, unused, fill
out << ' '
- << (xfig_flags.level_depth
- ? (900-cell->level())
- : (900+cell->material_id()))
- << " 0 "
- << xfig_flags.fill_style << " 0.0 "
- // some style parameters
- << " 0 0 -1 0 0 "
- // number of points
- << nv+1 << '\n';
-
- // For each point, write scaled
- // and shifted coordinates
- // multiplied by 1200
- // (dots/inch)
+ << (xfig_flags.level_depth
+ ? (900-cell->level())
+ : (900+cell->material_id()))
+ << " 0 "
+ << xfig_flags.fill_style << " 0.0 "
+ // some style parameters
+ << " 0 0 -1 0 0 "
+ // number of points
+ << nv+1 << '\n';
+
+ // For each point, write scaled
+ // and shifted coordinates
+ // multiplied by 1200
+ // (dots/inch)
for (unsigned int k=0;k<=nv;++k)
- {
- const Point<dim>& p = cell->vertex(
- GeometryInfo<dim>::ucd_to_deal[k % nv]);
- for (unsigned int d=0; d<static_cast<unsigned int>(dim); ++d)
- {
- int val = (int)(1200 * xfig_flags.scaling(d) *
- (p(d)-xfig_flags.offset(d)));
- out << '\t' << val;
- }
- out << '\n';
- }
- // Now write boundary edges
+ {
+ const Point<dim>& p = cell->vertex(
+ GeometryInfo<dim>::ucd_to_deal[k % nv]);
+ for (unsigned int d=0; d<static_cast<unsigned int>(dim); ++d)
+ {
+ int val = (int)(1200 * xfig_flags.scaling(d) *
+ (p(d)-xfig_flags.offset(d)));
+ out << '\t' << val;
+ }
+ out << '\n';
+ }
+ // Now write boundary edges
static const unsigned int face_reorder[4]={2,1,3,0};
if (xfig_flags.draw_boundary)
- for (unsigned int f=0;f<nf;++f)
- {
- Triangulation<dim>::face_iterator
- face = cell->face(face_reorder[f]);
- const types::boundary_id_t bi = face->boundary_indicator();
- if (bi != types::internal_face_boundary_id)
- {
- // Code for polyline
- out << "2 1 "
- // with line style and thickness
- << xfig_flags.boundary_style << ' '
- << xfig_flags.boundary_thickness << ' '
- << (1 + (unsigned int) bi);
- // Fill color
- out << " -1 ";
- // Depth 100 less than cells
- out << (xfig_flags.level_depth
- ? (800-cell->level())
- : 800+bi)
- // unused, no fill
- << " 0 -1 0.0 "
- // some style parameters
- << " 0 0 -1 0 0 "
- // number of points
- << nvf << '\n';
-
- // For each point, write scaled
- // and shifted coordinates
- // multiplied by 1200
- // (dots/inch)
-
- for (unsigned int k=0;k<nvf;++k)
- {
- const Point<dim>& p = face->vertex(k % nv);
- for (unsigned int d=0; d<static_cast<unsigned int>(dim); ++d)
- {
- int val = (int)(1200 * xfig_flags.scaling(d) *
- (p(d)-xfig_flags.offset(d)));
- out << '\t' << val;
- }
- out << '\n';
- }
- }
- }
+ for (unsigned int f=0;f<nf;++f)
+ {
+ Triangulation<dim>::face_iterator
+ face = cell->face(face_reorder[f]);
+ const types::boundary_id_t bi = face->boundary_indicator();
+ if (bi != types::internal_face_boundary_id)
+ {
+ // Code for polyline
+ out << "2 1 "
+ // with line style and thickness
+ << xfig_flags.boundary_style << ' '
+ << xfig_flags.boundary_thickness << ' '
+ << (1 + (unsigned int) bi);
+ // Fill color
+ out << " -1 ";
+ // Depth 100 less than cells
+ out << (xfig_flags.level_depth
+ ? (800-cell->level())
+ : 800+bi)
+ // unused, no fill
+ << " 0 -1 0.0 "
+ // some style parameters
+ << " 0 0 -1 0 0 "
+ // number of points
+ << nvf << '\n';
+
+ // For each point, write scaled
+ // and shifted coordinates
+ // multiplied by 1200
+ // (dots/inch)
+
+ for (unsigned int k=0;k<nvf;++k)
+ {
+ const Point<dim>& p = face->vertex(k % nv);
+ for (unsigned int d=0; d<static_cast<unsigned int>(dim); ++d)
+ {
+ int val = (int)(1200 * xfig_flags.scaling(d) *
+ (p(d)-xfig_flags.offset(d)));
+ out << '\t' << val;
+ }
+ out << '\n';
+ }
+ }
+ }
}
- // make sure everything now gets to
- // disk
+ // make sure everything now gets to
+ // disk
out.flush ();
AssertThrow (out, ExcIO());
for (face=tria.begin_active_face(), endf=tria.end_face();
face != endf; ++face)
if ((face->at_boundary()) &&
- (face->boundary_indicator() != 0))
+ (face->boundary_indicator() != 0))
n_faces++;
return n_faces;
for (edge=tria.begin_active_line(), endedge=tria.end_line();
edge != endedge; ++edge)
if ((edge->at_boundary()) &&
- (edge->boundary_indicator() != 0))
+ (edge->boundary_indicator() != 0))
n_lines++;
return n_lines;
void GridOut::write_msh_faces (const Triangulation<1> &,
- const unsigned int,
- std::ostream &) const
+ const unsigned int,
+ std::ostream &) const
{
return;
}
void GridOut::write_msh_faces (const Triangulation<1,2> &,
- const unsigned int,
- std::ostream &) const
+ const unsigned int,
+ std::ostream &) const
{
return;
}
void GridOut::write_msh_faces (const Triangulation<1,3> &,
- const unsigned int,
- std::ostream &) const
+ const unsigned int,
+ std::ostream &) const
{
return;
}
void GridOut::write_msh_lines (const Triangulation<1> &,
- const unsigned int,
- std::ostream &) const
+ const unsigned int,
+ std::ostream &) const
{
return;
}
void GridOut::write_msh_lines (const Triangulation<1,2> &,
- const unsigned int,
- std::ostream &) const
+ const unsigned int,
+ std::ostream &) const
{
return;
}
void GridOut::write_msh_lines (const Triangulation<1,3> &,
- const unsigned int,
- std::ostream &) const
+ const unsigned int,
+ std::ostream &) const
{
return;
}
void GridOut::write_msh_lines (const Triangulation<2> &,
- const unsigned int,
- std::ostream &) const
+ const unsigned int,
+ std::ostream &) const
{
return;
}
void GridOut::write_msh_lines (const Triangulation<2,3> &,
- const unsigned int,
- std::ostream &) const
+ const unsigned int,
+ std::ostream &) const
{
return;
}
template <int dim, int spacedim>
void GridOut::write_msh_faces (const Triangulation<dim,spacedim> &tria,
- const unsigned int starting_index,
- std::ostream &out) const
+ const unsigned int starting_index,
+ std::ostream &out) const
{
typename Triangulation<dim,spacedim>::active_face_iterator face, endf;
unsigned int index=starting_index;
for (face=tria.begin_active_face(), endf=tria.end_face();
face != endf; ++face)
if (face->at_boundary() &&
- (face->boundary_indicator() != 0))
+ (face->boundary_indicator() != 0))
{
- out << index << ' ';
- switch (dim)
- {
- case 2: out << 1 << ' '; break;
- case 3: out << 3 << ' '; break;
- default:
- Assert (false, ExcNotImplemented());
- };
- out << static_cast<unsigned int>(face->boundary_indicator())
- << ' '
- << static_cast<unsigned int>(face->boundary_indicator())
- << ' ' << GeometryInfo<dim>::vertices_per_face;
- // note: vertex numbers are 1-base
- for (unsigned int vertex=0; vertex<GeometryInfo<dim>::vertices_per_face; ++vertex)
- out << ' '
- << face->vertex_index(GeometryInfo<dim-1>::ucd_to_deal[vertex])+1;
- out << '\n';
-
- ++index;
+ out << index << ' ';
+ switch (dim)
+ {
+ case 2: out << 1 << ' '; break;
+ case 3: out << 3 << ' '; break;
+ default:
+ Assert (false, ExcNotImplemented());
+ };
+ out << static_cast<unsigned int>(face->boundary_indicator())
+ << ' '
+ << static_cast<unsigned int>(face->boundary_indicator())
+ << ' ' << GeometryInfo<dim>::vertices_per_face;
+ // note: vertex numbers are 1-base
+ for (unsigned int vertex=0; vertex<GeometryInfo<dim>::vertices_per_face; ++vertex)
+ out << ' '
+ << face->vertex_index(GeometryInfo<dim-1>::ucd_to_deal[vertex])+1;
+ out << '\n';
+
+ ++index;
};
}
template <int dim, int spacedim>
void GridOut::write_msh_lines (const Triangulation<dim, spacedim> &tria,
- const unsigned int starting_index,
- std::ostream &out) const
+ const unsigned int starting_index,
+ std::ostream &out) const
{
typename Triangulation<dim,spacedim>::active_line_iterator line, endl;
unsigned int index=starting_index;
for (line=tria.begin_active_line(), endl=tria.end_line();
line != endl; ++line)
if (line->at_boundary() &&
- (line->boundary_indicator() != 0))
+ (line->boundary_indicator() != 0))
{
- out << index << " 1 ";
- out << static_cast<unsigned int>(line->boundary_indicator())
- << ' '
- << static_cast<unsigned int>(line->boundary_indicator())
- << " 2 ";
- // note: vertex numbers are 1-base
- for (unsigned int vertex=0; vertex<2; ++vertex)
- out << ' '
- << line->vertex_index(GeometryInfo<dim-2>::ucd_to_deal[vertex])+1;
- out << '\n';
-
- ++index;
+ out << index << " 1 ";
+ out << static_cast<unsigned int>(line->boundary_indicator())
+ << ' '
+ << static_cast<unsigned int>(line->boundary_indicator())
+ << " 2 ";
+ // note: vertex numbers are 1-base
+ for (unsigned int vertex=0; vertex<2; ++vertex)
+ out << ' '
+ << line->vertex_index(GeometryInfo<dim-2>::ucd_to_deal[vertex])+1;
+ out << '\n';
+
+ ++index;
};
}
void GridOut::write_ucd_faces (const Triangulation<1> &,
- const unsigned int,
- std::ostream &) const
+ const unsigned int,
+ std::ostream &) const
{
return;
}
void GridOut::write_ucd_faces (const Triangulation<1,2> &,
- const unsigned int,
- std::ostream &) const
+ const unsigned int,
+ std::ostream &) const
{
return;
}
void GridOut::write_ucd_faces (const Triangulation<1,3> &,
- const unsigned int,
- std::ostream &) const
+ const unsigned int,
+ std::ostream &) const
{
return;
}
void GridOut::write_ucd_lines (const Triangulation<1> &,
- const unsigned int,
- std::ostream &) const
+ const unsigned int,
+ std::ostream &) const
{
return;
}
void GridOut::write_ucd_lines (const Triangulation<1,2> &,
- const unsigned int,
- std::ostream &) const
+ const unsigned int,
+ std::ostream &) const
{
return;
}
void GridOut::write_ucd_lines (const Triangulation<1,3> &,
- const unsigned int,
- std::ostream &) const
+ const unsigned int,
+ std::ostream &) const
{
return;
}
void GridOut::write_ucd_lines (const Triangulation<2> &,
- const unsigned int,
- std::ostream &) const
+ const unsigned int,
+ std::ostream &) const
{
return;
}
void GridOut::write_ucd_lines (const Triangulation<2,3> &,
- const unsigned int,
- std::ostream &) const
+ const unsigned int,
+ std::ostream &) const
{
return;
}
template <int dim, int spacedim>
void GridOut::write_ucd_faces (const Triangulation<dim, spacedim> &tria,
- const unsigned int starting_index,
- std::ostream &out) const
+ const unsigned int starting_index,
+ std::ostream &out) const
{
typename Triangulation<dim,spacedim>::active_face_iterator face, endf;
unsigned int index=starting_index;
for (face=tria.begin_active_face(), endf=tria.end_face();
face != endf; ++face)
if (face->at_boundary() &&
- (face->boundary_indicator() != 0))
+ (face->boundary_indicator() != 0))
{
- out << index << " "
- << static_cast<unsigned int>(face->boundary_indicator())
- << " ";
- switch (dim)
- {
- case 2: out << "line "; break;
- case 3: out << "quad "; break;
- default:
- Assert (false, ExcNotImplemented());
- };
- // note: vertex numbers are 1-base
- for (unsigned int vertex=0; vertex<GeometryInfo<dim>::vertices_per_face; ++vertex)
- out << face->vertex_index(GeometryInfo<dim-1>::ucd_to_deal[vertex])+1 << ' ';
- out << '\n';
-
- ++index;
+ out << index << " "
+ << static_cast<unsigned int>(face->boundary_indicator())
+ << " ";
+ switch (dim)
+ {
+ case 2: out << "line "; break;
+ case 3: out << "quad "; break;
+ default:
+ Assert (false, ExcNotImplemented());
+ };
+ // note: vertex numbers are 1-base
+ for (unsigned int vertex=0; vertex<GeometryInfo<dim>::vertices_per_face; ++vertex)
+ out << face->vertex_index(GeometryInfo<dim-1>::ucd_to_deal[vertex])+1 << ' ';
+ out << '\n';
+
+ ++index;
};
}
template <int dim, int spacedim>
void GridOut::write_ucd_lines (const Triangulation<dim, spacedim> &tria,
- const unsigned int starting_index,
- std::ostream &out) const
+ const unsigned int starting_index,
+ std::ostream &out) const
{
typename Triangulation<dim, spacedim>::active_line_iterator line, endl;
unsigned int index=starting_index;
for (line=tria.begin_active_line(), endl=tria.end_line();
line != endl; ++line)
if (line->at_boundary() &&
- (line->boundary_indicator() != 0))
+ (line->boundary_indicator() != 0))
{
- out << index << " "
- << static_cast<unsigned int>(line->boundary_indicator())
- << " line ";
- // note: vertex numbers are 1-base
- for (unsigned int vertex=0; vertex<2; ++vertex)
- out << line->vertex_index(GeometryInfo<dim-2>::ucd_to_deal[vertex])+1 << ' ';
- out << '\n';
-
- ++index;
+ out << index << " "
+ << static_cast<unsigned int>(line->boundary_indicator())
+ << " line ";
+ // note: vertex numbers are 1-base
+ for (unsigned int vertex=0; vertex<2; ++vertex)
+ out << line->vertex_index(GeometryInfo<dim-2>::ucd_to_deal[vertex])+1 << ' ';
+ out << '\n';
+
+ ++index;
};
}
{
template <int spacedim>
void write_gnuplot (const dealii::Triangulation<1,spacedim> &tria,
- std::ostream &out,
- const Mapping<1,spacedim> *,
- const GridOutFlags::Gnuplot &gnuplot_flags)
+ std::ostream &out,
+ const Mapping<1,spacedim> *,
+ const GridOutFlags::Gnuplot &gnuplot_flags)
{
AssertThrow (out, ExcIO());
const int dim = 1;
typename dealii::Triangulation<dim,spacedim>::active_cell_iterator
- cell=tria.begin_active();
+ cell=tria.begin_active();
const typename dealii::Triangulation<dim,spacedim>::active_cell_iterator
- endc=tria.end();
+ endc=tria.end();
for (; cell!=endc; ++cell)
- {
- if (gnuplot_flags.write_cell_numbers)
- out << "# cell " << cell << '\n';
-
- out << cell->vertex(0)
- << ' ' << cell->level()
- << ' ' << static_cast<unsigned int>(cell->material_id()) << '\n'
- << cell->vertex(1)
- << ' ' << cell->level()
- << ' ' << static_cast<unsigned int>(cell->material_id()) << '\n'
- << '\n';
- }
-
- // make sure everything now gets to
- // disk
+ {
+ if (gnuplot_flags.write_cell_numbers)
+ out << "# cell " << cell << '\n';
+
+ out << cell->vertex(0)
+ << ' ' << cell->level()
+ << ' ' << static_cast<unsigned int>(cell->material_id()) << '\n'
+ << cell->vertex(1)
+ << ' ' << cell->level()
+ << ' ' << static_cast<unsigned int>(cell->material_id()) << '\n'
+ << '\n';
+ }
+
+ // make sure everything now gets to
+ // disk
out.flush ();
AssertThrow (out, ExcIO());
template <int spacedim>
void write_gnuplot (const dealii::Triangulation<2,spacedim> &tria,
- std::ostream &out,
- const Mapping<2,spacedim> *mapping,
- const GridOutFlags::Gnuplot &gnuplot_flags)
+ std::ostream &out,
+ const Mapping<2,spacedim> *mapping,
+ const GridOutFlags::Gnuplot &gnuplot_flags)
{
AssertThrow (out, ExcIO());
const int dim = 2;
const unsigned int n_additional_points=
- gnuplot_flags.n_boundary_face_points;
+ gnuplot_flags.n_boundary_face_points;
const unsigned int n_points=2+n_additional_points;
typename dealii::Triangulation<dim,spacedim>::active_cell_iterator
- cell=tria.begin_active();
+ cell=tria.begin_active();
const typename dealii::Triangulation<dim,spacedim>::active_cell_iterator
- endc=tria.end();
+ endc=tria.end();
- // if we are to treat curved
- // boundaries, then generate a
- // quadrature formula which will be
- // used to probe boundary points at
- // curved faces
+ // if we are to treat curved
+ // boundaries, then generate a
+ // quadrature formula which will be
+ // used to probe boundary points at
+ // curved faces
Quadrature<dim> *q_projector=0;
std::vector<Point<dim-1> > boundary_points;
if (mapping!=0)
- {
- boundary_points.resize(n_points);
- boundary_points[0][0]=0;
- boundary_points[n_points-1][0]=1;
- for (unsigned int i=1; i<n_points-1; ++i)
- boundary_points[i](0)= 1.*i/(n_points-1);
+ {
+ boundary_points.resize(n_points);
+ boundary_points[0][0]=0;
+ boundary_points[n_points-1][0]=1;
+ for (unsigned int i=1; i<n_points-1; ++i)
+ boundary_points[i](0)= 1.*i/(n_points-1);
- std::vector<double> dummy_weights(n_points, 1./n_points);
- Quadrature<dim-1> quadrature(boundary_points, dummy_weights);
+ std::vector<double> dummy_weights(n_points, 1./n_points);
+ Quadrature<dim-1> quadrature(boundary_points, dummy_weights);
- q_projector = new Quadrature<dim> (QProjector<dim>::project_to_all_faces(quadrature));
- }
+ q_projector = new Quadrature<dim> (QProjector<dim>::project_to_all_faces(quadrature));
+ }
for (; cell!=endc; ++cell)
- {
- if (gnuplot_flags.write_cell_numbers)
- out << "# cell " << cell << '\n';
-
- if (mapping==0 ||
- (!cell->at_boundary() && !gnuplot_flags.curved_inner_cells))
- {
- // write out the four sides
- // of this cell by putting
- // the four points (+ the
- // initial point again) in
- // a row and lifting the
- // drawing pencil at the
- // end
- for (unsigned int i=0; i<GeometryInfo<dim>::vertices_per_cell; ++i)
- out << cell->vertex(GeometryInfo<dim>::ucd_to_deal[i])
- << ' ' << cell->level()
- << ' ' << static_cast<unsigned int>(cell->material_id()) << '\n';
- out << cell->vertex(0)
- << ' ' << cell->level()
- << ' ' << static_cast<unsigned int>(cell->material_id()) << '\n'
- << '\n' // double new line for gnuplot 3d plots
- << '\n';
- }
- else
- // cell is at boundary and we
- // are to treat curved
- // boundaries. so loop over
- // all faces and draw them as
- // small pieces of lines
- {
- for (unsigned int face_no=0;
- face_no<GeometryInfo<dim>::faces_per_cell; ++face_no)
- {
- const typename dealii::Triangulation<dim,spacedim>::face_iterator
- face = cell->face(face_no);
- if (face->at_boundary() || gnuplot_flags.curved_inner_cells)
- {
- // compute offset
- // of quadrature
- // points within
- // set of projected
- // points
- const unsigned int offset=face_no*n_points;
- for (unsigned int i=0; i<n_points; ++i)
- out << (mapping->transform_unit_to_real_cell
- (cell, q_projector->point(offset+i)))
- << ' ' << cell->level()
- << ' ' << static_cast<unsigned int>(cell->material_id())
- << '\n';
-
- out << '\n'
- << '\n';
- }
- else
- {
- // if, however, the
- // face is not at
- // the boundary,
- // then draw it as
- // usual
- out << face->vertex(0)
- << ' ' << cell->level()
- << ' ' << static_cast<unsigned int>(cell->material_id())
- << '\n'
- << face->vertex(1)
- << ' ' << cell->level()
- << ' ' << static_cast<unsigned int>(cell->material_id())
- << '\n'
- << '\n'
- << '\n';
- }
- }
- }
- }
+ {
+ if (gnuplot_flags.write_cell_numbers)
+ out << "# cell " << cell << '\n';
+
+ if (mapping==0 ||
+ (!cell->at_boundary() && !gnuplot_flags.curved_inner_cells))
+ {
+ // write out the four sides
+ // of this cell by putting
+ // the four points (+ the
+ // initial point again) in
+ // a row and lifting the
+ // drawing pencil at the
+ // end
+ for (unsigned int i=0; i<GeometryInfo<dim>::vertices_per_cell; ++i)
+ out << cell->vertex(GeometryInfo<dim>::ucd_to_deal[i])
+ << ' ' << cell->level()
+ << ' ' << static_cast<unsigned int>(cell->material_id()) << '\n';
+ out << cell->vertex(0)
+ << ' ' << cell->level()
+ << ' ' << static_cast<unsigned int>(cell->material_id()) << '\n'
+ << '\n' // double new line for gnuplot 3d plots
+ << '\n';
+ }
+ else
+ // cell is at boundary and we
+ // are to treat curved
+ // boundaries. so loop over
+ // all faces and draw them as
+ // small pieces of lines
+ {
+ for (unsigned int face_no=0;
+ face_no<GeometryInfo<dim>::faces_per_cell; ++face_no)
+ {
+ const typename dealii::Triangulation<dim,spacedim>::face_iterator
+ face = cell->face(face_no);
+ if (face->at_boundary() || gnuplot_flags.curved_inner_cells)
+ {
+ // compute offset
+ // of quadrature
+ // points within
+ // set of projected
+ // points
+ const unsigned int offset=face_no*n_points;
+ for (unsigned int i=0; i<n_points; ++i)
+ out << (mapping->transform_unit_to_real_cell
+ (cell, q_projector->point(offset+i)))
+ << ' ' << cell->level()
+ << ' ' << static_cast<unsigned int>(cell->material_id())
+ << '\n';
+
+ out << '\n'
+ << '\n';
+ }
+ else
+ {
+ // if, however, the
+ // face is not at
+ // the boundary,
+ // then draw it as
+ // usual
+ out << face->vertex(0)
+ << ' ' << cell->level()
+ << ' ' << static_cast<unsigned int>(cell->material_id())
+ << '\n'
+ << face->vertex(1)
+ << ' ' << cell->level()
+ << ' ' << static_cast<unsigned int>(cell->material_id())
+ << '\n'
+ << '\n'
+ << '\n';
+ }
+ }
+ }
+ }
if (q_projector != 0)
- delete q_projector;
+ delete q_projector;
- // make sure everything now gets to
- // disk
+ // make sure everything now gets to
+ // disk
out.flush ();
AssertThrow (out, ExcIO());
template <int spacedim>
void write_gnuplot (const dealii::Triangulation<3,spacedim> &tria,
- std::ostream &out,
- const Mapping<3,spacedim> *mapping,
- const GridOutFlags::Gnuplot &gnuplot_flags)
+ std::ostream &out,
+ const Mapping<3,spacedim> *mapping,
+ const GridOutFlags::Gnuplot &gnuplot_flags)
{
AssertThrow (out, ExcIO());
const int dim = 3;
const unsigned int n_additional_points=
- gnuplot_flags.n_boundary_face_points;
+ gnuplot_flags.n_boundary_face_points;
const unsigned int n_points=2+n_additional_points;
typename dealii::Triangulation<dim,spacedim>::active_cell_iterator
- cell=tria.begin_active();
+ cell=tria.begin_active();
const typename dealii::Triangulation<dim,spacedim>::active_cell_iterator
- endc=tria.end();
+ endc=tria.end();
- // if we are to treat curved
- // boundaries, then generate a
- // quadrature formula which will be
- // used to probe boundary points at
- // curved faces
+ // if we are to treat curved
+ // boundaries, then generate a
+ // quadrature formula which will be
+ // used to probe boundary points at
+ // curved faces
Quadrature<dim> *q_projector=0;
std::vector<Point<1> > boundary_points;
if (mapping!=0)
- {
- boundary_points.resize(n_points);
- boundary_points[0][0]=0;
- boundary_points[n_points-1][0]=1;
- for (unsigned int i=1; i<n_points-1; ++i)
- boundary_points[i](0)= 1.*i/(n_points-1);
-
- std::vector<double> dummy_weights(n_points, 1./n_points);
- Quadrature<1> quadrature1d(boundary_points, dummy_weights);
-
- // tensor product of points,
- // only one copy
- QIterated<dim-1> quadrature(quadrature1d, 1);
- q_projector = new Quadrature<dim> (QProjector<dim>::project_to_all_faces(quadrature));
- }
+ {
+ boundary_points.resize(n_points);
+ boundary_points[0][0]=0;
+ boundary_points[n_points-1][0]=1;
+ for (unsigned int i=1; i<n_points-1; ++i)
+ boundary_points[i](0)= 1.*i/(n_points-1);
+
+ std::vector<double> dummy_weights(n_points, 1./n_points);
+ Quadrature<1> quadrature1d(boundary_points, dummy_weights);
+
+ // tensor product of points,
+ // only one copy
+ QIterated<dim-1> quadrature(quadrature1d, 1);
+ q_projector = new Quadrature<dim> (QProjector<dim>::project_to_all_faces(quadrature));
+ }
for (; cell!=endc; ++cell)
- {
- if (gnuplot_flags.write_cell_numbers)
- out << "# cell " << cell << '\n';
-
- if (mapping==0 || n_points==2 ||
- (!cell->has_boundary_lines() && !gnuplot_flags.curved_inner_cells))
- {
- // front face
- out << cell->vertex(0)
- << ' ' << cell->level()
- << ' ' << static_cast<unsigned int>(cell->material_id()) << '\n'
- << cell->vertex(1)
- << ' ' << cell->level()
- << ' ' << static_cast<unsigned int>(cell->material_id()) << '\n'
- << cell->vertex(5)
- << ' ' << cell->level()
- << ' ' << static_cast<unsigned int>(cell->material_id()) << '\n'
- << cell->vertex(4)
- << ' ' << cell->level()
- << ' ' << static_cast<unsigned int>(cell->material_id()) << '\n'
- << cell->vertex(0)
- << ' ' << cell->level()
- << ' ' << static_cast<unsigned int>(cell->material_id()) << '\n'
- << '\n';
- // back face
- out << cell->vertex(2)
- << ' ' << cell->level()
- << ' ' << static_cast<unsigned int>(cell->material_id()) << '\n'
- << cell->vertex(3)
- << ' ' << cell->level()
- << ' ' << static_cast<unsigned int>(cell->material_id()) << '\n'
- << cell->vertex(7)
- << ' ' << cell->level()
- << ' ' << static_cast<unsigned int>(cell->material_id()) << '\n'
- << cell->vertex(6)
- << ' ' << cell->level()
- << ' ' << static_cast<unsigned int>(cell->material_id()) << '\n'
- << cell->vertex(2)
- << ' ' << cell->level()
- << ' ' << static_cast<unsigned int>(cell->material_id()) << '\n'
- << '\n';
-
- // now for the four connecting lines
- out << cell->vertex(0)
- << ' ' << cell->level()
- << ' ' << static_cast<unsigned int>(cell->material_id()) << '\n'
- << cell->vertex(2)
- << ' ' << cell->level()
- << ' ' << static_cast<unsigned int>(cell->material_id()) << '\n'
- << '\n';
- out << cell->vertex(1)
- << ' ' << cell->level()
- << ' ' << static_cast<unsigned int>(cell->material_id()) << '\n'
- << cell->vertex(3)
- << ' ' << cell->level()
- << ' ' << static_cast<unsigned int>(cell->material_id()) << '\n'
- << '\n';
- out << cell->vertex(5)
- << ' ' << cell->level()
- << ' ' << static_cast<unsigned int>(cell->material_id()) << '\n'
- << cell->vertex(7)
- << ' ' << cell->level()
- << ' ' << static_cast<unsigned int>(cell->material_id()) << '\n'
- << '\n';
- out << cell->vertex(4)
- << ' ' << cell->level()
- << ' ' << static_cast<unsigned int>(cell->material_id()) << '\n'
- << cell->vertex(6)
- << ' ' << cell->level()
- << ' ' << static_cast<unsigned int>(cell->material_id()) << '\n'
- << '\n';
- }
- else
- {
- for (unsigned int face_no=0; face_no<GeometryInfo<dim>::faces_per_cell; ++face_no)
- {
- const typename dealii::Triangulation<dim,spacedim>::face_iterator
- face = cell->face(face_no);
-
- if (face->at_boundary())
- {
- const unsigned int offset=face_no*n_points*n_points;
- for (unsigned int i=0; i<n_points-1; ++i)
- for (unsigned int j=0; j<n_points-1; ++j)
- {
- const Point<spacedim> p0=mapping->transform_unit_to_real_cell(
- cell, q_projector->point(offset+i*n_points+j));
- out << p0
- << ' ' << cell->level()
- << ' ' << static_cast<unsigned int>(cell->material_id()) << '\n';
- out << (mapping->transform_unit_to_real_cell(
- cell, q_projector->point(offset+(i+1)*n_points+j)))
- << ' ' << cell->level()
- << ' ' << static_cast<unsigned int>(cell->material_id()) << '\n';
- out << (mapping->transform_unit_to_real_cell(
- cell, q_projector->point(offset+(i+1)*n_points+j+1)))
- << ' ' << cell->level()
- << ' ' << static_cast<unsigned int>(cell->material_id()) << '\n';
- out << (mapping->transform_unit_to_real_cell(
- cell, q_projector->point(offset+i*n_points+j+1)))
- << ' ' << cell->level()
- << ' ' << static_cast<unsigned int>(cell->material_id()) << '\n';
- // and the
- // first
- // point
- // again
- out << p0
- << ' ' << cell->level()
- << ' ' << static_cast<unsigned int>(cell->material_id()) << '\n';
- out << '\n' << '\n';
- }
- }
- else
- {
- for (unsigned int l=0; l<GeometryInfo<dim>::lines_per_face; ++l)
- {
- const typename dealii::Triangulation<dim,spacedim>::line_iterator
- line=face->line(l);
-
- const Point<spacedim> &v0=line->vertex(0),
- &v1=line->vertex(1);
- if (line->at_boundary() || gnuplot_flags.curved_inner_cells)
- {
- // transform_real_to_unit_cell
- // could be
- // replaced
- // by using
- // QProjector<dim>::project_to_line
- // which is
- // not yet
- // implemented
- const Point<spacedim> u0=mapping->transform_real_to_unit_cell(cell, v0),
- u1=mapping->transform_real_to_unit_cell(cell, v1);
-
- for (unsigned int i=0; i<n_points; ++i)
- out << (mapping->transform_unit_to_real_cell
- (cell, (1-boundary_points[i][0])*u0+boundary_points[i][0]*u1))
- << ' ' << cell->level()
- << ' ' << static_cast<unsigned int>(cell->material_id()) << '\n';
- }
- else
- out << v0
- << ' ' << cell->level()
- << ' ' << static_cast<unsigned int>(cell->material_id()) << '\n'
- << v1
- << ' ' << cell->level()
- << ' ' << static_cast<unsigned int>(cell->material_id()) << '\n';
-
- out << '\n' << '\n';
- }
- }
- }
- }
- }
+ {
+ if (gnuplot_flags.write_cell_numbers)
+ out << "# cell " << cell << '\n';
+
+ if (mapping==0 || n_points==2 ||
+ (!cell->has_boundary_lines() && !gnuplot_flags.curved_inner_cells))
+ {
+ // front face
+ out << cell->vertex(0)
+ << ' ' << cell->level()
+ << ' ' << static_cast<unsigned int>(cell->material_id()) << '\n'
+ << cell->vertex(1)
+ << ' ' << cell->level()
+ << ' ' << static_cast<unsigned int>(cell->material_id()) << '\n'
+ << cell->vertex(5)
+ << ' ' << cell->level()
+ << ' ' << static_cast<unsigned int>(cell->material_id()) << '\n'
+ << cell->vertex(4)
+ << ' ' << cell->level()
+ << ' ' << static_cast<unsigned int>(cell->material_id()) << '\n'
+ << cell->vertex(0)
+ << ' ' << cell->level()
+ << ' ' << static_cast<unsigned int>(cell->material_id()) << '\n'
+ << '\n';
+ // back face
+ out << cell->vertex(2)
+ << ' ' << cell->level()
+ << ' ' << static_cast<unsigned int>(cell->material_id()) << '\n'
+ << cell->vertex(3)
+ << ' ' << cell->level()
+ << ' ' << static_cast<unsigned int>(cell->material_id()) << '\n'
+ << cell->vertex(7)
+ << ' ' << cell->level()
+ << ' ' << static_cast<unsigned int>(cell->material_id()) << '\n'
+ << cell->vertex(6)
+ << ' ' << cell->level()
+ << ' ' << static_cast<unsigned int>(cell->material_id()) << '\n'
+ << cell->vertex(2)
+ << ' ' << cell->level()
+ << ' ' << static_cast<unsigned int>(cell->material_id()) << '\n'
+ << '\n';
+
+ // now for the four connecting lines
+ out << cell->vertex(0)
+ << ' ' << cell->level()
+ << ' ' << static_cast<unsigned int>(cell->material_id()) << '\n'
+ << cell->vertex(2)
+ << ' ' << cell->level()
+ << ' ' << static_cast<unsigned int>(cell->material_id()) << '\n'
+ << '\n';
+ out << cell->vertex(1)
+ << ' ' << cell->level()
+ << ' ' << static_cast<unsigned int>(cell->material_id()) << '\n'
+ << cell->vertex(3)
+ << ' ' << cell->level()
+ << ' ' << static_cast<unsigned int>(cell->material_id()) << '\n'
+ << '\n';
+ out << cell->vertex(5)
+ << ' ' << cell->level()
+ << ' ' << static_cast<unsigned int>(cell->material_id()) << '\n'
+ << cell->vertex(7)
+ << ' ' << cell->level()
+ << ' ' << static_cast<unsigned int>(cell->material_id()) << '\n'
+ << '\n';
+ out << cell->vertex(4)
+ << ' ' << cell->level()
+ << ' ' << static_cast<unsigned int>(cell->material_id()) << '\n'
+ << cell->vertex(6)
+ << ' ' << cell->level()
+ << ' ' << static_cast<unsigned int>(cell->material_id()) << '\n'
+ << '\n';
+ }
+ else
+ {
+ for (unsigned int face_no=0; face_no<GeometryInfo<dim>::faces_per_cell; ++face_no)
+ {
+ const typename dealii::Triangulation<dim,spacedim>::face_iterator
+ face = cell->face(face_no);
+
+ if (face->at_boundary())
+ {
+ const unsigned int offset=face_no*n_points*n_points;
+ for (unsigned int i=0; i<n_points-1; ++i)
+ for (unsigned int j=0; j<n_points-1; ++j)
+ {
+ const Point<spacedim> p0=mapping->transform_unit_to_real_cell(
+ cell, q_projector->point(offset+i*n_points+j));
+ out << p0
+ << ' ' << cell->level()
+ << ' ' << static_cast<unsigned int>(cell->material_id()) << '\n';
+ out << (mapping->transform_unit_to_real_cell(
+ cell, q_projector->point(offset+(i+1)*n_points+j)))
+ << ' ' << cell->level()
+ << ' ' << static_cast<unsigned int>(cell->material_id()) << '\n';
+ out << (mapping->transform_unit_to_real_cell(
+ cell, q_projector->point(offset+(i+1)*n_points+j+1)))
+ << ' ' << cell->level()
+ << ' ' << static_cast<unsigned int>(cell->material_id()) << '\n';
+ out << (mapping->transform_unit_to_real_cell(
+ cell, q_projector->point(offset+i*n_points+j+1)))
+ << ' ' << cell->level()
+ << ' ' << static_cast<unsigned int>(cell->material_id()) << '\n';
+ // and the
+ // first
+ // point
+ // again
+ out << p0
+ << ' ' << cell->level()
+ << ' ' << static_cast<unsigned int>(cell->material_id()) << '\n';
+ out << '\n' << '\n';
+ }
+ }
+ else
+ {
+ for (unsigned int l=0; l<GeometryInfo<dim>::lines_per_face; ++l)
+ {
+ const typename dealii::Triangulation<dim,spacedim>::line_iterator
+ line=face->line(l);
+
+ const Point<spacedim> &v0=line->vertex(0),
+ &v1=line->vertex(1);
+ if (line->at_boundary() || gnuplot_flags.curved_inner_cells)
+ {
+ // transform_real_to_unit_cell
+ // could be
+ // replaced
+ // by using
+ // QProjector<dim>::project_to_line
+ // which is
+ // not yet
+ // implemented
+ const Point<spacedim> u0=mapping->transform_real_to_unit_cell(cell, v0),
+ u1=mapping->transform_real_to_unit_cell(cell, v1);
+
+ for (unsigned int i=0; i<n_points; ++i)
+ out << (mapping->transform_unit_to_real_cell
+ (cell, (1-boundary_points[i][0])*u0+boundary_points[i][0]*u1))
+ << ' ' << cell->level()
+ << ' ' << static_cast<unsigned int>(cell->material_id()) << '\n';
+ }
+ else
+ out << v0
+ << ' ' << cell->level()
+ << ' ' << static_cast<unsigned int>(cell->material_id()) << '\n'
+ << v1
+ << ' ' << cell->level()
+ << ' ' << static_cast<unsigned int>(cell->material_id()) << '\n';
+
+ out << '\n' << '\n';
+ }
+ }
+ }
+ }
+ }
if (q_projector != 0)
- delete q_projector;
+ delete q_projector;
- // make sure everything now gets to
- // disk
+ // make sure everything now gets to
+ // disk
out.flush ();
AssertThrow (out, ExcIO());
{
struct LineEntry
{
- Point<2> first;
- Point<2> second;
- bool colorize;
- unsigned int level;
- LineEntry (const Point<2> &f,
- const Point<2> &s,
- const bool c,
- const unsigned int l)
- :
- first(f), second(s),
- colorize(c), level(l)
- {}
+ Point<2> first;
+ Point<2> second;
+ bool colorize;
+ unsigned int level;
+ LineEntry (const Point<2> &f,
+ const Point<2> &s,
+ const bool c,
+ const unsigned int l)
+ :
+ first(f), second(s),
+ colorize(c), level(l)
+ {}
};
void write_eps (const dealii::Triangulation<1> &,
- std::ostream &,
- const Mapping<1> *,
- const GridOutFlags::Eps<2> &,
- const GridOutFlags::Eps<3> &)
+ std::ostream &,
+ const Mapping<1> *,
+ const GridOutFlags::Eps<2> &,
+ const GridOutFlags::Eps<3> &)
{
Assert(false, ExcNotImplemented());
}
template <int dim>
void write_eps (const dealii::Triangulation<dim> &tria,
- std::ostream &out,
- const Mapping<dim> *mapping,
- const GridOutFlags::Eps<2> &eps_flags_2,
- const GridOutFlags::Eps<3> &eps_flags_3)
+ std::ostream &out,
+ const Mapping<dim> *mapping,
+ const GridOutFlags::Eps<2> &eps_flags_2,
+ const GridOutFlags::Eps<3> &eps_flags_3)
{
typedef std::list<LineEntry> LineList;
- // get a pointer to the flags
- // common to all dimensions, in
- // order to avoid the recurring
- // distinctions between
- // eps_flags_1, eps_flags_2, ...
+ // get a pointer to the flags
+ // common to all dimensions, in
+ // order to avoid the recurring
+ // distinctions between
+ // eps_flags_1, eps_flags_2, ...
const GridOutFlags::EpsFlagsBase
- &eps_flags_base = (dim==2 ?
- static_cast<const GridOutFlags::EpsFlagsBase&>(eps_flags_2) :
- (dim==3 ?
- static_cast<const GridOutFlags::EpsFlagsBase&>(eps_flags_3) :
- *static_cast<const GridOutFlags::EpsFlagsBase*>(0)));
+ &eps_flags_base = (dim==2 ?
+ static_cast<const GridOutFlags::EpsFlagsBase&>(eps_flags_2) :
+ (dim==3 ?
+ static_cast<const GridOutFlags::EpsFlagsBase&>(eps_flags_3) :
+ *static_cast<const GridOutFlags::EpsFlagsBase*>(0)));
AssertThrow (out, ExcIO());
const unsigned int n_points = eps_flags_base.n_boundary_face_points;
- // make up a list of lines by which
- // we will construct the triangulation
- //
- // this part unfortunately is a bit
- // dimension dependent, so we have to
- // treat every dimension different.
- // however, by directly producing
- // the lines to be printed, i.e. their
- // 2d images, we can later do the
- // actual output dimension independent
- // again
+ // make up a list of lines by which
+ // we will construct the triangulation
+ //
+ // this part unfortunately is a bit
+ // dimension dependent, so we have to
+ // treat every dimension different.
+ // however, by directly producing
+ // the lines to be printed, i.e. their
+ // 2d images, we can later do the
+ // actual output dimension independent
+ // again
LineList line_list;
switch (dim)
- {
- case 1:
- {
- Assert(false, ExcInternalError());
- break;
- };
-
- case 2:
- {
- typename dealii::Triangulation<dim>::active_cell_iterator
- cell=tria.begin_active(),
- endc=tria.end();
-
- for (; cell!=endc; ++cell)
- for (unsigned int line_no=0;
- line_no<GeometryInfo<dim>::lines_per_cell; ++line_no)
- {
- typename dealii::Triangulation<dim>::line_iterator
- line=cell->line(line_no);
-
- // first treat all
- // interior lines and
- // make up a list of
- // them. if curved
- // lines shall not be
- // supported (i.e. no
- // mapping is
- // provided), then also
- // treat all other
- // lines
- if (!line->has_children() &&
- (mapping==0 || !line->at_boundary()))
- // one would expect
- // make_pair(line->vertex(0),
- // line->vertex(1))
- // here, but that is
- // not dimension
- // independent, since
- // vertex(i) is
- // Point<dim>, but we
- // want a Point<2>.
- // in fact, whenever
- // we're here, the
- // vertex is a
- // Point<dim>, but
- // the compiler does
- // not know
- // this. hopefully,
- // the compiler will
- // optimize away this
- // little kludge
- line_list.push_back (LineEntry(Point<2>(line->vertex(0)(0),
- line->vertex(0)(1)),
- Point<2>(line->vertex(1)(0),
- line->vertex(1)(1)),
- line->user_flag_set(),
- cell->level()));
- }
-
- // next if we are to treat
- // curved boundaries
- // specially, then add lines
- // to the list consisting of
- // pieces of the boundary
- // lines
- if (mapping!=0)
- {
- // to do so, first
- // generate a sequence of
- // points on a face and
- // project them onto the
- // faces of a unit cell
- std::vector<Point<dim-1> > boundary_points (n_points);
-
- for (unsigned int i=0; i<n_points; ++i)
- boundary_points[i](0) = 1.*(i+1)/(n_points+1);
-
- Quadrature<dim-1> quadrature (boundary_points);
- Quadrature<dim> q_projector (QProjector<dim>::project_to_all_faces(quadrature));
-
- // next loop over all
- // boundary faces and
- // generate the info from
- // them
- typename dealii::Triangulation<dim>::active_cell_iterator
- cell=tria.begin_active ();
- const typename dealii::Triangulation<dim>::active_cell_iterator
- end=tria.end ();
- for (; cell!=end; ++cell)
- for (unsigned int face_no=0; face_no<GeometryInfo<dim>::faces_per_cell; ++face_no)
- {
- const typename dealii::Triangulation<dim>::face_iterator
- face = cell->face(face_no);
-
- if (face->at_boundary())
- {
- Point<dim> p0_dim(face->vertex(0));
- Point<2> p0 (p0_dim(0), p0_dim(1));
-
- // loop over
- // all pieces
- // of the line
- // and generate
- // line-lets
- const unsigned int offset=face_no*n_points;
- for (unsigned int i=0; i<n_points; ++i)
- {
- const Point<dim> p1_dim (mapping->transform_unit_to_real_cell
- (cell, q_projector.point(offset+i)));
- const Point<2> p1 (p1_dim(0), p1_dim(1));
-
- line_list.push_back (LineEntry(p0, p1,
- face->user_flag_set(),
- cell->level() ));
- p0=p1;
- }
-
- // generate last piece
- const Point<dim> p1_dim (face->vertex(1));
- const Point<2> p1 (p1_dim(0), p1_dim(1));
- line_list.push_back (LineEntry(p0, p1,
- face->user_flag_set(),
- cell->level()));
- };
- };
- };
-
- break;
- };
-
- case 3:
- {
- // curved boundary output
- // presently not supported
- Assert (mapping == 0, ExcNotImplemented());
-
- typename dealii::Triangulation<dim>::active_cell_iterator
- cell=tria.begin_active(),
- endc=tria.end();
-
- // loop over all lines and compute their
- // projection on the plane perpendicular
- // to the direction of sight
-
- // direction of view equals the unit
- // vector of the position of the
- // spectator to the origin.
- //
- // we chose here the viewpoint as in
- // gnuplot as default.
- //
- //TODO:[WB] Fix a potential problem with viewing angles in 3d Eps GridOut
- // note: the following might be wrong
- // if one of the base vectors below
- // is in direction of the viewer, but
- // I am too tired at present to fix
- // this
- const double pi = numbers::PI;
- const double z_angle = eps_flags_3.azimut_angle;
- const double turn_angle = eps_flags_3.turn_angle;
- const Point<dim> view_direction(-std::sin(z_angle * 2.*pi / 360.) * std::sin(turn_angle * 2.*pi / 360.),
- +std::sin(z_angle * 2.*pi / 360.) * std::cos(turn_angle * 2.*pi / 360.),
- -std::cos(z_angle * 2.*pi / 360.));
-
- // decide about the two unit vectors
- // in this plane. we chose the first one
- // to be the projection of the z-axis
- // to this plane
- const Point<dim> vector1
- = Point<dim>(0,0,1) - ((Point<dim>(0,0,1) * view_direction) * view_direction);
- const Point<dim> unit_vector1 = vector1 / std::sqrt(vector1.square());
-
- // now the third vector is fixed. we
- // chose the projection of a more or
- // less arbitrary vector to the plane
- // perpendicular to the first one
- const Point<dim> vector2
- = (Point<dim>(1,0,0)
- - ((Point<dim>(1,0,0) * view_direction) * view_direction)
- - ((Point<dim>(1,0,0) * unit_vector1) * unit_vector1));
- const Point<dim> unit_vector2 = vector2 / std::sqrt(vector2.square());
-
-
- for (; cell!=endc; ++cell)
- for (unsigned int line_no=0;
- line_no<GeometryInfo<dim>::lines_per_cell; ++line_no)
- {
- typename dealii::Triangulation<dim>::line_iterator
- line=cell->line(line_no);
- line_list.push_back (LineEntry(Point<2>(line->vertex(0) * unit_vector2,
- line->vertex(0) * unit_vector1),
- Point<2>(line->vertex(1) * unit_vector2,
- line->vertex(1) * unit_vector1),
- line->user_flag_set(),
- cell->level()));
- }
-
- break;
- }
-
- default:
- Assert (false, ExcNotImplemented());
- }
-
-
-
- // find out minimum and maximum x and
- // y coordinates to compute offsets
- // and scaling factors
+ {
+ case 1:
+ {
+ Assert(false, ExcInternalError());
+ break;
+ };
+
+ case 2:
+ {
+ typename dealii::Triangulation<dim>::active_cell_iterator
+ cell=tria.begin_active(),
+ endc=tria.end();
+
+ for (; cell!=endc; ++cell)
+ for (unsigned int line_no=0;
+ line_no<GeometryInfo<dim>::lines_per_cell; ++line_no)
+ {
+ typename dealii::Triangulation<dim>::line_iterator
+ line=cell->line(line_no);
+
+ // first treat all
+ // interior lines and
+ // make up a list of
+ // them. if curved
+ // lines shall not be
+ // supported (i.e. no
+ // mapping is
+ // provided), then also
+ // treat all other
+ // lines
+ if (!line->has_children() &&
+ (mapping==0 || !line->at_boundary()))
+ // one would expect
+ // make_pair(line->vertex(0),
+ // line->vertex(1))
+ // here, but that is
+ // not dimension
+ // independent, since
+ // vertex(i) is
+ // Point<dim>, but we
+ // want a Point<2>.
+ // in fact, whenever
+ // we're here, the
+ // vertex is a
+ // Point<dim>, but
+ // the compiler does
+ // not know
+ // this. hopefully,
+ // the compiler will
+ // optimize away this
+ // little kludge
+ line_list.push_back (LineEntry(Point<2>(line->vertex(0)(0),
+ line->vertex(0)(1)),
+ Point<2>(line->vertex(1)(0),
+ line->vertex(1)(1)),
+ line->user_flag_set(),
+ cell->level()));
+ }
+
+ // next if we are to treat
+ // curved boundaries
+ // specially, then add lines
+ // to the list consisting of
+ // pieces of the boundary
+ // lines
+ if (mapping!=0)
+ {
+ // to do so, first
+ // generate a sequence of
+ // points on a face and
+ // project them onto the
+ // faces of a unit cell
+ std::vector<Point<dim-1> > boundary_points (n_points);
+
+ for (unsigned int i=0; i<n_points; ++i)
+ boundary_points[i](0) = 1.*(i+1)/(n_points+1);
+
+ Quadrature<dim-1> quadrature (boundary_points);
+ Quadrature<dim> q_projector (QProjector<dim>::project_to_all_faces(quadrature));
+
+ // next loop over all
+ // boundary faces and
+ // generate the info from
+ // them
+ typename dealii::Triangulation<dim>::active_cell_iterator
+ cell=tria.begin_active ();
+ const typename dealii::Triangulation<dim>::active_cell_iterator
+ end=tria.end ();
+ for (; cell!=end; ++cell)
+ for (unsigned int face_no=0; face_no<GeometryInfo<dim>::faces_per_cell; ++face_no)
+ {
+ const typename dealii::Triangulation<dim>::face_iterator
+ face = cell->face(face_no);
+
+ if (face->at_boundary())
+ {
+ Point<dim> p0_dim(face->vertex(0));
+ Point<2> p0 (p0_dim(0), p0_dim(1));
+
+ // loop over
+ // all pieces
+ // of the line
+ // and generate
+ // line-lets
+ const unsigned int offset=face_no*n_points;
+ for (unsigned int i=0; i<n_points; ++i)
+ {
+ const Point<dim> p1_dim (mapping->transform_unit_to_real_cell
+ (cell, q_projector.point(offset+i)));
+ const Point<2> p1 (p1_dim(0), p1_dim(1));
+
+ line_list.push_back (LineEntry(p0, p1,
+ face->user_flag_set(),
+ cell->level() ));
+ p0=p1;
+ }
+
+ // generate last piece
+ const Point<dim> p1_dim (face->vertex(1));
+ const Point<2> p1 (p1_dim(0), p1_dim(1));
+ line_list.push_back (LineEntry(p0, p1,
+ face->user_flag_set(),
+ cell->level()));
+ };
+ };
+ };
+
+ break;
+ };
+
+ case 3:
+ {
+ // curved boundary output
+ // presently not supported
+ Assert (mapping == 0, ExcNotImplemented());
+
+ typename dealii::Triangulation<dim>::active_cell_iterator
+ cell=tria.begin_active(),
+ endc=tria.end();
+
+ // loop over all lines and compute their
+ // projection on the plane perpendicular
+ // to the direction of sight
+
+ // direction of view equals the unit
+ // vector of the position of the
+ // spectator to the origin.
+ //
+ // we chose here the viewpoint as in
+ // gnuplot as default.
+ //
+ //TODO:[WB] Fix a potential problem with viewing angles in 3d Eps GridOut
+ // note: the following might be wrong
+ // if one of the base vectors below
+ // is in direction of the viewer, but
+ // I am too tired at present to fix
+ // this
+ const double pi = numbers::PI;
+ const double z_angle = eps_flags_3.azimut_angle;
+ const double turn_angle = eps_flags_3.turn_angle;
+ const Point<dim> view_direction(-std::sin(z_angle * 2.*pi / 360.) * std::sin(turn_angle * 2.*pi / 360.),
+ +std::sin(z_angle * 2.*pi / 360.) * std::cos(turn_angle * 2.*pi / 360.),
+ -std::cos(z_angle * 2.*pi / 360.));
+
+ // decide about the two unit vectors
+ // in this plane. we chose the first one
+ // to be the projection of the z-axis
+ // to this plane
+ const Point<dim> vector1
+ = Point<dim>(0,0,1) - ((Point<dim>(0,0,1) * view_direction) * view_direction);
+ const Point<dim> unit_vector1 = vector1 / std::sqrt(vector1.square());
+
+ // now the third vector is fixed. we
+ // chose the projection of a more or
+ // less arbitrary vector to the plane
+ // perpendicular to the first one
+ const Point<dim> vector2
+ = (Point<dim>(1,0,0)
+ - ((Point<dim>(1,0,0) * view_direction) * view_direction)
+ - ((Point<dim>(1,0,0) * unit_vector1) * unit_vector1));
+ const Point<dim> unit_vector2 = vector2 / std::sqrt(vector2.square());
+
+
+ for (; cell!=endc; ++cell)
+ for (unsigned int line_no=0;
+ line_no<GeometryInfo<dim>::lines_per_cell; ++line_no)
+ {
+ typename dealii::Triangulation<dim>::line_iterator
+ line=cell->line(line_no);
+ line_list.push_back (LineEntry(Point<2>(line->vertex(0) * unit_vector2,
+ line->vertex(0) * unit_vector1),
+ Point<2>(line->vertex(1) * unit_vector2,
+ line->vertex(1) * unit_vector1),
+ line->user_flag_set(),
+ cell->level()));
+ }
+
+ break;
+ }
+
+ default:
+ Assert (false, ExcNotImplemented());
+ }
+
+
+
+ // find out minimum and maximum x and
+ // y coordinates to compute offsets
+ // and scaling factors
double x_min = tria.begin_active_line()->vertex(0)(0);
double x_max = x_min;
double y_min = tria.begin_active_line()->vertex(0)(1);
unsigned int max_level = line_list.begin()->level;
for (LineList::const_iterator line=line_list.begin();
- line!=line_list.end(); ++line)
- {
- x_min = std::min (x_min, line->first(0));
- x_min = std::min (x_min, line->second(0));
+ line!=line_list.end(); ++line)
+ {
+ x_min = std::min (x_min, line->first(0));
+ x_min = std::min (x_min, line->second(0));
- x_max = std::max (x_max, line->first(0));
- x_max = std::max (x_max, line->second(0));
+ x_max = std::max (x_max, line->first(0));
+ x_max = std::max (x_max, line->second(0));
- y_min = std::min (y_min, line->first(1));
- y_min = std::min (y_min, line->second(1));
+ y_min = std::min (y_min, line->first(1));
+ y_min = std::min (y_min, line->second(1));
- y_max = std::max (y_max, line->first(1));
- y_max = std::max (y_max, line->second(1));
+ y_max = std::max (y_max, line->first(1));
+ y_max = std::max (y_max, line->second(1));
- max_level = std::max (max_level, line->level);
- };
+ max_level = std::max (max_level, line->level);
+ };
- // scale in x-direction such that
- // in the output 0 <= x <= 300.
- // don't scale in y-direction to
- // preserve the shape of the
- // triangulation
+ // scale in x-direction such that
+ // in the output 0 <= x <= 300.
+ // don't scale in y-direction to
+ // preserve the shape of the
+ // triangulation
const double scale = (eps_flags_base.size /
- (eps_flags_base.size_type==GridOutFlags::EpsFlagsBase::width ?
- x_max - x_min :
- y_min - y_max));
+ (eps_flags_base.size_type==GridOutFlags::EpsFlagsBase::width ?
+ x_max - x_min :
+ y_min - y_max));
- // now write preamble
+ // now write preamble
if (true)
- {
- // block this to have local
- // variables destroyed after
- // use
- std::time_t time1= std::time (0);
- std::tm *time = std::localtime(&time1);
- out << "%!PS-Adobe-2.0 EPSF-1.2" << '\n'
- << "%%Title: deal.II Output" << '\n'
- << "%%Creator: the deal.II library" << '\n'
- << "%%Creation Date: "
- << time->tm_year+1900 << "/"
- << time->tm_mon+1 << "/"
- << time->tm_mday << " - "
- << time->tm_hour << ":"
- << std::setw(2) << time->tm_min << ":"
- << std::setw(2) << time->tm_sec << '\n'
- << "%%BoundingBox: "
- // lower left corner
- << "0 0 "
- // upper right corner
- << static_cast<unsigned int>(std::floor(( (x_max-x_min) * scale )+1))
- << ' '
- << static_cast<unsigned int>(std::floor(( (y_max-y_min) * scale )+1))
- << '\n';
-
- // define some abbreviations to keep
- // the output small:
- // m=move turtle to
- // x=execute line stroke
- // b=black pen
- // r=red pen
- out << "/m {moveto} bind def" << '\n'
- << "/x {lineto stroke} bind def" << '\n'
- << "/b {0 0 0 setrgbcolor} def" << '\n'
- << "/r {1 0 0 setrgbcolor} def" << '\n';
-
- // calculate colors for level
- // coloring; level 0 is black,
- // other levels are blue
- // ... red
- if (eps_flags_base.color_lines_level)
- out << "/l { neg "
- << (max_level)
- << " add "
- << (0.66666/std::max(1U,(max_level-1)))
- << " mul 1 0.8 sethsbcolor} def" << '\n';
-
- // in 2d, we can also plot cell
- // and vertex numbers, but this
- // requires a somewhat more
- // lengthy preamble. please
- // don't ask me what most of
- // this means, it is reverse
- // engineered from what GNUPLOT
- // uses in its output
- if ((dim == 2) && (eps_flags_2.write_cell_numbers ||
- eps_flags_2.write_vertex_numbers))
- {
- out << ("/R {rmoveto} bind def\n"
- "/Symbol-Oblique /Symbol findfont [1 0 .167 1 0 0] makefont\n"
- "dup length dict begin {1 index /FID eq {pop pop} {def} ifelse} forall\n"
- "currentdict end definefont\n"
- "/MFshow {{dup dup 0 get findfont exch 1 get scalefont setfont\n"
- "[ currentpoint ] exch dup 2 get 0 exch rmoveto dup dup 5 get exch 4 get\n"
- "{show} {stringwidth pop 0 rmoveto}ifelse dup 3 get\n"
- "{2 get neg 0 exch rmoveto pop} {pop aload pop moveto}ifelse} forall} bind def\n"
- "/MFwidth {0 exch {dup 3 get{dup dup 0 get findfont exch 1 get scalefont setfont\n"
- "5 get stringwidth pop add}\n"
- "{pop} ifelse} forall} bind def\n"
- "/MCshow { currentpoint stroke m\n"
- "exch dup MFwidth -2 div 3 -1 roll R MFshow } def\n")
- << '\n';
- };
-
- out << "%%EndProlog" << '\n'
- << '\n';
-
- // set fine lines
- out << eps_flags_base.line_width << " setlinewidth" << '\n';
- };
-
- // now write the lines
+ {
+ // block this to have local
+ // variables destroyed after
+ // use
+ std::time_t time1= std::time (0);
+ std::tm *time = std::localtime(&time1);
+ out << "%!PS-Adobe-2.0 EPSF-1.2" << '\n'
+ << "%%Title: deal.II Output" << '\n'
+ << "%%Creator: the deal.II library" << '\n'
+ << "%%Creation Date: "
+ << time->tm_year+1900 << "/"
+ << time->tm_mon+1 << "/"
+ << time->tm_mday << " - "
+ << time->tm_hour << ":"
+ << std::setw(2) << time->tm_min << ":"
+ << std::setw(2) << time->tm_sec << '\n'
+ << "%%BoundingBox: "
+ // lower left corner
+ << "0 0 "
+ // upper right corner
+ << static_cast<unsigned int>(std::floor(( (x_max-x_min) * scale )+1))
+ << ' '
+ << static_cast<unsigned int>(std::floor(( (y_max-y_min) * scale )+1))
+ << '\n';
+
+ // define some abbreviations to keep
+ // the output small:
+ // m=move turtle to
+ // x=execute line stroke
+ // b=black pen
+ // r=red pen
+ out << "/m {moveto} bind def" << '\n'
+ << "/x {lineto stroke} bind def" << '\n'
+ << "/b {0 0 0 setrgbcolor} def" << '\n'
+ << "/r {1 0 0 setrgbcolor} def" << '\n';
+
+ // calculate colors for level
+ // coloring; level 0 is black,
+ // other levels are blue
+ // ... red
+ if (eps_flags_base.color_lines_level)
+ out << "/l { neg "
+ << (max_level)
+ << " add "
+ << (0.66666/std::max(1U,(max_level-1)))
+ << " mul 1 0.8 sethsbcolor} def" << '\n';
+
+ // in 2d, we can also plot cell
+ // and vertex numbers, but this
+ // requires a somewhat more
+ // lengthy preamble. please
+ // don't ask me what most of
+ // this means, it is reverse
+ // engineered from what GNUPLOT
+ // uses in its output
+ if ((dim == 2) && (eps_flags_2.write_cell_numbers ||
+ eps_flags_2.write_vertex_numbers))
+ {
+ out << ("/R {rmoveto} bind def\n"
+ "/Symbol-Oblique /Symbol findfont [1 0 .167 1 0 0] makefont\n"
+ "dup length dict begin {1 index /FID eq {pop pop} {def} ifelse} forall\n"
+ "currentdict end definefont\n"
+ "/MFshow {{dup dup 0 get findfont exch 1 get scalefont setfont\n"
+ "[ currentpoint ] exch dup 2 get 0 exch rmoveto dup dup 5 get exch 4 get\n"
+ "{show} {stringwidth pop 0 rmoveto}ifelse dup 3 get\n"
+ "{2 get neg 0 exch rmoveto pop} {pop aload pop moveto}ifelse} forall} bind def\n"
+ "/MFwidth {0 exch {dup 3 get{dup dup 0 get findfont exch 1 get scalefont setfont\n"
+ "5 get stringwidth pop add}\n"
+ "{pop} ifelse} forall} bind def\n"
+ "/MCshow { currentpoint stroke m\n"
+ "exch dup MFwidth -2 div 3 -1 roll R MFshow } def\n")
+ << '\n';
+ };
+
+ out << "%%EndProlog" << '\n'
+ << '\n';
+
+ // set fine lines
+ out << eps_flags_base.line_width << " setlinewidth" << '\n';
+ };
+
+ // now write the lines
const Point<2> offset(x_min, y_min);
for (LineList::const_iterator line=line_list.begin();
- line!=line_list.end(); ++line)
- if (eps_flags_base.color_lines_level && (line->level > 0))
- // lines colored according to
- // refinement level,
- // contributed by J�rg
- // R. Weimar
- out << line->level
- << " l "
- << (line->first - offset) * scale << " m "
- << (line->second - offset) * scale << " x" << '\n';
- else
- out << ((line->colorize && eps_flags_base.color_lines_on_user_flag) ? "r " : "b ")
- << (line->first - offset) * scale << " m "
- << (line->second - offset) * scale << " x" << '\n';
-
- // finally write the cell numbers
- // in 2d, if that is desired
+ line!=line_list.end(); ++line)
+ if (eps_flags_base.color_lines_level && (line->level > 0))
+ // lines colored according to
+ // refinement level,
+ // contributed by J�rg
+ // R. Weimar
+ out << line->level
+ << " l "
+ << (line->first - offset) * scale << " m "
+ << (line->second - offset) * scale << " x" << '\n';
+ else
+ out << ((line->colorize && eps_flags_base.color_lines_on_user_flag) ? "r " : "b ")
+ << (line->first - offset) * scale << " m "
+ << (line->second - offset) * scale << " x" << '\n';
+
+ // finally write the cell numbers
+ // in 2d, if that is desired
if ((dim == 2) && (eps_flags_2.write_cell_numbers == true))
- {
- out << "(Helvetica) findfont 140 scalefont setfont"
- << '\n';
-
- typename dealii::Triangulation<dim>::active_cell_iterator
- cell = tria.begin_active (),
- endc = tria.end ();
- for (; cell!=endc; ++cell)
- {
- out << (cell->center()(0)-offset(0))*scale << ' '
- << (cell->center()(1)-offset(1))*scale
- << " m" << '\n'
- << "[ [(Helvetica) 12.0 0.0 true true (";
- if (eps_flags_2.write_cell_number_level)
- out << cell;
- else
- out << cell->index();
-
- out << ")] "
- << "] -6 MCshow"
- << '\n';
- };
- };
-
- // and the vertex numbers
+ {
+ out << "(Helvetica) findfont 140 scalefont setfont"
+ << '\n';
+
+ typename dealii::Triangulation<dim>::active_cell_iterator
+ cell = tria.begin_active (),
+ endc = tria.end ();
+ for (; cell!=endc; ++cell)
+ {
+ out << (cell->center()(0)-offset(0))*scale << ' '
+ << (cell->center()(1)-offset(1))*scale
+ << " m" << '\n'
+ << "[ [(Helvetica) 12.0 0.0 true true (";
+ if (eps_flags_2.write_cell_number_level)
+ out << cell;
+ else
+ out << cell->index();
+
+ out << ")] "
+ << "] -6 MCshow"
+ << '\n';
+ };
+ };
+
+ // and the vertex numbers
if ((dim == 2) && (eps_flags_2.write_vertex_numbers == true))
- {
- out << "(Helvetica) findfont 140 scalefont setfont"
- << '\n';
-
- // have a list of those
- // vertices which we have
- // already tracked, to avoid
- // doing this multiply
- std::set<unsigned int> treated_vertices;
- typename dealii::Triangulation<dim>::active_cell_iterator
- cell = tria.begin_active (),
- endc = tria.end ();
- for (; cell!=endc; ++cell)
- for (unsigned int vertex=0;
- vertex<GeometryInfo<dim>::vertices_per_cell;
- ++vertex)
- if (treated_vertices.find(cell->vertex_index(vertex))
- ==
- treated_vertices.end())
- {
- treated_vertices.insert (cell->vertex_index(vertex));
-
- out << (cell->vertex(vertex)(0)-offset(0))*scale << ' '
- << (cell->vertex(vertex)(1)-offset(1))*scale
- << " m" << '\n'
- << "[ [(Helvetica) 10.0 0.0 true true ("
- << cell->vertex_index(vertex)
- << ")] "
- << "] -6 MCshow"
- << '\n';
- };
- };
+ {
+ out << "(Helvetica) findfont 140 scalefont setfont"
+ << '\n';
+
+ // have a list of those
+ // vertices which we have
+ // already tracked, to avoid
+ // doing this multiply
+ std::set<unsigned int> treated_vertices;
+ typename dealii::Triangulation<dim>::active_cell_iterator
+ cell = tria.begin_active (),
+ endc = tria.end ();
+ for (; cell!=endc; ++cell)
+ for (unsigned int vertex=0;
+ vertex<GeometryInfo<dim>::vertices_per_cell;
+ ++vertex)
+ if (treated_vertices.find(cell->vertex_index(vertex))
+ ==
+ treated_vertices.end())
+ {
+ treated_vertices.insert (cell->vertex_index(vertex));
+
+ out << (cell->vertex(vertex)(0)-offset(0))*scale << ' '
+ << (cell->vertex(vertex)(1)-offset(1))*scale
+ << " m" << '\n'
+ << "[ [(Helvetica) 10.0 0.0 true true ("
+ << cell->vertex_index(vertex)
+ << ")] "
+ << "] -6 MCshow"
+ << '\n';
+ };
+ };
out << "showpage" << '\n';
- // make sure everything now gets to
- // disk
+ // make sure everything now gets to
+ // disk
out.flush ();
AssertThrow (out, ExcIO());
template <int dim>
void GridOut::write_eps (const Triangulation<dim> &tria,
- std::ostream &out,
- const Mapping<dim> *mapping) const
+ std::ostream &out,
+ const Mapping<dim> *mapping) const
{
internal::write_eps (tria, out, mapping,
- eps_flags_2, eps_flags_3);
+ eps_flags_2, eps_flags_3);
}
template <int dim, int spacedim>
void GridOut::write (const Triangulation<dim, spacedim> &tria,
- std::ostream &out,
- const OutputFormat output_format,
- const Mapping<dim,spacedim> *mapping) const
+ std::ostream &out,
+ const OutputFormat output_format,
+ const Mapping<dim,spacedim> *mapping) const
{
switch (output_format)
{
case none:
- return;
+ return;
case dx:
- write_dx (tria, out);
- return;
+ write_dx (tria, out);
+ return;
case ucd:
- write_ucd (tria, out);
- return;
+ write_ucd (tria, out);
+ return;
case gnuplot:
- write_gnuplot (tria, out, mapping);
- return;
+ write_gnuplot (tria, out, mapping);
+ return;
case eps:
- write_eps (tria, out, mapping);
- return;
+ write_eps (tria, out, mapping);
+ return;
case xfig:
- write_xfig (tria, out, mapping);
- return;
+ write_xfig (tria, out, mapping);
+ return;
case msh:
- write_msh (tria, out);
- return;
+ write_msh (tria, out);
+ return;
}
Assert (false, ExcInternalError());
// $Id$
// Version: $Name$
//
-// Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 by the deal.II authors
+// Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
PetscScalar
max_element (const PETScWrappers::Vector &criteria)
{
- // this is horribly slow (since we have
- // to get the array of values from PETSc
- // in every iteration), but works
+ // this is horribly slow (since we have
+ // to get the array of values from PETSc
+ // in every iteration), but works
PetscScalar m = 0;
for (unsigned int i=0; i<criteria.size(); ++i)
- m = std::max (m, criteria(i));
+ m = std::max (m, criteria(i));
return m;
}
PetscScalar
min_element (const PETScWrappers::Vector &criteria)
{
- // this is horribly slow (since we have
- // to get the array of values from PETSc
- // in every iteration), but works
+ // this is horribly slow (since we have
+ // to get the array of values from PETSc
+ // in every iteration), but works
PetscScalar m = criteria(0);
for (unsigned int i=1; i<criteria.size(); ++i)
- m = std::min (m, criteria(i));
+ m = std::min (m, criteria(i));
return m;
}
#endif
template <typename Vector>
typename constraint_and_return_value<!IsBlockVector<Vector>::value,
- typename Vector::value_type>::type
+ typename Vector::value_type>::type
min_element (const Vector &criteria)
{
return internal::min_element (criteria);
template <typename Vector>
typename constraint_and_return_value<!IsBlockVector<Vector>::value,
- typename Vector::value_type>::type
+ typename Vector::value_type>::type
max_element (const Vector &criteria)
{
return internal::max_element (criteria);
template <typename Vector>
typename constraint_and_return_value<IsBlockVector<Vector>::value,
- typename Vector::value_type>::type
+ typename Vector::value_type>::type
min_element (const Vector &criteria)
{
typename Vector::value_type t = internal::min_element(criteria.block(0));
template <typename Vector>
typename constraint_and_return_value<IsBlockVector<Vector>::value,
- typename Vector::value_type>::type
+ typename Vector::value_type>::type
max_element (const Vector &criteria)
{
typename Vector::value_type t = internal::max_element(criteria.block(0));
namespace
{
- /**
- * Sorts the vector @p ind as an
- * index vector of @p a in
- * increasing order. This
- * implementation of quicksort
- * seems to be faster than the
- * STL version and is needed in
- * @p refine_and_coarsen_optimize
- */
+ /**
+ * Sorts the vector @p ind as an
+ * index vector of @p a in
+ * increasing order. This
+ * implementation of quicksort
+ * seems to be faster than the
+ * STL version and is needed in
+ * @p refine_and_coarsen_optimize
+ */
template <class Vector>
void qsort_index (const Vector &a,
- std::vector<unsigned int> &ind,
- int l,
- int r)
+ std::vector<unsigned int> &ind,
+ int l,
+ int r)
{
int i,j;
typename Vector::value_type v;
j = r;
do
{
- do
- {
- ++i;
- }
- while ((a(ind[i])>v) && (i<r));
- do
- {
- --j;
- }
- while ((a(ind[j])<v) && (j>0));
-
- if (i<j)
- std::swap (ind[i], ind[j]);
- else
- std::swap (ind[i], ind[r]);
+ do
+ {
+ ++i;
+ }
+ while ((a(ind[i])>v) && (i<r));
+ do
+ {
+ --j;
+ }
+ while ((a(ind[j])<v) && (j>0));
+
+ if (i<j)
+ std::swap (ind[i], ind[j]);
+ else
+ std::swap (ind[i], ind[r]);
}
while (i<j);
qsort_index(a,ind,l,i-1);
template <int dim, class Vector, int spacedim>
void GridRefinement::refine (Triangulation<dim,spacedim> &tria,
- const Vector &criteria,
- const double threshold)
+ const Vector &criteria,
+ const double threshold)
{
Assert (criteria.size() == tria.n_active_cells(),
- ExcDimensionMismatch(criteria.size(), tria.n_active_cells()));
+ ExcDimensionMismatch(criteria.size(), tria.n_active_cells()));
Assert (criteria.is_non_negative (), ExcNegativeCriteria());
- // when all indicators are zero we
- // do not need to refine but only
- // to coarsen
+ // when all indicators are zero we
+ // do not need to refine but only
+ // to coarsen
if (criteria.all_zero())
return;
//TODO: This is undocumented, looks fishy and seems unnecessary
double new_threshold=threshold;
- // when threshold==0 find the
- // smallest value in criteria
- // greater 0
+ // when threshold==0 find the
+ // smallest value in criteria
+ // greater 0
if (new_threshold==0)
{
new_threshold = criteria(0);
for (unsigned int index=1; index<n_cells; ++index)
- if (criteria(index)>0
- && (criteria(index)<new_threshold))
- new_threshold=criteria(index);
+ if (criteria(index)>0
+ && (criteria(index)<new_threshold))
+ new_threshold=criteria(index);
}
for (unsigned int index=0; index<n_cells; ++cell, ++index)
template <int dim, class Vector, int spacedim>
void GridRefinement::coarsen (Triangulation<dim,spacedim> &tria,
- const Vector &criteria,
- const double threshold)
+ const Vector &criteria,
+ const double threshold)
{
Assert (criteria.size() == tria.n_active_cells(),
- ExcDimensionMismatch(criteria.size(), tria.n_active_cells()));
+ ExcDimensionMismatch(criteria.size(), tria.n_active_cells()));
Assert (criteria.is_non_negative (), ExcNegativeCriteria());
typename Triangulation<dim,spacedim>::active_cell_iterator cell = tria.begin_active();
template <int dim, class Vector, int spacedim>
void
GridRefinement::refine_and_coarsen_fixed_number (Triangulation<dim,spacedim> &tria,
- const Vector &criteria,
- const double top_fraction,
- const double bottom_fraction,
- const unsigned int max_n_cells)
+ const Vector &criteria,
+ const double top_fraction,
+ const double bottom_fraction,
+ const unsigned int max_n_cells)
{
- // correct number of cells is
- // checked in @p{refine}
+ // correct number of cells is
+ // checked in @p{refine}
Assert ((top_fraction>=0) && (top_fraction<=1), ExcInvalidParameterValue());
Assert ((bottom_fraction>=0) && (bottom_fraction<=1), ExcInvalidParameterValue());
Assert (top_fraction+bottom_fraction <= 1, ExcInvalidParameterValue());
int refine_cells = static_cast<int>(top_fraction*criteria.size());
int coarsen_cells = static_cast<int>(bottom_fraction*criteria.size());
- // first we have to see whether we
- // currently already exceed the target
- // number of cells
+ // first we have to see whether we
+ // currently already exceed the target
+ // number of cells
if (tria.n_active_cells() >= max_n_cells)
{
- // if yes, then we need to stop
- // refining cells and instead try to
- // only coarsen as many as it would
- // take to get to the target
-
- // as we have no information on cells
- // being refined isotropically or
- // anisotropically, assume isotropic
- // refinement here, though that may
- // result in a worse approximation
+ // if yes, then we need to stop
+ // refining cells and instead try to
+ // only coarsen as many as it would
+ // take to get to the target
+
+ // as we have no information on cells
+ // being refined isotropically or
+ // anisotropically, assume isotropic
+ // refinement here, though that may
+ // result in a worse approximation
refine_cells = 0;
coarsen_cells = (tria.n_active_cells() - max_n_cells) *
- GeometryInfo<dim>::max_children_per_cell /
- (GeometryInfo<dim>::max_children_per_cell - 1);
+ GeometryInfo<dim>::max_children_per_cell /
+ (GeometryInfo<dim>::max_children_per_cell - 1);
}
- // otherwise, see if we would exceed the
- // maximum desired number of cells with the
- // number of cells that are likely going to
- // result from refinement. here, each cell
- // to be refined is replaced by
- // C=GeometryInfo<dim>::max_children_per_cell
- // new cells, i.e. there will be C-1 more
- // cells than before. similarly, C cells
- // will be replaced by 1
-
- // again, this is true for isotropically
- // refined cells. we take this as an
- // approximation of a mixed refinement.
+ // otherwise, see if we would exceed the
+ // maximum desired number of cells with the
+ // number of cells that are likely going to
+ // result from refinement. here, each cell
+ // to be refined is replaced by
+ // C=GeometryInfo<dim>::max_children_per_cell
+ // new cells, i.e. there will be C-1 more
+ // cells than before. similarly, C cells
+ // will be replaced by 1
+
+ // again, this is true for isotropically
+ // refined cells. we take this as an
+ // approximation of a mixed refinement.
else if (static_cast<unsigned int>
- (tria.n_active_cells()
- + refine_cells * (GeometryInfo<dim>::max_children_per_cell - 1)
- - (coarsen_cells *
- (GeometryInfo<dim>::max_children_per_cell - 1) /
- GeometryInfo<dim>::max_children_per_cell))
- >
- max_n_cells)
+ (tria.n_active_cells()
+ + refine_cells * (GeometryInfo<dim>::max_children_per_cell - 1)
+ - (coarsen_cells *
+ (GeometryInfo<dim>::max_children_per_cell - 1) /
+ GeometryInfo<dim>::max_children_per_cell))
+ >
+ max_n_cells)
{
- // we have to adjust the
- // fractions. assume we want
- // alpha*refine_fraction and
- // alpha*coarsen_fraction as new
- // fractions and the resulting number
- // of cells to be equal to
- // max_n_cells. this leads to the
- // following equation for lambda
+ // we have to adjust the
+ // fractions. assume we want
+ // alpha*refine_fraction and
+ // alpha*coarsen_fraction as new
+ // fractions and the resulting number
+ // of cells to be equal to
+ // max_n_cells. this leads to the
+ // following equation for lambda
const double alpha
- =
- 1. *
- (max_n_cells - tria.n_active_cells())
- /
- (refine_cells * (GeometryInfo<dim>::max_children_per_cell - 1)
- - (coarsen_cells *
- (GeometryInfo<dim>::max_children_per_cell - 1) /
- GeometryInfo<dim>::max_children_per_cell));
+ =
+ 1. *
+ (max_n_cells - tria.n_active_cells())
+ /
+ (refine_cells * (GeometryInfo<dim>::max_children_per_cell - 1)
+ - (coarsen_cells *
+ (GeometryInfo<dim>::max_children_per_cell - 1) /
+ GeometryInfo<dim>::max_children_per_cell));
refine_cells = static_cast<int> (refine_cells * alpha);
coarsen_cells = static_cast<int> (coarsen_cells * alpha);
}
{
dealii::Vector<typename Vector::value_type> tmp (criteria);
if (refine_cells)
- {
- std::nth_element (tmp.begin(), tmp.begin()+refine_cells,
- tmp.end(),
- std::greater<double>());
- refine (tria, criteria, *(tmp.begin() + refine_cells));
- }
+ {
+ std::nth_element (tmp.begin(), tmp.begin()+refine_cells,
+ tmp.end(),
+ std::greater<double>());
+ refine (tria, criteria, *(tmp.begin() + refine_cells));
+ }
if (coarsen_cells)
- {
- std::nth_element (tmp.begin(), tmp.begin()+tmp.size()-coarsen_cells,
- tmp.end(),
- std::greater<double>());
- coarsen (tria, criteria,
- *(tmp.begin() + tmp.size() - coarsen_cells));
- }
+ {
+ std::nth_element (tmp.begin(), tmp.begin()+tmp.size()-coarsen_cells,
+ tmp.end(),
+ std::greater<double>());
+ coarsen (tria, criteria,
+ *(tmp.begin() + tmp.size() - coarsen_cells));
+ }
}
}
template <int dim, class Vector, int spacedim>
void
GridRefinement::refine_and_coarsen_fixed_fraction (Triangulation<dim,spacedim> &tria,
- const Vector &criteria,
- const double top_fraction,
- const double bottom_fraction,
- const unsigned int max_n_cells)
+ const Vector &criteria,
+ const double top_fraction,
+ const double bottom_fraction,
+ const unsigned int max_n_cells)
{
- // correct number of cells is
- // checked in @p{refine}
+ // correct number of cells is
+ // checked in @p{refine}
Assert ((top_fraction>=0) && (top_fraction<=1), ExcInvalidParameterValue());
Assert ((bottom_fraction>=0) && (bottom_fraction<=1), ExcInvalidParameterValue());
Assert (top_fraction+bottom_fraction <= 1, ExcInvalidParameterValue());
Assert (criteria.is_non_negative (), ExcNegativeCriteria());
- // let tmp be the cellwise square of the
- // error, which is what we have to sum
- // up and compare with
- // @p{fraction_of_error*total_error}.
+ // let tmp be the cellwise square of the
+ // error, which is what we have to sum
+ // up and compare with
+ // @p{fraction_of_error*total_error}.
dealii::Vector<typename Vector::value_type> tmp;
tmp = criteria;
const double total_error = tmp.l1_norm();
- // sort the largest criteria to the
- // beginning of the vector
+ // sort the largest criteria to the
+ // beginning of the vector
std::sort (tmp.begin(), tmp.end(), std::greater<double>());
- // compute thresholds
+ // compute thresholds
typename dealii::Vector<typename Vector::value_type>::const_iterator
pp=tmp.begin();
for (double sum=0;
++pp)
sum += *pp;
double top_threshold = ( pp != tmp.begin () ?
- (*pp+*(pp-1))/2 :
- *pp );
+ (*pp+*(pp-1))/2 :
+ *pp );
typename dealii::Vector<typename Vector::value_type>::const_iterator
qq=(tmp.end()-1);
for (double sum=0;
--qq)
sum += *qq;
double bottom_threshold = ( qq != (tmp.end()-1) ?
- (*qq + *(qq+1))/2 :
- 0);
-
- // we now have an idea how many cells we
- // are going to refine and coarsen. we use
- // this information to see whether we are
- // over the limit and if so use a function
- // that knows how to deal with this
- // situation
-
- // note, that at this point, we have no
- // information about anisotropically refined
- // cells, thus use the situation of purely
- // isotropic refinement as guess for a mixed
- // refinemnt as well.
+ (*qq + *(qq+1))/2 :
+ 0);
+
+ // we now have an idea how many cells we
+ // are going to refine and coarsen. we use
+ // this information to see whether we are
+ // over the limit and if so use a function
+ // that knows how to deal with this
+ // situation
+
+ // note, that at this point, we have no
+ // information about anisotropically refined
+ // cells, thus use the situation of purely
+ // isotropic refinement as guess for a mixed
+ // refinemnt as well.
{
const unsigned int refine_cells = pp - tmp.begin(),
- coarsen_cells = tmp.end() - qq;
+ coarsen_cells = tmp.end() - qq;
if (static_cast<unsigned int>
- (tria.n_active_cells()
- + refine_cells * (GeometryInfo<dim>::max_children_per_cell - 1)
- - (coarsen_cells *
- (GeometryInfo<dim>::max_children_per_cell - 1) /
- GeometryInfo<dim>::max_children_per_cell))
- >
- max_n_cells)
+ (tria.n_active_cells()
+ + refine_cells * (GeometryInfo<dim>::max_children_per_cell - 1)
+ - (coarsen_cells *
+ (GeometryInfo<dim>::max_children_per_cell - 1) /
+ GeometryInfo<dim>::max_children_per_cell))
+ >
+ max_n_cells)
{
- refine_and_coarsen_fixed_number (tria,
- criteria,
- 1.*refine_cells/criteria.size(),
- 1.*coarsen_cells/criteria.size(),
- max_n_cells);
- return;
+ refine_and_coarsen_fixed_number (tria,
+ criteria,
+ 1.*refine_cells/criteria.size(),
+ 1.*coarsen_cells/criteria.size(),
+ max_n_cells);
+ return;
}
}
- // in some rare cases it may happen that
- // both thresholds are the same (e.g. if
- // there are many cells with the same
- // error indicator). That would mean that
- // all cells will be flagged for
- // refinement or coarsening, but some will
- // be flagged for both, namely those for
- // which the indicator equals the
- // thresholds. This is forbidden, however.
- //
- // In some rare cases with very few cells
- // we also could get integer round off
- // errors and get problems with
- // the top and bottom fractions.
- //
- // In these case we arbitrarily reduce the
- // bottom threshold by one permille below
- // the top threshold
- //
- // Finally, in some cases
- // (especially involving symmetric
- // solutions) there are many cells
- // with the same error indicator
- // values. if there are many with
- // indicator equal to the top
- // threshold, no refinement will
- // take place below; to avoid this
- // case, we also lower the top
- // threshold if it equals the
- // largest indicator and the
- // top_fraction!=1
+ // in some rare cases it may happen that
+ // both thresholds are the same (e.g. if
+ // there are many cells with the same
+ // error indicator). That would mean that
+ // all cells will be flagged for
+ // refinement or coarsening, but some will
+ // be flagged for both, namely those for
+ // which the indicator equals the
+ // thresholds. This is forbidden, however.
+ //
+ // In some rare cases with very few cells
+ // we also could get integer round off
+ // errors and get problems with
+ // the top and bottom fractions.
+ //
+ // In these case we arbitrarily reduce the
+ // bottom threshold by one permille below
+ // the top threshold
+ //
+ // Finally, in some cases
+ // (especially involving symmetric
+ // solutions) there are many cells
+ // with the same error indicator
+ // values. if there are many with
+ // indicator equal to the top
+ // threshold, no refinement will
+ // take place below; to avoid this
+ // case, we also lower the top
+ // threshold if it equals the
+ // largest indicator and the
+ // top_fraction!=1
if ((top_threshold == max_element(criteria)) &&
(top_fraction != 1))
top_threshold *= 0.999;
if (bottom_threshold>=top_threshold)
bottom_threshold = 0.999*top_threshold;
- // actually flag cells
+ // actually flag cells
if (top_threshold < max_element(criteria))
refine (tria, criteria, top_threshold);
template <int dim, class Vector, int spacedim>
void
GridRefinement::refine_and_coarsen_optimize (Triangulation<dim,spacedim> &tria,
- const Vector &criteria,
- const unsigned int order)
+ const Vector &criteria,
+ const unsigned int order)
{
Assert (criteria.size() == tria.n_active_cells(),
- ExcDimensionMismatch(criteria.size(), tria.n_active_cells()));
+ ExcDimensionMismatch(criteria.size(), tria.n_active_cells()));
Assert (criteria.is_non_negative (), ExcNegativeCriteria());
- // get an increasing order on
- // the error indicator
+ // get an increasing order on
+ // the error indicator
std::vector<unsigned int> tmp(criteria.size());
for (unsigned int i=0;i<criteria.size();++i)
tmp[i] = i;
unsigned int N = criteria.size();
unsigned int M = 0;
- // The first M cells are refined
- // to minimize the expected error
- // multiplied with the expected
- // number of cells to the power of
- // 2 * expected order of the finite
- // element space divided by the dimension
- // of the discretized space.
- // We assume that the error is
- // decreased by (1-2^(-order)) a_K if the cell
- // K with error indicator a_K is
- // refined and 'order' ist the expected
+ // The first M cells are refined
+ // to minimize the expected error
+ // multiplied with the expected
+ // number of cells to the power of
+ // 2 * expected order of the finite
+ // element space divided by the dimension
+ // of the discretized space.
+ // We assume that the error is
+ // decreased by (1-2^(-order)) a_K if the cell
+ // K with error indicator a_K is
+ // refined and 'order' ist the expected
// order of convergence.
- // The expected number of cells is
- // N+(2^d-1)*M (N is the current number
- // of cells)
+ // The expected number of cells is
+ // N+(2^d-1)*M (N is the current number
+ // of cells)
double min =std::pow( ((std::pow(2.,dim)-1)*(1.+M)+N),(double) order/dim) * (E-s0);
unsigned int minArg = N-1;
s0 += (1-std::pow(2.,-1.*order)) * criteria(tmp[M]);
if ( std::pow(((std::pow(2.,dim)-1)*(1+M)+N), (double) order/dim) * (E-s0) <= min)
- {
- min = std::pow(((std::pow(2.,dim)-1)*(1+M)+N), (double) order/dim) * (E-s0);
- minArg = M;
- }
+ {
+ min = std::pow(((std::pow(2.,dim)-1)*(1+M)+N), (double) order/dim) * (E-s0);
+ minArg = M;
+ }
}
refine(tria,criteria,criteria(tmp[minArg]));
}
// grid_reordering.cc,v 1.27 2002/05/28 07:43:22 wolf Exp
// Version:
//
-// Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2010, 2011 by the deal.II authors
+// Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2010, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
void
GridReordering<1>::reorder_cells (std::vector<CellData<1> > &)
{
- // there should not be much to do
- // in 1d...
+ // there should not be much to do
+ // in 1d...
}
template<>
void
GridReordering<1>::invert_all_cells_of_negative_grid(const std::vector<Point<1> > &,
- std::vector<CellData<1> > &)
+ std::vector<CellData<1> > &)
{
- // nothing to be done in 1d
+ // nothing to be done in 1d
}
template<>
void
GridReordering<1,2>::reorder_cells (std::vector<CellData<1> > &)
{
- // there should not be much to do
- // in 1d...
+ // there should not be much to do
+ // in 1d...
}
template<>
void
GridReordering<1,2>::invert_all_cells_of_negative_grid(const std::vector<Point<2> > &,
- std::vector<CellData<1> > &)
+ std::vector<CellData<1> > &)
{
- // nothing to be done in 1d
+ // nothing to be done in 1d
}
for (; c != cells.end(); ++c)
{
// construct the four edges
- // in reverse order
+ // in reverse order
const Edge reverse_edges[4] = { Edge (c->vertices[1],
c->vertices[0]),
Edge (c->vertices[2],
// for each of them, check
// whether they are already
// in the set
- if ((edges.find (reverse_edges[0]) != edges.end()) ||
- (edges.find (reverse_edges[1]) != edges.end()) ||
- (edges.find (reverse_edges[2]) != edges.end()) ||
- (edges.find (reverse_edges[3]) != edges.end()))
+ if ((edges.find (reverse_edges[0]) != edges.end()) ||
+ (edges.find (reverse_edges[1]) != edges.end()) ||
+ (edges.find (reverse_edges[2]) != edges.end()) ||
+ (edges.find (reverse_edges[3]) != edges.end()))
return false;
// ok, not. insert them
- // in the order in which
- // we want them
+ // in the order in which
+ // we want them
// (std::set eliminates
// duplicated by itself)
for (unsigned int i = 0; i<4; ++i)
- {
- const Edge e(reverse_edges[i].v1, reverse_edges[i].v0);
- edges.insert (e);
- }
+ {
+ const Edge e(reverse_edges[i].v1, reverse_edges[i].v0);
+ edges.insert (e);
+ }
// then go on with next
// cell
}
struct MSide::SideRectify : public std::unary_function<MSide,void>
{
- void operator() (MSide &s) const
- {
- if (s.v0>s.v1)
- std::swap (s.v0, s.v1);
- }
+ void operator() (MSide &s) const
+ {
+ if (s.v0>s.v1)
+ std::swap (s.v0, s.v1);
+ }
};
struct MSide::SideSortLess : public std::binary_function<MSide,MSide,bool>
{
- bool operator()(const MSide &s1, const MSide &s2) const
- {
- int s1vmin,s1vmax;
- int s2vmin,s2vmax;
- if (s1.v0<s1.v1)
- {
- s1vmin = s1.v0;
- s1vmax = s1.v1;
- }
- else
- {
- s1vmin = s1.v1;
- s1vmax = s1.v0;
- }
- if (s2.v0<s2.v1)
- {
- s2vmin = s2.v0;
- s2vmax = s2.v1;
- }
- else
- {
- s2vmin = s2.v1;
- s2vmax = s2.v0;
- }
-
- if (s1vmin<s2vmin)
- return true;
- if (s1vmin>s2vmin)
- return false;
- return s1vmax<s2vmax;
- }
+ bool operator()(const MSide &s1, const MSide &s2) const
+ {
+ int s1vmin,s1vmax;
+ int s2vmin,s2vmax;
+ if (s1.v0<s1.v1)
+ {
+ s1vmin = s1.v0;
+ s1vmax = s1.v1;
+ }
+ else
+ {
+ s1vmin = s1.v1;
+ s1vmax = s1.v0;
+ }
+ if (s2.v0<s2.v1)
+ {
+ s2vmin = s2.v0;
+ s2vmax = s2.v1;
+ }
+ else
+ {
+ s2vmin = s2.v1;
+ s2vmax = s2.v0;
+ }
+
+ if (s1vmin<s2vmin)
+ return true;
+ if (s1vmin>s2vmin)
+ return false;
+ return s1vmax<s2vmax;
+ }
};
{
Assert (i<4, ExcInternalError());
return MSide(q.vertices[ConnectGlobals::EdgeToNode[i][0]],
- q.vertices[ConnectGlobals::EdgeToNode[i][1]]);
+ q.vertices[ConnectGlobals::EdgeToNode[i][1]]);
}
*/
struct QuadSide: public std::binary_function<CellData<2>,int,MSide>
{
- MSide operator()(const CellData<2>& q, int i) const
- {
- return quadside(q,i);
- }
+ MSide operator()(const CellData<2>& q, int i) const
+ {
+ return quadside(q,i);
+ }
};
MQuad::MQuad (const unsigned int v0,
- const unsigned int v1,
- const unsigned int v2,
- const unsigned int v3,
- const unsigned int s0,
- const unsigned int s1,
- const unsigned int s2,
- const unsigned int s3,
- const CellData<2> &cd)
- :
- original_cell_data (cd)
+ const unsigned int v1,
+ const unsigned int v2,
+ const unsigned int v3,
+ const unsigned int s0,
+ const unsigned int s1,
+ const unsigned int s2,
+ const unsigned int s3,
+ const CellData<2> &cd)
+ :
+ original_cell_data (cd)
{
v[0] = v0;
v[1] = v1;
MSide::MSide (const unsigned int initv0,
- const unsigned int initv1)
- :
- v0(initv0), v1(initv1),
- Q0(numbers::invalid_unsigned_int),
+ const unsigned int initv1)
+ :
+ v0(initv0), v1(initv1),
+ Q0(numbers::invalid_unsigned_int),
Q1(numbers::invalid_unsigned_int),
- lsn0(numbers::invalid_unsigned_int),
+ lsn0(numbers::invalid_unsigned_int),
lsn1(numbers::invalid_unsigned_int),
- Oriented(false)
+ Oriented(false)
{}
namespace
{
- /**
- * Create an MQuad object from the
- * indices of the four vertices by
- * looking up the indices of the four
- * sides.
- */
+ /**
+ * Create an MQuad object from the
+ * indices of the four vertices by
+ * looking up the indices of the four
+ * sides.
+ */
MQuad build_quad_from_vertices(const CellData<2> &q,
- const std::vector<MSide> &elist)
+ const std::vector<MSide> &elist)
{
- // compute the indices of the four
- // sides that bound this quad. note
- // that the incoming list elist is
- // sorted with regard to the
- // MSide::SideSortLess criterion
- unsigned int edges[4] = { numbers::invalid_unsigned_int,
- numbers::invalid_unsigned_int,
- numbers::invalid_unsigned_int,
- numbers::invalid_unsigned_int };
-
- for (unsigned int i=0; i<4; ++i)
- edges[i] = (Utilities::lower_bound (elist.begin(),
- elist.end(),
- quadside(q,i),
- MSide::SideSortLess())
- -
- elist.begin());
-
- return MQuad(q.vertices[0],q.vertices[1], q.vertices[2], q.vertices[3],
- edges[0], edges[1], edges[2], edges[3],
- q);
+ // compute the indices of the four
+ // sides that bound this quad. note
+ // that the incoming list elist is
+ // sorted with regard to the
+ // MSide::SideSortLess criterion
+ unsigned int edges[4] = { numbers::invalid_unsigned_int,
+ numbers::invalid_unsigned_int,
+ numbers::invalid_unsigned_int,
+ numbers::invalid_unsigned_int };
+
+ for (unsigned int i=0; i<4; ++i)
+ edges[i] = (Utilities::lower_bound (elist.begin(),
+ elist.end(),
+ quadside(q,i),
+ MSide::SideSortLess())
+ -
+ elist.begin());
+
+ return MQuad(q.vertices[0],q.vertices[1], q.vertices[2], q.vertices[3],
+ edges[0], edges[1], edges[2], edges[3],
+ q);
}
}
-
+
void
void
GridReordering::build_graph (const std::vector<CellData<2> > &inquads)
{
- //Reserve some space
+ //Reserve some space
sides.reserve(4*inquads.size());
- //Insert all the sides into the side vector
+ //Insert all the sides into the side vector
for (int i = 0;i<4;++i)
- {
- std::transform(inquads.begin(),inquads.end(),
- std::back_inserter(sides), std::bind2nd(QuadSide(),i));
- }
+ {
+ std::transform(inquads.begin(),inquads.end(),
+ std::back_inserter(sides), std::bind2nd(QuadSide(),i));
+ }
- //Change each edge so that v0<v1
+ //Change each edge so that v0<v1
std::for_each(sides.begin(),sides.end(),
- MSide::SideRectify() );
+ MSide::SideRectify() );
- //Sort them by Sidevertices.
+ //Sort them by Sidevertices.
std::sort(sides.begin(),sides.end(),
- MSide::SideSortLess());
+ MSide::SideSortLess());
- //Remove duplicates
+ //Remove duplicates
sides.erase(std::unique(sides.begin(),sides.end()),
- sides.end());
+ sides.end());
- // Swap trick to shrink the
- // side vector
+ // Swap trick to shrink the
+ // side vector
std::vector<MSide>(sides).swap(sides);
-
- // Now assign the correct sides to
- // each quads
+
+ // Now assign the correct sides to
+ // each quads
mquads.reserve(inquads.size());
std::transform(inquads.begin(),
- inquads.end(),
- std::back_inserter(mquads),
- std_cxx1x::bind(build_quad_from_vertices,
- std_cxx1x::_1,
- std_cxx1x::cref(sides)) );
+ inquads.end(),
+ std::back_inserter(mquads),
+ std_cxx1x::bind(build_quad_from_vertices,
+ std_cxx1x::_1,
+ std_cxx1x::cref(sides)) );
- // Assign the quads to their sides also.
+ // Assign the quads to their sides also.
int qctr = 0;
for (std::vector<MQuad>::iterator it = mquads.begin(); it != mquads.end(); ++it)
- {
- for (unsigned int i = 0;i<4;++i)
- {
- MSide &ss = sides[(*it).side[i]];
- if (ss.Q0 == numbers::invalid_unsigned_int)
- {
- ss.Q0 = qctr;
- ss.lsn0 = i;
- }
- else if (ss.Q1 == numbers::invalid_unsigned_int)
- {
- ss.Q1 = qctr;
- ss.lsn1 = i;
- }
- else
- AssertThrow (false, ExcInternalError());
- }
- qctr++;
- }
+ {
+ for (unsigned int i = 0;i<4;++i)
+ {
+ MSide &ss = sides[(*it).side[i]];
+ if (ss.Q0 == numbers::invalid_unsigned_int)
+ {
+ ss.Q0 = qctr;
+ ss.lsn0 = i;
+ }
+ else if (ss.Q1 == numbers::invalid_unsigned_int)
+ {
+ ss.Q1 = qctr;
+ ss.lsn1 = i;
+ }
+ else
+ AssertThrow (false, ExcInternalError());
+ }
+ qctr++;
+ }
}
void GridReordering::orient()
{
- // do what the comment in the
- // class declaration says
+ // do what the comment in the
+ // class declaration says
unsigned int qnum = 0;
while (get_unoriented_quad(qnum))
- {
- unsigned int lsn = 0;
- while (get_unoriented_side(qnum,lsn))
- {
- orient_side(qnum,lsn);
- unsigned int qqnum = qnum;
- while (side_hop(qqnum,lsn))
- {
- // switch this face
- lsn = (lsn+2)%4;
- if (!is_oriented_side(qqnum,lsn))
- orient_side(qqnum,lsn);
- else
- //We've found a
- //cycle.. and
- //oriented all
- //quads in it.
- break;
- }
- }
- }
+ {
+ unsigned int lsn = 0;
+ while (get_unoriented_side(qnum,lsn))
+ {
+ orient_side(qnum,lsn);
+ unsigned int qqnum = qnum;
+ while (side_hop(qqnum,lsn))
+ {
+ // switch this face
+ lsn = (lsn+2)%4;
+ if (!is_oriented_side(qqnum,lsn))
+ orient_side(qqnum,lsn);
+ else
+ //We've found a
+ //cycle.. and
+ //oriented all
+ //quads in it.
+ break;
+ }
+ }
+ }
}
void
GridReordering::orient_side(const unsigned int quadnum,
- const unsigned int localsidenum)
+ const unsigned int localsidenum)
{
MQuad &quad = mquads[quadnum];
int op_side_l = (localsidenum+2)%4;
MSide &side = sides[mquads[quadnum].side[localsidenum]];
const MSide &op_side = sides[mquads[quadnum].side[op_side_l]];
- //is the opposite side oriented?
+ //is the opposite side oriented?
if (op_side.Oriented)
- {
- //YES - Make the orientations match
- //Is op side in default orientation?
- if (op_side.v0 == quad.v[ConnectGlobals::DefaultOrientation[op_side_l][0]])
- {
- //YES
- side.v0 = quad.v[ConnectGlobals::DefaultOrientation[localsidenum][0]];
- side.v1 = quad.v[ConnectGlobals::DefaultOrientation[localsidenum][1]];
- }
- else
- {
- //NO, its reversed
- side.v0 = quad.v[ConnectGlobals::DefaultOrientation[localsidenum][1]];
- side.v1 = quad.v[ConnectGlobals::DefaultOrientation[localsidenum][0]];
- }
- }
+ {
+ //YES - Make the orientations match
+ //Is op side in default orientation?
+ if (op_side.v0 == quad.v[ConnectGlobals::DefaultOrientation[op_side_l][0]])
+ {
+ //YES
+ side.v0 = quad.v[ConnectGlobals::DefaultOrientation[localsidenum][0]];
+ side.v1 = quad.v[ConnectGlobals::DefaultOrientation[localsidenum][1]];
+ }
+ else
+ {
+ //NO, its reversed
+ side.v0 = quad.v[ConnectGlobals::DefaultOrientation[localsidenum][1]];
+ side.v1 = quad.v[ConnectGlobals::DefaultOrientation[localsidenum][0]];
+ }
+ }
else
- {
- //NO
- //Just use the default orientation
- side.v0 = quad.v[ConnectGlobals::DefaultOrientation[localsidenum][0]];
- side.v1 = quad.v[ConnectGlobals::DefaultOrientation[localsidenum][1]];
- }
+ {
+ //NO
+ //Just use the default orientation
+ side.v0 = quad.v[ConnectGlobals::DefaultOrientation[localsidenum][0]];
+ side.v1 = quad.v[ConnectGlobals::DefaultOrientation[localsidenum][1]];
+ }
side.Oriented = true;
}
GridReordering::is_fully_oriented_quad(const unsigned int quadnum) const
{
return (
- (sides[mquads[quadnum].side[0]].Oriented)&&
- (sides[mquads[quadnum].side[1]].Oriented)&&
- (sides[mquads[quadnum].side[2]].Oriented)&&
- (sides[mquads[quadnum].side[3]].Oriented)
+ (sides[mquads[quadnum].side[0]].Oriented)&&
+ (sides[mquads[quadnum].side[1]].Oriented)&&
+ (sides[mquads[quadnum].side[2]].Oriented)&&
+ (sides[mquads[quadnum].side[3]].Oriented)
);
}
bool
GridReordering::is_oriented_side(const unsigned int quadnum,
- const unsigned int lsn) const
+ const unsigned int lsn) const
{
return (sides[mquads[quadnum].side[lsn]].Oriented);
}
GridReordering::get_unoriented_quad(unsigned int &UnOrQLoc) const
{
while( (UnOrQLoc<mquads.size()) &&
- is_fully_oriented_quad(UnOrQLoc) )
- UnOrQLoc++;
+ is_fully_oriented_quad(UnOrQLoc) )
+ UnOrQLoc++;
return (UnOrQLoc != mquads.size());
}
bool
GridReordering::get_unoriented_side (const unsigned int quadnum,
- unsigned int &lsn) const
+ unsigned int &lsn) const
{
const MQuad &mq = mquads[quadnum];
if (!sides[mq.side[0]].Oriented)
- {
- lsn = 0;
- return true;
- }
+ {
+ lsn = 0;
+ return true;
+ }
if (!sides[mq.side[1]].Oriented)
- {
- lsn = 1;
- return true;
- }
+ {
+ lsn = 1;
+ return true;
+ }
if (!sides[mq.side[2]].Oriented)
- {
- lsn = 2;
- return true;
- }
+ {
+ lsn = 2;
+ return true;
+ }
if (!sides[mq.side[3]].Oriented)
- {
- lsn = 3;
- return true;
- }
+ {
+ lsn = 3;
+ return true;
+ }
return false;
}
const MSide &s = sides[mq.side[lsn]];
unsigned int opquad = 0;
if (s.Q0 == qnum)
- {
- opquad = s.Q1;
- lsn = s.lsn1;
- }
+ {
+ opquad = s.Q1;
+ lsn = s.lsn1;
+ }
else
- {
- opquad = s.Q0;
- lsn = s.lsn0;
- }
+ {
+ opquad = s.Q0;
+ lsn = s.lsn0;
+ }
if (opquad != numbers::invalid_unsigned_int)
- {
- qnum = opquad;
- return true;
- }
+ {
+ qnum = opquad;
+ return true;
+ }
return false;
}
outquads.clear();
outquads.reserve(mquads.size());
for (unsigned int qn = 0;qn<mquads.size();++qn)
- {
- // initialize CellData object with
- // previous contents, and the
- // overwrite all the fields that
- // might have changed in the
- // process of rotating things
- CellData<2> q = mquads[qn].original_cell_data;
-
- // Are the sides oriented?
- Assert (is_fully_oriented_quad(qn), ExcInternalError());
- bool s[4]; //whether side 1 ,2, 3, 4 are in the default orientation
- for (int sn = 0;sn<4;sn++)
- {
- s[sn] = is_side_default_oriented(qn,sn);
- }
- // Are they oriented in the "deal way"?
- Assert (s[0] == s[2], ExcInternalError());
- Assert (s[1] == s[3], ExcInternalError());
- // How much we rotate them by.
- int rotn = 2*(s[0]?1:0)+ ((s[0]^s[1])?1:0);
-
- for (int i = 0;i<4;++i)
- {
- q.vertices[(i+rotn)%4] = mquads[qn].v[i];
- }
- outquads.push_back(q);
- }
+ {
+ // initialize CellData object with
+ // previous contents, and the
+ // overwrite all the fields that
+ // might have changed in the
+ // process of rotating things
+ CellData<2> q = mquads[qn].original_cell_data;
+
+ // Are the sides oriented?
+ Assert (is_fully_oriented_quad(qn), ExcInternalError());
+ bool s[4]; //whether side 1 ,2, 3, 4 are in the default orientation
+ for (int sn = 0;sn<4;sn++)
+ {
+ s[sn] = is_side_default_oriented(qn,sn);
+ }
+ // Are they oriented in the "deal way"?
+ Assert (s[0] == s[2], ExcInternalError());
+ Assert (s[1] == s[3], ExcInternalError());
+ // How much we rotate them by.
+ int rotn = 2*(s[0]?1:0)+ ((s[0]^s[1])?1:0);
+
+ for (int i = 0;i<4;++i)
+ {
+ q.vertices[(i+rotn)%4] = mquads[qn].v[i];
+ }
+ outquads.push_back(q);
+ }
}
bool
GridReordering::is_side_default_oriented (const unsigned int qnum,
- const unsigned int lsn) const
+ const unsigned int lsn) const
{
return (sides[mquads[qnum].side[lsn]].v0 ==
- mquads[qnum].v[ConnectGlobals::DefaultOrientation[lsn][0]]);
+ mquads[qnum].v[ConnectGlobals::DefaultOrientation[lsn][0]]);
}
} // namespace GridReordering2d
} // namespace internal
template<>
void
GridReordering<2>::invert_all_cells_of_negative_grid(const std::vector<Point<2> > &all_vertices,
- std::vector<CellData<2> > &cells)
+ std::vector<CellData<2> > &cells)
{
unsigned int vertices_lex[GeometryInfo<2>::vertices_per_cell];
unsigned int n_negative_cells=0;
for (unsigned int cell_no=0; cell_no<cells.size(); ++cell_no)
{
- // GridTools::cell_measure
- // requires the vertices to be
- // in lexicographic ordering
+ // GridTools::cell_measure
+ // requires the vertices to be
+ // in lexicographic ordering
for (unsigned int i=0; i<GeometryInfo<2>::vertices_per_cell; ++i)
- vertices_lex[GeometryInfo<2>::ucd_to_deal[i]]=cells[cell_no].vertices[i];
+ vertices_lex[GeometryInfo<2>::ucd_to_deal[i]]=cells[cell_no].vertices[i];
if (GridTools::cell_measure<2>(all_vertices, vertices_lex) < 0)
- {
- ++n_negative_cells;
- std::swap(cells[cell_no].vertices[1], cells[cell_no].vertices[3]);
-
- // check whether the
- // resulting cell is now ok.
- // if not, then the grid is
- // seriously broken and
- // should be sticked into the
- // bin
- for (unsigned int i=0; i<GeometryInfo<2>::vertices_per_cell; ++i)
- vertices_lex[GeometryInfo<2>::ucd_to_deal[i]]=cells[cell_no].vertices[i];
- AssertThrow(GridTools::cell_measure<2>(all_vertices, vertices_lex) > 0,
- ExcInternalError());
- }
+ {
+ ++n_negative_cells;
+ std::swap(cells[cell_no].vertices[1], cells[cell_no].vertices[3]);
+
+ // check whether the
+ // resulting cell is now ok.
+ // if not, then the grid is
+ // seriously broken and
+ // should be sticked into the
+ // bin
+ for (unsigned int i=0; i<GeometryInfo<2>::vertices_per_cell; ++i)
+ vertices_lex[GeometryInfo<2>::ucd_to_deal[i]]=cells[cell_no].vertices[i];
+ AssertThrow(GridTools::cell_measure<2>(all_vertices, vertices_lex) > 0,
+ ExcInternalError());
+ }
}
- // We assume that all cells of a grid have
- // either positive or negative volumes but
- // not both mixed. Although above reordering
- // might work also on single cells, grids
- // with both kind of cells are very likely to
- // be broken. Check for this here.
+ // We assume that all cells of a grid have
+ // either positive or negative volumes but
+ // not both mixed. Although above reordering
+ // might work also on single cells, grids
+ // with both kind of cells are very likely to
+ // be broken. Check for this here.
AssertThrow(n_negative_cells==0 || n_negative_cells==cells.size(), ExcInternalError());
}
template<>
void
GridReordering<2,3>::invert_all_cells_of_negative_grid(const std::vector<Point<3> > &,
- std::vector<CellData<2> > &)
+ std::vector<CellData<2> > &)
{
Assert(false, ExcNotImplemented());
}
namespace GridReordering3d
{
DeclException1 (ExcGridOrientError,
- char *,
- << "Grid Orientation Error: " << arg1);
+ char *,
+ << "Grid Orientation Error: " << arg1);
const EdgeOrientation unoriented_edge = {'u'};
const EdgeOrientation forward_edge = {'f'};
operator == (const EdgeOrientation &edge_orientation) const
{
Assert ((orientation == 'u') || (orientation == 'f') || (orientation == 'b'),
- ExcInternalError());
+ ExcInternalError());
return orientation == edge_orientation.orientation;
}
namespace ElementInfo
{
- /**
- * The numbers of the edges
- * coming into node i are
- * given by
- * edge_to_node[i][k] where
- * k=0,1,2.
- */
+ /**
+ * The numbers of the edges
+ * coming into node i are
+ * given by
+ * edge_to_node[i][k] where
+ * k=0,1,2.
+ */
static const unsigned int edge_to_node[8][3] =
{
- {0,4,8},
- {0,5,9},
- {3,5,10},
- {3,4,11},
- {1,7,8},
- {1,6,9},
- {2,6,10},
- {2,7,11}
+ {0,4,8},
+ {0,5,9},
+ {3,5,10},
+ {3,4,11},
+ {1,7,8},
+ {1,6,9},
+ {2,6,10},
+ {2,7,11}
};
- /**
- * The orientation of edge
- * coming into node i is
- * given by
- * edge_to_node_orient[i][k]
- * where k=0,1,2. 1 means the
- * given node is the start of
- * the edge -1 means the end
- * of the edge.
- */
+ /**
+ * The orientation of edge
+ * coming into node i is
+ * given by
+ * edge_to_node_orient[i][k]
+ * where k=0,1,2. 1 means the
+ * given node is the start of
+ * the edge -1 means the end
+ * of the edge.
+ */
static const EdgeOrientation edge_to_node_orient[8][3] =
{
- {forward_edge, forward_edge, forward_edge},
- {backward_edge, forward_edge, forward_edge},
- {backward_edge, backward_edge, forward_edge},
- {forward_edge, backward_edge, forward_edge},
- {forward_edge, forward_edge, backward_edge},
- {backward_edge, forward_edge, backward_edge},
- {backward_edge, backward_edge, backward_edge},
- {forward_edge, backward_edge, backward_edge}
+ {forward_edge, forward_edge, forward_edge},
+ {backward_edge, forward_edge, forward_edge},
+ {backward_edge, backward_edge, forward_edge},
+ {forward_edge, backward_edge, forward_edge},
+ {forward_edge, forward_edge, backward_edge},
+ {backward_edge, forward_edge, backward_edge},
+ {backward_edge, backward_edge, backward_edge},
+ {forward_edge, backward_edge, backward_edge}
};
- /**
- * nodesonedge[i][0] is the
- * start node for edge i.
- * nodesonedge[i][1] is the
- * end node for edge i.
- */
+ /**
+ * nodesonedge[i][0] is the
+ * start node for edge i.
+ * nodesonedge[i][1] is the
+ * end node for edge i.
+ */
static const unsigned int nodes_on_edge[12][2] =
{
- {0,1},
- {4,5},
- {7,6},
- {3,2},
- {0,3},
- {1,2},
- {5,6},
- {4,7},
- {0,4},
- {1,5},
- {2,6},
- {3,7}
+ {0,1},
+ {4,5},
+ {7,6},
+ {3,2},
+ {0,3},
+ {1,2},
+ {5,6},
+ {4,7},
+ {0,4},
+ {1,5},
+ {2,6},
+ {3,7}
};
}
CheapEdge::CheapEdge (const unsigned int n0,
- const unsigned int n1)
- :
+ const unsigned int n1)
+ :
// sort the
// entries so
// that
// node0<node1
- node0(std::min (n0, n1)),
+ node0(std::min (n0, n1)),
node1(std::max (n0, n1))
{}
Edge::Edge (const unsigned int n0,
- const unsigned int n1)
- :
- orientation_flag (unoriented_edge),
- group (numbers::invalid_unsigned_int)
+ const unsigned int n1)
+ :
+ orientation_flag (unoriented_edge),
+ group (numbers::invalid_unsigned_int)
{
nodes[0] = n0;
nodes[1] = n1;
Cell::Cell ()
{
for (unsigned int i=0; i<GeometryInfo<3>::lines_per_cell; ++i)
- {
- edges[i] = numbers::invalid_unsigned_int;
- local_orientation_flags[i] = forward_edge;
- }
+ {
+ edges[i] = numbers::invalid_unsigned_int;
+ local_orientation_flags[i] = forward_edge;
+ }
for (unsigned int i=0; i<GeometryInfo<3>::vertices_per_cell; ++i)
- nodes[i] = numbers::invalid_unsigned_int;
+ nodes[i] = numbers::invalid_unsigned_int;
waiting_to_be_processed = false;
}
Mesh::sanity_check () const
{
for (unsigned int i=0; i<cell_list.size(); ++i)
- for (unsigned int j=0; j<8; ++j)
- sanity_check_node (cell_list[i], j);
+ for (unsigned int j=0; j<8; ++j)
+ sanity_check_node (cell_list[i], j);
}
// same node value
// Get the Local Node Numbers
- // of the incoming edges
+ // of the incoming edges
const unsigned int e0 = ElementInfo::edge_to_node[local_node_num][0];
const unsigned int e1 = ElementInfo::edge_to_node[local_node_num][1];
const unsigned int e2 = ElementInfo::edge_to_node[local_node_num][2];
- // Global Edge Numbers
+ // Global Edge Numbers
const unsigned int ge0 = c.edges[e0];
const unsigned int ge1 = c.edges[e1];
const unsigned int ge2 = c.edges[e2];
const EdgeOrientation or0 = ElementInfo::edge_to_node_orient[local_node_num][0] ==
- c.local_orientation_flags[e0] ?
- forward_edge : backward_edge;
+ c.local_orientation_flags[e0] ?
+ forward_edge : backward_edge;
const EdgeOrientation or1 = ElementInfo::edge_to_node_orient[local_node_num][1] ==
- c.local_orientation_flags[e1] ?
- forward_edge : backward_edge;
+ c.local_orientation_flags[e1] ?
+ forward_edge : backward_edge;
const EdgeOrientation or2 = ElementInfo::edge_to_node_orient[local_node_num][2] ==
- c.local_orientation_flags[e2] ?
- forward_edge : backward_edge;
+ c.local_orientation_flags[e2] ?
+ forward_edge : backward_edge;
- // Make sure that edges agree
- // what the current node should
- // be.
+ // Make sure that edges agree
+ // what the current node should
+ // be.
Assert ((edge_list[ge0].nodes[or0 == forward_edge ? 0 : 1] ==
- edge_list[ge1].nodes[or1 == forward_edge ? 0 : 1])
- &&
- (edge_list[ge1].nodes[or1 == forward_edge ? 0 : 1] ==
- edge_list[ge2].nodes[or2 == forward_edge ? 0 : 1]),
- ExcMessage ("This message does not satisfy the internal "
- "consistency check"));
+ edge_list[ge1].nodes[or1 == forward_edge ? 0 : 1])
+ &&
+ (edge_list[ge1].nodes[or1 == forward_edge ? 0 : 1] ==
+ edge_list[ge2].nodes[or2 == forward_edge ? 0 : 1]),
+ ExcMessage ("This message does not satisfy the internal "
+ "consistency check"));
}
- // This is the guts of the matter...
+ // This is the guts of the matter...
void Mesh::build_connectivity ()
{
const unsigned int n_cells = cell_list.size();
unsigned int n_edges = 0;
- // Correctly build the edge
- // list
+ // Correctly build the edge
+ // list
{
- // edge_map stores the
- // edge_number associated
- // with a given CheapEdge
- std::map<CheapEdge,unsigned int> edge_map;
- unsigned int ctr = 0;
- for (unsigned int cur_cell_id = 0;
- cur_cell_id<n_cells;
- ++cur_cell_id)
- {
- // Get the local node
- // numbers on edge
- // edge_num
- const Cell & cur_cell = cell_list[cur_cell_id];
-
- for (unsigned short int edge_num = 0;
- edge_num<12;
- ++edge_num)
- {
- unsigned int gl_edge_num = 0;
- EdgeOrientation l_edge_orient = forward_edge;
-
- // Construct the
- // CheapEdge
- const unsigned int
- node0 = cur_cell.nodes[ElementInfo::nodes_on_edge[edge_num][0]],
- node1 = cur_cell.nodes[ElementInfo::nodes_on_edge[edge_num][1]];
- const CheapEdge cur_edge (node0, node1);
-
- if (edge_map.count(cur_edge) == 0)
- // Edge not in map
- {
- // put edge in
- // hash map with
- // ctr value;
- edge_map[cur_edge] = ctr;
- gl_edge_num = ctr;
-
- // put the edge
- // into the
- // global edge
- // list
- edge_list.push_back(Edge(node0,node1));
- ctr++;
- }
- else
- {
- // get edge_num
- // from hash_map
- gl_edge_num = edge_map[cur_edge];
- if (edge_list[gl_edge_num].nodes[0] != node0)
- l_edge_orient = backward_edge;
- }
- // set edge number to
- // edgenum
- cell_list[cur_cell_id].edges[edge_num] = gl_edge_num;
- cell_list[cur_cell_id].local_orientation_flags[edge_num]
- = l_edge_orient;
- }
- }
- n_edges = ctr;
+ // edge_map stores the
+ // edge_number associated
+ // with a given CheapEdge
+ std::map<CheapEdge,unsigned int> edge_map;
+ unsigned int ctr = 0;
+ for (unsigned int cur_cell_id = 0;
+ cur_cell_id<n_cells;
+ ++cur_cell_id)
+ {
+ // Get the local node
+ // numbers on edge
+ // edge_num
+ const Cell & cur_cell = cell_list[cur_cell_id];
+
+ for (unsigned short int edge_num = 0;
+ edge_num<12;
+ ++edge_num)
+ {
+ unsigned int gl_edge_num = 0;
+ EdgeOrientation l_edge_orient = forward_edge;
+
+ // Construct the
+ // CheapEdge
+ const unsigned int
+ node0 = cur_cell.nodes[ElementInfo::nodes_on_edge[edge_num][0]],
+ node1 = cur_cell.nodes[ElementInfo::nodes_on_edge[edge_num][1]];
+ const CheapEdge cur_edge (node0, node1);
+
+ if (edge_map.count(cur_edge) == 0)
+ // Edge not in map
+ {
+ // put edge in
+ // hash map with
+ // ctr value;
+ edge_map[cur_edge] = ctr;
+ gl_edge_num = ctr;
+
+ // put the edge
+ // into the
+ // global edge
+ // list
+ edge_list.push_back(Edge(node0,node1));
+ ctr++;
+ }
+ else
+ {
+ // get edge_num
+ // from hash_map
+ gl_edge_num = edge_map[cur_edge];
+ if (edge_list[gl_edge_num].nodes[0] != node0)
+ l_edge_orient = backward_edge;
+ }
+ // set edge number to
+ // edgenum
+ cell_list[cur_cell_id].edges[edge_num] = gl_edge_num;
+ cell_list[cur_cell_id].local_orientation_flags[edge_num]
+ = l_edge_orient;
+ }
+ }
+ n_edges = ctr;
}
- // Count each of the edges.
+ // Count each of the edges.
{
- std::vector<int> edge_count(n_edges,0);
+ std::vector<int> edge_count(n_edges,0);
- // Count every time an edge
- // occurs in a cube.
- for (unsigned int cur_cell_id=0; cur_cell_id<n_cells; ++cur_cell_id)
+ // Count every time an edge
+ // occurs in a cube.
+ for (unsigned int cur_cell_id=0; cur_cell_id<n_cells; ++cur_cell_id)
for (unsigned short int edge_num = 0; edge_num<12; ++edge_num)
++edge_count[cell_list[cur_cell_id].edges[edge_num]];
- // So we now know how many
- // cubes contain a given
- // edge. Just need to store
- // the list of cubes in the
- // edge
+ // So we now know how many
+ // cubes contain a given
+ // edge. Just need to store
+ // the list of cubes in the
+ // edge
- // Allocate the space for the
- // neighbor list
- for (unsigned int cur_edge_id=0; cur_edge_id<n_edges; ++cur_edge_id)
+ // Allocate the space for the
+ // neighbor list
+ for (unsigned int cur_edge_id=0; cur_edge_id<n_edges; ++cur_edge_id)
edge_list[cur_edge_id].neighboring_cubes
.resize (edge_count[cur_edge_id]);
- // Store the position of the
- // current neighbor in the
- // edge's neighbor list
- std::vector<int> cur_cell_edge_list_posn(n_edges,0);
- for (unsigned int cur_cell_id=0; cur_cell_id<n_cells; ++cur_cell_id)
+ // Store the position of the
+ // current neighbor in the
+ // edge's neighbor list
+ std::vector<int> cur_cell_edge_list_posn(n_edges,0);
+ for (unsigned int cur_cell_id=0; cur_cell_id<n_cells; ++cur_cell_id)
for (unsigned short int edge_num=0; edge_num<12; ++edge_num)
{
const unsigned int
cur_edge_group (0)
{
for (unsigned int i = 0; i<12; ++i)
- edge_orient_array[i] = false;
+ edge_orient_array[i] = false;
}
{
Orienter orienter (incubes);
- // First check that the mesh is
- // sensible
+ // First check that the mesh is
+ // sensible
orienter.mesh.sanity_check ();
// Orient the mesh
- // if not successful, break here, else go
- // on
+ // if not successful, break here, else go
+ // on
if (!orienter.orient_edges ())
- return false;
+ return false;
// Now we have a bunch of oriented
// edges int the structure we only
// internal structure back into
// their original location.
orienter.mesh.export_to_deal_format (incubes);
- // reordering was successful
+ // reordering was successful
return true;
}
- /**
- * This assigns an orientation
- * to each edge so that every
- * cube is a rotated Deal.II
- * cube.
- */
+ /**
+ * This assigns an orientation
+ * to each edge so that every
+ * cube is a rotated Deal.II
+ * cube.
+ */
bool Orienter::orient_edges ()
{
- // While there are still cubes
- // to orient
+ // While there are still cubes
+ // to orient
while (get_next_unoriented_cube())
// And there are edges in
// the cube to orient
// have a
// contradiction
if (!cell_is_consistent(cur_posn))
- return false;
+ return false;
// If we needed to
// orient any edges
bool Orienter::get_next_unoriented_cube ()
{
- // The last cube in the list
+ // The last cube in the list
const unsigned int n_cubes = mesh.cell_list.size();
- // Keep shifting along the list
- // until we find a cube which
- // is not fully oriented or the
- // end.
+ // Keep shifting along the list
+ // until we find a cube which
+ // is not fully oriented or the
+ // end.
while( (marker_cube<n_cubes) &&
(is_oriented(marker_cube)) )
- ++marker_cube;
+ ++marker_cube;
cur_posn = marker_cube;
- // Return true if we now point
- // at a valid cube.
+ // Return true if we now point
+ // at a valid cube.
return (cur_posn < n_cubes);
}
bool Orienter::is_oriented (const unsigned int cell_num) const
{
for (unsigned int i=0; i<12; ++i)
- if (mesh.edge_list[mesh.cell_list[cell_num].edges[i]].orientation_flag
+ if (mesh.edge_list[mesh.cell_list[cell_num].edges[i]].orientation_flag
== unoriented_edge)
- return false;
+ return false;
return true;
}
const Cell& c = mesh.cell_list[cell_num];
- // Checks that all oriented
- // edges in the group are
- // oriented consistently.
+ // Checks that all oriented
+ // edges in the group are
+ // oriented consistently.
for (unsigned int group=0; group<3; ++group)
- {
- // When a nonzero
- // orientation is first
- // encountered in the group
- // it is stored in this
- EdgeOrientation value = unoriented_edge;
- // Loop over all parallel
- // edges
- for (unsigned int i=4*group; i<4*(group+1); ++i)
- {
- // If the edge has
- // orientation
- if ((c.local_orientation_flags[i] !=
- unoriented_edge)
- &&
- (mesh.edge_list[c.edges[i]].orientation_flag !=
- unoriented_edge))
- {
- const EdgeOrientation this_edge_direction
- = (c.local_orientation_flags[i]
- == mesh.edge_list[c.edges[i]].orientation_flag ?
- forward_edge : backward_edge);
-
- // If we haven't
- // seen an oriented
- // edge before,
- // then store its
- // value:
- if (value == unoriented_edge)
- value = this_edge_direction;
- else
- // If we have
- // seen an
- // oriented edge
- // in this group
- // we'd better
- // have the same
- // orientation.
- if (value != this_edge_direction)
- return false;
- }
- }
- }
+ {
+ // When a nonzero
+ // orientation is first
+ // encountered in the group
+ // it is stored in this
+ EdgeOrientation value = unoriented_edge;
+ // Loop over all parallel
+ // edges
+ for (unsigned int i=4*group; i<4*(group+1); ++i)
+ {
+ // If the edge has
+ // orientation
+ if ((c.local_orientation_flags[i] !=
+ unoriented_edge)
+ &&
+ (mesh.edge_list[c.edges[i]].orientation_flag !=
+ unoriented_edge))
+ {
+ const EdgeOrientation this_edge_direction
+ = (c.local_orientation_flags[i]
+ == mesh.edge_list[c.edges[i]].orientation_flag ?
+ forward_edge : backward_edge);
+
+ // If we haven't
+ // seen an oriented
+ // edge before,
+ // then store its
+ // value:
+ if (value == unoriented_edge)
+ value = this_edge_direction;
+ else
+ // If we have
+ // seen an
+ // oriented edge
+ // in this group
+ // we'd better
+ // have the same
+ // orientation.
+ if (value != this_edge_direction)
+ return false;
+ }
+ }
+ }
return true;
}
const Cell& c = mesh.cell_list[cur_posn];
unsigned int edge = 0;
- // search for the unoriented
- // side
+ // search for the unoriented
+ // side
while ((edge<12) &&
- (mesh.edge_list[c.edges[edge]].orientation_flag !=
- unoriented_edge))
- ++edge;
+ (mesh.edge_list[c.edges[edge]].orientation_flag !=
+ unoriented_edge))
+ ++edge;
- // if we found none then return
- // false
+ // if we found none then return
+ // false
if (edge == 12)
- return false;
+ return false;
- // Which edge group we're in.
+ // Which edge group we're in.
const unsigned int edge_group = edge/4;
- // A sanity check that none of
- // the other edges in the group
- // have been oriented yet Each
- // of the edges in the group
- // should be un-oriented
+ // A sanity check that none of
+ // the other edges in the group
+ // have been oriented yet Each
+ // of the edges in the group
+ // should be un-oriented
for (unsigned int j = edge_group*4; j<edge_group*4+4; ++j)
- Assert (mesh.edge_list[c.edges[j]].orientation_flag ==
- unoriented_edge,
- ExcGridOrientError("Tried to orient edge when other edges "
+ Assert (mesh.edge_list[c.edges[j]].orientation_flag ==
+ unoriented_edge,
+ ExcGridOrientError("Tried to orient edge when other edges "
"in group are already oriented!"));
- // Make the edge alignment
- // match that of the local
- // cube.
+ // Make the edge alignment
+ // match that of the local
+ // cube.
mesh.edge_list[c.edges[edge]].orientation_flag
- = c.local_orientation_flags[edge];
+ = c.local_orientation_flags[edge];
mesh.edge_list[c.edges[edge]].group = cur_edge_group;
// Remember that we have oriented
bool Orienter::orient_edges_in_current_cube ()
{
for (unsigned int edge_group=0; edge_group<3; ++edge_group)
- if (orient_edge_set_in_current_cube(edge_group) == true)
- return true;
+ if (orient_edge_set_in_current_cube(edge_group) == true)
+ return true;
return false;
}
{
const Cell& c = mesh.cell_list[cur_posn];
- // Check if any edge is
- // oriented
+ // Check if any edge is
+ // oriented
unsigned int n_oriented = 0;
EdgeOrientation glorient = unoriented_edge;
unsigned int edge_flags = 0;
unsigned int cur_flag = 1;
for (unsigned int i = 4*n; i<4*(n+1); ++i, cur_flag<<=1)
- {
- if ((mesh.edge_list[c.edges[i]].orientation_flag !=
- unoriented_edge)
- &&
- (c.local_orientation_flags[i] !=
- unoriented_edge))
- {
- ++n_oriented;
-
- const EdgeOrientation orient
- = (mesh.edge_list[c.edges[i]].orientation_flag ==
- c.local_orientation_flags[i] ?
- forward_edge : backward_edge);
-
- if (glorient == unoriented_edge)
- glorient = orient;
- else
- AssertThrow(orient == glorient,
- ExcGridOrientError("Attempted to Orient Misaligned cube"));
- }
- else
- edge_flags |= cur_flag;
- }
-
- // were any of the sides
- // oriented? were they all
- // already oriented?
+ {
+ if ((mesh.edge_list[c.edges[i]].orientation_flag !=
+ unoriented_edge)
+ &&
+ (c.local_orientation_flags[i] !=
+ unoriented_edge))
+ {
+ ++n_oriented;
+
+ const EdgeOrientation orient
+ = (mesh.edge_list[c.edges[i]].orientation_flag ==
+ c.local_orientation_flags[i] ?
+ forward_edge : backward_edge);
+
+ if (glorient == unoriented_edge)
+ glorient = orient;
+ else
+ AssertThrow(orient == glorient,
+ ExcGridOrientError("Attempted to Orient Misaligned cube"));
+ }
+ else
+ edge_flags |= cur_flag;
+ }
+
+ // were any of the sides
+ // oriented? were they all
+ // already oriented?
if ((glorient == unoriented_edge) || (n_oriented == 4))
- return false;
+ return false;
- // If so orient all edges
- // consistently.
+ // If so orient all edges
+ // consistently.
cur_flag = 1;
for (unsigned int i=4*n; i<4*(n+1); ++i, cur_flag<<=1)
- if ((edge_flags & cur_flag) != 0)
- {
- mesh.edge_list[c.edges[i]].orientation_flag
- = (c.local_orientation_flags[i] == glorient ?
- forward_edge : backward_edge);
+ if ((edge_flags & cur_flag) != 0)
+ {
+ mesh.edge_list[c.edges[i]].orientation_flag
+ = (c.local_orientation_flags[i] == glorient ?
+ forward_edge : backward_edge);
- mesh.edge_list[c.edges[i]].group = cur_edge_group;
+ mesh.edge_list[c.edges[i]].group = cur_edge_group;
// Remember that we have oriented
// this edge in the current cell.
- edge_orient_array[i] = true;
- }
+ edge_orient_array[i] = true;
+ }
return true;
}
{
const Cell &c = mesh.cell_list[cur_posn];
for (unsigned int e=0; e<12; ++e)
- // Only need to add the adjacent
- // cubes for edges we recently
- // oriented
- if (edge_orient_array[e] == true)
- {
- const Edge & the_edge = mesh.edge_list[c.edges[e]];
- for (unsigned int local_cube_num = 0;
- local_cube_num < the_edge.neighboring_cubes.size();
- ++local_cube_num)
- {
- const unsigned int
- global_cell_num = the_edge.neighboring_cubes[local_cube_num];
- Cell &ncell = mesh.cell_list[global_cell_num];
-
- // If the cell is waiting to be
- // processed we dont want to add
- // it to the list a second time.
- if (!ncell.waiting_to_be_processed)
- {
- sheet_to_process.push_back(global_cell_num);
- ncell.waiting_to_be_processed = true;
- }
- }
- }
+ // Only need to add the adjacent
+ // cubes for edges we recently
+ // oriented
+ if (edge_orient_array[e] == true)
+ {
+ const Edge & the_edge = mesh.edge_list[c.edges[e]];
+ for (unsigned int local_cube_num = 0;
+ local_cube_num < the_edge.neighboring_cubes.size();
+ ++local_cube_num)
+ {
+ const unsigned int
+ global_cell_num = the_edge.neighboring_cubes[local_cube_num];
+ Cell &ncell = mesh.cell_list[global_cell_num];
+
+ // If the cell is waiting to be
+ // processed we dont want to add
+ // it to the list a second time.
+ if (!ncell.waiting_to_be_processed)
+ {
+ sheet_to_process.push_back(global_cell_num);
+ ncell.waiting_to_be_processed = true;
+ }
+ }
+ }
// we're done with this cube so
// clear its processing flags.
for (unsigned int e=0; e<12; ++e)
- edge_orient_array[e] = false;
+ edge_orient_array[e] = false;
}
bool Orienter::get_next_active_cube ()
{
- // Mark the curent Cube as
- // finished with.
+ // Mark the curent Cube as
+ // finished with.
Cell &c = mesh.cell_list[cur_posn];
c.waiting_to_be_processed = false;
if (sheet_to_process.empty() == false)
- {
- cur_posn = sheet_to_process.back();
- sheet_to_process.pop_back();
- return true;
- }
+ {
+ cur_posn = sheet_to_process.back();
+ sheet_to_process.pop_back();
+ return true;
+ }
return false;
}
void Orienter::orient_cubes ()
{
- // We assume that the mesh has
- // all edges oriented already.
-
- // This is a list of
- // permutations that take node
- // 0 to node i but only rotate
- // the cube. (This set is far
- // from unique (there are 3 for
- // each node - for our
- // algorithm it doesn't matter
- // which of the three we use)
+ // We assume that the mesh has
+ // all edges oriented already.
+
+ // This is a list of
+ // permutations that take node
+ // 0 to node i but only rotate
+ // the cube. (This set is far
+ // from unique (there are 3 for
+ // each node - for our
+ // algorithm it doesn't matter
+ // which of the three we use)
static const unsigned int CubePermutations[8][8] = {
- {0,1,2,3,4,5,6,7},
- {1,2,3,0,5,6,7,4},
- {2,3,0,1,6,7,4,5},
- {3,0,1,2,7,4,5,6},
- {4,7,6,5,0,3,2,1},
- {5,4,7,6,1,0,3,2},
- {6,5,4,7,2,1,0,3},
- {7,6,5,4,3,2,1,0}
+ {0,1,2,3,4,5,6,7},
+ {1,2,3,0,5,6,7,4},
+ {2,3,0,1,6,7,4,5},
+ {3,0,1,2,7,4,5,6},
+ {4,7,6,5,0,3,2,1},
+ {5,4,7,6,1,0,3,2},
+ {6,5,4,7,2,1,0,3},
+ {7,6,5,4,3,2,1,0}
};
- // So now we need to work out
- // which node needs to be
- // mapped to the zero node.
- // The trick is that the node
- // that should be the local
- // zero node has three edges
- // coming into it.
+ // So now we need to work out
+ // which node needs to be
+ // mapped to the zero node.
+ // The trick is that the node
+ // that should be the local
+ // zero node has three edges
+ // coming into it.
for (unsigned int i=0; i<mesh.cell_list.size(); ++i)
- {
- Cell& the_cell = mesh.cell_list[i];
-
- // This stores whether the
- // global oriented edge
- // points in the same
- // direction as it's local
- // edge on the current
- // cube. (for each edge on
- // the curent cube)
- EdgeOrientation local_edge_orientation[12];
- for (unsigned int j = 0; j<12; ++j)
- {
- // get the global edge
- const Edge& the_edge = mesh.edge_list[the_cell.edges[j]];
- // All edges should be
- // oriented at this
- // stage..
- Assert (the_edge.orientation_flag != unoriented_edge,
- ExcGridOrientError ("Unoriented edge encountered"));
- // calculate whether it
- // points the right way
- // or not
- local_edge_orientation[j] = (the_cell.local_orientation_flags[j] ==
- the_edge.orientation_flag ?
- forward_edge : backward_edge);
- }
-
- // Here the number of
- // incoming edges is
- // tallied for each node.
- unsigned int perm_num = numbers::invalid_unsigned_int;
- for (unsigned int node_num=0; node_num<8; ++node_num)
- {
- // The local edge
- // numbers coming into
- // the node
- const unsigned int e0 = ElementInfo::edge_to_node[node_num][0];
- const unsigned int e1 = ElementInfo::edge_to_node[node_num][1];
- const unsigned int e2 = ElementInfo::edge_to_node[node_num][2];
-
- // The local
- // orientation of the
- // edge coming into the
- // node.
- const EdgeOrientation sign0 = ElementInfo::edge_to_node_orient[node_num][0];
- const EdgeOrientation sign1 = ElementInfo::edge_to_node_orient[node_num][1];
- const EdgeOrientation sign2 = ElementInfo::edge_to_node_orient[node_num][2];
-
- // Add one to the total
- // for each edge
- // pointing in
- Assert (local_edge_orientation[e0] != unoriented_edge,
- ExcInternalError());
- Assert (local_edge_orientation[e1] != unoriented_edge,
- ExcInternalError());
- Assert (local_edge_orientation[e2] != unoriented_edge,
- ExcInternalError());
-
- const unsigned int
- total = (((local_edge_orientation[e0] == sign0) ? 1 : 0)
- +((local_edge_orientation[e1] == sign1) ? 1 : 0)
- +((local_edge_orientation[e2] == sign2) ? 1 : 0));
-
- if (total == 3)
- {
- Assert (perm_num == numbers::invalid_unsigned_int,
- ExcGridOrientError("More than one node with 3 incoming "
- "edges found in curent hex."));
- perm_num = node_num;
- }
- }
- // We should now have a
- // valid permutation number
- Assert (perm_num != numbers::invalid_unsigned_int,
- ExcGridOrientError("No node having 3 incoming edges found in curent hex."));
-
- // So use the apropriate
- // rotation to get the new
- // cube
- unsigned int temp[8];
- for (unsigned int i=0; i<8; ++i)
- temp[i] = the_cell.nodes[CubePermutations[perm_num][i]];
- for (unsigned int i=0; i<8; ++i)
- the_cell.nodes[i] = temp[i];
- }
+ {
+ Cell& the_cell = mesh.cell_list[i];
+
+ // This stores whether the
+ // global oriented edge
+ // points in the same
+ // direction as it's local
+ // edge on the current
+ // cube. (for each edge on
+ // the curent cube)
+ EdgeOrientation local_edge_orientation[12];
+ for (unsigned int j = 0; j<12; ++j)
+ {
+ // get the global edge
+ const Edge& the_edge = mesh.edge_list[the_cell.edges[j]];
+ // All edges should be
+ // oriented at this
+ // stage..
+ Assert (the_edge.orientation_flag != unoriented_edge,
+ ExcGridOrientError ("Unoriented edge encountered"));
+ // calculate whether it
+ // points the right way
+ // or not
+ local_edge_orientation[j] = (the_cell.local_orientation_flags[j] ==
+ the_edge.orientation_flag ?
+ forward_edge : backward_edge);
+ }
+
+ // Here the number of
+ // incoming edges is
+ // tallied for each node.
+ unsigned int perm_num = numbers::invalid_unsigned_int;
+ for (unsigned int node_num=0; node_num<8; ++node_num)
+ {
+ // The local edge
+ // numbers coming into
+ // the node
+ const unsigned int e0 = ElementInfo::edge_to_node[node_num][0];
+ const unsigned int e1 = ElementInfo::edge_to_node[node_num][1];
+ const unsigned int e2 = ElementInfo::edge_to_node[node_num][2];
+
+ // The local
+ // orientation of the
+ // edge coming into the
+ // node.
+ const EdgeOrientation sign0 = ElementInfo::edge_to_node_orient[node_num][0];
+ const EdgeOrientation sign1 = ElementInfo::edge_to_node_orient[node_num][1];
+ const EdgeOrientation sign2 = ElementInfo::edge_to_node_orient[node_num][2];
+
+ // Add one to the total
+ // for each edge
+ // pointing in
+ Assert (local_edge_orientation[e0] != unoriented_edge,
+ ExcInternalError());
+ Assert (local_edge_orientation[e1] != unoriented_edge,
+ ExcInternalError());
+ Assert (local_edge_orientation[e2] != unoriented_edge,
+ ExcInternalError());
+
+ const unsigned int
+ total = (((local_edge_orientation[e0] == sign0) ? 1 : 0)
+ +((local_edge_orientation[e1] == sign1) ? 1 : 0)
+ +((local_edge_orientation[e2] == sign2) ? 1 : 0));
+
+ if (total == 3)
+ {
+ Assert (perm_num == numbers::invalid_unsigned_int,
+ ExcGridOrientError("More than one node with 3 incoming "
+ "edges found in curent hex."));
+ perm_num = node_num;
+ }
+ }
+ // We should now have a
+ // valid permutation number
+ Assert (perm_num != numbers::invalid_unsigned_int,
+ ExcGridOrientError("No node having 3 incoming edges found in curent hex."));
+
+ // So use the apropriate
+ // rotation to get the new
+ // cube
+ unsigned int temp[8];
+ for (unsigned int i=0; i<8; ++i)
+ temp[i] = the_cell.nodes[CubePermutations[perm_num][i]];
+ for (unsigned int i=0; i<8; ++i)
+ the_cell.nodes[i] = temp[i];
+ }
}
} // namespace GridReordering3d
} // namespace internal
{
Assert (incubes.size() != 0,
- ExcMessage("List of elements to orient was of zero length"));
+ ExcMessage("List of elements to orient was of zero length"));
- // create a backup to use if GridReordering
- // was not successful
+ // create a backup to use if GridReordering
+ // was not successful
std::vector<CellData<3> > backup=incubes;
- // This does the real work
+ // This does the real work
bool success=
internal::GridReordering3d::Orienter::orient_mesh (incubes);
- // if reordering was not successful use
- // original connectivity, otherwiese do
- // nothing (i.e. use the reordered
- // connectivity)
+ // if reordering was not successful use
+ // original connectivity, otherwiese do
+ // nothing (i.e. use the reordered
+ // connectivity)
if (!success)
incubes=backup;
}
unsigned int n_negative_cells=0;
for (unsigned int cell_no=0; cell_no<cells.size(); ++cell_no)
{
- // GridTools::cell_measure
- // requires the vertices to be
- // in lexicographic ordering
+ // GridTools::cell_measure
+ // requires the vertices to be
+ // in lexicographic ordering
for (unsigned int i=0; i<GeometryInfo<3>::vertices_per_cell; ++i)
- vertices_lex[GeometryInfo<3>::ucd_to_deal[i]]=cells[cell_no].vertices[i];
+ vertices_lex[GeometryInfo<3>::ucd_to_deal[i]]=cells[cell_no].vertices[i];
if (GridTools::cell_measure<3>(all_vertices, vertices_lex) < 0)
- {
- ++n_negative_cells;
- // reorder vertices: swap front and back face
- for (unsigned int i=0; i<4; ++i)
- std::swap(cells[cell_no].vertices[i], cells[cell_no].vertices[i+4]);
-
- // check whether the
- // resulting cell is now ok.
- // if not, then the grid is
- // seriously broken and
- // should be sticked into the
- // bin
- for (unsigned int i=0; i<GeometryInfo<3>::vertices_per_cell; ++i)
- vertices_lex[GeometryInfo<3>::ucd_to_deal[i]]=cells[cell_no].vertices[i];
- AssertThrow(GridTools::cell_measure<3>(all_vertices, vertices_lex) > 0,
- ExcInternalError());
- }
+ {
+ ++n_negative_cells;
+ // reorder vertices: swap front and back face
+ for (unsigned int i=0; i<4; ++i)
+ std::swap(cells[cell_no].vertices[i], cells[cell_no].vertices[i+4]);
+
+ // check whether the
+ // resulting cell is now ok.
+ // if not, then the grid is
+ // seriously broken and
+ // should be sticked into the
+ // bin
+ for (unsigned int i=0; i<GeometryInfo<3>::vertices_per_cell; ++i)
+ vertices_lex[GeometryInfo<3>::ucd_to_deal[i]]=cells[cell_no].vertices[i];
+ AssertThrow(GridTools::cell_measure<3>(all_vertices, vertices_lex) > 0,
+ ExcInternalError());
+ }
}
- // We assume that all cells of a
- // grid have either positive or
- // negative volumes but not both
- // mixed. Although above reordering
- // might work also on single cells,
- // grids with both kind of cells
- // are very likely to be
- // broken. Check for this here.
+ // We assume that all cells of a
+ // grid have either positive or
+ // negative volumes but not both
+ // mixed. Although above reordering
+ // might work also on single cells,
+ // grids with both kind of cells
+ // are very likely to be
+ // broken. Check for this here.
AssertThrow(n_negative_cells==0 || n_negative_cells==cells.size(), ExcInternalError());
}
double
diameter (const Triangulation<dim, spacedim> &tria)
{
- // we can't deal with distributed meshes
- // since we don't have all vertices
- // locally. there is one exception,
- // however: if the mesh has never been
- // refined. the way to test this is not to
- // ask tria.n_levels()==1, since this is
- // something that can happen on one
- // processor without being true on
- // all. however, we can ask for the global
- // number of active cells and use that
+ // we can't deal with distributed meshes
+ // since we don't have all vertices
+ // locally. there is one exception,
+ // however: if the mesh has never been
+ // refined. the way to test this is not to
+ // ask tria.n_levels()==1, since this is
+ // something that can happen on one
+ // processor without being true on
+ // all. however, we can ask for the global
+ // number of active cells and use that
#ifdef DEAL_II_USE_P4EST
if (const parallel::distributed::Triangulation<dim,spacedim> *p_tria
- = dynamic_cast<const parallel::distributed::Triangulation<dim,spacedim>*>(&tria))
+ = dynamic_cast<const parallel::distributed::Triangulation<dim,spacedim>*>(&tria))
Assert (p_tria->n_global_active_cells() == tria.n_cells(0),
- ExcNotImplemented());
+ ExcNotImplemented());
#endif
- // the algorithm used simply
- // traverses all cells and picks
- // out the boundary vertices. it
- // may or may not be faster to
- // simply get all vectors, don't
- // mark boundary vertices, and
- // compute the distances thereof,
- // but at least as the mesh is
- // refined, it seems better to
- // first mark boundary nodes, as
- // marking is O(N) in the number of
- // cells/vertices, while computing
- // the maximal distance is O(N*N)
+ // the algorithm used simply
+ // traverses all cells and picks
+ // out the boundary vertices. it
+ // may or may not be faster to
+ // simply get all vectors, don't
+ // mark boundary vertices, and
+ // compute the distances thereof,
+ // but at least as the mesh is
+ // refined, it seems better to
+ // first mark boundary nodes, as
+ // marking is O(N) in the number of
+ // cells/vertices, while computing
+ // the maximal distance is O(N*N)
const std::vector<Point<spacedim> > &vertices = tria.get_vertices ();
std::vector<bool> boundary_vertices (vertices.size(), false);
endc = tria.end();
for (; cell!=endc; ++cell)
for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
- if (cell->face(face)->at_boundary ())
- for (unsigned int i=0; i<GeometryInfo<dim>::vertices_per_face; ++i)
- boundary_vertices[cell->face(face)->vertex_index(i)] = true;
-
- // now traverse the list of
- // boundary vertices and check
- // distances. since distances are
- // symmetric, we only have to check
- // one half
+ if (cell->face(face)->at_boundary ())
+ for (unsigned int i=0; i<GeometryInfo<dim>::vertices_per_face; ++i)
+ boundary_vertices[cell->face(face)->vertex_index(i)] = true;
+
+ // now traverse the list of
+ // boundary vertices and check
+ // distances. since distances are
+ // symmetric, we only have to check
+ // one half
double max_distance_sqr = 0;
std::vector<bool>::const_iterator pi = boundary_vertices.begin();
const unsigned int N = boundary_vertices.size();
for (unsigned int i=0; i<N; ++i, ++pi)
{
- std::vector<bool>::const_iterator pj = pi+1;
- for (unsigned int j=i+1; j<N; ++j, ++pj)
- if ((*pi==true) && (*pj==true) &&
- ((vertices[i]-vertices[j]).square() > max_distance_sqr))
- max_distance_sqr = (vertices[i]-vertices[j]).square();
+ std::vector<bool>::const_iterator pj = pi+1;
+ for (unsigned int j=i+1; j<N; ++j, ++pj)
+ if ((*pi==true) && (*pj==true) &&
+ ((vertices[i]-vertices[j]).square() > max_distance_sqr))
+ max_distance_sqr = (vertices[i]-vertices[j]).square();
};
return std::sqrt(max_distance_sqr);
template <int dim, int spacedim>
double
volume (const Triangulation<dim, spacedim> &triangulation,
- const Mapping<dim,spacedim> &mapping)
+ const Mapping<dim,spacedim> &mapping)
{
- // get the degree of the mapping if possible. if not, just assume 1
+ // get the degree of the mapping if possible. if not, just assume 1
const unsigned int mapping_degree
= (dynamic_cast<const MappingQ<dim,spacedim>*>(&mapping) != 0 ?
- dynamic_cast<const MappingQ<dim,spacedim>*>(&mapping)->get_degree() :
- 1);
+ dynamic_cast<const MappingQ<dim,spacedim>*>(&mapping)->get_degree() :
+ 1);
- // then initialize an appropriate quadrature formula
+ // then initialize an appropriate quadrature formula
const QGauss<dim> quadrature_formula (mapping_degree + 1);
const unsigned int n_q_points = quadrature_formula.size();
FE_DGQ<dim,spacedim> dummy_fe(0);
FEValues<dim,spacedim> fe_values (mapping, dummy_fe, quadrature_formula,
- update_JxW_values);
+ update_JxW_values);
typename Triangulation<dim,spacedim>::active_cell_iterator
cell = triangulation.begin_active(),
double local_volume = 0;
- // compute the integral quantities by quadrature
+ // compute the integral quantities by quadrature
for (; cell!=endc; ++cell)
if (cell->is_locally_owned())
- {
- fe_values.reinit (cell);
- for (unsigned int q=0; q<n_q_points; ++q)
- local_volume += fe_values.JxW(q);
- }
+ {
+ fe_values.reinit (cell);
+ for (unsigned int q=0; q<n_q_points; ++q)
+ local_volume += fe_values.JxW(q);
+ }
double global_volume = 0;
#ifdef DEAL_II_COMPILER_SUPPORTS_MPI
if (const parallel::distributed::Triangulation<dim,spacedim>* p_tria
- = dynamic_cast<const parallel::distributed::Triangulation<dim,spacedim>*>(&triangulation))
+ = dynamic_cast<const parallel::distributed::Triangulation<dim,spacedim>*>(&triangulation))
global_volume = Utilities::MPI::sum (local_volume, p_tria->get_communicator());
else
global_volume = local_volume;
template <>
double
cell_measure<3>(const std::vector<Point<3> > &all_vertices,
- const unsigned int (&vertex_indices)[GeometryInfo<3>::vertices_per_cell])
+ const unsigned int (&vertex_indices)[GeometryInfo<3>::vertices_per_cell])
{
- // note that this is the
- // cell_measure based on the new
- // deal.II numbering. When called
- // from inside GridReordering make
- // sure that you reorder the
- // vertex_indices before
+ // note that this is the
+ // cell_measure based on the new
+ // deal.II numbering. When called
+ // from inside GridReordering make
+ // sure that you reorder the
+ // vertex_indices before
const double x[8] = { all_vertices[vertex_indices[0]](0),
- all_vertices[vertex_indices[1]](0),
- all_vertices[vertex_indices[2]](0),
- all_vertices[vertex_indices[3]](0),
- all_vertices[vertex_indices[4]](0),
- all_vertices[vertex_indices[5]](0),
- all_vertices[vertex_indices[6]](0),
- all_vertices[vertex_indices[7]](0) };
+ all_vertices[vertex_indices[1]](0),
+ all_vertices[vertex_indices[2]](0),
+ all_vertices[vertex_indices[3]](0),
+ all_vertices[vertex_indices[4]](0),
+ all_vertices[vertex_indices[5]](0),
+ all_vertices[vertex_indices[6]](0),
+ all_vertices[vertex_indices[7]](0) };
const double y[8] = { all_vertices[vertex_indices[0]](1),
- all_vertices[vertex_indices[1]](1),
- all_vertices[vertex_indices[2]](1),
- all_vertices[vertex_indices[3]](1),
- all_vertices[vertex_indices[4]](1),
- all_vertices[vertex_indices[5]](1),
- all_vertices[vertex_indices[6]](1),
- all_vertices[vertex_indices[7]](1) };
+ all_vertices[vertex_indices[1]](1),
+ all_vertices[vertex_indices[2]](1),
+ all_vertices[vertex_indices[3]](1),
+ all_vertices[vertex_indices[4]](1),
+ all_vertices[vertex_indices[5]](1),
+ all_vertices[vertex_indices[6]](1),
+ all_vertices[vertex_indices[7]](1) };
const double z[8] = { all_vertices[vertex_indices[0]](2),
- all_vertices[vertex_indices[1]](2),
- all_vertices[vertex_indices[2]](2),
- all_vertices[vertex_indices[3]](2),
- all_vertices[vertex_indices[4]](2),
- all_vertices[vertex_indices[5]](2),
- all_vertices[vertex_indices[6]](2),
- all_vertices[vertex_indices[7]](2) };
+ all_vertices[vertex_indices[1]](2),
+ all_vertices[vertex_indices[2]](2),
+ all_vertices[vertex_indices[3]](2),
+ all_vertices[vertex_indices[4]](2),
+ all_vertices[vertex_indices[5]](2),
+ all_vertices[vertex_indices[6]](2),
+ all_vertices[vertex_indices[7]](2) };
/*
This is the same Maple script as in the barycenter method above
template <>
double
cell_measure(const std::vector<Point<2> > &all_vertices,
- const unsigned int (&vertex_indices) [GeometryInfo<2>::vertices_per_cell])
+ const unsigned int (&vertex_indices) [GeometryInfo<2>::vertices_per_cell])
{
/*
Get the computation of the measure by this little Maple script. We
*/
const double x[4] = { all_vertices[vertex_indices[0]](0),
- all_vertices[vertex_indices[1]](0),
- all_vertices[vertex_indices[2]](0),
- all_vertices[vertex_indices[3]](0)};
+ all_vertices[vertex_indices[1]](0),
+ all_vertices[vertex_indices[2]](0),
+ all_vertices[vertex_indices[3]](0)};
const double y[4] = { all_vertices[vertex_indices[0]](1),
- all_vertices[vertex_indices[1]](1),
- all_vertices[vertex_indices[2]](1),
- all_vertices[vertex_indices[3]](1)};
+ all_vertices[vertex_indices[1]](1),
+ all_vertices[vertex_indices[2]](1),
+ all_vertices[vertex_indices[3]](1)};
return (-x[1]*y[0]+x[1]*y[3]+y[0]*x[2]+x[0]*y[1]-x[0]*y[2]-y[1]*x[3]-x[2]*y[3]+x[3]*y[2])/2;
template <int dim>
double
cell_measure(const std::vector<Point<dim> > &,
- const unsigned int (&) [GeometryInfo<dim>::vertices_per_cell])
+ const unsigned int (&) [GeometryInfo<dim>::vertices_per_cell])
{
Assert(false, ExcNotImplemented());
return 0.;
template <int dim, int spacedim>
void
delete_unused_vertices (std::vector<Point<spacedim> > &vertices,
- std::vector<CellData<dim> > &cells,
- SubCellData &subcelldata)
+ std::vector<CellData<dim> > &cells,
+ SubCellData &subcelldata)
{
- // first check which vertices are
- // actually used
+ // first check which vertices are
+ // actually used
std::vector<bool> vertex_used (vertices.size(), false);
for (unsigned int c=0; c<cells.size(); ++c)
for (unsigned int v=0; v<GeometryInfo<dim>::vertices_per_cell; ++v)
- vertex_used[cells[c].vertices[v]] = true;
+ vertex_used[cells[c].vertices[v]] = true;
- // then renumber the vertices that
- // are actually used in the same
- // order as they were beforehand
+ // then renumber the vertices that
+ // are actually used in the same
+ // order as they were beforehand
const unsigned int invalid_vertex = numbers::invalid_unsigned_int;
std::vector<unsigned int> new_vertex_numbers (vertices.size(), invalid_vertex);
unsigned int next_free_number = 0;
for (unsigned int i=0; i<vertices.size(); ++i)
if (vertex_used[i] == true)
- {
- new_vertex_numbers[i] = next_free_number;
- ++next_free_number;
- };
+ {
+ new_vertex_numbers[i] = next_free_number;
+ ++next_free_number;
+ };
- // next replace old vertex numbers
- // by the new ones
+ // next replace old vertex numbers
+ // by the new ones
for (unsigned int c=0; c<cells.size(); ++c)
for (unsigned int v=0; v<GeometryInfo<dim>::vertices_per_cell; ++v)
- cells[c].vertices[v] = new_vertex_numbers[cells[c].vertices[v]];
+ cells[c].vertices[v] = new_vertex_numbers[cells[c].vertices[v]];
- // same for boundary data
+ // same for boundary data
for (unsigned int c=0; c<subcelldata.boundary_lines.size(); ++c)
for (unsigned int v=0; v<GeometryInfo<1>::vertices_per_cell; ++v)
- subcelldata.boundary_lines[c].vertices[v]
- = new_vertex_numbers[subcelldata.boundary_lines[c].vertices[v]];
+ subcelldata.boundary_lines[c].vertices[v]
+ = new_vertex_numbers[subcelldata.boundary_lines[c].vertices[v]];
for (unsigned int c=0; c<subcelldata.boundary_quads.size(); ++c)
for (unsigned int v=0; v<GeometryInfo<2>::vertices_per_cell; ++v)
- subcelldata.boundary_quads[c].vertices[v]
- = new_vertex_numbers[subcelldata.boundary_quads[c].vertices[v]];
+ subcelldata.boundary_quads[c].vertices[v]
+ = new_vertex_numbers[subcelldata.boundary_quads[c].vertices[v]];
- // finally copy over the vertices
- // which we really need to a new
- // array and replace the old one by
- // the new one
+ // finally copy over the vertices
+ // which we really need to a new
+ // array and replace the old one by
+ // the new one
std::vector<Point<spacedim> > tmp;
tmp.reserve (std::count(vertex_used.begin(), vertex_used.end(), true));
for (unsigned int v=0; v<vertices.size(); ++v)
if (vertex_used[v] == true)
- tmp.push_back (vertices[v]);
+ tmp.push_back (vertices[v]);
swap (vertices, tmp);
}
template <int dim, int spacedim>
void
delete_duplicated_vertices (std::vector<Point<spacedim> > &vertices,
- std::vector<CellData<dim> > &cells,
- SubCellData &subcelldata,
- std::vector<unsigned int> &considered_vertices,
- double tol)
+ std::vector<CellData<dim> > &cells,
+ SubCellData &subcelldata,
+ std::vector<unsigned int> &considered_vertices,
+ double tol)
{
- // create a vector of vertex
- // indices. initialize it to the identity,
- // later on change that if necessary.
+ // create a vector of vertex
+ // indices. initialize it to the identity,
+ // later on change that if necessary.
std::vector<unsigned int> new_vertex_numbers(vertices.size());
for (unsigned int i=0; i<vertices.size(); ++i)
new_vertex_numbers[i]=i;
- // if the considered_vertices vector is
- // empty, consider all vertices
+ // if the considered_vertices vector is
+ // empty, consider all vertices
if (considered_vertices.size()==0)
considered_vertices=new_vertex_numbers;
- // now loop over all vertices to be
- // considered and try to find an identical
- // one
+ // now loop over all vertices to be
+ // considered and try to find an identical
+ // one
for (unsigned int i=0; i<considered_vertices.size(); ++i)
{
- if (new_vertex_numbers[considered_vertices[i]]!=considered_vertices[i])
- // this vertex has been identified with
- // another one already, skip it in the
- // test
- continue;
- // this vertex is not identified with
- // another one so far. search in the list
- // of remaining vertices. if a duplicate
- // vertex is found, set the new vertex
- // index for that vertex to this vertex'
- // index.
- for (unsigned int j=i+1; j<considered_vertices.size(); ++j)
- {
- bool equal=true;
- for (unsigned int d=0; d<dim; ++d)
- equal &= (fabs(vertices[considered_vertices[j]](d)-vertices[considered_vertices[i]](d))<tol);
- if (equal)
- {
- new_vertex_numbers[considered_vertices[j]]=considered_vertices[i];
- // we do not suppose, that there might be another duplicate
- // vertex, so break here
- break;
- }
- }
+ if (new_vertex_numbers[considered_vertices[i]]!=considered_vertices[i])
+ // this vertex has been identified with
+ // another one already, skip it in the
+ // test
+ continue;
+ // this vertex is not identified with
+ // another one so far. search in the list
+ // of remaining vertices. if a duplicate
+ // vertex is found, set the new vertex
+ // index for that vertex to this vertex'
+ // index.
+ for (unsigned int j=i+1; j<considered_vertices.size(); ++j)
+ {
+ bool equal=true;
+ for (unsigned int d=0; d<dim; ++d)
+ equal &= (fabs(vertices[considered_vertices[j]](d)-vertices[considered_vertices[i]](d))<tol);
+ if (equal)
+ {
+ new_vertex_numbers[considered_vertices[j]]=considered_vertices[i];
+ // we do not suppose, that there might be another duplicate
+ // vertex, so break here
+ break;
+ }
+ }
}
- // now we got a renumbering list. simply
- // renumber all vertices (non-duplicate
- // vertices get renumbered to themselves, so
- // nothing bad happens). after that, the
- // duplicate vertices will be unused, so call
- // delete_unused_vertices() to do that part
- // of the job.
+ // now we got a renumbering list. simply
+ // renumber all vertices (non-duplicate
+ // vertices get renumbered to themselves, so
+ // nothing bad happens). after that, the
+ // duplicate vertices will be unused, so call
+ // delete_unused_vertices() to do that part
+ // of the job.
for (unsigned int c=0; c<cells.size(); ++c)
for (unsigned int v=0; v<GeometryInfo<dim>::vertices_per_cell; ++v)
- cells[c].vertices[v]=new_vertex_numbers[cells[c].vertices[v]];
+ cells[c].vertices[v]=new_vertex_numbers[cells[c].vertices[v]];
delete_unused_vertices(vertices,cells,subcelldata);
}
class ShiftPoint
{
public:
- ShiftPoint (const Point<spacedim> &shift)
- :
- shift(shift)
- {}
- Point<spacedim> operator() (const Point<spacedim> p) const
- {
- return p+shift;
- }
+ ShiftPoint (const Point<spacedim> &shift)
+ :
+ shift(shift)
+ {}
+ Point<spacedim> operator() (const Point<spacedim> p) const
+ {
+ return p+shift;
+ }
private:
- const Point<spacedim> shift;
+ const Point<spacedim> shift;
};
- // the following class is only
- // needed in 2d, so avoid trouble
- // with compilers warning otherwise
+ // the following class is only
+ // needed in 2d, so avoid trouble
+ // with compilers warning otherwise
class Rotate2d
{
public:
- Rotate2d (const double angle)
- :
- angle(angle)
- {}
- Point<2> operator() (const Point<2> &p) const
- {
- return Point<2> (std::cos(angle)*p(0) - std::sin(angle) * p(1),
- std::sin(angle)*p(0) + std::cos(angle) * p(1));
- }
+ Rotate2d (const double angle)
+ :
+ angle(angle)
+ {}
+ Point<2> operator() (const Point<2> &p) const
+ {
+ return Point<2> (std::cos(angle)*p(0) - std::sin(angle) * p(1),
+ std::sin(angle)*p(0) + std::cos(angle) * p(1));
+ }
private:
- const double angle;
+ const double angle;
};
class ScalePoint
{
public:
- ScalePoint (const double factor)
- :
- factor(factor)
- {}
- Point<spacedim> operator() (const Point<spacedim> p) const
- {
- return p*factor;
- }
+ ScalePoint (const double factor)
+ :
+ factor(factor)
+ {}
+ Point<spacedim> operator() (const Point<spacedim> p) const
+ {
+ return p*factor;
+ }
private:
- const double factor;
+ const double factor;
};
}
template <int dim, int spacedim>
void
shift (const Point<spacedim> &shift_vector,
- Triangulation<dim, spacedim> &triangulation)
+ Triangulation<dim, spacedim> &triangulation)
{
#ifdef DEAL_II_ANON_NAMESPACE_BOGUS_WARNING
transform (TRANS::ShiftPoint<spacedim>(shift_vector), triangulation);
void
rotate (const double angle,
- Triangulation<2> &triangulation)
+ Triangulation<2> &triangulation)
{
#ifdef DEAL_II_ANON_NAMESPACE_BOGUS_WARNING
transform (TRANS::Rotate2d(angle), triangulation);
template <int dim, int spacedim>
void
scale (const double scaling_factor,
- Triangulation<dim, spacedim> &triangulation)
+ Triangulation<dim, spacedim> &triangulation)
{
Assert (scaling_factor>0, ExcScalingFactorNotPositive (scaling_factor));
#ifdef DEAL_II_ANON_NAMESPACE_BOGUS_WARNING
template <int dim, template <int, int> class Container, int spacedim>
unsigned int
find_closest_vertex (const Container<dim,spacedim> &container,
- const Point<spacedim> &p)
+ const Point<spacedim> &p)
{
- // first get the underlying
- // triangulation from the
- // container and determine vertices
- // and used vertices
+ // first get the underlying
+ // triangulation from the
+ // container and determine vertices
+ // and used vertices
const Triangulation<dim, spacedim> &tria = get_tria(container);
const std::vector< Point<spacedim> > &vertices = tria.get_vertices();
const std::vector< bool > &used = tria.get_used_vertices();
- // At the beginning, the first
- // used vertex is the closest one
+ // At the beginning, the first
+ // used vertex is the closest one
std::vector<bool>::const_iterator first =
std::find(used.begin(), used.end(), true);
- // Assert that at least one vertex
- // is actually used
+ // Assert that at least one vertex
+ // is actually used
Assert(first != used.end(), ExcInternalError());
unsigned int best_vertex = std::distance(used.begin(), first);
double best_dist = (p - vertices[best_vertex]).square();
- // For all remaining vertices, test
- // whether they are any closer
+ // For all remaining vertices, test
+ // whether they are any closer
for(unsigned int j = best_vertex+1; j < vertices.size(); j++)
if(used[j])
- {
- double dist = (p - vertices[j]).square();
- if(dist < best_dist)
- {
- best_vertex = j;
- best_dist = dist;
- }
- }
+ {
+ double dist = (p - vertices[j]).square();
+ if(dist < best_dist)
+ {
+ best_vertex = j;
+ best_dist = dist;
+ }
+ }
return best_vertex;
}
template<int dim, template<int, int> class Container, int spacedim>
std::vector<typename Container<dim,spacedim>::active_cell_iterator>
find_cells_adjacent_to_vertex(const Container<dim,spacedim> &container,
- const unsigned int vertex)
+ const unsigned int vertex)
{
- // make sure that the given vertex is
- // an active vertex of the underlying
- // triangulation
+ // make sure that the given vertex is
+ // an active vertex of the underlying
+ // triangulation
Assert(vertex < get_tria(container).n_vertices(),
- ExcIndexRange(0,get_tria(container).n_vertices(),vertex));
+ ExcIndexRange(0,get_tria(container).n_vertices(),vertex));
Assert(get_tria(container).get_used_vertices()[vertex],
- ExcVertexNotUsed(vertex));
+ ExcVertexNotUsed(vertex));
- // We use a set instead of a vector
- // to ensure that cells are inserted only
- // once. A bug in the previous version
- // prevented some cases to be
- // treated correctly
+ // We use a set instead of a vector
+ // to ensure that cells are inserted only
+ // once. A bug in the previous version
+ // prevented some cases to be
+ // treated correctly
std::set<typename Container<dim,spacedim>::active_cell_iterator> adj_cells_set;
typename Container<dim,spacedim>::active_cell_iterator
cell = container.begin_active(),
endc = container.end();
- // go through all active cells and look
- // if the vertex is part of that cell
+ // go through all active cells and look
+ // if the vertex is part of that cell
for (; cell != endc; ++cell)
for (unsigned v = 0; v < GeometryInfo<dim>::vertices_per_cell; v++)
- if (cell->vertex_index(v) == vertex)
- {
- // OK, we found a cell that contains
- // the particular vertex. We add it
- // to the list.
- adj_cells_set.insert(cell);
-
- // Now we need to make sure that the
- // vertex is not a locally refined
- // vertex not being part of the
- // neighboring cells. So we loop over
- // all faces to which this vertex
- // belongs, check the level of
- // the neighbor, and if it is coarser,
- // then check whether the vertex is
- // part of that neighbor or not.
- for (unsigned vface = 0; vface < dim; vface++)
- {
- const unsigned face =
- GeometryInfo<dim>::vertex_to_face[v][vface];
- if (!cell->at_boundary(face))
- {
- typename Container<dim,spacedim>::cell_iterator
- nb = cell->neighbor(face);
-
- // Here we
- // check
- // whether
- // the
- // neighbor
- // is
- // coarser. If
- // it is, we
- // search
- // for the
- // vertex in
- // this
- // coarser
- // cell and
- // only if
- // not found
- // we will
- // add the
- // coarser
- // cell
- // itself
- if (nb->level() < cell->level())
- {
- bool found = false;
- for (unsigned v=0; v<GeometryInfo<dim>::vertices_per_cell; v++)
- if (nb->vertex_index(v) == vertex)
- {
- found = true;
- break;
- }
- if (!found)
- adj_cells_set.insert(nb);
- }
- }
- }
-
- break;
- }
+ if (cell->vertex_index(v) == vertex)
+ {
+ // OK, we found a cell that contains
+ // the particular vertex. We add it
+ // to the list.
+ adj_cells_set.insert(cell);
+
+ // Now we need to make sure that the
+ // vertex is not a locally refined
+ // vertex not being part of the
+ // neighboring cells. So we loop over
+ // all faces to which this vertex
+ // belongs, check the level of
+ // the neighbor, and if it is coarser,
+ // then check whether the vertex is
+ // part of that neighbor or not.
+ for (unsigned vface = 0; vface < dim; vface++)
+ {
+ const unsigned face =
+ GeometryInfo<dim>::vertex_to_face[v][vface];
+ if (!cell->at_boundary(face))
+ {
+ typename Container<dim,spacedim>::cell_iterator
+ nb = cell->neighbor(face);
+
+ // Here we
+ // check
+ // whether
+ // the
+ // neighbor
+ // is
+ // coarser. If
+ // it is, we
+ // search
+ // for the
+ // vertex in
+ // this
+ // coarser
+ // cell and
+ // only if
+ // not found
+ // we will
+ // add the
+ // coarser
+ // cell
+ // itself
+ if (nb->level() < cell->level())
+ {
+ bool found = false;
+ for (unsigned v=0; v<GeometryInfo<dim>::vertices_per_cell; v++)
+ if (nb->vertex_index(v) == vertex)
+ {
+ found = true;
+ break;
+ }
+ if (!found)
+ adj_cells_set.insert(nb);
+ }
+ }
+ }
+
+ break;
+ }
std::vector<typename Container<dim,spacedim>::active_cell_iterator>
adjacent_cells;
- // We now produce the output vector
- // from the set that we assembled above.
+ // We now produce the output vector
+ // from the set that we assembled above.
typename std::set<typename Container<dim,spacedim>::active_cell_iterator>::iterator
it = adj_cells_set.begin(),
endit = adj_cells_set.end();
template <int dim, template<int, int> class Container, int spacedim>
typename Container<dim,spacedim>::active_cell_iterator
find_active_cell_around_point (const Container<dim,spacedim> &container,
- const Point<spacedim> &p)
+ const Point<spacedim> &p)
{
return find_active_cell_around_point(StaticMappingQ1<dim,spacedim>::mapping,
- container, p).first;
+ container, p).first;
}
template <int dim, template <int, int> class Container, int spacedim>
std::pair<typename Container<dim,spacedim>::active_cell_iterator, Point<dim> >
find_active_cell_around_point (const Mapping<dim,spacedim> &mapping,
- const Container<dim,spacedim> &container,
- const Point<spacedim> &p)
+ const Container<dim,spacedim> &container,
+ const Point<spacedim> &p)
{
typedef typename Container<dim,spacedim>::active_cell_iterator cell_iterator;
- // The best distance is set to the
- // maximum allowable distance from
- // the unit cell; we assume a
- // max. deviation of 1e-10
+ // The best distance is set to the
+ // maximum allowable distance from
+ // the unit cell; we assume a
+ // max. deviation of 1e-10
double best_distance = 1e-10;
int best_level = -1;
std::pair<cell_iterator, Point<dim> > best_cell;
- // Find closest vertex and determine
- // all adjacent cells
+ // Find closest vertex and determine
+ // all adjacent cells
unsigned int vertex = find_closest_vertex(container, p);
std::vector<cell_iterator> adjacent_cells =
for(; cell != endc; ++cell)
{
- try
- {
- const Point<dim> p_cell = mapping.transform_real_to_unit_cell(*cell, p);
-
- // calculate the infinity norm of
- // the distance vector to the unit cell.
- const double dist = GeometryInfo<dim>::distance_to_unit_cell(p_cell);
-
- // We compare if the point is inside the
- // unit cell (or at least not too far
- // outside). If it is, it is also checked
- // that the cell has a more refined state
- if (dist < best_distance ||
- (dist == best_distance && (*cell)->level() > best_level))
- {
- best_distance = dist;
- best_level = (*cell)->level();
- best_cell = std::make_pair(*cell, p_cell);
- }
- }
- catch (typename MappingQ1<dim,spacedim>::ExcTransformationFailed &)
- {
+ try
+ {
+ const Point<dim> p_cell = mapping.transform_real_to_unit_cell(*cell, p);
+
+ // calculate the infinity norm of
+ // the distance vector to the unit cell.
+ const double dist = GeometryInfo<dim>::distance_to_unit_cell(p_cell);
+
+ // We compare if the point is inside the
+ // unit cell (or at least not too far
+ // outside). If it is, it is also checked
+ // that the cell has a more refined state
+ if (dist < best_distance ||
+ (dist == best_distance && (*cell)->level() > best_level))
+ {
+ best_distance = dist;
+ best_level = (*cell)->level();
+ best_cell = std::make_pair(*cell, p_cell);
+ }
+ }
+ catch (typename MappingQ1<dim,spacedim>::ExcTransformationFailed &)
+ {
//TODO: Maybe say something
- }
+ }
}
Assert (best_cell.first.state() == IteratorState::valid,
- ExcPointNotFound<spacedim>(p));
+ ExcPointNotFound<spacedim>(p));
return best_cell;
}
template <int dim, int spacedim>
std::pair<typename hp::DoFHandler<dim,spacedim>::active_cell_iterator, Point<dim> >
find_active_cell_around_point (const hp::MappingCollection<dim,spacedim> &mapping,
- const hp::DoFHandler<dim,spacedim> &container,
- const Point<spacedim> &p)
+ const hp::DoFHandler<dim,spacedim> &container,
+ const Point<spacedim> &p)
{
Assert ((mapping.size() == 1) ||
- (mapping.size() == container.get_fe().size()),
- ExcMessage ("Mapping collection needs to have either size 1 "
- "or size equal to the number of elements in "
- "the FECollection."));
+ (mapping.size() == container.get_fe().size()),
+ ExcMessage ("Mapping collection needs to have either size 1 "
+ "or size equal to the number of elements in "
+ "the FECollection."));
typedef typename hp::DoFHandler<dim,spacedim>::active_cell_iterator cell_iterator;
std::pair<cell_iterator, Point<dim> > best_cell;
- //If we have only one element in the MappingCollection,
- //we use find_active_cell_around_point using only one
- //mapping.
+ //If we have only one element in the MappingCollection,
+ //we use find_active_cell_around_point using only one
+ //mapping.
if(mapping.size()==1)
best_cell = find_active_cell_around_point(mapping[0], container, p);
else
{
- // The best distance is set to the
- // maximum allowable distance from
- // the unit cell; we assume a
- // max. deviation of 1e-10
+ // The best distance is set to the
+ // maximum allowable distance from
+ // the unit cell; we assume a
+ // max. deviation of 1e-10
double best_distance = 1e-10;
int best_level = -1;
- // Find closest vertex and determine
- // all adjacent cells
+ // Find closest vertex and determine
+ // all adjacent cells
unsigned int vertex = find_closest_vertex(container, p);
std::vector<cell_iterator> adjacent_cells =
for(; cell != endc; ++cell)
{
- const Point<dim> p_cell
- = mapping[(*cell)->active_fe_index()].transform_real_to_unit_cell(*cell, p);
-
- // calculate the infinity norm of
- // the distance vector to the unit cell.
- const double dist = GeometryInfo<dim>::distance_to_unit_cell(p_cell);
-
- // We compare if the point is inside the
- // unit cell (or at least not too far
- // outside). If it is, it is also checked
- // that the cell has a more refined state
- if (dist < best_distance ||
- (dist == best_distance && (*cell)->level() > best_level))
- {
- best_distance = dist;
- best_level = (*cell)->level();
- best_cell = std::make_pair(*cell, p_cell);
- }
- }
-
- Assert (best_cell.first.state() == IteratorState::valid,
- ExcPointNotFound<spacedim>(p));
+ const Point<dim> p_cell
+ = mapping[(*cell)->active_fe_index()].transform_real_to_unit_cell(*cell, p);
+
+ // calculate the infinity norm of
+ // the distance vector to the unit cell.
+ const double dist = GeometryInfo<dim>::distance_to_unit_cell(p_cell);
+
+ // We compare if the point is inside the
+ // unit cell (or at least not too far
+ // outside). If it is, it is also checked
+ // that the cell has a more refined state
+ if (dist < best_distance ||
+ (dist == best_distance && (*cell)->level() > best_level))
+ {
+ best_distance = dist;
+ best_level = (*cell)->level();
+ best_cell = std::make_pair(*cell, p_cell);
+ }
+ }
+
+ Assert (best_cell.first.state() == IteratorState::valid,
+ ExcPointNotFound<spacedim>(p));
}
return best_cell;
}
template <int dim, int spacedim>
void
get_face_connectivity_of_cells (const Triangulation<dim,spacedim> &triangulation,
- SparsityPattern &cell_connectivity)
+ SparsityPattern &cell_connectivity)
{
- // as built in this function, we
- // only consider face neighbors,
- // which leads to a fixed number of
- // entries per row (don't forget
- // that each cell couples with
- // itself, and that neighbors can
- // be refined)
+ // as built in this function, we
+ // only consider face neighbors,
+ // which leads to a fixed number of
+ // entries per row (don't forget
+ // that each cell couples with
+ // itself, and that neighbors can
+ // be refined)
cell_connectivity.reinit (triangulation.n_active_cells(),
- triangulation.n_active_cells(),
- GeometryInfo<dim>::faces_per_cell
- * GeometryInfo<dim>::max_children_per_face
- +
- 1);
-
- // next we have to build a mapping from the
- // list of cells to their indices. for
- // this, use the user_index field
+ triangulation.n_active_cells(),
+ GeometryInfo<dim>::faces_per_cell
+ * GeometryInfo<dim>::max_children_per_face
+ +
+ 1);
+
+ // next we have to build a mapping from the
+ // list of cells to their indices. for
+ // this, use the user_index field
std::vector<unsigned int> saved_user_indices;
triangulation.save_user_indices (saved_user_indices);
unsigned int index = 0;
for (typename Triangulation<dim,spacedim>::active_cell_iterator
- cell = triangulation.begin_active();
- cell != triangulation.end(); ++cell, ++index)
+ cell = triangulation.begin_active();
+ cell != triangulation.end(); ++cell, ++index)
cell->set_user_index (index);
- // next loop over all cells and
- // their neighbors to build the
- // sparsity pattern. note that it's
- // a bit hard to enter all the
- // connections when a neighbor has
- // children since we would need to
- // find out which of its children
- // is adjacent to the current
- // cell. this problem can be
- // omitted if we only do something
- // if the neighbor has no children
- // -- in that case it is either on
- // the same or a coarser level than
- // we are. in return, we have to
- // add entries in both directions
- // for both cells
+ // next loop over all cells and
+ // their neighbors to build the
+ // sparsity pattern. note that it's
+ // a bit hard to enter all the
+ // connections when a neighbor has
+ // children since we would need to
+ // find out which of its children
+ // is adjacent to the current
+ // cell. this problem can be
+ // omitted if we only do something
+ // if the neighbor has no children
+ // -- in that case it is either on
+ // the same or a coarser level than
+ // we are. in return, we have to
+ // add entries in both directions
+ // for both cells
index = 0;
for (typename Triangulation<dim,spacedim>::active_cell_iterator
- cell = triangulation.begin_active();
- cell != triangulation.end(); ++cell, ++index)
+ cell = triangulation.begin_active();
+ cell != triangulation.end(); ++cell, ++index)
{
- cell_connectivity.add (index, index);
- for (unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell; ++f)
- if ((cell->at_boundary(f) == false)
- &&
- (cell->neighbor(f)->has_children() == false))
- {
- cell_connectivity.add (index,
- cell->neighbor(f)->user_index());
- cell_connectivity.add (cell->neighbor(f)->user_index(),
- index);
- }
+ cell_connectivity.add (index, index);
+ for (unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell; ++f)
+ if ((cell->at_boundary(f) == false)
+ &&
+ (cell->neighbor(f)->has_children() == false))
+ {
+ cell_connectivity.add (index,
+ cell->neighbor(f)->user_index());
+ cell_connectivity.add (cell->neighbor(f)->user_index(),
+ index);
+ }
}
- // now compress the so-built connectivity
- // pattern and restore user indices. the
- // const-cast is necessary since we treat
- // the triangulation as constant (we here
- // return it to its original state)
+ // now compress the so-built connectivity
+ // pattern and restore user indices. the
+ // const-cast is necessary since we treat
+ // the triangulation as constant (we here
+ // return it to its original state)
cell_connectivity.compress ();
const_cast<Triangulation<dim,spacedim>&>(triangulation)
.load_user_indices (saved_user_indices);
template <int dim, int spacedim>
void
partition_triangulation (const unsigned int n_partitions,
- Triangulation<dim,spacedim> &triangulation)
+ Triangulation<dim,spacedim> &triangulation)
{
Assert ((dynamic_cast<parallel::distributed::Triangulation<dim,spacedim>*>
- (&triangulation)
- == 0),
- ExcMessage ("Objects of type parallel::distributed::Triangulation "
- "are already partitioned implicitly and can not be "
- "partitioned again explicitly."));
+ (&triangulation)
+ == 0),
+ ExcMessage ("Objects of type parallel::distributed::Triangulation "
+ "are already partitioned implicitly and can not be "
+ "partitioned again explicitly."));
Assert (n_partitions > 0, ExcInvalidNumberOfPartitions(n_partitions));
- // check for an easy return
+ // check for an easy return
if (n_partitions == 1)
{
- for (typename Triangulation<dim,spacedim>::active_cell_iterator
- cell = triangulation.begin_active();
- cell != triangulation.end(); ++cell)
- cell->set_subdomain_id (0);
- return;
+ for (typename Triangulation<dim,spacedim>::active_cell_iterator
+ cell = triangulation.begin_active();
+ cell != triangulation.end(); ++cell)
+ cell->set_subdomain_id (0);
+ return;
}
- // we decompose the domain by first
- // generating the connection graph of all
- // cells with their neighbors, and then
- // passing this graph off to METIS.
- // finally defer to the other function for
- // partitioning and assigning subdomain ids
+ // we decompose the domain by first
+ // generating the connection graph of all
+ // cells with their neighbors, and then
+ // passing this graph off to METIS.
+ // finally defer to the other function for
+ // partitioning and assigning subdomain ids
SparsityPattern cell_connectivity;
get_face_connectivity_of_cells (triangulation, cell_connectivity);
partition_triangulation (n_partitions,
- cell_connectivity,
- triangulation);
+ cell_connectivity,
+ triangulation);
}
template <int dim, int spacedim>
void
partition_triangulation (const unsigned int n_partitions,
- const SparsityPattern &cell_connection_graph,
- Triangulation<dim,spacedim> &triangulation)
+ const SparsityPattern &cell_connection_graph,
+ Triangulation<dim,spacedim> &triangulation)
{
Assert ((dynamic_cast<parallel::distributed::Triangulation<dim,spacedim>*>
- (&triangulation)
- == 0),
- ExcMessage ("Objects of type parallel::distributed::Triangulation "
- "are already partitioned implicitly and can not be "
- "partitioned again explicitly."));
+ (&triangulation)
+ == 0),
+ ExcMessage ("Objects of type parallel::distributed::Triangulation "
+ "are already partitioned implicitly and can not be "
+ "partitioned again explicitly."));
Assert (n_partitions > 0, ExcInvalidNumberOfPartitions(n_partitions));
Assert (cell_connection_graph.n_rows() == triangulation.n_active_cells(),
- ExcMessage ("Connectivity graph has wrong size"));
+ ExcMessage ("Connectivity graph has wrong size"));
Assert (cell_connection_graph.n_cols() == triangulation.n_active_cells(),
- ExcMessage ("Connectivity graph has wrong size"));
+ ExcMessage ("Connectivity graph has wrong size"));
- // check for an easy return
+ // check for an easy return
if (n_partitions == 1)
{
- for (typename Triangulation<dim,spacedim>::active_cell_iterator
- cell = triangulation.begin_active();
- cell != triangulation.end(); ++cell)
- cell->set_subdomain_id (0);
- return;
+ for (typename Triangulation<dim,spacedim>::active_cell_iterator
+ cell = triangulation.begin_active();
+ cell != triangulation.end(); ++cell)
+ cell->set_subdomain_id (0);
+ return;
}
- // partition this connection graph and get
- // back a vector of indices, one per degree
- // of freedom (which is associated with a
- // cell)
+ // partition this connection graph and get
+ // back a vector of indices, one per degree
+ // of freedom (which is associated with a
+ // cell)
std::vector<unsigned int> partition_indices (triangulation.n_active_cells());
SparsityTools::partition (cell_connection_graph, n_partitions, partition_indices);
- // finally loop over all cells and set the
- // subdomain ids
+ // finally loop over all cells and set the
+ // subdomain ids
std::vector<unsigned int> dof_indices(1);
unsigned int index = 0;
for (typename Triangulation<dim,spacedim>::active_cell_iterator
- cell = triangulation.begin_active();
- cell != triangulation.end(); ++cell, ++index)
+ cell = triangulation.begin_active();
+ cell != triangulation.end(); ++cell, ++index)
cell->set_subdomain_id (partition_indices[index]);
}
template <int dim, int spacedim>
void
get_subdomain_association (const Triangulation<dim, spacedim> &triangulation,
- std::vector<types::subdomain_id_t> &subdomain)
+ std::vector<types::subdomain_id_t> &subdomain)
{
Assert (subdomain.size() == triangulation.n_active_cells(),
- ExcDimensionMismatch (subdomain.size(),
- triangulation.n_active_cells()));
+ ExcDimensionMismatch (subdomain.size(),
+ triangulation.n_active_cells()));
unsigned int index = 0;
for (typename Triangulation<dim, spacedim>::active_cell_iterator
- cell = triangulation.begin_active();
- cell!=triangulation.end(); ++cell, ++index)
+ cell = triangulation.begin_active();
+ cell!=triangulation.end(); ++cell, ++index)
subdomain[index] = cell->subdomain_id();
Assert (index == subdomain.size(), ExcInternalError());
unsigned int
count_cells_with_subdomain_association (const Triangulation<dim, spacedim> &triangulation,
- const types::subdomain_id_t subdomain)
+ const types::subdomain_id_t subdomain)
{
unsigned int count = 0;
for (typename Triangulation<dim, spacedim>::active_cell_iterator
- cell = triangulation.begin_active();
- cell!=triangulation.end(); ++cell)
+ cell = triangulation.begin_active();
+ cell!=triangulation.end(); ++cell)
if (cell->subdomain_id() == subdomain)
- ++count;
+ ++count;
return count;
}
template <typename Container>
std::list<std::pair<typename Container::cell_iterator,
- typename Container::cell_iterator> >
+ typename Container::cell_iterator> >
get_finest_common_cells (const Container &mesh_1,
- const Container &mesh_2)
+ const Container &mesh_2)
{
Assert (have_same_coarse_mesh (mesh_1, mesh_2),
- ExcMessage ("The two containers must be represent triangulations that "
- "have the same coarse meshes"));
-
- // the algorithm goes as follows:
- // first, we fill a list with pairs
- // of iterators common to the two
- // meshes on the coarsest
- // level. then we traverse the
- // list; each time, we find a pair
- // of iterators for which both
- // correspond to non-active cells,
- // we delete this item and push the
- // pairs of iterators to their
- // children to the back. if these
- // again both correspond to
- // non-active cells, we will get to
- // the later on for further
- // consideration
+ ExcMessage ("The two containers must be represent triangulations that "
+ "have the same coarse meshes"));
+
+ // the algorithm goes as follows:
+ // first, we fill a list with pairs
+ // of iterators common to the two
+ // meshes on the coarsest
+ // level. then we traverse the
+ // list; each time, we find a pair
+ // of iterators for which both
+ // correspond to non-active cells,
+ // we delete this item and push the
+ // pairs of iterators to their
+ // children to the back. if these
+ // again both correspond to
+ // non-active cells, we will get to
+ // the later on for further
+ // consideration
typedef
std::list<std::pair<typename Container::cell_iterator,
typename Container::cell_iterator> >
CellList cell_list;
- // first push the coarse level cells
+ // first push the coarse level cells
typename Container::cell_iterator
cell_1 = mesh_1.begin(0),
cell_2 = mesh_2.begin(0);
for (; cell_1 != mesh_1.end(0); ++cell_1, ++cell_2)
cell_list.push_back (std::make_pair (cell_1, cell_2));
- // then traverse list as described
- // above
+ // then traverse list as described
+ // above
typename CellList::iterator cell_pair = cell_list.begin();
while (cell_pair != cell_list.end())
{
- // if both cells in this pair
- // have children, then erase
- // this element and push their
- // children instead
- if (cell_pair->first->has_children()
- &&
- cell_pair->second->has_children())
- {
- Assert(cell_pair->first->refinement_case()==
- cell_pair->second->refinement_case(), ExcNotImplemented());
- for (unsigned int c=0; c<cell_pair->first->n_children(); ++c)
- cell_list.push_back (std::make_pair (cell_pair->first->child(c),
- cell_pair->second->child(c)));
-
- // erasing an iterator
- // keeps other iterators
- // valid, so already
- // advance the present
- // iterator by one and then
- // delete the element we've
- // visited before
- const typename CellList::iterator previous_cell_pair = cell_pair;
- ++cell_pair;
-
- cell_list.erase (previous_cell_pair);
- }
- else
- // both cells are active, do
- // nothing
- ++cell_pair;
+ // if both cells in this pair
+ // have children, then erase
+ // this element and push their
+ // children instead
+ if (cell_pair->first->has_children()
+ &&
+ cell_pair->second->has_children())
+ {
+ Assert(cell_pair->first->refinement_case()==
+ cell_pair->second->refinement_case(), ExcNotImplemented());
+ for (unsigned int c=0; c<cell_pair->first->n_children(); ++c)
+ cell_list.push_back (std::make_pair (cell_pair->first->child(c),
+ cell_pair->second->child(c)));
+
+ // erasing an iterator
+ // keeps other iterators
+ // valid, so already
+ // advance the present
+ // iterator by one and then
+ // delete the element we've
+ // visited before
+ const typename CellList::iterator previous_cell_pair = cell_pair;
+ ++cell_pair;
+
+ cell_list.erase (previous_cell_pair);
+ }
+ else
+ // both cells are active, do
+ // nothing
+ ++cell_pair;
}
- // just to make sure everything is ok,
- // validate that all pairs have at least one
- // active iterator or have different
- // refinement_cases
+ // just to make sure everything is ok,
+ // validate that all pairs have at least one
+ // active iterator or have different
+ // refinement_cases
for (cell_pair = cell_list.begin(); cell_pair != cell_list.end(); ++cell_pair)
Assert (cell_pair->first->active()
- ||
- cell_pair->second->active()
- ||
- (cell_pair->first->refinement_case()
- != cell_pair->second->refinement_case()),
- ExcInternalError());
+ ||
+ cell_pair->second->active()
+ ||
+ (cell_pair->first->refinement_case()
+ != cell_pair->second->refinement_case()),
+ ExcInternalError());
return cell_list;
}
template <int dim, int spacedim>
bool
have_same_coarse_mesh (const Triangulation<dim, spacedim> &mesh_1,
- const Triangulation<dim, spacedim> &mesh_2)
+ const Triangulation<dim, spacedim> &mesh_2)
{
- // make sure the two meshes have
- // the same number of coarse cells
+ // make sure the two meshes have
+ // the same number of coarse cells
if (mesh_1.n_cells (0) != mesh_2.n_cells (0))
return false;
- // if so, also make sure they have
- // the same vertices on the cells
- // of the coarse mesh
+ // if so, also make sure they have
+ // the same vertices on the cells
+ // of the coarse mesh
typename Triangulation<dim, spacedim>::cell_iterator
cell_1 = mesh_1.begin(0),
cell_2 = mesh_2.begin(0),
endc = mesh_1.end(0);
for (; cell_1!=endc; ++cell_1, ++cell_2)
for (unsigned int v=0; v<GeometryInfo<dim>::vertices_per_cell; ++v)
- if (cell_1->vertex(v) != cell_2->vertex(v))
- return false;
+ if (cell_1->vertex(v) != cell_2->vertex(v))
+ return false;
- // if we've gotten through all
- // this, then the meshes really
- // seem to have a common coarse
- // mesh
+ // if we've gotten through all
+ // this, then the meshes really
+ // seem to have a common coarse
+ // mesh
return true;
}
template <typename Container>
bool
have_same_coarse_mesh (const Container &mesh_1,
- const Container &mesh_2)
+ const Container &mesh_2)
{
return have_same_coarse_mesh (mesh_1.get_tria(),
- mesh_2.get_tria());
+ mesh_2.get_tria());
}
{
double min_diameter = triangulation.begin_active()->diameter();
for (typename Triangulation<dim, spacedim>::active_cell_iterator
- cell = triangulation.begin_active(); cell != triangulation.end();
- ++cell)
+ cell = triangulation.begin_active(); cell != triangulation.end();
+ ++cell)
min_diameter = std::min (min_diameter,
- cell->diameter());
+ cell->diameter());
return min_diameter;
}
{
double max_diameter = triangulation.begin_active()->diameter();
for (typename Triangulation<dim, spacedim>::active_cell_iterator
- cell = triangulation.begin_active(); cell != triangulation.end();
- ++cell)
+ cell = triangulation.begin_active(); cell != triangulation.end();
+ ++cell)
max_diameter = std::max (max_diameter,
- cell->diameter());
+ cell->diameter());
return max_diameter;
}
template <int dim, int spacedim>
void
create_union_triangulation (const Triangulation<dim, spacedim> &triangulation_1,
- const Triangulation<dim, spacedim> &triangulation_2,
- Triangulation<dim, spacedim> &result)
+ const Triangulation<dim, spacedim> &triangulation_2,
+ Triangulation<dim, spacedim> &result)
{
Assert (have_same_coarse_mesh (triangulation_1, triangulation_2),
- ExcMessage ("The two input triangulations are not derived from "
- "the same coarse mesh as required."));
-
- // first copy triangulation_1, and
- // then do as many iterations as
- // there are levels in
- // triangulation_2 to refine
- // additional cells. since this is
- // the maximum number of
- // refinements to get from the
- // coarse grid to triangulation_2,
- // it is clear that this is also
- // the maximum number of
- // refinements to get from any cell
- // on triangulation_1 to
- // triangulation_2
+ ExcMessage ("The two input triangulations are not derived from "
+ "the same coarse mesh as required."));
+
+ // first copy triangulation_1, and
+ // then do as many iterations as
+ // there are levels in
+ // triangulation_2 to refine
+ // additional cells. since this is
+ // the maximum number of
+ // refinements to get from the
+ // coarse grid to triangulation_2,
+ // it is clear that this is also
+ // the maximum number of
+ // refinements to get from any cell
+ // on triangulation_1 to
+ // triangulation_2
result.clear ();
result.copy_triangulation (triangulation_1);
for (unsigned int iteration=0; iteration<triangulation_2.n_levels();
- ++iteration)
+ ++iteration)
{
- InterGridMap<Triangulation<dim, spacedim> > intergrid_map;
- intergrid_map.make_mapping (result, triangulation_2);
-
- bool any_cell_flagged = false;
- for (typename Triangulation<dim, spacedim>::active_cell_iterator
- result_cell = result.begin_active();
- result_cell != result.end(); ++result_cell)
- if (intergrid_map[result_cell]->has_children())
- {
- any_cell_flagged = true;
- result_cell->set_refine_flag ();
- }
-
- if (any_cell_flagged == false)
- break;
- else
- result.execute_coarsening_and_refinement();
+ InterGridMap<Triangulation<dim, spacedim> > intergrid_map;
+ intergrid_map.make_mapping (result, triangulation_2);
+
+ bool any_cell_flagged = false;
+ for (typename Triangulation<dim, spacedim>::active_cell_iterator
+ result_cell = result.begin_active();
+ result_cell != result.end(); ++result_cell)
+ if (intergrid_map[result_cell]->has_children())
+ {
+ any_cell_flagged = true;
+ result_cell->set_refine_flag ();
+ }
+
+ if (any_cell_flagged == false)
+ break;
+ else
+ result.execute_coarsening_and_refinement();
}
}
{
namespace FixUpDistortedChildCells
{
- // compute the mean square
- // deviation of the alternating
- // forms of the children of the
- // given object from that of
- // the object itself. for
- // objects with
- // structdim==spacedim, the
- // alternating form is the
- // determinant of the jacobian,
- // whereas for faces with
- // structdim==spacedim-1, the
- // alternating form is the
- // (signed and scaled) normal
- // vector
- //
- // this average square
- // deviation is computed for an
- // object where the center node
- // has been replaced by the
- // second argument to this
- // function
+ // compute the mean square
+ // deviation of the alternating
+ // forms of the children of the
+ // given object from that of
+ // the object itself. for
+ // objects with
+ // structdim==spacedim, the
+ // alternating form is the
+ // determinant of the jacobian,
+ // whereas for faces with
+ // structdim==spacedim-1, the
+ // alternating form is the
+ // (signed and scaled) normal
+ // vector
+ //
+ // this average square
+ // deviation is computed for an
+ // object where the center node
+ // has been replaced by the
+ // second argument to this
+ // function
template <typename Iterator, int spacedim>
double
objective_function (const Iterator &object,
- const Point<spacedim> &object_mid_point)
+ const Point<spacedim> &object_mid_point)
{
- const unsigned int structdim = Iterator::AccessorType::structure_dimension;
- Assert (spacedim == Iterator::AccessorType::dimension,
- ExcInternalError());
-
- // everything below is wrong
- // if not for the following
- // condition
- Assert (object->refinement_case() == RefinementCase<structdim>::isotropic_refinement,
- ExcNotImplemented());
- // first calculate the
- // average alternating form
- // for the parent cell/face
- Point<spacedim> parent_vertices
- [GeometryInfo<structdim>::vertices_per_cell];
- Tensor<spacedim-structdim,spacedim> parent_alternating_forms
- [GeometryInfo<structdim>::vertices_per_cell];
-
- for (unsigned int i=0; i<GeometryInfo<structdim>::vertices_per_cell; ++i)
- parent_vertices[i] = object->vertex(i);
-
- GeometryInfo<structdim>::alternating_form_at_vertices (parent_vertices,
- parent_alternating_forms);
-
- const Tensor<spacedim-structdim,spacedim>
- average_parent_alternating_form
- = std::accumulate (&parent_alternating_forms[0],
- &parent_alternating_forms[GeometryInfo<structdim>::vertices_per_cell],
- Tensor<spacedim-structdim,spacedim>());
-
- // now do the same
- // computation for the
- // children where we use the
- // given location for the
- // object mid point instead of
- // the one the triangulation
- // currently reports
- Point<spacedim> child_vertices
- [GeometryInfo<structdim>::max_children_per_cell]
- [GeometryInfo<structdim>::vertices_per_cell];
- Tensor<spacedim-structdim,spacedim> child_alternating_forms
- [GeometryInfo<structdim>::max_children_per_cell]
- [GeometryInfo<structdim>::vertices_per_cell];
-
- for (unsigned int c=0; c<object->n_children(); ++c)
- for (unsigned int i=0; i<GeometryInfo<structdim>::vertices_per_cell; ++i)
- child_vertices[c][i] = object->child(c)->vertex(i);
-
- // replace mid-object
- // vertex. note that for
- // child i, the mid-object
- // vertex happens to have the
- // number
- // max_children_per_cell-i
- for (unsigned int c=0; c<object->n_children(); ++c)
- child_vertices[c][GeometryInfo<structdim>::max_children_per_cell-c-1]
- = object_mid_point;
-
- for (unsigned int c=0; c<object->n_children(); ++c)
- GeometryInfo<structdim>::alternating_form_at_vertices (child_vertices[c],
- child_alternating_forms[c]);
-
- // on a uniformly refined
- // hypercube object, the child
- // alternating forms should
- // all be smaller by a factor
- // of 2^structdim than the
- // ones of the parent. as a
- // consequence, we'll use the
- // squared deviation from
- // this ideal value as an
- // objective function
- double objective = 0;
- for (unsigned int c=0; c<object->n_children(); ++c)
- for (unsigned int i=0; i<GeometryInfo<structdim>::vertices_per_cell; ++i)
- objective += (child_alternating_forms[c][i] -
- average_parent_alternating_form/std::pow(2.,1.*structdim))
- .norm_square();
-
- return objective;
+ const unsigned int structdim = Iterator::AccessorType::structure_dimension;
+ Assert (spacedim == Iterator::AccessorType::dimension,
+ ExcInternalError());
+
+ // everything below is wrong
+ // if not for the following
+ // condition
+ Assert (object->refinement_case() == RefinementCase<structdim>::isotropic_refinement,
+ ExcNotImplemented());
+ // first calculate the
+ // average alternating form
+ // for the parent cell/face
+ Point<spacedim> parent_vertices
+ [GeometryInfo<structdim>::vertices_per_cell];
+ Tensor<spacedim-structdim,spacedim> parent_alternating_forms
+ [GeometryInfo<structdim>::vertices_per_cell];
+
+ for (unsigned int i=0; i<GeometryInfo<structdim>::vertices_per_cell; ++i)
+ parent_vertices[i] = object->vertex(i);
+
+ GeometryInfo<structdim>::alternating_form_at_vertices (parent_vertices,
+ parent_alternating_forms);
+
+ const Tensor<spacedim-structdim,spacedim>
+ average_parent_alternating_form
+ = std::accumulate (&parent_alternating_forms[0],
+ &parent_alternating_forms[GeometryInfo<structdim>::vertices_per_cell],
+ Tensor<spacedim-structdim,spacedim>());
+
+ // now do the same
+ // computation for the
+ // children where we use the
+ // given location for the
+ // object mid point instead of
+ // the one the triangulation
+ // currently reports
+ Point<spacedim> child_vertices
+ [GeometryInfo<structdim>::max_children_per_cell]
+ [GeometryInfo<structdim>::vertices_per_cell];
+ Tensor<spacedim-structdim,spacedim> child_alternating_forms
+ [GeometryInfo<structdim>::max_children_per_cell]
+ [GeometryInfo<structdim>::vertices_per_cell];
+
+ for (unsigned int c=0; c<object->n_children(); ++c)
+ for (unsigned int i=0; i<GeometryInfo<structdim>::vertices_per_cell; ++i)
+ child_vertices[c][i] = object->child(c)->vertex(i);
+
+ // replace mid-object
+ // vertex. note that for
+ // child i, the mid-object
+ // vertex happens to have the
+ // number
+ // max_children_per_cell-i
+ for (unsigned int c=0; c<object->n_children(); ++c)
+ child_vertices[c][GeometryInfo<structdim>::max_children_per_cell-c-1]
+ = object_mid_point;
+
+ for (unsigned int c=0; c<object->n_children(); ++c)
+ GeometryInfo<structdim>::alternating_form_at_vertices (child_vertices[c],
+ child_alternating_forms[c]);
+
+ // on a uniformly refined
+ // hypercube object, the child
+ // alternating forms should
+ // all be smaller by a factor
+ // of 2^structdim than the
+ // ones of the parent. as a
+ // consequence, we'll use the
+ // squared deviation from
+ // this ideal value as an
+ // objective function
+ double objective = 0;
+ for (unsigned int c=0; c<object->n_children(); ++c)
+ for (unsigned int i=0; i<GeometryInfo<structdim>::vertices_per_cell; ++i)
+ objective += (child_alternating_forms[c][i] -
+ average_parent_alternating_form/std::pow(2.,1.*structdim))
+ .norm_square();
+
+ return objective;
}
- /**
- * Return the location of the midpoint
- * of the 'f'th face (vertex) of this 1d
- * object.
- */
+ /**
+ * Return the location of the midpoint
+ * of the 'f'th face (vertex) of this 1d
+ * object.
+ */
template <typename Iterator>
Point<Iterator::AccessorType::space_dimension>
get_face_midpoint (const Iterator &object,
- const unsigned int f,
- dealii::internal::int2type<1>)
+ const unsigned int f,
+ dealii::internal::int2type<1>)
{
- return object->vertex(f);
+ return object->vertex(f);
}
- /**
- * Return the location of the midpoint
- * of the 'f'th face (line) of this 2d
- * object.
- */
+ /**
+ * Return the location of the midpoint
+ * of the 'f'th face (line) of this 2d
+ * object.
+ */
template <typename Iterator>
Point<Iterator::AccessorType::space_dimension>
get_face_midpoint (const Iterator &object,
- const unsigned int f,
- dealii::internal::int2type<2>)
+ const unsigned int f,
+ dealii::internal::int2type<2>)
{
- return object->line(f)->center();
+ return object->line(f)->center();
}
- /**
- * Return the location of the midpoint
- * of the 'f'th face (quad) of this 3d
- * object.
- */
+ /**
+ * Return the location of the midpoint
+ * of the 'f'th face (quad) of this 3d
+ * object.
+ */
template <typename Iterator>
Point<Iterator::AccessorType::space_dimension>
get_face_midpoint (const Iterator &object,
- const unsigned int f,
- dealii::internal::int2type<3>)
+ const unsigned int f,
+ dealii::internal::int2type<3>)
{
- return object->face(f)->center();
+ return object->face(f)->center();
}
- /**
- * Compute the minimal diameter of an
- * object by looking for the minimal
- * distance between the mid-points of
- * its faces. This minimal diameter is
- * used to determine the step length
- * for our grid cell improvement
- * algorithm, and it should be small
- * enough that the point moves around
- * within the cell even if it is highly
- * elongated -- thus, the diameter of
- * the object is not a good measure,
- * while the minimal diameter is. Note
- * that the algorithm below works for
- * both cells that are long rectangles
- * with parallel sides where the
- * nearest distance is between opposite
- * edges as well as highly slanted
- * parallelograms where the shortest
- * distance is between neighboring
- * edges.
- */
+ /**
+ * Compute the minimal diameter of an
+ * object by looking for the minimal
+ * distance between the mid-points of
+ * its faces. This minimal diameter is
+ * used to determine the step length
+ * for our grid cell improvement
+ * algorithm, and it should be small
+ * enough that the point moves around
+ * within the cell even if it is highly
+ * elongated -- thus, the diameter of
+ * the object is not a good measure,
+ * while the minimal diameter is. Note
+ * that the algorithm below works for
+ * both cells that are long rectangles
+ * with parallel sides where the
+ * nearest distance is between opposite
+ * edges as well as highly slanted
+ * parallelograms where the shortest
+ * distance is between neighboring
+ * edges.
+ */
template <typename Iterator>
double
minimal_diameter (const Iterator &object)
{
- const unsigned int
- structdim = Iterator::AccessorType::structure_dimension;
-
- double diameter = object->diameter();
- for (unsigned int f=0;
- f<GeometryInfo<structdim>::faces_per_cell;
- ++f)
- for (unsigned int e=f+1;
- e<GeometryInfo<structdim>::faces_per_cell;
- ++e)
- diameter = std::min (diameter,
- get_face_midpoint
- (object, f,
- dealii::internal::int2type<structdim>())
- .distance (get_face_midpoint
- (object,
- e,
- dealii::internal::int2type<structdim>())));
-
- return diameter;
+ const unsigned int
+ structdim = Iterator::AccessorType::structure_dimension;
+
+ double diameter = object->diameter();
+ for (unsigned int f=0;
+ f<GeometryInfo<structdim>::faces_per_cell;
+ ++f)
+ for (unsigned int e=f+1;
+ e<GeometryInfo<structdim>::faces_per_cell;
+ ++e)
+ diameter = std::min (diameter,
+ get_face_midpoint
+ (object, f,
+ dealii::internal::int2type<structdim>())
+ .distance (get_face_midpoint
+ (object,
+ e,
+ dealii::internal::int2type<structdim>())));
+
+ return diameter;
}
- /**
- * Try to fix up a single cell. Return
- * whether we succeeded with this.
- *
- * The second argument indicates
- * whether we need to respect the
- * manifold/boundary on which this
- * object lies when moving around its
- * mid-point.
- */
+ /**
+ * Try to fix up a single cell. Return
+ * whether we succeeded with this.
+ *
+ * The second argument indicates
+ * whether we need to respect the
+ * manifold/boundary on which this
+ * object lies when moving around its
+ * mid-point.
+ */
template <typename Iterator>
bool
fix_up_object (const Iterator &object,
- const bool respect_manifold)
+ const bool respect_manifold)
{
- const Boundary<Iterator::AccessorType::dimension,
- Iterator::AccessorType::space_dimension>
- *manifold = (respect_manifold ?
- &object->get_boundary() :
- 0);
-
- const unsigned int structdim = Iterator::AccessorType::structure_dimension;
- const unsigned int spacedim = Iterator::AccessorType::space_dimension;
-
- // right now we can only deal
- // with cells that have been
- // refined isotropically
- // because that is the only
- // case where we have a cell
- // mid-point that can be moved
- // around without having to
- // consider boundary
- // information
- Assert (object->has_children(), ExcInternalError());
- Assert (object->refinement_case() == RefinementCase<structdim>::isotropic_refinement,
- ExcNotImplemented());
-
- // get the current location of
- // the object mid-vertex:
- Point<spacedim> object_mid_point
- = object->child(0)->vertex (GeometryInfo<structdim>::max_children_per_cell-1);
-
- // now do a few steepest descent
- // steps to reduce the objective
- // function. compute the diameter in
- // the helper function above
- unsigned int iteration = 0;
- const double diameter = minimal_diameter (object);
-
- // current value of objective
- // function and initial delta
- double current_value = objective_function (object, object_mid_point);
- double initial_delta = 0;
-
- do
- {
- // choose a step length
- // that is initially 1/4
- // of the child objects'
- // diameter, and a sequence
- // whose sum does not
- // converge (to avoid
- // premature termination of
- // the iteration)
- const double step_length = diameter / 4 / (iteration + 1);
-
- // compute the objective
- // function's derivative using a
- // two-sided difference formula
- // with eps=step_length/10
- Tensor<1,spacedim> gradient;
- for (unsigned int d=0; d<spacedim; ++d)
- {
- const double eps = step_length/10;
-
- Point<spacedim> h;
- h[d] = eps/2;
-
- if (respect_manifold == false)
- gradient[d]
- = ((objective_function (object, object_mid_point + h)
- -
- objective_function (object, object_mid_point - h))
- /
- eps);
- else
- gradient[d]
- = ((objective_function (object,
- manifold->project_to_surface(object,
- object_mid_point + h))
- -
- objective_function (object,
- manifold->project_to_surface(object,
- object_mid_point - h)))
- /
- eps);
- }
-
- // sometimes, the
- // (unprojected) gradient
- // is perpendicular to
- // the manifold, but we
- // can't go there if
- // respect_manifold==true. in
- // that case, gradient=0,
- // and we simply need to
- // quite the loop here
- if (gradient.norm() == 0)
- break;
-
- // so we need to go in
- // direction -gradient. the
- // optimal value of the
- // objective function is
- // zero, so assuming that
- // the model is quadratic
- // we would have to go
- // -2*val/||gradient|| in
- // this direction, make
- // sure we go at most
- // step_length into this
- // direction
- object_mid_point -= std::min(2 * current_value / (gradient*gradient),
- step_length / gradient.norm()) *
- gradient;
-
- if (respect_manifold == true)
- object_mid_point = manifold->project_to_surface(object,
- object_mid_point);
-
- // compute current value of the
- // objective function
- const double previous_value = current_value;
- current_value = objective_function (object, object_mid_point);
-
- if (iteration == 0)
- initial_delta = (previous_value - current_value);
-
- // stop if we aren't moving much
- // any more
- if ((iteration >= 1) &&
- ((previous_value - current_value < 0)
- ||
- (std::fabs (previous_value - current_value)
- <
- 0.001 * initial_delta)))
- break;
-
- ++iteration;
- }
- while (iteration < 20);
-
- // verify that the new
- // location is indeed better
- // than the one before. check
- // this by comparing whether
- // the minimum value of the
- // products of parent and
- // child alternating forms is
- // positive. for cells this
- // means that the
- // determinants have the same
- // sign, for faces that the
- // face normals of parent and
- // children point in the same
- // general direction
- double old_min_product, new_min_product;
-
- Point<spacedim> parent_vertices
- [GeometryInfo<structdim>::vertices_per_cell];
- for (unsigned int i=0; i<GeometryInfo<structdim>::vertices_per_cell; ++i)
- parent_vertices[i] = object->vertex(i);
-
- Tensor<spacedim-structdim,spacedim> parent_alternating_forms
- [GeometryInfo<structdim>::vertices_per_cell];
- GeometryInfo<structdim>::alternating_form_at_vertices (parent_vertices,
- parent_alternating_forms);
-
- Point<spacedim> child_vertices
- [GeometryInfo<structdim>::max_children_per_cell]
- [GeometryInfo<structdim>::vertices_per_cell];
-
- for (unsigned int c=0; c<object->n_children(); ++c)
- for (unsigned int i=0; i<GeometryInfo<structdim>::vertices_per_cell; ++i)
- child_vertices[c][i] = object->child(c)->vertex(i);
-
- Tensor<spacedim-structdim,spacedim> child_alternating_forms
- [GeometryInfo<structdim>::max_children_per_cell]
- [GeometryInfo<structdim>::vertices_per_cell];
-
- for (unsigned int c=0; c<object->n_children(); ++c)
- GeometryInfo<structdim>::alternating_form_at_vertices (child_vertices[c],
- child_alternating_forms[c]);
-
- old_min_product = child_alternating_forms[0][0] * parent_alternating_forms[0];
- for (unsigned int c=0; c<object->n_children(); ++c)
- for (unsigned int i=0; i<GeometryInfo<structdim>::vertices_per_cell; ++i)
- for (unsigned int j=0; j<GeometryInfo<structdim>::vertices_per_cell; ++j)
- old_min_product = std::min (old_min_product,
- child_alternating_forms[c][i] *
- parent_alternating_forms[j]);
-
- // for the new minimum value,
- // replace mid-object
- // vertex. note that for child
- // i, the mid-object vertex
- // happens to have the number
- // max_children_per_cell-i
- for (unsigned int c=0; c<object->n_children(); ++c)
- child_vertices[c][GeometryInfo<structdim>::max_children_per_cell-c-1]
- = object_mid_point;
-
- for (unsigned int c=0; c<object->n_children(); ++c)
- GeometryInfo<structdim>::alternating_form_at_vertices (child_vertices[c],
- child_alternating_forms[c]);
-
- new_min_product = child_alternating_forms[0][0] * parent_alternating_forms[0];
- for (unsigned int c=0; c<object->n_children(); ++c)
- for (unsigned int i=0; i<GeometryInfo<structdim>::vertices_per_cell; ++i)
- for (unsigned int j=0; j<GeometryInfo<structdim>::vertices_per_cell; ++j)
- new_min_product = std::min (new_min_product,
- child_alternating_forms[c][i] *
- parent_alternating_forms[j]);
-
- // if new minimum value is
- // better than before, then set the
- // new mid point. otherwise
- // return this object as one of
- // those that can't apparently
- // be fixed
- if (new_min_product >= old_min_product)
- object->child(0)->vertex (GeometryInfo<structdim>::max_children_per_cell-1)
- = object_mid_point;
-
- // return whether after this
- // operation we have an object that
- // is well oriented
- return (std::max (new_min_product, old_min_product) > 0);
+ const Boundary<Iterator::AccessorType::dimension,
+ Iterator::AccessorType::space_dimension>
+ *manifold = (respect_manifold ?
+ &object->get_boundary() :
+ 0);
+
+ const unsigned int structdim = Iterator::AccessorType::structure_dimension;
+ const unsigned int spacedim = Iterator::AccessorType::space_dimension;
+
+ // right now we can only deal
+ // with cells that have been
+ // refined isotropically
+ // because that is the only
+ // case where we have a cell
+ // mid-point that can be moved
+ // around without having to
+ // consider boundary
+ // information
+ Assert (object->has_children(), ExcInternalError());
+ Assert (object->refinement_case() == RefinementCase<structdim>::isotropic_refinement,
+ ExcNotImplemented());
+
+ // get the current location of
+ // the object mid-vertex:
+ Point<spacedim> object_mid_point
+ = object->child(0)->vertex (GeometryInfo<structdim>::max_children_per_cell-1);
+
+ // now do a few steepest descent
+ // steps to reduce the objective
+ // function. compute the diameter in
+ // the helper function above
+ unsigned int iteration = 0;
+ const double diameter = minimal_diameter (object);
+
+ // current value of objective
+ // function and initial delta
+ double current_value = objective_function (object, object_mid_point);
+ double initial_delta = 0;
+
+ do
+ {
+ // choose a step length
+ // that is initially 1/4
+ // of the child objects'
+ // diameter, and a sequence
+ // whose sum does not
+ // converge (to avoid
+ // premature termination of
+ // the iteration)
+ const double step_length = diameter / 4 / (iteration + 1);
+
+ // compute the objective
+ // function's derivative using a
+ // two-sided difference formula
+ // with eps=step_length/10
+ Tensor<1,spacedim> gradient;
+ for (unsigned int d=0; d<spacedim; ++d)
+ {
+ const double eps = step_length/10;
+
+ Point<spacedim> h;
+ h[d] = eps/2;
+
+ if (respect_manifold == false)
+ gradient[d]
+ = ((objective_function (object, object_mid_point + h)
+ -
+ objective_function (object, object_mid_point - h))
+ /
+ eps);
+ else
+ gradient[d]
+ = ((objective_function (object,
+ manifold->project_to_surface(object,
+ object_mid_point + h))
+ -
+ objective_function (object,
+ manifold->project_to_surface(object,
+ object_mid_point - h)))
+ /
+ eps);
+ }
+
+ // sometimes, the
+ // (unprojected) gradient
+ // is perpendicular to
+ // the manifold, but we
+ // can't go there if
+ // respect_manifold==true. in
+ // that case, gradient=0,
+ // and we simply need to
+ // quite the loop here
+ if (gradient.norm() == 0)
+ break;
+
+ // so we need to go in
+ // direction -gradient. the
+ // optimal value of the
+ // objective function is
+ // zero, so assuming that
+ // the model is quadratic
+ // we would have to go
+ // -2*val/||gradient|| in
+ // this direction, make
+ // sure we go at most
+ // step_length into this
+ // direction
+ object_mid_point -= std::min(2 * current_value / (gradient*gradient),
+ step_length / gradient.norm()) *
+ gradient;
+
+ if (respect_manifold == true)
+ object_mid_point = manifold->project_to_surface(object,
+ object_mid_point);
+
+ // compute current value of the
+ // objective function
+ const double previous_value = current_value;
+ current_value = objective_function (object, object_mid_point);
+
+ if (iteration == 0)
+ initial_delta = (previous_value - current_value);
+
+ // stop if we aren't moving much
+ // any more
+ if ((iteration >= 1) &&
+ ((previous_value - current_value < 0)
+ ||
+ (std::fabs (previous_value - current_value)
+ <
+ 0.001 * initial_delta)))
+ break;
+
+ ++iteration;
+ }
+ while (iteration < 20);
+
+ // verify that the new
+ // location is indeed better
+ // than the one before. check
+ // this by comparing whether
+ // the minimum value of the
+ // products of parent and
+ // child alternating forms is
+ // positive. for cells this
+ // means that the
+ // determinants have the same
+ // sign, for faces that the
+ // face normals of parent and
+ // children point in the same
+ // general direction
+ double old_min_product, new_min_product;
+
+ Point<spacedim> parent_vertices
+ [GeometryInfo<structdim>::vertices_per_cell];
+ for (unsigned int i=0; i<GeometryInfo<structdim>::vertices_per_cell; ++i)
+ parent_vertices[i] = object->vertex(i);
+
+ Tensor<spacedim-structdim,spacedim> parent_alternating_forms
+ [GeometryInfo<structdim>::vertices_per_cell];
+ GeometryInfo<structdim>::alternating_form_at_vertices (parent_vertices,
+ parent_alternating_forms);
+
+ Point<spacedim> child_vertices
+ [GeometryInfo<structdim>::max_children_per_cell]
+ [GeometryInfo<structdim>::vertices_per_cell];
+
+ for (unsigned int c=0; c<object->n_children(); ++c)
+ for (unsigned int i=0; i<GeometryInfo<structdim>::vertices_per_cell; ++i)
+ child_vertices[c][i] = object->child(c)->vertex(i);
+
+ Tensor<spacedim-structdim,spacedim> child_alternating_forms
+ [GeometryInfo<structdim>::max_children_per_cell]
+ [GeometryInfo<structdim>::vertices_per_cell];
+
+ for (unsigned int c=0; c<object->n_children(); ++c)
+ GeometryInfo<structdim>::alternating_form_at_vertices (child_vertices[c],
+ child_alternating_forms[c]);
+
+ old_min_product = child_alternating_forms[0][0] * parent_alternating_forms[0];
+ for (unsigned int c=0; c<object->n_children(); ++c)
+ for (unsigned int i=0; i<GeometryInfo<structdim>::vertices_per_cell; ++i)
+ for (unsigned int j=0; j<GeometryInfo<structdim>::vertices_per_cell; ++j)
+ old_min_product = std::min (old_min_product,
+ child_alternating_forms[c][i] *
+ parent_alternating_forms[j]);
+
+ // for the new minimum value,
+ // replace mid-object
+ // vertex. note that for child
+ // i, the mid-object vertex
+ // happens to have the number
+ // max_children_per_cell-i
+ for (unsigned int c=0; c<object->n_children(); ++c)
+ child_vertices[c][GeometryInfo<structdim>::max_children_per_cell-c-1]
+ = object_mid_point;
+
+ for (unsigned int c=0; c<object->n_children(); ++c)
+ GeometryInfo<structdim>::alternating_form_at_vertices (child_vertices[c],
+ child_alternating_forms[c]);
+
+ new_min_product = child_alternating_forms[0][0] * parent_alternating_forms[0];
+ for (unsigned int c=0; c<object->n_children(); ++c)
+ for (unsigned int i=0; i<GeometryInfo<structdim>::vertices_per_cell; ++i)
+ for (unsigned int j=0; j<GeometryInfo<structdim>::vertices_per_cell; ++j)
+ new_min_product = std::min (new_min_product,
+ child_alternating_forms[c][i] *
+ parent_alternating_forms[j]);
+
+ // if new minimum value is
+ // better than before, then set the
+ // new mid point. otherwise
+ // return this object as one of
+ // those that can't apparently
+ // be fixed
+ if (new_min_product >= old_min_product)
+ object->child(0)->vertex (GeometryInfo<structdim>::max_children_per_cell-1)
+ = object_mid_point;
+
+ // return whether after this
+ // operation we have an object that
+ // is well oriented
+ return (std::max (new_min_product, old_min_product) > 0);
}
void fix_up_faces (const dealii::Triangulation<1,1>::cell_iterator &,
- dealii::internal::int2type<1>,
- dealii::internal::int2type<1>)
+ dealii::internal::int2type<1>,
+ dealii::internal::int2type<1>)
{
- // nothing to do for the faces of
- // cells in 1d
+ // nothing to do for the faces of
+ // cells in 1d
}
-
-
- // possibly fix up the faces of
- // a cell by moving around its
- // mid-points
+
+
+ // possibly fix up the faces of
+ // a cell by moving around its
+ // mid-points
template <int structdim, int spacedim>
void fix_up_faces (const typename dealii::Triangulation<structdim,spacedim>::cell_iterator &cell,
- dealii::internal::int2type<structdim>,
- dealii::internal::int2type<spacedim>)
+ dealii::internal::int2type<structdim>,
+ dealii::internal::int2type<spacedim>)
{
- // see if we first can fix up
- // some of the faces of this
- // object. we can mess with
- // faces if and only if it is
- // not at the boundary (since
- // otherwise the location of
- // the face mid-point has been
- // determined by the boundary
- // object) and if the
- // neighboring cell is not even
- // more refined than we are
- // (since in that case the
- // sub-faces have themselves
- // children that we can't move
- // around any more). however,
- // the latter case shouldn't
- // happen anyway: if the
- // current face is distorted
- // but the neighbor is even
- // more refined, then the face
- // had been deformed before
- // already, and had been
- // ignored at the time; we
- // should then also be able to
- // ignore it this time as well
- for (unsigned int f=0; f<GeometryInfo<structdim>::faces_per_cell; ++f)
- {
- Assert (cell->face(f)->has_children(), ExcInternalError());
- Assert (cell->face(f)->refinement_case() ==
- RefinementCase<structdim-1>::isotropic_refinement,
- ExcInternalError());
-
- bool subface_is_more_refined = false;
- for (unsigned int g=0; g<GeometryInfo<structdim>::max_children_per_face; ++g)
- if (cell->face(f)->child(g)->has_children())
- {
- subface_is_more_refined = true;
- break;
- }
-
- if (subface_is_more_refined == true)
- continue;
-
- // so, now we finally know
- // that we can do something
- // about this face
- fix_up_object (cell->face(f), cell->at_boundary(f));
- }
+ // see if we first can fix up
+ // some of the faces of this
+ // object. we can mess with
+ // faces if and only if it is
+ // not at the boundary (since
+ // otherwise the location of
+ // the face mid-point has been
+ // determined by the boundary
+ // object) and if the
+ // neighboring cell is not even
+ // more refined than we are
+ // (since in that case the
+ // sub-faces have themselves
+ // children that we can't move
+ // around any more). however,
+ // the latter case shouldn't
+ // happen anyway: if the
+ // current face is distorted
+ // but the neighbor is even
+ // more refined, then the face
+ // had been deformed before
+ // already, and had been
+ // ignored at the time; we
+ // should then also be able to
+ // ignore it this time as well
+ for (unsigned int f=0; f<GeometryInfo<structdim>::faces_per_cell; ++f)
+ {
+ Assert (cell->face(f)->has_children(), ExcInternalError());
+ Assert (cell->face(f)->refinement_case() ==
+ RefinementCase<structdim-1>::isotropic_refinement,
+ ExcInternalError());
+
+ bool subface_is_more_refined = false;
+ for (unsigned int g=0; g<GeometryInfo<structdim>::max_children_per_face; ++g)
+ if (cell->face(f)->child(g)->has_children())
+ {
+ subface_is_more_refined = true;
+ break;
+ }
+
+ if (subface_is_more_refined == true)
+ continue;
+
+ // so, now we finally know
+ // that we can do something
+ // about this face
+ fix_up_object (cell->face(f), cell->at_boundary(f));
+ }
}
-
-
+
+
}
}
typename Triangulation<dim,spacedim>::DistortedCellList
fix_up_distorted_child_cells (const typename Triangulation<dim,spacedim>::DistortedCellList &distorted_cells,
- Triangulation<dim,spacedim> &/*triangulation*/)
+ Triangulation<dim,spacedim> &/*triangulation*/)
{
typename Triangulation<dim,spacedim>::DistortedCellList unfixable_subset;
- // loop over all cells that we have
- // to fix up
+ // loop over all cells that we have
+ // to fix up
for (typename std::list<typename Triangulation<dim,spacedim>::cell_iterator>::const_iterator
- cell_ptr = distorted_cells.distorted_cells.begin();
- cell_ptr != distorted_cells.distorted_cells.end(); ++cell_ptr)
+ cell_ptr = distorted_cells.distorted_cells.begin();
+ cell_ptr != distorted_cells.distorted_cells.end(); ++cell_ptr)
{
- const typename Triangulation<dim,spacedim>::cell_iterator
- cell = *cell_ptr;
-
- internal::FixUpDistortedChildCells
- ::fix_up_faces (cell,
- dealii::internal::int2type<dim>(),
- dealii::internal::int2type<spacedim>());
-
- // fix up the object. we need to
- // respect the manifold if the cell is
- // embedded in a higher dimensional
- // space; otherwise, like a hex in 3d,
- // every point within the cell interior
- // is fair game
- if (! internal::FixUpDistortedChildCells::fix_up_object (cell,
- (dim < spacedim)))
- unfixable_subset.distorted_cells.push_back (cell);
+ const typename Triangulation<dim,spacedim>::cell_iterator
+ cell = *cell_ptr;
+
+ internal::FixUpDistortedChildCells
+ ::fix_up_faces (cell,
+ dealii::internal::int2type<dim>(),
+ dealii::internal::int2type<spacedim>());
+
+ // fix up the object. we need to
+ // respect the manifold if the cell is
+ // embedded in a higher dimensional
+ // space; otherwise, like a hex in 3d,
+ // every point within the cell interior
+ // is fair game
+ if (! internal::FixUpDistortedChildCells::fix_up_object (cell,
+ (dim < spacedim)))
+ unfixable_subset.distorted_cells.push_back (cell);
}
return unfixable_subset;
template <template <int,int> class Container, int dim, int spacedim>
std::map<typename Container<dim-1,spacedim>::cell_iterator,
- typename Container<dim,spacedim>::face_iterator>
+ typename Container<dim,spacedim>::face_iterator>
extract_boundary_mesh (const Container<dim,spacedim> &volume_mesh,
- Container<dim-1,spacedim> &surface_mesh,
- const std::set<types::boundary_id_t> &boundary_ids)
+ Container<dim-1,spacedim> &surface_mesh,
+ const std::set<types::boundary_id_t> &boundary_ids)
{
// Assumption:
// We are relying below on the fact that Triangulation::create_triangulation(...) will keep the order
const unsigned int boundary_dim = dim-1; //dimension of the boundary mesh
- // First create surface mesh and mapping
- // from only level(0) cells of volume_mesh
+ // First create surface mesh and mapping
+ // from only level(0) cells of volume_mesh
std::vector<typename Container<dim,spacedim>::face_iterator>
mapping; // temporary map for level==0
CellData< boundary_dim > c_data;
for (typename Container<dim,spacedim>::cell_iterator
- cell = volume_mesh.begin(0);
- cell != volume_mesh.end(0);
- ++cell)
+ cell = volume_mesh.begin(0);
+ cell != volume_mesh.end(0);
+ ++cell)
for (unsigned int i=0; i < GeometryInfo<dim>::faces_per_cell; ++i)
- {
- const typename Container<dim,spacedim>::face_iterator
- face = cell->face(i);
-
- if ( face->at_boundary()
- &&
- (boundary_ids.empty() ||
- ( boundary_ids.find(face->boundary_indicator()) != boundary_ids.end())) )
- {
- for (unsigned int j=0;
- j<GeometryInfo<boundary_dim>::vertices_per_cell; ++j)
- {
- v_index = face->vertex_index(j);
-
- if ( !touched[v_index] )
- {
- vertices.push_back(face->vertex(j));
- map_vert_index[v_index] = vertices.size() - 1;
- touched[v_index] = true;
- }
-
- c_data.vertices[j] = map_vert_index[v_index];
- c_data.material_id = face->boundary_indicator();
- }
-
- cells.push_back(c_data);
- mapping.push_back(face);
- }
- }
-
- // create level 0 surface triangulation
+ {
+ const typename Container<dim,spacedim>::face_iterator
+ face = cell->face(i);
+
+ if ( face->at_boundary()
+ &&
+ (boundary_ids.empty() ||
+ ( boundary_ids.find(face->boundary_indicator()) != boundary_ids.end())) )
+ {
+ for (unsigned int j=0;
+ j<GeometryInfo<boundary_dim>::vertices_per_cell; ++j)
+ {
+ v_index = face->vertex_index(j);
+
+ if ( !touched[v_index] )
+ {
+ vertices.push_back(face->vertex(j));
+ map_vert_index[v_index] = vertices.size() - 1;
+ touched[v_index] = true;
+ }
+
+ c_data.vertices[j] = map_vert_index[v_index];
+ c_data.material_id = face->boundary_indicator();
+ }
+
+ cells.push_back(c_data);
+ mapping.push_back(face);
+ }
+ }
+
+ // create level 0 surface triangulation
Assert (cells.size() > 0, ExcMessage ("No boundary faces selected"));
const_cast<Triangulation<dim-1,spacedim>&>(get_tria(surface_mesh))
.create_triangulation (vertices, cells, SubCellData());
- // Make the actual mapping
+ // Make the actual mapping
for (typename Container<dim-1,spacedim>::active_cell_iterator
- cell = surface_mesh.begin(0);
- cell!=surface_mesh.end(0); ++cell)
+ cell = surface_mesh.begin(0);
+ cell!=surface_mesh.end(0); ++cell)
surface_to_volume_mapping[cell] = mapping.at(cell->index());
do
{
- bool changed = false;
- typename Container<dim-1,spacedim>::active_cell_iterator
- cell = surface_mesh.begin_active(),
- endc = surface_mesh.end();
-
- for (; cell!=endc; ++cell)
- if (surface_to_volume_mapping[cell]->has_children() == true )
- {
- cell->set_refine_flag ();
- changed = true;
- }
-
- if (changed)
- {
- const_cast<Triangulation<dim-1,spacedim>&>(get_tria(surface_mesh))
- .execute_coarsening_and_refinement();
-
- typename Container<dim-1,spacedim>::cell_iterator
- cell = surface_mesh.begin(),
- endc = surface_mesh.end();
- for (; cell!=endc; ++cell)
- for (unsigned int c=0; c<cell->n_children(); c++)
- if (surface_to_volume_mapping.find(cell->child(c)) == surface_to_volume_mapping.end())
- surface_to_volume_mapping[cell->child(c)]
- = surface_to_volume_mapping[cell]->child(c);
- }
- else
- break;
+ bool changed = false;
+ typename Container<dim-1,spacedim>::active_cell_iterator
+ cell = surface_mesh.begin_active(),
+ endc = surface_mesh.end();
+
+ for (; cell!=endc; ++cell)
+ if (surface_to_volume_mapping[cell]->has_children() == true )
+ {
+ cell->set_refine_flag ();
+ changed = true;
+ }
+
+ if (changed)
+ {
+ const_cast<Triangulation<dim-1,spacedim>&>(get_tria(surface_mesh))
+ .execute_coarsening_and_refinement();
+
+ typename Container<dim-1,spacedim>::cell_iterator
+ cell = surface_mesh.begin(),
+ endc = surface_mesh.end();
+ for (; cell!=endc; ++cell)
+ for (unsigned int c=0; c<cell->n_children(); c++)
+ if (surface_to_volume_mapping.find(cell->child(c)) == surface_to_volume_mapping.end())
+ surface_to_volume_mapping[cell->child(c)]
+ = surface_to_volume_mapping[cell]->child(c);
+ }
+ else
+ break;
}
while (true);
// $Id$
// Version: $Name$
//
-// Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2008, 2011 by the deal.II authors
+// Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2008, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
unsigned int
get_n_levels (const GridClass &grid)
{
- // all objects we deal with are able
- // to deliver a pointer to the
- // underlying triangulation.
- //
- // for the triangulation as GridClass
- // of this object, there is a
- // specialization of this function
+ // all objects we deal with are able
+ // to deliver a pointer to the
+ // underlying triangulation.
+ //
+ // for the triangulation as GridClass
+ // of this object, there is a
+ // specialization of this function
return grid.get_tria().n_levels();
}
unsigned int
get_n_levels (const Triangulation<dim, spacedim> &grid)
{
- // if GridClass==Triangulation, then
- // we can ask directly.
+ // if GridClass==Triangulation, then
+ // we can ask directly.
return grid.n_levels();
}
}
template <class GridClass>
InterGridMap<GridClass>::InterGridMap ()
- :
- source_grid(0, typeid(*this).name()),
- destination_grid(0, typeid(*this).name())
+ :
+ source_grid(0, typeid(*this).name()),
+ destination_grid(0, typeid(*this).name())
{}
template <class GridClass>
void InterGridMap<GridClass>::make_mapping (const GridClass &source_grid,
- const GridClass &destination_grid)
+ const GridClass &destination_grid)
{
- // first delete all contents
+ // first delete all contents
clear ();
- // next store pointers to grids
+ // next store pointers to grids
this->source_grid = &source_grid;
this->destination_grid = &destination_grid;
- // then set up the containers from
- // scratch and fill them with end-iterators
+ // then set up the containers from
+ // scratch and fill them with end-iterators
const unsigned int n_levels = get_n_levels(source_grid);
mapping.resize (n_levels);
for (unsigned int level=0; level<n_levels; ++level)
{
- // first find out about the highest
- // index used on this level. We could
- // in principle ask the triangulation
- // about this, but we would have to
- // know the underlying data structure
- // for this and we would like to
- // avoid such knowledge here
+ // first find out about the highest
+ // index used on this level. We could
+ // in principle ask the triangulation
+ // about this, but we would have to
+ // know the underlying data structure
+ // for this and we would like to
+ // avoid such knowledge here
unsigned int n_cells = 0;
cell_iterator cell = source_grid.begin(level),
- endc = source_grid.end(level);
+ endc = source_grid.end(level);
for (; cell!=endc; ++cell)
- if (static_cast<unsigned int>(cell->index()) > n_cells)
- n_cells = cell->index();
+ if (static_cast<unsigned int>(cell->index()) > n_cells)
+ n_cells = cell->index();
- // note: n_cells is now the largest
- // zero-based index, but we need the
- // number of cells, which is one larger
+ // note: n_cells is now the largest
+ // zero-based index, but we need the
+ // number of cells, which is one larger
mapping[level].resize (n_cells+1, destination_grid.end());
};
- // now make up the mapping
- // loop over all cells and set the user
- // pointers as well as the contents of
- // the two arrays. note that the function
- // takes a *reference* to the int and
- // this may change it
+ // now make up the mapping
+ // loop over all cells and set the user
+ // pointers as well as the contents of
+ // the two arrays. note that the function
+ // takes a *reference* to the int and
+ // this may change it
cell_iterator src_cell = source_grid.begin(0),
- dst_cell = destination_grid.begin(0),
- endc = source_grid.end(0);
+ dst_cell = destination_grid.begin(0),
+ endc = source_grid.end(0);
for (; src_cell!=endc; ++src_cell, ++dst_cell)
set_mapping (src_cell, dst_cell);
- // little assertion that the two grids
- // are indeed related:
+ // little assertion that the two grids
+ // are indeed related:
Assert (dst_cell == destination_grid.end(0),
- ExcIncompatibleGrids ());
+ ExcIncompatibleGrids ());
}
template <class GridClass>
void
InterGridMap<GridClass>::set_mapping (const cell_iterator &src_cell,
- const cell_iterator &dst_cell)
+ const cell_iterator &dst_cell)
{
- // first set the map for this cell
+ // first set the map for this cell
mapping[src_cell->level()][src_cell->index()] = dst_cell;
- // if both cells have children, we may
- // recurse further into the hierarchy
+ // if both cells have children, we may
+ // recurse further into the hierarchy
if (src_cell->has_children() && dst_cell->has_children())
{
Assert(src_cell->n_children()==
- GeometryInfo<GridClass::dimension>::max_children_per_cell,
- ExcNotImplemented());
+ GeometryInfo<GridClass::dimension>::max_children_per_cell,
+ ExcNotImplemented());
Assert(dst_cell->n_children()==
- GeometryInfo<GridClass::dimension>::max_children_per_cell,
- ExcNotImplemented());
+ GeometryInfo<GridClass::dimension>::max_children_per_cell,
+ ExcNotImplemented());
Assert(src_cell->refinement_case()==dst_cell->refinement_case(),
- ExcNotImplemented());
+ ExcNotImplemented());
for (unsigned int c=0; c<GeometryInfo<GridClass::dimension>::max_children_per_cell; ++c)
- set_mapping (src_cell->child(c),
- dst_cell->child(c));
+ set_mapping (src_cell->child(c),
+ dst_cell->child(c));
}
else
if (src_cell->has_children() &&
- !dst_cell->has_children())
- // src grid is more refined here.
- // set entries for all children
- // of this cell to the one
- // dst_cell
+ !dst_cell->has_children())
+ // src grid is more refined here.
+ // set entries for all children
+ // of this cell to the one
+ // dst_cell
for (unsigned int c=0; c<src_cell->n_children(); ++c)
- set_entries_to_cell (src_cell->child(c),
- dst_cell);
- // else (no cell is refined or
- // dst_cell is refined): no pointers
- // to be set
+ set_entries_to_cell (src_cell->child(c),
+ dst_cell);
+ // else (no cell is refined or
+ // dst_cell is refined): no pointers
+ // to be set
}
template <class GridClass>
void
InterGridMap<GridClass>::set_entries_to_cell (const cell_iterator &src_cell,
- const cell_iterator &dst_cell)
+ const cell_iterator &dst_cell)
{
- // first set the map for this cell
+ // first set the map for this cell
mapping[src_cell->level()][src_cell->index()] = dst_cell;
- // then do so for the children as well
- // if there are any
+ // then do so for the children as well
+ // if there are any
if (src_cell->has_children())
for (unsigned int c=0; c<src_cell->n_children(); ++c)
set_entries_to_cell (src_cell->child(c),
- dst_cell);
+ dst_cell);
}
InterGridMap<GridClass>::operator [] (const cell_iterator &source_cell) const
{
Assert (source_cell.state() == IteratorState::valid,
- ExcInvalidKey (source_cell));
+ ExcInvalidKey (source_cell));
Assert (source_cell->level() <= static_cast<int>(mapping.size()),
- ExcInvalidKey (source_cell));
+ ExcInvalidKey (source_cell));
Assert (source_cell->index() <= static_cast<int>(mapping[source_cell->level()].size()),
- ExcInvalidKey (source_cell));
+ ExcInvalidKey (source_cell));
return mapping[source_cell->level()][source_cell->index()];
}
template <class GridClass>
-void InterGridMap<GridClass>::clear ()
+void InterGridMap<GridClass>::clear ()
{
mapping.clear ();
source_grid = 0;
InterGridMap<GridClass>::memory_consumption () const
{
return (MemoryConsumption::memory_consumption (mapping) +
- MemoryConsumption::memory_consumption (source_grid) +
- MemoryConsumption::memory_consumption (destination_grid));
+ MemoryConsumption::memory_consumption (source_grid) +
+ MemoryConsumption::memory_consumption (destination_grid));
}
-
+
// explicit instantiations
#include "intergrid_map.inst"
// $Id$
// Version: $Name$
//
-// Copyright (C) 1999, 2000, 2001, 2002, 2003, 2005, 2006, 2007, 2009, 2010, 2011 by the deal.II authors
+// Copyright (C) 1999, 2000, 2001, 2002, 2003, 2005, 2006, 2007, 2009, 2010, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
PersistentTriangulation<dim,spacedim>::
PersistentTriangulation (const Triangulation<dim,spacedim> &coarse_grid)
:
- coarse_grid (&coarse_grid, typeid(*this).name())
+ coarse_grid (&coarse_grid, typeid(*this).name())
{}
PersistentTriangulation<dim,spacedim>::
PersistentTriangulation (const PersistentTriangulation<dim,spacedim> &old_tria)
:
- // default initialize
- // tria, i.e. it will be
- // empty on first use
- Triangulation<dim,spacedim> (),
+ // default initialize
+ // tria, i.e. it will be
+ // empty on first use
+ Triangulation<dim,spacedim> (),
coarse_grid (old_tria.coarse_grid),
refine_flags (old_tria.refine_flags),
coarsen_flags (old_tria.coarsen_flags)
void
PersistentTriangulation<dim,spacedim>::execute_coarsening_and_refinement ()
{
- // first save flags
+ // first save flags
refine_flags.push_back (std::vector<bool>());
coarsen_flags.push_back (std::vector<bool>());
this->save_refine_flags (refine_flags.back());
this->save_coarsen_flags (coarsen_flags.back());
- // then refine triangulation. if
- // this function throws an
- // exception, that's fine since it
- // is the last call here
+ // then refine triangulation. if
+ // this function throws an
+ // exception, that's fine since it
+ // is the last call here
Triangulation<dim,spacedim>::execute_coarsening_and_refinement ();
}
void
PersistentTriangulation<dim,spacedim>::restore ()
{
- // for each of the previous
- // refinement sweeps
+ // for each of the previous
+ // refinement sweeps
for (unsigned int i=0; i<refine_flags.size()+1; ++i)
restore(i);
}
{
if (step==0)
- // copy the old triangulation.
- // this will yield an error if
- // the underlying triangulation
- // was not empty
+ // copy the old triangulation.
+ // this will yield an error if
+ // the underlying triangulation
+ // was not empty
Triangulation<dim,spacedim>::copy_triangulation (*coarse_grid);
else
- // for each of the previous
- // refinement sweeps
+ // for each of the previous
+ // refinement sweeps
{
Assert(step<refine_flags.size()+1,
- ExcDimensionMismatch(step, refine_flags.size()+1));
+ ExcDimensionMismatch(step, refine_flags.size()+1));
this->load_refine_flags (refine_flags[step-1]);
this->load_coarsen_flags (coarsen_flags[step-1]);
template <int dim, int spacedim>
void
PersistentTriangulation<dim,spacedim>::create_triangulation (const std::vector<Point<spacedim> > &,
- const std::vector<CellData<dim> > &,
- const SubCellData &)
+ const std::vector<CellData<dim> > &,
+ const SubCellData &)
{
Assert (false, ExcImpossibleInDim(dim));
}
PersistentTriangulation<dim,spacedim>::read_flags(std::istream &in)
{
Assert(refine_flags.size()==0 && coarsen_flags.size()==0,
- ExcFlagsNotCleared());
+ ExcFlagsNotCleared());
AssertThrow (in, ExcIO());
unsigned int magic_number;
in >> magic_number;
AssertThrow(magic_number==mn_persistent_tria_flags_begin,
- typename Triangulation<dim>::ExcGridReadError());
+ typename Triangulation<dim>::ExcGridReadError());
unsigned int n_flag_levels;
in >> n_flag_levels;
in >> magic_number;
AssertThrow(magic_number==mn_persistent_tria_flags_end,
- typename Triangulation<dim>::ExcGridReadError());
+ typename Triangulation<dim>::ExcGridReadError());
AssertThrow (in, ExcIO());
}
PersistentTriangulation<dim,spacedim>::memory_consumption () const
{
return (Triangulation<dim,spacedim>::memory_consumption () +
- MemoryConsumption::memory_consumption (coarse_grid) +
- MemoryConsumption::memory_consumption (refine_flags) +
- MemoryConsumption::memory_consumption (coarsen_flags));
+ MemoryConsumption::memory_consumption (coarse_grid) +
+ MemoryConsumption::memory_consumption (refine_flags) +
+ MemoryConsumption::memory_consumption (coarsen_flags));
}
switch (dim)
{
case 1:
- return ((boundary_lines.size() == 0) &&
- (boundary_quads.size() == 0));
+ return ((boundary_lines.size() == 0) &&
+ (boundary_quads.size() == 0));
case 2:
- return (boundary_quads.size() == 0);
+ return (boundary_quads.size() == 0);
};
return true;
}
{
NumberCache<1>::NumberCache ()
- :
- n_levels (0),
+ :
+ n_levels (0),
n_lines (0),
n_active_lines (0)
// all other fields are
// anonymous namespace for internal helper functions
namespace
{
- // return whether the given cell is
- // patch_level_1, i.e. determine
- // whether either all or none of
- // its children are further
- // refined. this function can only
- // be called for non-active cells.
+ // return whether the given cell is
+ // patch_level_1, i.e. determine
+ // whether either all or none of
+ // its children are further
+ // refined. this function can only
+ // be called for non-active cells.
template <int dim, int spacedim>
bool cell_is_patch_level_1 (const TriaIterator<dealii::CellAccessor<dim, spacedim> > &cell)
{
unsigned int n_active_children = 0;
for (unsigned int i=0; i<cell->n_children(); ++i)
if (cell->child(i)->active())
- ++n_active_children;
+ ++n_active_children;
return (n_active_children == 0) || (n_active_children == cell->n_children());
}
- // return, wheter a given @p cell will be
- // coarsened, which is the case if all
- // children are active and have their coarsen
- // flag set. In case only part of the coarsen
- // flags are set, remove them.
+ // return, wheter a given @p cell will be
+ // coarsened, which is the case if all
+ // children are active and have their coarsen
+ // flag set. In case only part of the coarsen
+ // flags are set, remove them.
template <int dim, int spacedim>
bool cell_will_be_coarsened (const TriaIterator<dealii::CellAccessor<dim,spacedim> > &cell)
{
- // only cells with children should be
- // considered for coarsening
+ // only cells with children should be
+ // considered for coarsening
if (cell->has_children())
{
- unsigned int children_to_coarsen=0;
- const unsigned int n_children=cell->n_children();
-
- for (unsigned int c=0; c<n_children; ++c)
- if (cell->child(c)->active() &&
- cell->child(c)->coarsen_flag_set())
- ++children_to_coarsen;
- if (children_to_coarsen==n_children)
- return true;
- else
- for (unsigned int c=0; c<n_children; ++c)
- if (cell->child(c)->active())
- cell->child(c)->clear_coarsen_flag();
+ unsigned int children_to_coarsen=0;
+ const unsigned int n_children=cell->n_children();
+
+ for (unsigned int c=0; c<n_children; ++c)
+ if (cell->child(c)->active() &&
+ cell->child(c)->coarsen_flag_set())
+ ++children_to_coarsen;
+ if (children_to_coarsen==n_children)
+ return true;
+ else
+ for (unsigned int c=0; c<n_children; ++c)
+ if (cell->child(c)->active())
+ cell->child(c)->clear_coarsen_flag();
}
- // no children, so no coarsening
- // possible. however, no children also
- // means that this cell will be in the same
- // state as if it had children and was
- // coarsened. So, what should we return -
- // false or true?
- // make sure we do not have to do this at
- // all...
+ // no children, so no coarsening
+ // possible. however, no children also
+ // means that this cell will be in the same
+ // state as if it had children and was
+ // coarsened. So, what should we return -
+ // false or true?
+ // make sure we do not have to do this at
+ // all...
Assert(cell->has_children(), ExcInternalError());
- // ... and then simply return false
+ // ... and then simply return false
return false;
}
- // return, whether the face @p face_no of the
- // given @p cell will be refined after the
- // current refinement step, considering
- // refine and coarsen flags and considering
- // only those refinemnts that will be caused
- // by the neighboring cell.
-
- // this function is used on both active cells
- // and cells with children. on cells with
- // children it also of interest to know 'how'
- // the face will be refined. thus there is an
- // additional third argument @p
- // expected_face_ref_case returning just
- // that. be aware, that this vriable will
- // only contain useful information if this
- // function is called for an active cell.
- //
- // thus, this is an internal function, users
- // should call one of the two alternatives
- // following below.
+ // return, whether the face @p face_no of the
+ // given @p cell will be refined after the
+ // current refinement step, considering
+ // refine and coarsen flags and considering
+ // only those refinemnts that will be caused
+ // by the neighboring cell.
+
+ // this function is used on both active cells
+ // and cells with children. on cells with
+ // children it also of interest to know 'how'
+ // the face will be refined. thus there is an
+ // additional third argument @p
+ // expected_face_ref_case returning just
+ // that. be aware, that this vriable will
+ // only contain useful information if this
+ // function is called for an active cell.
+ //
+ // thus, this is an internal function, users
+ // should call one of the two alternatives
+ // following below.
template <int dim, int spacedim>
bool
face_will_be_refined_by_neighbor_internal(const TriaIterator<dealii::CellAccessor<dim,spacedim> > &cell,
- const unsigned int face_no,
- RefinementCase<dim-1> &expected_face_ref_case)
+ const unsigned int face_no,
+ RefinementCase<dim-1> &expected_face_ref_case)
{
- // first of all: set the default value for
- // expected_face_ref_case, which is no
- // refinement at all
+ // first of all: set the default value for
+ // expected_face_ref_case, which is no
+ // refinement at all
expected_face_ref_case=RefinementCase<dim-1>::no_refinement;
const typename Triangulation<dim,spacedim>::cell_iterator neighbor=cell->neighbor(face_no);
- // If we are at the boundary, there is no
- // neighbor which could refine the face
+ // If we are at the boundary, there is no
+ // neighbor which could refine the face
if (neighbor.state()!=IteratorState::valid)
return false;
if (neighbor->has_children())
{
- // if the neighbor is refined, it may be
- // coarsened. if so, then it won't refine
- // the face, no matter what else happens
- if (cell_will_be_coarsened(neighbor))
- return false;
- else
- // if the neighor is refined, then he
- // is also refined at our current
- // face. He will stay so without
- // coarsening, so return true in that
- // case.
- {
- expected_face_ref_case=cell->face(face_no)->refinement_case();
- return true;
- }
+ // if the neighbor is refined, it may be
+ // coarsened. if so, then it won't refine
+ // the face, no matter what else happens
+ if (cell_will_be_coarsened(neighbor))
+ return false;
+ else
+ // if the neighor is refined, then he
+ // is also refined at our current
+ // face. He will stay so without
+ // coarsening, so return true in that
+ // case.
+ {
+ expected_face_ref_case=cell->face(face_no)->refinement_case();
+ return true;
+ }
}
- // now, the neighbor is not refined, but
- // perhaps he will be
+ // now, the neighbor is not refined, but
+ // perhaps he will be
const RefinementCase<dim> nb_ref_flag=neighbor->refine_flag_set();
if (nb_ref_flag != RefinementCase<dim>::no_refinement)
{
- // now we need to know, which of the
- // neighbors faces points towards us
- const unsigned int neighbor_neighbor=cell->neighbor_face_no(face_no);
- // check, whether the cell will be
- // refined in a way that refines our
- // face
- const RefinementCase<dim-1> face_ref_case=
- GeometryInfo<dim>::face_refinement_case(nb_ref_flag,
- neighbor_neighbor,
- neighbor->face_orientation(neighbor_neighbor),
- neighbor->face_flip(neighbor_neighbor),
- neighbor->face_rotation(neighbor_neighbor));
- if (face_ref_case != RefinementCase<dim-1>::no_refinement)
- {
- const typename Triangulation<dim,spacedim>::face_iterator neighbor_face=neighbor->face(neighbor_neighbor);
- const int this_face_index=cell->face_index(face_no);
-
- // there are still two basic
- // possibilities here: the neighbor
- // might be coarser or as coarse
- // as we are
- if (neighbor_face->index()==this_face_index)
- // the neighbor is as coarse as
- // we are and will be refined at
- // the face of consideration, so
- // return true
- {
- expected_face_ref_case = face_ref_case;
- return true;
- }
- else
- {
-
- // the neighbor is coarser.
- // this is the most complicated
- // case. It might be, that the
- // neighbor's face will be
- // refined, but that we will
- // not see this, as we are
- // refined in a similar way.
-
- // so, the neighbor's face must
- // have children. check, if our
- // cell's face is one of these
- // (it could also be a
- // grand_child)
- for (unsigned int c=0; c<neighbor_face->n_children(); ++c)
- if (neighbor_face->child_index(c)==this_face_index)
- {
- // if the flagged refine
- // case of the face is a
- // subset or the same as
- // the current refine case,
- // then the face, as seen
- // from our cell, won't be
- // refined by the neighbor
- if ((neighbor_face->refinement_case() | face_ref_case)
- == neighbor_face->refinement_case())
- return false;
- else
- {
- // if we are active, we
- // must be an
- // anisotropic child
- // and the coming
- // face_ref_case is
- // isotropic. Thus,
- // from our cell we
- // will see exactly the
- // opposite refine case
- // that the face has
- // now...
- Assert(face_ref_case==RefinementCase<dim-1>::isotropic_refinement, ExcInternalError());
- expected_face_ref_case = ~neighbor_face->refinement_case();
- return true;
- }
- }
-
- // so, obviously we were not
- // one of the children, but a
- // grandchild. This is only
- // possible in 3d.
- Assert(dim==3, ExcInternalError());
- // In that case, however, no
- // matter what the neighbor
- // does, he won't be finer
- // after the next refinement
- // step.
- return false;
- }
- }// if face will be refined
+ // now we need to know, which of the
+ // neighbors faces points towards us
+ const unsigned int neighbor_neighbor=cell->neighbor_face_no(face_no);
+ // check, whether the cell will be
+ // refined in a way that refines our
+ // face
+ const RefinementCase<dim-1> face_ref_case=
+ GeometryInfo<dim>::face_refinement_case(nb_ref_flag,
+ neighbor_neighbor,
+ neighbor->face_orientation(neighbor_neighbor),
+ neighbor->face_flip(neighbor_neighbor),
+ neighbor->face_rotation(neighbor_neighbor));
+ if (face_ref_case != RefinementCase<dim-1>::no_refinement)
+ {
+ const typename Triangulation<dim,spacedim>::face_iterator neighbor_face=neighbor->face(neighbor_neighbor);
+ const int this_face_index=cell->face_index(face_no);
+
+ // there are still two basic
+ // possibilities here: the neighbor
+ // might be coarser or as coarse
+ // as we are
+ if (neighbor_face->index()==this_face_index)
+ // the neighbor is as coarse as
+ // we are and will be refined at
+ // the face of consideration, so
+ // return true
+ {
+ expected_face_ref_case = face_ref_case;
+ return true;
+ }
+ else
+ {
+
+ // the neighbor is coarser.
+ // this is the most complicated
+ // case. It might be, that the
+ // neighbor's face will be
+ // refined, but that we will
+ // not see this, as we are
+ // refined in a similar way.
+
+ // so, the neighbor's face must
+ // have children. check, if our
+ // cell's face is one of these
+ // (it could also be a
+ // grand_child)
+ for (unsigned int c=0; c<neighbor_face->n_children(); ++c)
+ if (neighbor_face->child_index(c)==this_face_index)
+ {
+ // if the flagged refine
+ // case of the face is a
+ // subset or the same as
+ // the current refine case,
+ // then the face, as seen
+ // from our cell, won't be
+ // refined by the neighbor
+ if ((neighbor_face->refinement_case() | face_ref_case)
+ == neighbor_face->refinement_case())
+ return false;
+ else
+ {
+ // if we are active, we
+ // must be an
+ // anisotropic child
+ // and the coming
+ // face_ref_case is
+ // isotropic. Thus,
+ // from our cell we
+ // will see exactly the
+ // opposite refine case
+ // that the face has
+ // now...
+ Assert(face_ref_case==RefinementCase<dim-1>::isotropic_refinement, ExcInternalError());
+ expected_face_ref_case = ~neighbor_face->refinement_case();
+ return true;
+ }
+ }
+
+ // so, obviously we were not
+ // one of the children, but a
+ // grandchild. This is only
+ // possible in 3d.
+ Assert(dim==3, ExcInternalError());
+ // In that case, however, no
+ // matter what the neighbor
+ // does, he won't be finer
+ // after the next refinement
+ // step.
+ return false;
+ }
+ }// if face will be refined
}// if neighbor is flagged for refinement
- // no cases left, so the neighbor will not
- // refine the face
+ // no cases left, so the neighbor will not
+ // refine the face
return false;
}
- // version of above function for both active
- // and non-active cells
+ // version of above function for both active
+ // and non-active cells
template <int dim, int spacedim>
bool
face_will_be_refined_by_neighbor(const TriaIterator<dealii::CellAccessor<dim, spacedim> > &cell,
- const unsigned int face_no)
+ const unsigned int face_no)
{
RefinementCase<dim-1> dummy = RefinementCase<dim-1>::no_refinement;
return face_will_be_refined_by_neighbor_internal(cell, face_no, dummy);
}
- // version of above function for active cells
- // only. Additionally returning the refine
- // case (to come) of the face under
- // consideration
+ // version of above function for active cells
+ // only. Additionally returning the refine
+ // case (to come) of the face under
+ // consideration
template <int dim, int spacedim>
bool
face_will_be_refined_by_neighbor(const TriaActiveIterator<dealii::CellAccessor<dim,spacedim> > &cell,
- const unsigned int face_no,
- RefinementCase<dim-1> &expected_face_ref_case)
+ const unsigned int face_no,
+ RefinementCase<dim-1> &expected_face_ref_case)
{
return face_will_be_refined_by_neighbor_internal(cell, face_no,
- expected_face_ref_case);
+ expected_face_ref_case);
}
satisfies_level1_at_vertex_rule (const Triangulation<dim,spacedim> &triangulation)
{
std::vector<unsigned int> min_adjacent_cell_level (triangulation.n_vertices(),
- triangulation.n_levels());
+ triangulation.n_levels());
std::vector<unsigned int> max_adjacent_cell_level (triangulation.n_vertices(),
- 0);
+ 0);
for (typename Triangulation<dim,spacedim>::active_cell_iterator
- cell = triangulation.begin_active();
- cell != triangulation.end(); ++cell)
+ cell = triangulation.begin_active();
+ cell != triangulation.end(); ++cell)
for (unsigned int v=0; v<GeometryInfo<dim>::vertices_per_cell; ++v)
- {
- min_adjacent_cell_level[cell->vertex_index(v)]
- = std::min<unsigned int>
- (min_adjacent_cell_level[cell->vertex_index(v)],
- cell->level());
- max_adjacent_cell_level[cell->vertex_index(v)]
- = std::max<unsigned int> (min_adjacent_cell_level[cell->vertex_index(v)],
- cell->level());
- }
+ {
+ min_adjacent_cell_level[cell->vertex_index(v)]
+ = std::min<unsigned int>
+ (min_adjacent_cell_level[cell->vertex_index(v)],
+ cell->level());
+ max_adjacent_cell_level[cell->vertex_index(v)]
+ = std::max<unsigned int> (min_adjacent_cell_level[cell->vertex_index(v)],
+ cell->level());
+ }
for (unsigned int k=0; k<triangulation.n_vertices(); ++k)
if (triangulation.vertex_used(k))
- if (max_adjacent_cell_level[k] -
- min_adjacent_cell_level[k] > 1)
- return false;
+ if (max_adjacent_cell_level[k] -
+ min_adjacent_cell_level[k] > 1)
+ return false;
return true;
}
- /**
- * Fill the vector @p line_cell_count
- * needed by @p delete_children with the
- * number of cells bounded by a given
- * line.
- */
+ /**
+ * Fill the vector @p line_cell_count
+ * needed by @p delete_children with the
+ * number of cells bounded by a given
+ * line.
+ */
template <int dim, int spacedim>
std::vector<unsigned int>
count_cells_bounded_by_line (const Triangulation<dim,spacedim> &triangulation)
{
if (dim >= 2)
{
- std::vector<unsigned int> line_cell_count(triangulation.n_raw_lines(),0);
- typename Triangulation<dim,spacedim>::cell_iterator
- cell=triangulation.begin(),
- endc=triangulation.end();
- for (; cell!=endc; ++cell)
- for (unsigned int l=0; l<GeometryInfo<dim>::lines_per_cell; ++l)
- ++line_cell_count[cell->line_index(l)];
- return line_cell_count;
+ std::vector<unsigned int> line_cell_count(triangulation.n_raw_lines(),0);
+ typename Triangulation<dim,spacedim>::cell_iterator
+ cell=triangulation.begin(),
+ endc=triangulation.end();
+ for (; cell!=endc; ++cell)
+ for (unsigned int l=0; l<GeometryInfo<dim>::lines_per_cell; ++l)
+ ++line_cell_count[cell->line_index(l)];
+ return line_cell_count;
}
else
return std::vector<unsigned int>();
- /**
- * Fill the vector @p quad_cell_count
- * needed by @p delete_children with the
- * number of cells bounded by a given
- * quad.
- */
+ /**
+ * Fill the vector @p quad_cell_count
+ * needed by @p delete_children with the
+ * number of cells bounded by a given
+ * quad.
+ */
template <int dim, int spacedim>
std::vector<unsigned int>
count_cells_bounded_by_quad (const Triangulation<dim,spacedim> &triangulation)
{
if (dim >= 3)
{
- std::vector<unsigned int> quad_cell_count (triangulation.n_raw_quads(),0);
- typename Triangulation<dim,spacedim>::cell_iterator
- cell=triangulation.begin(),
- endc=triangulation.end();
- for (; cell!=endc; ++cell)
- for (unsigned int q=0; q<GeometryInfo<dim>::faces_per_cell; ++q)
- ++quad_cell_count[cell->quad_index(q)];
- return quad_cell_count;
+ std::vector<unsigned int> quad_cell_count (triangulation.n_raw_quads(),0);
+ typename Triangulation<dim,spacedim>::cell_iterator
+ cell=triangulation.begin(),
+ endc=triangulation.end();
+ for (; cell!=endc; ++cell)
+ for (unsigned int q=0; q<GeometryInfo<dim>::faces_per_cell; ++q)
+ ++quad_cell_count[cell->quad_index(q)];
+ return quad_cell_count;
}
else
return std::vector<unsigned int>();
}
- /**
- * For a given Triangulation, update the
- * number cache for lines. For 1d, we have
- * to deal with the fact that lines have
- * levels, whereas for higher dimensions
- * they do not.
- *
- * The second argument indicates
- * for how many levels the
- * Triangulation has objects,
- * though the highest levels need
- * not contain active cells if they
- * have previously all been
- * coarsened away.
- */
+ /**
+ * For a given Triangulation, update the
+ * number cache for lines. For 1d, we have
+ * to deal with the fact that lines have
+ * levels, whereas for higher dimensions
+ * they do not.
+ *
+ * The second argument indicates
+ * for how many levels the
+ * Triangulation has objects,
+ * though the highest levels need
+ * not contain active cells if they
+ * have previously all been
+ * coarsened away.
+ */
template <int dim, int spacedim>
void compute_number_cache (const Triangulation<dim,spacedim> &triangulation,
- const unsigned int level_objects,
- internal::Triangulation::NumberCache<1> &number_cache)
+ const unsigned int level_objects,
+ internal::Triangulation::NumberCache<1> &number_cache)
{
typedef
typename Triangulation<dim,spacedim>::line_iterator line_iterator;
number_cache.n_levels = 0;
if (level_objects > 0)
{
- // check whether there are
- // cells on the highest
- // levels (there need not be,
- // since they might all have
- // been coarsened away)
- typename Triangulation<dim,spacedim>::raw_cell_iterator
- cell = triangulation.last_raw (level_objects-1),
- endc = triangulation.end();
- for (; cell!=endc; --cell)
- if (cell->used())
- {
- // return level of most
- // refined existing cell
- // (+1 because of
- // counting conventions)
- number_cache.n_levels = cell->level()+1;
- break;
- }
-
- // no cells at all?
- Assert (number_cache.n_levels > 0, ExcInternalError());
+ // check whether there are
+ // cells on the highest
+ // levels (there need not be,
+ // since they might all have
+ // been coarsened away)
+ typename Triangulation<dim,spacedim>::raw_cell_iterator
+ cell = triangulation.last_raw (level_objects-1),
+ endc = triangulation.end();
+ for (; cell!=endc; --cell)
+ if (cell->used())
+ {
+ // return level of most
+ // refined existing cell
+ // (+1 because of
+ // counting conventions)
+ number_cache.n_levels = cell->level()+1;
+ break;
+ }
+
+ // no cells at all?
+ Assert (number_cache.n_levels > 0, ExcInternalError());
}
- ///////////////////////////////////
- // update the number of lines
- // on the different levels in
- // the cache
+ ///////////////////////////////////
+ // update the number of lines
+ // on the different levels in
+ // the cache
number_cache.n_lines_level.resize (number_cache.n_levels);
number_cache.n_lines = 0;
number_cache.n_active_lines_level.resize (number_cache.n_levels);
number_cache.n_active_lines = 0;
- // for 1d, lines have levels so take
- // count the objects per level and
- // globally
+ // for 1d, lines have levels so take
+ // count the objects per level and
+ // globally
if (dim == 1)
{
- for (unsigned int level=0; level<number_cache.n_levels; ++level)
- {
- // count lines on this level
- number_cache.n_lines_level[level] = 0;
-
- line_iterator line = triangulation.begin_line (level),
- endc = (level == number_cache.n_levels-1 ?
- line_iterator(triangulation.end_line()) :
- triangulation.begin_line (level+1));
- for (; line!=endc; ++line)
- ++number_cache.n_lines_level[level];
-
- // update total number of lines
- number_cache.n_lines += number_cache.n_lines_level[level];
- }
-
- // do the update for the number of
- // active lines as well
- for (unsigned int level=0; level<number_cache.n_levels; ++level)
- {
- // count lines on this level
- number_cache.n_active_lines_level[level] = 0;
-
- active_line_iterator line = triangulation.begin_active_line (level),
- endc = triangulation.end_active_line (level);
- for (; line!=endc; ++line)
- ++number_cache.n_active_lines_level[level];
-
- // update total number of lines
- number_cache.n_active_lines += number_cache.n_active_lines_level[level];
- }
+ for (unsigned int level=0; level<number_cache.n_levels; ++level)
+ {
+ // count lines on this level
+ number_cache.n_lines_level[level] = 0;
+
+ line_iterator line = triangulation.begin_line (level),
+ endc = (level == number_cache.n_levels-1 ?
+ line_iterator(triangulation.end_line()) :
+ triangulation.begin_line (level+1));
+ for (; line!=endc; ++line)
+ ++number_cache.n_lines_level[level];
+
+ // update total number of lines
+ number_cache.n_lines += number_cache.n_lines_level[level];
+ }
+
+ // do the update for the number of
+ // active lines as well
+ for (unsigned int level=0; level<number_cache.n_levels; ++level)
+ {
+ // count lines on this level
+ number_cache.n_active_lines_level[level] = 0;
+
+ active_line_iterator line = triangulation.begin_active_line (level),
+ endc = triangulation.end_active_line (level);
+ for (; line!=endc; ++line)
+ ++number_cache.n_active_lines_level[level];
+
+ // update total number of lines
+ number_cache.n_active_lines += number_cache.n_active_lines_level[level];
+ }
}
else
{
- // for dim>1, there are no
- // levels for lines
- {
- line_iterator line = triangulation.begin_line (),
- endc = triangulation.end_line();
- for (; line!=endc; ++line)
- ++number_cache.n_lines;
- }
-
- {
- active_line_iterator line = triangulation.begin_active_line (),
- endc = triangulation.end_line();
- for (; line!=endc; ++line)
- ++number_cache.n_active_lines;
- }
+ // for dim>1, there are no
+ // levels for lines
+ {
+ line_iterator line = triangulation.begin_line (),
+ endc = triangulation.end_line();
+ for (; line!=endc; ++line)
+ ++number_cache.n_lines;
+ }
+
+ {
+ active_line_iterator line = triangulation.begin_active_line (),
+ endc = triangulation.end_line();
+ for (; line!=endc; ++line)
+ ++number_cache.n_active_lines;
+ }
}
}
- /**
- * For a given Triangulation, update the
- * number cache for quads. For 2d, we have
- * to deal with the fact that quads have
- * levels, whereas for higher dimensions
- * they do not.
- *
- * The second argument indicates
- * for how many levels the
- * Triangulation has objects,
- * though the highest levels need
- * not contain active cells if they
- * have previously all been
- * coarsened away.
- *
- * At the beginning of the function, we call the
- * respective function to update the number
- * cache for lines.
- */
+ /**
+ * For a given Triangulation, update the
+ * number cache for quads. For 2d, we have
+ * to deal with the fact that quads have
+ * levels, whereas for higher dimensions
+ * they do not.
+ *
+ * The second argument indicates
+ * for how many levels the
+ * Triangulation has objects,
+ * though the highest levels need
+ * not contain active cells if they
+ * have previously all been
+ * coarsened away.
+ *
+ * At the beginning of the function, we call the
+ * respective function to update the number
+ * cache for lines.
+ */
template <int dim, int spacedim>
void compute_number_cache (const Triangulation<dim,spacedim> &triangulation,
- const unsigned int level_objects,
- internal::Triangulation::NumberCache<2> &number_cache)
+ const unsigned int level_objects,
+ internal::Triangulation::NumberCache<2> &number_cache)
{
- // update lines and n_levels
+ // update lines and n_levels
compute_number_cache (triangulation,
- level_objects,
- static_cast<internal::Triangulation::NumberCache<1>&>
- (number_cache));
+ level_objects,
+ static_cast<internal::Triangulation::NumberCache<1>&>
+ (number_cache));
typedef
typename Triangulation<dim,spacedim>::quad_iterator quad_iterator;
typedef
typename Triangulation<dim,spacedim>::active_quad_iterator active_quad_iterator;
- ///////////////////////////////////
- // update the number of quads
- // on the different levels in
- // the cache
+ ///////////////////////////////////
+ // update the number of quads
+ // on the different levels in
+ // the cache
number_cache.n_quads_level.resize (number_cache.n_levels);
number_cache.n_quads = 0;
number_cache.n_active_quads_level.resize (number_cache.n_levels);
number_cache.n_active_quads = 0;
- // for 2d, quads have levels so take
- // count the objects per level and
- // globally
+ // for 2d, quads have levels so take
+ // count the objects per level and
+ // globally
if (dim == 2)
{
- for (unsigned int level=0; level<number_cache.n_levels; ++level)
- {
- // count quads on this level
- number_cache.n_quads_level[level] = 0;
-
- quad_iterator quad = triangulation.begin_quad (level),
- endc = (level == number_cache.n_levels-1 ?
- quad_iterator(triangulation.end_quad()) :
- triangulation.begin_quad (level+1));
- for (; quad!=endc; ++quad)
- ++number_cache.n_quads_level[level];
-
- // update total number of quads
- number_cache.n_quads += number_cache.n_quads_level[level];
- }
-
- // do the update for the number of
- // active quads as well
- for (unsigned int level=0; level<number_cache.n_levels; ++level)
- {
- // count quads on this level
- number_cache.n_active_quads_level[level] = 0;
-
- active_quad_iterator quad = triangulation.begin_active_quad (level),
- endc = triangulation.end_active_quad (level);
- for (; quad!=endc; ++quad)
- ++number_cache.n_active_quads_level[level];
-
- // update total number of quads
- number_cache.n_active_quads += number_cache.n_active_quads_level[level];
- }
+ for (unsigned int level=0; level<number_cache.n_levels; ++level)
+ {
+ // count quads on this level
+ number_cache.n_quads_level[level] = 0;
+
+ quad_iterator quad = triangulation.begin_quad (level),
+ endc = (level == number_cache.n_levels-1 ?
+ quad_iterator(triangulation.end_quad()) :
+ triangulation.begin_quad (level+1));
+ for (; quad!=endc; ++quad)
+ ++number_cache.n_quads_level[level];
+
+ // update total number of quads
+ number_cache.n_quads += number_cache.n_quads_level[level];
+ }
+
+ // do the update for the number of
+ // active quads as well
+ for (unsigned int level=0; level<number_cache.n_levels; ++level)
+ {
+ // count quads on this level
+ number_cache.n_active_quads_level[level] = 0;
+
+ active_quad_iterator quad = triangulation.begin_active_quad (level),
+ endc = triangulation.end_active_quad (level);
+ for (; quad!=endc; ++quad)
+ ++number_cache.n_active_quads_level[level];
+
+ // update total number of quads
+ number_cache.n_active_quads += number_cache.n_active_quads_level[level];
+ }
}
else
{
- // for dim>2, there are no
- // levels for quads
- {
- quad_iterator quad = triangulation.begin_quad (),
- endc = triangulation.end_quad();
- for (; quad!=endc; ++quad)
- ++number_cache.n_quads;
- }
-
- {
- active_quad_iterator quad = triangulation.begin_active_quad (),
- endc = triangulation.end_quad();
- for (; quad!=endc; ++quad)
- ++number_cache.n_active_quads;
- }
+ // for dim>2, there are no
+ // levels for quads
+ {
+ quad_iterator quad = triangulation.begin_quad (),
+ endc = triangulation.end_quad();
+ for (; quad!=endc; ++quad)
+ ++number_cache.n_quads;
+ }
+
+ {
+ active_quad_iterator quad = triangulation.begin_active_quad (),
+ endc = triangulation.end_quad();
+ for (; quad!=endc; ++quad)
+ ++number_cache.n_active_quads;
+ }
}
}
- /**
- * For a given Triangulation, update the
- * number cache for hexes. For 3d, we have
- * to deal with the fact that hexes have
- * levels, whereas for higher dimensions
- * they do not.
- *
- * The second argument indicates
- * for how many levels the
- * Triangulation has objects,
- * though the highest levels need
- * not contain active cells if they
- * have previously all been
- * coarsened away.
- *
- * At the end of the function, we call the
- * respective function to update the number
- * cache for quads, which will in turn call
- * the respective function for lines.
- */
+ /**
+ * For a given Triangulation, update the
+ * number cache for hexes. For 3d, we have
+ * to deal with the fact that hexes have
+ * levels, whereas for higher dimensions
+ * they do not.
+ *
+ * The second argument indicates
+ * for how many levels the
+ * Triangulation has objects,
+ * though the highest levels need
+ * not contain active cells if they
+ * have previously all been
+ * coarsened away.
+ *
+ * At the end of the function, we call the
+ * respective function to update the number
+ * cache for quads, which will in turn call
+ * the respective function for lines.
+ */
template <int dim, int spacedim>
void compute_number_cache (const Triangulation<dim,spacedim> &triangulation,
- const unsigned int level_objects,
- internal::Triangulation::NumberCache<3> &number_cache)
+ const unsigned int level_objects,
+ internal::Triangulation::NumberCache<3> &number_cache)
{
- // update quads, lines and n_levels
+ // update quads, lines and n_levels
compute_number_cache (triangulation,
- level_objects,
- static_cast<internal::Triangulation::NumberCache<2>&>
- (number_cache));
+ level_objects,
+ static_cast<internal::Triangulation::NumberCache<2>&>
+ (number_cache));
typedef
typename Triangulation<dim,spacedim>::hex_iterator hex_iterator;
typedef
typename Triangulation<dim,spacedim>::active_hex_iterator active_hex_iterator;
- ///////////////////////////////////
- // update the number of hexes
- // on the different levels in
- // the cache
+ ///////////////////////////////////
+ // update the number of hexes
+ // on the different levels in
+ // the cache
number_cache.n_hexes_level.resize (number_cache.n_levels);
number_cache.n_hexes = 0;
number_cache.n_active_hexes_level.resize (number_cache.n_levels);
number_cache.n_active_hexes = 0;
- // for 3d, hexes have levels so take
- // count the objects per level and
- // globally
+ // for 3d, hexes have levels so take
+ // count the objects per level and
+ // globally
if (dim == 3)
{
- for (unsigned int level=0; level<number_cache.n_levels; ++level)
- {
- // count hexes on this level
- number_cache.n_hexes_level[level] = 0;
-
- hex_iterator hex = triangulation.begin_hex (level),
- endc = (level == number_cache.n_levels-1 ?
- hex_iterator(triangulation.end_hex()) :
- triangulation.begin_hex (level+1));
- for (; hex!=endc; ++hex)
- ++number_cache.n_hexes_level[level];
-
- // update total number of hexes
- number_cache.n_hexes += number_cache.n_hexes_level[level];
- }
-
- // do the update for the number of
- // active hexes as well
- for (unsigned int level=0; level<number_cache.n_levels; ++level)
- {
- // count hexes on this level
- number_cache.n_active_hexes_level[level] = 0;
-
- active_hex_iterator hex = triangulation.begin_active_hex (level),
- endc = triangulation.end_active_hex (level);
- for (; hex!=endc; ++hex)
- ++number_cache.n_active_hexes_level[level];
-
- // update total number of hexes
- number_cache.n_active_hexes += number_cache.n_active_hexes_level[level];
- }
+ for (unsigned int level=0; level<number_cache.n_levels; ++level)
+ {
+ // count hexes on this level
+ number_cache.n_hexes_level[level] = 0;
+
+ hex_iterator hex = triangulation.begin_hex (level),
+ endc = (level == number_cache.n_levels-1 ?
+ hex_iterator(triangulation.end_hex()) :
+ triangulation.begin_hex (level+1));
+ for (; hex!=endc; ++hex)
+ ++number_cache.n_hexes_level[level];
+
+ // update total number of hexes
+ number_cache.n_hexes += number_cache.n_hexes_level[level];
+ }
+
+ // do the update for the number of
+ // active hexes as well
+ for (unsigned int level=0; level<number_cache.n_levels; ++level)
+ {
+ // count hexes on this level
+ number_cache.n_active_hexes_level[level] = 0;
+
+ active_hex_iterator hex = triangulation.begin_active_hex (level),
+ endc = triangulation.end_active_hex (level);
+ for (; hex!=endc; ++hex)
+ ++number_cache.n_active_hexes_level[level];
+
+ // update total number of hexes
+ number_cache.n_active_hexes += number_cache.n_active_hexes_level[level];
+ }
}
else
{
- // for dim>3, there are no
- // levels for hexs
- {
- hex_iterator hex = triangulation.begin_hex (),
- endc = triangulation.end_hex();
- for (; hex!=endc; ++hex)
- ++number_cache.n_hexes;
- }
-
- {
- active_hex_iterator hex = triangulation.begin_active_hex (),
- endc = triangulation.end_hex();
- for (; hex!=endc; ++hex)
- ++number_cache.n_active_hexes;
- }
+ // for dim>3, there are no
+ // levels for hexs
+ {
+ hex_iterator hex = triangulation.begin_hex (),
+ endc = triangulation.end_hex();
+ for (; hex!=endc; ++hex)
+ ++number_cache.n_hexes;
+ }
+
+ {
+ active_hex_iterator hex = triangulation.begin_active_hex (),
+ endc = triangulation.end_hex();
+ for (; hex!=endc; ++hex)
+ ++number_cache.n_active_hexes;
+ }
}
}
- /**
- * A set of three functions that
- * reorder the data given to
- * create_triangulation_compatibility
- * from the "classic" to the
- * "current" format of vertex
- * numbering of cells and
- * faces. These functions do the
- * reordering of their arguments
- * in-place.
- */
+ /**
+ * A set of three functions that
+ * reorder the data given to
+ * create_triangulation_compatibility
+ * from the "classic" to the
+ * "current" format of vertex
+ * numbering of cells and
+ * faces. These functions do the
+ * reordering of their arguments
+ * in-place.
+ */
void
reorder_compatibility (const std::vector<CellData<1> > &,
- const SubCellData &)
+ const SubCellData &)
{
- // nothing to do here: the format
- // hasn't changed for 1d
+ // nothing to do here: the format
+ // hasn't changed for 1d
}
void
reorder_compatibility (std::vector<CellData<2> > &cells,
- const SubCellData &)
+ const SubCellData &)
{
for (unsigned int cell=0; cell<cells.size(); ++cell)
std::swap(cells[cell].vertices[2],cells[cell].vertices[3]);
void
reorder_compatibility (std::vector<CellData<3> > &cells,
- SubCellData &subcelldata)
+ SubCellData &subcelldata)
{
unsigned int tmp[GeometryInfo<3>::vertices_per_cell];
for (unsigned int cell=0; cell<cells.size(); ++cell)
{
- for (unsigned int i=0; i<GeometryInfo<3>::vertices_per_cell; ++i)
- tmp[i] = cells[cell].vertices[i];
- for (unsigned int i=0; i<GeometryInfo<3>::vertices_per_cell; ++i)
- cells[cell].vertices[GeometryInfo<3>::ucd_to_deal[i]] = tmp[i];
+ for (unsigned int i=0; i<GeometryInfo<3>::vertices_per_cell; ++i)
+ tmp[i] = cells[cell].vertices[i];
+ for (unsigned int i=0; i<GeometryInfo<3>::vertices_per_cell; ++i)
+ cells[cell].vertices[GeometryInfo<3>::ucd_to_deal[i]] = tmp[i];
}
- // now points in boundary quads
+ // now points in boundary quads
std::vector<CellData<2> >::iterator boundary_quad
= subcelldata.boundary_quads.begin();
std::vector<CellData<2> >::iterator end_quad
- /**
- * Return the index of the vertex
- * in the middle of this object,
- * if it exists. In order to
- * exist, the object needs to be
- * refined - for 2D and 3D it
- * needs to be refined
- * isotropically or else the
- * anisotropic children have to
- * be refined again. If the
- * middle vertex does not exist,
- * return
- * <tt>numbers::invalid_unsigned_int</tt>.
- *
- * This function should not really be
- * used in application programs.
- */
+ /**
+ * Return the index of the vertex
+ * in the middle of this object,
+ * if it exists. In order to
+ * exist, the object needs to be
+ * refined - for 2D and 3D it
+ * needs to be refined
+ * isotropically or else the
+ * anisotropic children have to
+ * be refined again. If the
+ * middle vertex does not exist,
+ * return
+ * <tt>numbers::invalid_unsigned_int</tt>.
+ *
+ * This function should not really be
+ * used in application programs.
+ */
template <int dim, int spacedim>
unsigned int
middle_vertex_index(const typename Triangulation<dim,spacedim>::line_iterator &line)
{
switch (static_cast<unsigned char> (quad->refinement_case()))
{
- case RefinementCase<2>::cut_x:
- return middle_vertex_index<dim,spacedim>(quad->child(0)->line(1));
- break;
- case RefinementCase<2>::cut_y:
- return middle_vertex_index<dim,spacedim>(quad->child(0)->line(3));
- break;
- case RefinementCase<2>::cut_xy:
- return quad->child(0)->vertex_index(3);
- break;
- default:
- break;
+ case RefinementCase<2>::cut_x:
+ return middle_vertex_index<dim,spacedim>(quad->child(0)->line(1));
+ break;
+ case RefinementCase<2>::cut_y:
+ return middle_vertex_index<dim,spacedim>(quad->child(0)->line(3));
+ break;
+ case RefinementCase<2>::cut_xy:
+ return quad->child(0)->vertex_index(3);
+ break;
+ default:
+ break;
}
return numbers::invalid_unsigned_int;
}
{
switch (static_cast<unsigned char> (hex->refinement_case()))
{
- case RefinementCase<3>::cut_x:
- return middle_vertex_index<dim,spacedim>(hex->child(0)->quad(1));
- break;
- case RefinementCase<3>::cut_y:
- return middle_vertex_index<dim,spacedim>(hex->child(0)->quad(3));
- break;
- case RefinementCase<3>::cut_z:
- return middle_vertex_index<dim,spacedim>(hex->child(0)->quad(5));
- break;
- case RefinementCase<3>::cut_xy:
- return middle_vertex_index<dim,spacedim>(hex->child(0)->line(11));
- break;
- case RefinementCase<3>::cut_xz:
- return middle_vertex_index<dim,spacedim>(hex->child(0)->line(5));
- break;
- case RefinementCase<3>::cut_yz:
- return middle_vertex_index<dim,spacedim>(hex->child(0)->line(7));
- break;
- case RefinementCase<3>::cut_xyz:
- return hex->child(0)->vertex_index(7);
- break;
- default:
- break;
+ case RefinementCase<3>::cut_x:
+ return middle_vertex_index<dim,spacedim>(hex->child(0)->quad(1));
+ break;
+ case RefinementCase<3>::cut_y:
+ return middle_vertex_index<dim,spacedim>(hex->child(0)->quad(3));
+ break;
+ case RefinementCase<3>::cut_z:
+ return middle_vertex_index<dim,spacedim>(hex->child(0)->quad(5));
+ break;
+ case RefinementCase<3>::cut_xy:
+ return middle_vertex_index<dim,spacedim>(hex->child(0)->line(11));
+ break;
+ case RefinementCase<3>::cut_xz:
+ return middle_vertex_index<dim,spacedim>(hex->child(0)->line(5));
+ break;
+ case RefinementCase<3>::cut_yz:
+ return middle_vertex_index<dim,spacedim>(hex->child(0)->line(7));
+ break;
+ case RefinementCase<3>::cut_xyz:
+ return hex->child(0)->vertex_index(7);
+ break;
+ default:
+ break;
}
return numbers::invalid_unsigned_int;
}
- /**
- * Collect all coarse mesh cells
- * with at least one vertex at
- * which the determinant of the
- * Jacobian is zero or
- * negative. This is the function
- * for the case dim==spacedim.
- */
+ /**
+ * Collect all coarse mesh cells
+ * with at least one vertex at
+ * which the determinant of the
+ * Jacobian is zero or
+ * negative. This is the function
+ * for the case dim==spacedim.
+ */
template <int dim>
typename Triangulation<dim,dim>::DistortedCellList
collect_distorted_coarse_cells (const Triangulation<dim,dim> &triangulation)
{
typename Triangulation<dim,dim>::DistortedCellList distorted_cells;
for (typename Triangulation<dim,dim>::cell_iterator
- cell = triangulation.begin(0); cell != triangulation.end(0); ++cell)
+ cell = triangulation.begin(0); cell != triangulation.end(0); ++cell)
{
- Point<dim> vertices[GeometryInfo<dim>::vertices_per_cell];
- for (unsigned int i=0; i<GeometryInfo<dim>::vertices_per_cell; ++i)
- vertices[i] = cell->vertex(i);
-
- Tensor<0,dim> determinants[GeometryInfo<dim>::vertices_per_cell];
- GeometryInfo<dim>::alternating_form_at_vertices (vertices,
- determinants);
-
- for (unsigned int i=0; i<GeometryInfo<dim>::vertices_per_cell; ++i)
- if (determinants[i] <= 1e-9 * std::pow (cell->diameter(),
- 1.*dim))
- {
- distorted_cells.distorted_cells.push_back (cell);
- break;
- }
+ Point<dim> vertices[GeometryInfo<dim>::vertices_per_cell];
+ for (unsigned int i=0; i<GeometryInfo<dim>::vertices_per_cell; ++i)
+ vertices[i] = cell->vertex(i);
+
+ Tensor<0,dim> determinants[GeometryInfo<dim>::vertices_per_cell];
+ GeometryInfo<dim>::alternating_form_at_vertices (vertices,
+ determinants);
+
+ for (unsigned int i=0; i<GeometryInfo<dim>::vertices_per_cell; ++i)
+ if (determinants[i] <= 1e-9 * std::pow (cell->diameter(),
+ 1.*dim))
+ {
+ distorted_cells.distorted_cells.push_back (cell);
+ break;
+ }
}
return distorted_cells;
}
- /**
- * Collect all coarse mesh cells
- * with at least one vertex at
- * which the determinant of the
- * Jacobian is zero or
- * negative. This is the function
- * for the case dim!=spacedim,
- * where we can not determine
- * whether a cell is twisted as it
- * may, for example, discretize a
- * manifold with a twist.
- */
+ /**
+ * Collect all coarse mesh cells
+ * with at least one vertex at
+ * which the determinant of the
+ * Jacobian is zero or
+ * negative. This is the function
+ * for the case dim!=spacedim,
+ * where we can not determine
+ * whether a cell is twisted as it
+ * may, for example, discretize a
+ * manifold with a twist.
+ */
template <int dim, int spacedim>
typename Triangulation<dim,spacedim>::DistortedCellList
collect_distorted_coarse_cells (const Triangulation<dim,spacedim> &)
- /**
- * Return whether any of the
- * children of the given cell is
- * distorted or not. This is the
- * function for dim==spacedim.
- */
+ /**
+ * Return whether any of the
+ * children of the given cell is
+ * distorted or not. This is the
+ * function for dim==spacedim.
+ */
template <int dim>
bool
has_distorted_children (const typename Triangulation<dim,dim>::cell_iterator &cell,
- internal::int2type<dim>,
- internal::int2type<dim>)
+ internal::int2type<dim>,
+ internal::int2type<dim>)
{
Assert (cell->has_children(), ExcInternalError());
for (unsigned int c=0; c<cell->n_children(); ++c)
{
- Point<dim> vertices[GeometryInfo<dim>::vertices_per_cell];
- for (unsigned int i=0; i<GeometryInfo<dim>::vertices_per_cell; ++i)
- vertices[i] = cell->child(c)->vertex(i);
-
- Tensor<0,dim> determinants[GeometryInfo<dim>::vertices_per_cell];
- GeometryInfo<dim>::alternating_form_at_vertices (vertices,
- determinants);
-
- for (unsigned int i=0; i<GeometryInfo<dim>::vertices_per_cell; ++i)
- if (determinants[i] <= 1e-9 * std::pow (cell->child(c)->diameter(),
- 1.*dim))
- return true;
+ Point<dim> vertices[GeometryInfo<dim>::vertices_per_cell];
+ for (unsigned int i=0; i<GeometryInfo<dim>::vertices_per_cell; ++i)
+ vertices[i] = cell->child(c)->vertex(i);
+
+ Tensor<0,dim> determinants[GeometryInfo<dim>::vertices_per_cell];
+ GeometryInfo<dim>::alternating_form_at_vertices (vertices,
+ determinants);
+
+ for (unsigned int i=0; i<GeometryInfo<dim>::vertices_per_cell; ++i)
+ if (determinants[i] <= 1e-9 * std::pow (cell->child(c)->diameter(),
+ 1.*dim))
+ return true;
}
return false;
}
- /**
- * Function for dim!=spacedim. As
- * for
- * collect_distorted_coarse_cells,
- * there is nothing that we can do
- * in this case.
- */
+ /**
+ * Function for dim!=spacedim. As
+ * for
+ * collect_distorted_coarse_cells,
+ * there is nothing that we can do
+ * in this case.
+ */
template <int dim, int spacedim>
bool
has_distorted_children (const typename Triangulation<dim,spacedim>::cell_iterator &,
- internal::int2type<dim>,
- internal::int2type<spacedim>)
+ internal::int2type<dim>,
+ internal::int2type<spacedim>)
{
return false;
}
- /**
- * For a given triangulation: set up the
- * neighbor information on all cells.
- */
+ /**
+ * For a given triangulation: set up the
+ * neighbor information on all cells.
+ */
template <int spacedim>
void
update_neighbors (Triangulation<1,spacedim> &/*triangulation*/)
void
update_neighbors (Triangulation<dim,spacedim> &triangulation)
{
- // each face can be neighbored on two sides
- // by cells. according to the face's
- // intrinsic normal we define the left
- // neighbor as the one for which the face
- // normal points outward, and store that
- // one first; the second one is then
- // the right neighbor for which the
- // face normal points inward. This
- // information depends on the type of cell
- // and local number of face for the
- // 'standard ordering and orientation' of
- // faces and then on the face_orientation
- // information for the real mesh. Set up a
- // table to have fast access to those
- // offsets (0 for left and 1 for
- // right). Some of the values are invalid
- // as they reference too large face
- // numbers, but we just leave them at a
- // zero value.
- //
- // Note, that in 2d for lines as faces the
- // normal direction given in the
- // GeometryInfo class is not consistent. We
- // thus define here that the normal for a
- // line points to the right if the line
- // points upwards.
- //
- // There is one more point to
- // consider, however: if we have
- // dim<spacedim, then we may have
- // cases where cells are
- // inverted. In effect, both
- // cells think they are the left
- // neighbor of an edge, for
- // example, which leads us to
- // forget neighborship
- // information (a case that shows
- // this is
- // codim_one/hanging_nodes_02). We
- // store whether a cell is
- // inverted using the
- // direction_flag, so if a cell
- // has a false direction_flag,
- // then we need to invert our
- // selection whether we are a
- // left or right neighbor in all
- // following computations.
- //
- // first index: dimension (minus 2)
- // second index: local face index
- // third index: face_orientation (false and true)
+ // each face can be neighbored on two sides
+ // by cells. according to the face's
+ // intrinsic normal we define the left
+ // neighbor as the one for which the face
+ // normal points outward, and store that
+ // one first; the second one is then
+ // the right neighbor for which the
+ // face normal points inward. This
+ // information depends on the type of cell
+ // and local number of face for the
+ // 'standard ordering and orientation' of
+ // faces and then on the face_orientation
+ // information for the real mesh. Set up a
+ // table to have fast access to those
+ // offsets (0 for left and 1 for
+ // right). Some of the values are invalid
+ // as they reference too large face
+ // numbers, but we just leave them at a
+ // zero value.
+ //
+ // Note, that in 2d for lines as faces the
+ // normal direction given in the
+ // GeometryInfo class is not consistent. We
+ // thus define here that the normal for a
+ // line points to the right if the line
+ // points upwards.
+ //
+ // There is one more point to
+ // consider, however: if we have
+ // dim<spacedim, then we may have
+ // cases where cells are
+ // inverted. In effect, both
+ // cells think they are the left
+ // neighbor of an edge, for
+ // example, which leads us to
+ // forget neighborship
+ // information (a case that shows
+ // this is
+ // codim_one/hanging_nodes_02). We
+ // store whether a cell is
+ // inverted using the
+ // direction_flag, so if a cell
+ // has a false direction_flag,
+ // then we need to invert our
+ // selection whether we are a
+ // left or right neighbor in all
+ // following computations.
+ //
+ // first index: dimension (minus 2)
+ // second index: local face index
+ // third index: face_orientation (false and true)
static const unsigned int left_right_offset[2][6][2] =
{
- // quadrilateral
- {{0,1}, // face 0, face_orientation = false and true
- {1,0}, // face 1, face_orientation = false and true
- {1,0}, // face 2, face_orientation = false and true
- {0,1}, // face 3, face_orientation = false and true
- {0,0}, // face 4, invalid face
- {0,0}},// face 5, invalid face
- // hexahedron
- {{0,1},
- {1,0},
- {0,1},
- {1,0},
- {0,1},
- {1,0}}};
-
- // now create a vector of the two active
- // neighbors (left and right) for each face
- // and fill it by looping over all cells. For
- // cases with anisotropic refinement and more
- // then one cell neighboring at a given side
- // of the face we will automatically get the
- // active one on the highest level as we loop
- // over cells from lower levels first.
+ // quadrilateral
+ {{0,1}, // face 0, face_orientation = false and true
+ {1,0}, // face 1, face_orientation = false and true
+ {1,0}, // face 2, face_orientation = false and true
+ {0,1}, // face 3, face_orientation = false and true
+ {0,0}, // face 4, invalid face
+ {0,0}},// face 5, invalid face
+ // hexahedron
+ {{0,1},
+ {1,0},
+ {0,1},
+ {1,0},
+ {0,1},
+ {1,0}}};
+
+ // now create a vector of the two active
+ // neighbors (left and right) for each face
+ // and fill it by looping over all cells. For
+ // cases with anisotropic refinement and more
+ // then one cell neighboring at a given side
+ // of the face we will automatically get the
+ // active one on the highest level as we loop
+ // over cells from lower levels first.
const typename Triangulation<dim,spacedim>::cell_iterator dummy;
std::vector<typename Triangulation<dim,spacedim>::cell_iterator>
adjacent_cells(2*triangulation.n_raw_faces(), dummy);
endc = triangulation.end();
for (; cell != endc; ++cell)
for (unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell; ++f)
- {
- const typename Triangulation<dim,spacedim>::face_iterator
- face=cell->face(f);
-
- const unsigned int
- offset = (cell->direction_flag()
- ?
- left_right_offset[dim-2][f][cell->face_orientation(f)]
- :
- 1-left_right_offset[dim-2][f][cell->face_orientation(f)]);
-
- adjacent_cells[2*face->index() + offset] = cell;
-
- // if this cell is not refined, but the
- // face is, then we'll have to set our
- // cell as neighbor for the cild faces
- // as well. Fortunately the normal
- // orientation of children will be just
- // the same.
- if (dim==2)
- {
- if (cell->active() && face->has_children())
- {
- adjacent_cells[2*face->child(0)->index() + offset] = cell;
- adjacent_cells[2*face->child(1)->index() + offset] = cell;
- }
- }
- else // -> dim == 3
- {
- // We need the same as in 2d
- // here. Furthermore, if the face is
- // refined with cut_x or cut_y then
- // those children again in the other
- // direction, and if this cell is
- // refined isotropically (along the
- // face) then the neighbor will
- // (probably) be refined as cut_x or
- // cut_y along the face. For those
- // neighboring children cells, their
- // neighbor will be the current,
- // inactive cell, as our children are
- // too fine to be neighbors. Catch that
- // case by also acting on inactive
- // cells with isotropic refinement
- // along the face. If the situation
- // described is not present, the data
- // will be overwritten later on when we
- // visit cells on finer levels, so no
- // harm will be done.
- if (face->has_children() &&
- (cell->active() ||
- GeometryInfo<dim>::face_refinement_case(cell->refinement_case(),f) == RefinementCase<dim-1>::isotropic_refinement))
- {
-
- for (unsigned int c=0; c<face->n_children(); ++c)
- adjacent_cells[2*face->child(c)->index() + offset] = cell;
- if (face->child(0)->has_children())
- {
- adjacent_cells[2*face->child(0)->child(0)->index() + offset] = cell;
- adjacent_cells[2*face->child(0)->child(1)->index() + offset] = cell;
- }
- if (face->child(1)->has_children())
- {
- adjacent_cells[2*face->child(1)->child(0)->index() + offset] = cell;
- adjacent_cells[2*face->child(1)->child(1)->index() + offset] = cell;
- }
- } // if cell active and face refined
- } // else -> dim==3
- } // for all faces of all cells
-
- // now loop again over all cells and set the
- // corresponding neighbor cell. Note, that we
- // have to use the opposite of the
- // left_right_offset in this case as we want
- // the offset of the neighbor, not our own.
+ {
+ const typename Triangulation<dim,spacedim>::face_iterator
+ face=cell->face(f);
+
+ const unsigned int
+ offset = (cell->direction_flag()
+ ?
+ left_right_offset[dim-2][f][cell->face_orientation(f)]
+ :
+ 1-left_right_offset[dim-2][f][cell->face_orientation(f)]);
+
+ adjacent_cells[2*face->index() + offset] = cell;
+
+ // if this cell is not refined, but the
+ // face is, then we'll have to set our
+ // cell as neighbor for the cild faces
+ // as well. Fortunately the normal
+ // orientation of children will be just
+ // the same.
+ if (dim==2)
+ {
+ if (cell->active() && face->has_children())
+ {
+ adjacent_cells[2*face->child(0)->index() + offset] = cell;
+ adjacent_cells[2*face->child(1)->index() + offset] = cell;
+ }
+ }
+ else // -> dim == 3
+ {
+ // We need the same as in 2d
+ // here. Furthermore, if the face is
+ // refined with cut_x or cut_y then
+ // those children again in the other
+ // direction, and if this cell is
+ // refined isotropically (along the
+ // face) then the neighbor will
+ // (probably) be refined as cut_x or
+ // cut_y along the face. For those
+ // neighboring children cells, their
+ // neighbor will be the current,
+ // inactive cell, as our children are
+ // too fine to be neighbors. Catch that
+ // case by also acting on inactive
+ // cells with isotropic refinement
+ // along the face. If the situation
+ // described is not present, the data
+ // will be overwritten later on when we
+ // visit cells on finer levels, so no
+ // harm will be done.
+ if (face->has_children() &&
+ (cell->active() ||
+ GeometryInfo<dim>::face_refinement_case(cell->refinement_case(),f) == RefinementCase<dim-1>::isotropic_refinement))
+ {
+
+ for (unsigned int c=0; c<face->n_children(); ++c)
+ adjacent_cells[2*face->child(c)->index() + offset] = cell;
+ if (face->child(0)->has_children())
+ {
+ adjacent_cells[2*face->child(0)->child(0)->index() + offset] = cell;
+ adjacent_cells[2*face->child(0)->child(1)->index() + offset] = cell;
+ }
+ if (face->child(1)->has_children())
+ {
+ adjacent_cells[2*face->child(1)->child(0)->index() + offset] = cell;
+ adjacent_cells[2*face->child(1)->child(1)->index() + offset] = cell;
+ }
+ } // if cell active and face refined
+ } // else -> dim==3
+ } // for all faces of all cells
+
+ // now loop again over all cells and set the
+ // corresponding neighbor cell. Note, that we
+ // have to use the opposite of the
+ // left_right_offset in this case as we want
+ // the offset of the neighbor, not our own.
for (cell=triangulation.begin(); cell != endc; ++cell)
for (unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell; ++f)
- {
- const unsigned int
- offset = (cell->direction_flag()
- ?
- left_right_offset[dim-2][f][cell->face_orientation(f)]
- :
- 1-left_right_offset[dim-2][f][cell->face_orientation(f)]);
- cell->set_neighbor(f,
- adjacent_cells[2*cell->face(f)->index() + 1 - offset]);
- }
+ {
+ const unsigned int
+ offset = (cell->direction_flag()
+ ?
+ left_right_offset[dim-2][f][cell->face_orientation(f)]
+ :
+ 1-left_right_offset[dim-2][f][cell->face_orientation(f)]);
+ cell->set_neighbor(f,
+ adjacent_cells[2*cell->face(f)->index() + 1 - offset]);
+ }
}
}// end of anonymous namespace
{
namespace Triangulation
{
- // make sure that if in the following we
- // write Triangulation<dim,spacedim>
- // we mean the *class*
- // dealii::Triangulation, not the
- // enclosing namespace
- // internal::Triangulation
+ // make sure that if in the following we
+ // write Triangulation<dim,spacedim>
+ // we mean the *class*
+ // dealii::Triangulation, not the
+ // enclosing namespace
+ // internal::Triangulation
using dealii::Triangulation;
- /**
- * Exception
- * @ingroup Exceptions
- */
+ /**
+ * Exception
+ * @ingroup Exceptions
+ */
DeclException0 (ExcCellShouldBeUnused);
- /**
- * Exception
- * @ingroup Exceptions
- */
+ /**
+ * Exception
+ * @ingroup Exceptions
+ */
DeclException0 (ExcTooFewVerticesAllocated);
- /**
- * Exception
- * @ingroup Exceptions
- */
+ /**
+ * Exception
+ * @ingroup Exceptions
+ */
DeclException0 (ExcUncaughtState);
- /**
- * Exception
- * @ingroup Exceptions
- */
+ /**
+ * Exception
+ * @ingroup Exceptions
+ */
DeclException2 (ExcGridsDoNotMatch,
- int, int,
- << "The present grid has " << arg1 << " active cells, "
- << "but the one in the file had " << arg2);
- /**
- * Exception
- * @ingroup Exceptions
- */
+ int, int,
+ << "The present grid has " << arg1 << " active cells, "
+ << "but the one in the file had " << arg2);
+ /**
+ * Exception
+ * @ingroup Exceptions
+ */
DeclException1 (ExcGridHasInvalidCell,
- int,
- << "Something went wrong when making cell " << arg1
- << ". Read the docs and the source code "
- << "for more information.");
- /**
- * Exception
- * @ingroup Exceptions
- */
+ int,
+ << "Something went wrong when making cell " << arg1
+ << ". Read the docs and the source code "
+ << "for more information.");
+ /**
+ * Exception
+ * @ingroup Exceptions
+ */
DeclException0 (ExcGridHasInvalidVertices);
- /**
- * Exception
- * @ingroup Exceptions
- */
+ /**
+ * Exception
+ * @ingroup Exceptions
+ */
DeclException1 (ExcInternalErrorOnCell,
- int,
- << "Something went wrong upon construction of cell "
- << arg1);
- /**
- * A cell was entered which has
- * negative measure. In most
- * cases, this is due to a wrong
- * order of the vertices of the
- * cell.
- *
- * @ingroup Exceptions
- */
+ int,
+ << "Something went wrong upon construction of cell "
+ << arg1);
+ /**
+ * A cell was entered which has
+ * negative measure. In most
+ * cases, this is due to a wrong
+ * order of the vertices of the
+ * cell.
+ *
+ * @ingroup Exceptions
+ */
DeclException1 (ExcCellHasNegativeMeasure,
- int,
- << "Cell " << arg1 << " has negative measure.");
- /**
- * A cell is created with a
- * vertex number exceeding the
- * vertex array.
- *
- * @ingroup Exceptions
- */
+ int,
+ << "Cell " << arg1 << " has negative measure.");
+ /**
+ * A cell is created with a
+ * vertex number exceeding the
+ * vertex array.
+ *
+ * @ingroup Exceptions
+ */
DeclException3 (ExcInvalidVertexIndex,
- int, int, int,
- << "Error while creating cell " << arg1
- << ": the vertex index " << arg2 << " must be between 0 and "
- << arg3 << ".");
- /**
- * Exception
- * @ingroup Exceptions
- */
+ int, int, int,
+ << "Error while creating cell " << arg1
+ << ": the vertex index " << arg2 << " must be between 0 and "
+ << arg3 << ".");
+ /**
+ * Exception
+ * @ingroup Exceptions
+ */
DeclException2 (ExcLineInexistant,
- int, int,
- << "When trying to give a boundary indicator to a line: "
- << "the line with end vertices " << arg1 << " and "
- << arg2 << " does not exist.");
- /**
- * Exception
- * @ingroup Exceptions
- */
+ int, int,
+ << "When trying to give a boundary indicator to a line: "
+ << "the line with end vertices " << arg1 << " and "
+ << arg2 << " does not exist.");
+ /**
+ * Exception
+ * @ingroup Exceptions
+ */
DeclException4 (ExcQuadInexistant,
int, int, int, int,
- << "When trying to give a boundary indicator to a quad: "
- << "the quad with bounding lines " << arg1 << ", " << arg2
- << ", " << arg3 << ", " << arg4 << " does not exist.");
- /**
- * Exception
- * @ingroup Exceptions
- */
+ << "When trying to give a boundary indicator to a quad: "
+ << "the quad with bounding lines " << arg1 << ", " << arg2
+ << ", " << arg3 << ", " << arg4 << " does not exist.");
+ /**
+ * Exception
+ * @ingroup Exceptions
+ */
DeclException0 (ExcInteriorLineCantBeBoundary);
- /**
- * Exception
- * @ingroup Exceptions
- */
+ /**
+ * Exception
+ * @ingroup Exceptions
+ */
DeclException0 (ExcInteriorQuadCantBeBoundary);
- /**
- * Exception
- * @ingroup Exceptions
- */
+ /**
+ * Exception
+ * @ingroup Exceptions
+ */
DeclException2 (ExcMultiplySetLineInfoOfLine,
- int, int,
- << "In SubCellData the line info of the line with vertex indices "
- << arg1 << " and " << arg2 << " is multiply set.");
+ int, int,
+ << "In SubCellData the line info of the line with vertex indices "
+ << arg1 << " and " << arg2 << " is multiply set.");
/**
*/
struct Implementation
{
- /**
- * Create a triangulation from
- * given data. This function does
- * this work for 1-dimensional
- * triangulations independently
- * of the actual space dimension.
- */
- template <int spacedim>
- static
- void
- create_triangulation (const std::vector<Point<spacedim> > &v,
- const std::vector<CellData<1> > &cells,
- const SubCellData &/*subcelldata*/,
- Triangulation<1,spacedim> &triangulation)
- {
- AssertThrow (v.size() > 0, ExcMessage ("No vertices given"));
- AssertThrow (cells.size() > 0, ExcMessage ("No cells given"));
-
- // note: since no boundary
- // information can be given in one
- // dimension, the @p{subcelldata}
- // field is ignored. (only used for
- // error checking, which is a good
- // idea in any case)
- const unsigned int dim=1;
-
- // copy vertices
- triangulation.vertices = v;
- triangulation.vertices_used = std::vector<bool> (v.size(), true);
-
- // store the indices of the lines
- // which are adjacent to a given
- // vertex
- std::vector<std::vector<int> > lines_at_vertex (v.size());
-
- // reserve enough space
- triangulation.levels.push_back (new internal::Triangulation::TriaLevel<dim>);
- triangulation.levels[0]->reserve_space (cells.size(), dim, spacedim);
- triangulation.levels[0]->cells.reserve_space (0,cells.size());
-
- // make up cells
- typename Triangulation<dim,spacedim>::raw_line_iterator
- next_free_line = triangulation.begin_raw_line ();
- for (unsigned int cell=0; cell<cells.size(); ++cell)
- {
- while (next_free_line->used())
- ++next_free_line;
-
- next_free_line->set (internal::Triangulation
- ::TriaObject<1> (cells[cell].vertices[0],
- cells[cell].vertices[1]));
- next_free_line->set_used_flag ();
- next_free_line->set_material_id (cells[cell].material_id);
- next_free_line->clear_user_data ();
- next_free_line->set_subdomain_id (0);
-
- // note that this cell is
- // adjacent to these vertices
- lines_at_vertex[cells[cell].vertices[0]].push_back (cell);
- lines_at_vertex[cells[cell].vertices[1]].push_back (cell);
- }
-
-
- // some security tests
- {
- unsigned int boundary_nodes = 0;
- for (unsigned int i=0; i<lines_at_vertex.size(); ++i)
- switch (lines_at_vertex[i].size())
- {
- case 1:
- // this vertex has only
- // one adjacent line
- ++boundary_nodes;
- break;
- case 2:
- break;
- default:
- // a node must have one
- // or two adjacent
- // lines
- AssertThrow (false, ExcInternalError());
- }
-
- // assert there are no more
- // than two boundary
- // nodes. note that if the
- // space dimension is
- // bigger than 1, then we
- // can have fewer than 2
- // nodes (for example a
- // ring of cells -- no end
- // points at all)
- AssertThrow (((spacedim == 1) && (boundary_nodes == 2))
- ||
- (spacedim > 1),
- ExcMessage("The Triangulation has too many end points"));
- }
-
-
-
- // update neighborship info
- typename Triangulation<dim,spacedim>::active_line_iterator
- line = triangulation.begin_active_line ();
- // for all lines
- for (; line!=triangulation.end(); ++line)
- // for each of the two vertices
- for (unsigned int vertex=0; vertex<GeometryInfo<dim>::vertices_per_cell; ++vertex)
- // if first cell adjacent to
- // this vertex is the present
- // one, then the neighbor is
- // the second adjacent cell and
- // vice versa
- if (lines_at_vertex[line->vertex_index(vertex)][0] == line->index())
- if (lines_at_vertex[line->vertex_index(vertex)].size() == 2)
- {
- const typename Triangulation<dim,spacedim>::cell_iterator
- neighbor (&triangulation,
- 0, // level
- lines_at_vertex[line->vertex_index(vertex)][1]);
- line->set_neighbor (vertex, neighbor);
- }
- else
- // no second adjacent cell
- // entered -> cell at
- // boundary
- line->set_neighbor (vertex, triangulation.end());
- else
- // present line is not first
- // adjacent one -> first
- // adjacent one is neighbor
- {
- const typename Triangulation<dim,spacedim>::cell_iterator
- neighbor (&triangulation,
- 0, // level
- lines_at_vertex[line->vertex_index(vertex)][0]);
- line->set_neighbor (vertex, neighbor);
- }
-
- // finally set the
- // vertex_to_boundary_id_map_1d
- // map
- triangulation.vertex_to_boundary_id_map_1d->clear();
- for (typename Triangulation<dim,spacedim>::active_cell_iterator
- cell = triangulation.begin_active();
- cell != triangulation.end(); ++cell)
- for (unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell; ++f)
- if (cell->at_boundary(f))
- (*triangulation
- .vertex_to_boundary_id_map_1d)[cell->face(f)->vertex_index()]
- = f;
- }
-
-
- /**
- * Create a triangulation from
- * given data. This function does
- * this work for 2-dimensional
- * triangulations independently
- * of the actual space dimension.
- */
- template <int spacedim>
- static
- void
- create_triangulation (const std::vector<Point<spacedim> > &v,
- const std::vector<CellData<2> > &cells,
- const SubCellData &subcelldata,
- Triangulation<2,spacedim> &triangulation)
- {
- AssertThrow (v.size() > 0, ExcMessage ("No vertices given"));
- AssertThrow (cells.size() > 0, ExcMessage ("No cells given"));
-
- const unsigned int dim=2;
-
- // copy vertices
- triangulation.vertices = v;
- triangulation.vertices_used = std::vector<bool> (v.size(), true);
-
- // make up a list of the needed
- // lines each line is a pair of
- // vertices. The list is kept
- // sorted and it is guaranteed that
- // each line is inserted only once.
- // While the key of such an entry
- // is the pair of vertices, the
- // thing it points to is an
- // iterator pointing to the line
- // object itself. In the first run,
- // these iterators are all invalid
- // ones, but they are filled
- // afterwards
- std::map<std::pair<int,int>,
- typename Triangulation<dim,spacedim>::line_iterator> needed_lines;
- for (unsigned int cell=0; cell<cells.size(); ++cell)
- {
- for (unsigned int vertex=0; vertex<4; ++vertex)
- AssertThrow (cells[cell].vertices[vertex] < triangulation.vertices.size(),
- ExcInvalidVertexIndex (cell, cells[cell].vertices[vertex],
- triangulation.vertices.size()));
-
- for (unsigned int line=0; line<GeometryInfo<dim>::faces_per_cell; ++line)
- {
- // given a line vertex number
- // (0,1) on a specific line we
- // get the cell vertex number
- // (0-4) through the
- // line_to_cell_vertices
- // function
- std::pair<int,int> line_vertices(
- cells[cell].vertices[GeometryInfo<dim>::line_to_cell_vertices(line, 0)],
- cells[cell].vertices[GeometryInfo<dim>::line_to_cell_vertices(line, 1)]);
-
- // assert that the line was
- // not already inserted in
- // reverse order. This
- // happens in spite of the
- // vertex rotation above,
- // if the sense of the cell
- // was incorrect.
- //
- // Here is what usually
- // happened when this
- // exception is thrown:
- // consider these two cells
- // and the vertices
- // 3---4---5
- // | | |
- // 0---1---2
- // If in the input vector
- // the two cells are given
- // with vertices <0 1 4 3>
- // and <4 1 2 5>, in the
- // first cell the middle
- // line would have
- // direction 1->4, while in
- // the second it would be
- // 4->1. This will cause
- // the exception.
- AssertThrow (needed_lines.find(std::make_pair(line_vertices.second,
- line_vertices.first))
- ==
- needed_lines.end(),
- ExcGridHasInvalidCell(cell));
-
- // insert line, with
- // invalid iterator if line
- // already exists, then
- // nothing bad happens here
- needed_lines[line_vertices] = triangulation.end_line();
- }
- }
-
-
- // check that every vertex has at
- // least two adjacent lines
- {
- std::vector<unsigned short int> vertex_touch_count (v.size(), 0);
- typename std::map<std::pair<int,int>,
- typename Triangulation<dim,spacedim>::line_iterator>::iterator i;
- for (i=needed_lines.begin(); i!=needed_lines.end(); i++)
- {
- // touch the vertices of
- // this line
- ++vertex_touch_count[i->first.first];
- ++vertex_touch_count[i->first.second];
- }
-
- // assert minimum touch count
- // is at least two. if not so,
- // then clean triangulation and
- // exit with an exception
- AssertThrow (* (std::min_element(vertex_touch_count.begin(),
- vertex_touch_count.end())) >= 2,
- ExcGridHasInvalidVertices());
- }
-
- // reserve enough space
- triangulation.levels.push_back (new internal::Triangulation::TriaLevel<dim>);
- triangulation.faces = new internal::Triangulation::TriaFaces<dim>;
- triangulation.levels[0]->reserve_space (cells.size(), dim, spacedim);
- triangulation.faces->lines.reserve_space (0,needed_lines.size());
- triangulation.levels[0]->cells.reserve_space (0,cells.size());
-
- // make up lines
- {
- typename Triangulation<dim,spacedim>::raw_line_iterator
- line = triangulation.begin_raw_line();
- typename std::map<std::pair<int,int>,
- typename Triangulation<dim,spacedim>::line_iterator>::iterator i;
- for (i = needed_lines.begin();
- line!=triangulation.end_line(); ++line, ++i)
- {
- line->set (internal::Triangulation::TriaObject<1>(i->first.first,
- i->first.second));
- line->set_used_flag ();
- line->clear_user_flag ();
- line->clear_user_data ();
- i->second = line;
- }
- }
-
-
- // store for each line index
- // the adjacent cells
- std::map<int,std::vector<typename Triangulation<dim,spacedim>::cell_iterator> >
- adjacent_cells;
-
- // finally make up cells
- {
- typename Triangulation<dim,spacedim>::raw_cell_iterator
- cell = triangulation.begin_raw_quad();
- for (unsigned int c=0; c<cells.size(); ++c, ++cell)
- {
- typename Triangulation<dim,spacedim>::line_iterator
- lines[GeometryInfo<dim>::lines_per_cell];
- for (unsigned int line=0; line<GeometryInfo<dim>::lines_per_cell; ++line)
- lines[line]=needed_lines[std::make_pair(
- cells[c].vertices[GeometryInfo<dim>::line_to_cell_vertices(line, 0)],
- cells[c].vertices[GeometryInfo<dim>::line_to_cell_vertices(line, 1)])];
-
- cell->set (internal::Triangulation::TriaObject<2> (lines[0]->index(),
- lines[1]->index(),
- lines[2]->index(),
- lines[3]->index()));
-
- cell->set_used_flag ();
- cell->set_material_id (cells[c].material_id);
- cell->clear_user_data ();
- cell->set_subdomain_id (0);
-
- // note that this cell is
- // adjacent to the four
- // lines
- for (unsigned int line=0; line<GeometryInfo<dim>::lines_per_cell; ++line)
- adjacent_cells[lines[line]->index()].push_back (cell);
- }
- }
-
-
- for (typename Triangulation<dim,spacedim>::line_iterator
- line=triangulation.begin_line();
- line!=triangulation.end_line(); ++line)
- {
- const unsigned int n_adj_cells = adjacent_cells[line->index()].size();
- // assert that every line has
- // one or two adjacent cells
- AssertThrow ((n_adj_cells >= 1) &&
- (n_adj_cells <= 2),
- ExcInternalError());
-
- // if only one cell: line is at
- // boundary -> give it the
- // boundary indicator zero by
- // default
- if (n_adj_cells == 1)
- line->set_boundary_indicator (0);
- else
- // interior line -> types::internal_face_boundary_id
- line->set_boundary_indicator (types::internal_face_boundary_id);
- }
-
- // set boundary indicators where
- // given
- std::vector<CellData<1> >::const_iterator boundary_line
- = subcelldata.boundary_lines.begin();
- std::vector<CellData<1> >::const_iterator end_boundary_line
- = subcelldata.boundary_lines.end();
- for (; boundary_line!=end_boundary_line; ++boundary_line)
- {
- typename Triangulation<dim,spacedim>::line_iterator line;
- std::pair<int,int> line_vertices(std::make_pair(boundary_line->vertices[0],
- boundary_line->vertices[1]));
- if (needed_lines.find(line_vertices) != needed_lines.end())
- // line found in this
- // direction
- line = needed_lines[line_vertices];
- else
- {
- // look whether it exists
- // in reverse direction
- std::swap (line_vertices.first, line_vertices.second);
- if (needed_lines.find(line_vertices) != needed_lines.end())
- line = needed_lines[line_vertices];
- else
- // line does not exist
- AssertThrow (false, ExcLineInexistant(line_vertices.first,
- line_vertices.second));
- }
-
- // assert that we only set
- // boundary info once
- AssertThrow (! (line->boundary_indicator() != 0 &&
- line->boundary_indicator() != types::internal_face_boundary_id),
- ExcMultiplySetLineInfoOfLine(line_vertices.first,
- line_vertices.second));
-
- // Assert that only exterior lines
- // are given a boundary indicator
- AssertThrow (! (line->boundary_indicator() == types::internal_face_boundary_id),
- ExcInteriorLineCantBeBoundary());
-
- line->set_boundary_indicator (boundary_line->boundary_id);
- }
-
-
- // finally update neighborship info
- for (typename Triangulation<dim,spacedim>::cell_iterator
- cell=triangulation.begin(); cell!=triangulation.end(); ++cell)
- for (unsigned int side=0; side<4; ++side)
- if (adjacent_cells[cell->line(side)->index()][0] == cell)
- // first adjacent cell is
- // this one
- {
- if (adjacent_cells[cell->line(side)->index()].size() == 2)
- // there is another
- // adjacent cell
- cell->set_neighbor (side,
- adjacent_cells[cell->line(side)->index()][1]);
- }
- // first adjacent cell is not this
- // one, -> it must be the neighbor
- // we are looking for
- else
- cell->set_neighbor (side,
- adjacent_cells[cell->line(side)->index()][0]);
- }
+ /**
+ * Create a triangulation from
+ * given data. This function does
+ * this work for 1-dimensional
+ * triangulations independently
+ * of the actual space dimension.
+ */
+ template <int spacedim>
+ static
+ void
+ create_triangulation (const std::vector<Point<spacedim> > &v,
+ const std::vector<CellData<1> > &cells,
+ const SubCellData &/*subcelldata*/,
+ Triangulation<1,spacedim> &triangulation)
+ {
+ AssertThrow (v.size() > 0, ExcMessage ("No vertices given"));
+ AssertThrow (cells.size() > 0, ExcMessage ("No cells given"));
+
+ // note: since no boundary
+ // information can be given in one
+ // dimension, the @p{subcelldata}
+ // field is ignored. (only used for
+ // error checking, which is a good
+ // idea in any case)
+ const unsigned int dim=1;
+
+ // copy vertices
+ triangulation.vertices = v;
+ triangulation.vertices_used = std::vector<bool> (v.size(), true);
+
+ // store the indices of the lines
+ // which are adjacent to a given
+ // vertex
+ std::vector<std::vector<int> > lines_at_vertex (v.size());
+
+ // reserve enough space
+ triangulation.levels.push_back (new internal::Triangulation::TriaLevel<dim>);
+ triangulation.levels[0]->reserve_space (cells.size(), dim, spacedim);
+ triangulation.levels[0]->cells.reserve_space (0,cells.size());
+
+ // make up cells
+ typename Triangulation<dim,spacedim>::raw_line_iterator
+ next_free_line = triangulation.begin_raw_line ();
+ for (unsigned int cell=0; cell<cells.size(); ++cell)
+ {
+ while (next_free_line->used())
+ ++next_free_line;
+
+ next_free_line->set (internal::Triangulation
+ ::TriaObject<1> (cells[cell].vertices[0],
+ cells[cell].vertices[1]));
+ next_free_line->set_used_flag ();
+ next_free_line->set_material_id (cells[cell].material_id);
+ next_free_line->clear_user_data ();
+ next_free_line->set_subdomain_id (0);
+
+ // note that this cell is
+ // adjacent to these vertices
+ lines_at_vertex[cells[cell].vertices[0]].push_back (cell);
+ lines_at_vertex[cells[cell].vertices[1]].push_back (cell);
+ }
+
+
+ // some security tests
+ {
+ unsigned int boundary_nodes = 0;
+ for (unsigned int i=0; i<lines_at_vertex.size(); ++i)
+ switch (lines_at_vertex[i].size())
+ {
+ case 1:
+ // this vertex has only
+ // one adjacent line
+ ++boundary_nodes;
+ break;
+ case 2:
+ break;
+ default:
+ // a node must have one
+ // or two adjacent
+ // lines
+ AssertThrow (false, ExcInternalError());
+ }
+
+ // assert there are no more
+ // than two boundary
+ // nodes. note that if the
+ // space dimension is
+ // bigger than 1, then we
+ // can have fewer than 2
+ // nodes (for example a
+ // ring of cells -- no end
+ // points at all)
+ AssertThrow (((spacedim == 1) && (boundary_nodes == 2))
+ ||
+ (spacedim > 1),
+ ExcMessage("The Triangulation has too many end points"));
+ }
+
+
+
+ // update neighborship info
+ typename Triangulation<dim,spacedim>::active_line_iterator
+ line = triangulation.begin_active_line ();
+ // for all lines
+ for (; line!=triangulation.end(); ++line)
+ // for each of the two vertices
+ for (unsigned int vertex=0; vertex<GeometryInfo<dim>::vertices_per_cell; ++vertex)
+ // if first cell adjacent to
+ // this vertex is the present
+ // one, then the neighbor is
+ // the second adjacent cell and
+ // vice versa
+ if (lines_at_vertex[line->vertex_index(vertex)][0] == line->index())
+ if (lines_at_vertex[line->vertex_index(vertex)].size() == 2)
+ {
+ const typename Triangulation<dim,spacedim>::cell_iterator
+ neighbor (&triangulation,
+ 0, // level
+ lines_at_vertex[line->vertex_index(vertex)][1]);
+ line->set_neighbor (vertex, neighbor);
+ }
+ else
+ // no second adjacent cell
+ // entered -> cell at
+ // boundary
+ line->set_neighbor (vertex, triangulation.end());
+ else
+ // present line is not first
+ // adjacent one -> first
+ // adjacent one is neighbor
+ {
+ const typename Triangulation<dim,spacedim>::cell_iterator
+ neighbor (&triangulation,
+ 0, // level
+ lines_at_vertex[line->vertex_index(vertex)][0]);
+ line->set_neighbor (vertex, neighbor);
+ }
+
+ // finally set the
+ // vertex_to_boundary_id_map_1d
+ // map
+ triangulation.vertex_to_boundary_id_map_1d->clear();
+ for (typename Triangulation<dim,spacedim>::active_cell_iterator
+ cell = triangulation.begin_active();
+ cell != triangulation.end(); ++cell)
+ for (unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell; ++f)
+ if (cell->at_boundary(f))
+ (*triangulation
+ .vertex_to_boundary_id_map_1d)[cell->face(f)->vertex_index()]
+ = f;
+ }
+
+
+ /**
+ * Create a triangulation from
+ * given data. This function does
+ * this work for 2-dimensional
+ * triangulations independently
+ * of the actual space dimension.
+ */
+ template <int spacedim>
+ static
+ void
+ create_triangulation (const std::vector<Point<spacedim> > &v,
+ const std::vector<CellData<2> > &cells,
+ const SubCellData &subcelldata,
+ Triangulation<2,spacedim> &triangulation)
+ {
+ AssertThrow (v.size() > 0, ExcMessage ("No vertices given"));
+ AssertThrow (cells.size() > 0, ExcMessage ("No cells given"));
+
+ const unsigned int dim=2;
+
+ // copy vertices
+ triangulation.vertices = v;
+ triangulation.vertices_used = std::vector<bool> (v.size(), true);
+
+ // make up a list of the needed
+ // lines each line is a pair of
+ // vertices. The list is kept
+ // sorted and it is guaranteed that
+ // each line is inserted only once.
+ // While the key of such an entry
+ // is the pair of vertices, the
+ // thing it points to is an
+ // iterator pointing to the line
+ // object itself. In the first run,
+ // these iterators are all invalid
+ // ones, but they are filled
+ // afterwards
+ std::map<std::pair<int,int>,
+ typename Triangulation<dim,spacedim>::line_iterator> needed_lines;
+ for (unsigned int cell=0; cell<cells.size(); ++cell)
+ {
+ for (unsigned int vertex=0; vertex<4; ++vertex)
+ AssertThrow (cells[cell].vertices[vertex] < triangulation.vertices.size(),
+ ExcInvalidVertexIndex (cell, cells[cell].vertices[vertex],
+ triangulation.vertices.size()));
+
+ for (unsigned int line=0; line<GeometryInfo<dim>::faces_per_cell; ++line)
+ {
+ // given a line vertex number
+ // (0,1) on a specific line we
+ // get the cell vertex number
+ // (0-4) through the
+ // line_to_cell_vertices
+ // function
+ std::pair<int,int> line_vertices(
+ cells[cell].vertices[GeometryInfo<dim>::line_to_cell_vertices(line, 0)],
+ cells[cell].vertices[GeometryInfo<dim>::line_to_cell_vertices(line, 1)]);
+
+ // assert that the line was
+ // not already inserted in
+ // reverse order. This
+ // happens in spite of the
+ // vertex rotation above,
+ // if the sense of the cell
+ // was incorrect.
+ //
+ // Here is what usually
+ // happened when this
+ // exception is thrown:
+ // consider these two cells
+ // and the vertices
+ // 3---4---5
+ // | | |
+ // 0---1---2
+ // If in the input vector
+ // the two cells are given
+ // with vertices <0 1 4 3>
+ // and <4 1 2 5>, in the
+ // first cell the middle
+ // line would have
+ // direction 1->4, while in
+ // the second it would be
+ // 4->1. This will cause
+ // the exception.
+ AssertThrow (needed_lines.find(std::make_pair(line_vertices.second,
+ line_vertices.first))
+ ==
+ needed_lines.end(),
+ ExcGridHasInvalidCell(cell));
+
+ // insert line, with
+ // invalid iterator if line
+ // already exists, then
+ // nothing bad happens here
+ needed_lines[line_vertices] = triangulation.end_line();
+ }
+ }
+
+
+ // check that every vertex has at
+ // least two adjacent lines
+ {
+ std::vector<unsigned short int> vertex_touch_count (v.size(), 0);
+ typename std::map<std::pair<int,int>,
+ typename Triangulation<dim,spacedim>::line_iterator>::iterator i;
+ for (i=needed_lines.begin(); i!=needed_lines.end(); i++)
+ {
+ // touch the vertices of
+ // this line
+ ++vertex_touch_count[i->first.first];
+ ++vertex_touch_count[i->first.second];
+ }
+
+ // assert minimum touch count
+ // is at least two. if not so,
+ // then clean triangulation and
+ // exit with an exception
+ AssertThrow (* (std::min_element(vertex_touch_count.begin(),
+ vertex_touch_count.end())) >= 2,
+ ExcGridHasInvalidVertices());
+ }
+
+ // reserve enough space
+ triangulation.levels.push_back (new internal::Triangulation::TriaLevel<dim>);
+ triangulation.faces = new internal::Triangulation::TriaFaces<dim>;
+ triangulation.levels[0]->reserve_space (cells.size(), dim, spacedim);
+ triangulation.faces->lines.reserve_space (0,needed_lines.size());
+ triangulation.levels[0]->cells.reserve_space (0,cells.size());
+
+ // make up lines
+ {
+ typename Triangulation<dim,spacedim>::raw_line_iterator
+ line = triangulation.begin_raw_line();
+ typename std::map<std::pair<int,int>,
+ typename Triangulation<dim,spacedim>::line_iterator>::iterator i;
+ for (i = needed_lines.begin();
+ line!=triangulation.end_line(); ++line, ++i)
+ {
+ line->set (internal::Triangulation::TriaObject<1>(i->first.first,
+ i->first.second));
+ line->set_used_flag ();
+ line->clear_user_flag ();
+ line->clear_user_data ();
+ i->second = line;
+ }
+ }
+
+
+ // store for each line index
+ // the adjacent cells
+ std::map<int,std::vector<typename Triangulation<dim,spacedim>::cell_iterator> >
+ adjacent_cells;
+
+ // finally make up cells
+ {
+ typename Triangulation<dim,spacedim>::raw_cell_iterator
+ cell = triangulation.begin_raw_quad();
+ for (unsigned int c=0; c<cells.size(); ++c, ++cell)
+ {
+ typename Triangulation<dim,spacedim>::line_iterator
+ lines[GeometryInfo<dim>::lines_per_cell];
+ for (unsigned int line=0; line<GeometryInfo<dim>::lines_per_cell; ++line)
+ lines[line]=needed_lines[std::make_pair(
+ cells[c].vertices[GeometryInfo<dim>::line_to_cell_vertices(line, 0)],
+ cells[c].vertices[GeometryInfo<dim>::line_to_cell_vertices(line, 1)])];
+
+ cell->set (internal::Triangulation::TriaObject<2> (lines[0]->index(),
+ lines[1]->index(),
+ lines[2]->index(),
+ lines[3]->index()));
+
+ cell->set_used_flag ();
+ cell->set_material_id (cells[c].material_id);
+ cell->clear_user_data ();
+ cell->set_subdomain_id (0);
+
+ // note that this cell is
+ // adjacent to the four
+ // lines
+ for (unsigned int line=0; line<GeometryInfo<dim>::lines_per_cell; ++line)
+ adjacent_cells[lines[line]->index()].push_back (cell);
+ }
+ }
+
+
+ for (typename Triangulation<dim,spacedim>::line_iterator
+ line=triangulation.begin_line();
+ line!=triangulation.end_line(); ++line)
+ {
+ const unsigned int n_adj_cells = adjacent_cells[line->index()].size();
+ // assert that every line has
+ // one or two adjacent cells
+ AssertThrow ((n_adj_cells >= 1) &&
+ (n_adj_cells <= 2),
+ ExcInternalError());
+
+ // if only one cell: line is at
+ // boundary -> give it the
+ // boundary indicator zero by
+ // default
+ if (n_adj_cells == 1)
+ line->set_boundary_indicator (0);
+ else
+ // interior line -> types::internal_face_boundary_id
+ line->set_boundary_indicator (types::internal_face_boundary_id);
+ }
+
+ // set boundary indicators where
+ // given
+ std::vector<CellData<1> >::const_iterator boundary_line
+ = subcelldata.boundary_lines.begin();
+ std::vector<CellData<1> >::const_iterator end_boundary_line
+ = subcelldata.boundary_lines.end();
+ for (; boundary_line!=end_boundary_line; ++boundary_line)
+ {
+ typename Triangulation<dim,spacedim>::line_iterator line;
+ std::pair<int,int> line_vertices(std::make_pair(boundary_line->vertices[0],
+ boundary_line->vertices[1]));
+ if (needed_lines.find(line_vertices) != needed_lines.end())
+ // line found in this
+ // direction
+ line = needed_lines[line_vertices];
+ else
+ {
+ // look whether it exists
+ // in reverse direction
+ std::swap (line_vertices.first, line_vertices.second);
+ if (needed_lines.find(line_vertices) != needed_lines.end())
+ line = needed_lines[line_vertices];
+ else
+ // line does not exist
+ AssertThrow (false, ExcLineInexistant(line_vertices.first,
+ line_vertices.second));
+ }
+
+ // assert that we only set
+ // boundary info once
+ AssertThrow (! (line->boundary_indicator() != 0 &&
+ line->boundary_indicator() != types::internal_face_boundary_id),
+ ExcMultiplySetLineInfoOfLine(line_vertices.first,
+ line_vertices.second));
+
+ // Assert that only exterior lines
+ // are given a boundary indicator
+ AssertThrow (! (line->boundary_indicator() == types::internal_face_boundary_id),
+ ExcInteriorLineCantBeBoundary());
+
+ line->set_boundary_indicator (boundary_line->boundary_id);
+ }
+
+
+ // finally update neighborship info
+ for (typename Triangulation<dim,spacedim>::cell_iterator
+ cell=triangulation.begin(); cell!=triangulation.end(); ++cell)
+ for (unsigned int side=0; side<4; ++side)
+ if (adjacent_cells[cell->line(side)->index()][0] == cell)
+ // first adjacent cell is
+ // this one
+ {
+ if (adjacent_cells[cell->line(side)->index()].size() == 2)
+ // there is another
+ // adjacent cell
+ cell->set_neighbor (side,
+ adjacent_cells[cell->line(side)->index()][1]);
+ }
+ // first adjacent cell is not this
+ // one, -> it must be the neighbor
+ // we are looking for
+ else
+ cell->set_neighbor (side,
+ adjacent_cells[cell->line(side)->index()][0]);
+ }
/**
* Since this comparison is not canonical, we do not include it into the
* general internal::Triangulation::TriaObject<2> class.
*/
- struct QuadComparator
- {
- inline bool operator () (const internal::Triangulation::TriaObject<2> &q1,
- const internal::Triangulation::TriaObject<2> &q2) const
- {
- // here is room to
- // optimize the repeated
- // equality test of the
- // previous lines; the
- // compiler will probably
- // take care of most of
- // it anyway
- if ((q1.face(0) < q2.face(0)) ||
- ((q1.face(0) == q2.face(0)) &&
- (q1.face(1) < q2.face(1))) ||
- ((q1.face(0) == q2.face(0)) &&
- (q1.face(1) == q2.face(1)) &&
- (q1.face(2) < q2.face(2))) ||
- ((q1.face(0) == q2.face(0)) &&
- (q1.face(1) == q2.face(1)) &&
- (q1.face(2) == q2.face(2)) &&
- (q1.face(3) < q2.face(3))))
- return true;
- else
- return false;
- }
- };
-
-
-
- template <int spacedim>
- static
- void
- create_triangulation (const std::vector<Point<spacedim> > &v,
- const std::vector<CellData<3> > &cells,
- const SubCellData &subcelldata,
- Triangulation<3,spacedim> &triangulation)
- {
- AssertThrow (v.size() > 0, ExcMessage ("No vertices given"));
- AssertThrow (cells.size() > 0, ExcMessage ("No cells given"));
-
- const unsigned int dim=3;
-
- // copy vertices
- triangulation.vertices = v;
- triangulation.vertices_used = std::vector<bool> (v.size(), true);
-
- // check that all cells have
- // positive volume. if not call the
- // invert_all_cells_of_negative_grid
- // and reorder_cells function of
- // GridReordering before creating
- // the triangulation
- for (unsigned int cell_no=0; cell_no<cells.size(); ++cell_no)
- AssertThrow (dealii::GridTools::cell_measure(triangulation.vertices,
- cells[cell_no].vertices) >= 0,
- ExcGridHasInvalidCell(cell_no));
-
- ///////////////////////////////////////
- // first set up some collections of data
- //
- // make up a list of the needed
- // lines
- //
- // each line is a pair of
- // vertices. The list is kept
- // sorted and it is guaranteed that
- // each line is inserted only once.
- // While the key of such an entry
- // is the pair of vertices, the
- // thing it points to is an
- // iterator pointing to the line
- // object itself. In the first run,
- // these iterators are all invalid
- // ones, but they are filled
- // afterwards same applies for the
- // quads
- typename std::map<std::pair<int,int>,
- typename Triangulation<dim,spacedim>::line_iterator> needed_lines;
- for (unsigned int cell=0; cell<cells.size(); ++cell)
- {
- // check whether vertex indices
- // are valid ones
- for (unsigned int vertex=0; vertex<GeometryInfo<dim>::vertices_per_cell; ++vertex)
- AssertThrow (cells[cell].vertices[vertex] < triangulation.vertices.size(),
- ExcInvalidVertexIndex (cell, cells[cell].vertices[vertex],
- triangulation.vertices.size()));
-
- for (unsigned int line=0; line<GeometryInfo<dim>::lines_per_cell; ++line)
- {
- // given a line vertex number
- // (0,1) on a specific line we
- // get the cell vertex number
- // (0-7) through the
- // line_to_cell_vertices
- // function
- std::pair<int,int> line_vertices(
- cells[cell].vertices[GeometryInfo<dim>::line_to_cell_vertices(line, 0)],
- cells[cell].vertices[GeometryInfo<dim>::line_to_cell_vertices(line, 1)]);
-
- // if that line was already inserted
- // in reverse order do nothing, else
- // insert the line
- if ( (needed_lines.find(std::make_pair(line_vertices.second,
- line_vertices.first))
- ==
- needed_lines.end()))
- {
- // insert line, with
- // invalid iterator. if line
- // already exists, then
- // nothing bad happens here
- needed_lines[line_vertices] = triangulation.end_line();
- }
- }
- }
-
-
- /////////////////////////////////
- // now for some sanity-checks:
- //
- // check that every vertex has at
- // least tree adjacent lines
- {
- std::vector<unsigned short int> vertex_touch_count (v.size(), 0);
- typename std::map<std::pair<int,int>,
- typename Triangulation<dim,spacedim>::line_iterator>::iterator i;
- for (i=needed_lines.begin(); i!=needed_lines.end(); i++)
- {
- // touch the vertices of
- // this line
- ++vertex_touch_count[i->first.first];
- ++vertex_touch_count[i->first.second];
- }
-
- // assert minimum touch count
- // is at least three. if not so,
- // then clean triangulation and
- // exit with an exception
- AssertThrow (* (std::min_element(vertex_touch_count.begin(),
- vertex_touch_count.end())) >= 3,
- ExcGridHasInvalidVertices());
- }
-
-
- ///////////////////////////////////
- // actually set up data structures
- // for the lines
- // reserve enough space
- triangulation.levels.push_back (new internal::Triangulation::TriaLevel<dim>);
- triangulation.faces = new internal::Triangulation::TriaFaces<dim>;
- triangulation.levels[0]->reserve_space (cells.size(), dim, spacedim);
- triangulation.faces->lines.reserve_space (0,needed_lines.size());
-
- // make up lines
- {
- typename Triangulation<dim,spacedim>::raw_line_iterator
- line = triangulation.begin_raw_line();
- typename std::map<std::pair<int,int>,
- typename Triangulation<dim,spacedim>::line_iterator>::iterator i;
- for (i = needed_lines.begin(); line!=triangulation.end_line(); ++line, ++i)
- {
- line->set (internal::Triangulation::TriaObject<1>(i->first.first,
- i->first.second));
- line->set_used_flag ();
- line->clear_user_flag ();
- line->clear_user_data ();
-
- // now set the iterator for
- // this line
- i->second = line;
- }
- }
-
-
- ///////////////////////////////////////////
- // make up the quads of this triangulation
- //
- // same thing: the iterators are
- // set to the invalid value at
- // first, we only collect the data
- // now
-
- // the bool array stores, wether the lines
- // are in the standard orientation or not
-
- // note that QuadComparator is a
- // class declared and defined in
- // this file
- std::map<internal::Triangulation::TriaObject<2>,
- std::pair<typename Triangulation<dim,spacedim>::quad_iterator,
- std_cxx1x::array<bool,GeometryInfo<dim>::lines_per_face> >,
- QuadComparator>
- needed_quads;
- for (unsigned int cell=0; cell<cells.size(); ++cell)
- {
- // the faces are quads which
- // consist of four numbers
- // denoting the index of the
- // four lines bounding the
- // quad. we can get this index
- // by asking @p{needed_lines}
- // for an iterator to this
- // line, dereferencing it and
- // thus return an iterator into
- // the @p{lines} array of the
- // triangulation, which is
- // already set up. we can then
- // ask this iterator for its
- // index within the present
- // level (the level is zero, of
- // course)
- //
- // to make things easier, we
- // don't create the lines
- // (pairs of their vertex
- // indices) in place, but
- // before they are really
- // needed.
- std::pair<int,int> line_list[GeometryInfo<dim>::lines_per_cell],
- inverse_line_list[GeometryInfo<dim>::lines_per_cell];
- unsigned int face_line_list[GeometryInfo<dim>::lines_per_face];
- std_cxx1x::array<bool,GeometryInfo<dim>::lines_per_face> orientation;
-
- for (unsigned int line=0; line<GeometryInfo<dim>::lines_per_cell; ++line)
- {
- line_list[line]=std::pair<int,int> (
- cells[cell].vertices[GeometryInfo<dim>::line_to_cell_vertices(line, 0)],
- cells[cell].vertices[GeometryInfo<dim>::line_to_cell_vertices(line, 1)]);
- inverse_line_list[line]=std::pair<int,int> (
- cells[cell].vertices[GeometryInfo<dim>::line_to_cell_vertices(line, 1)],
- cells[cell].vertices[GeometryInfo<dim>::line_to_cell_vertices(line, 0)]);
- }
-
- for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
- {
- // set up a list of the lines to be
- // used for this face. check the
- // direction for each line
- //
- // given a face line number (0-3) on
- // a specific face we get the cell
- // line number (0-11) through the
- // face_to_cell_lines function
- for (unsigned int l=0; l<GeometryInfo<dim>::lines_per_face; ++l)
- if (needed_lines.find (inverse_line_list[GeometryInfo<dim>::
- face_to_cell_lines(face,l)]) == needed_lines.end())
- {
- face_line_list[l]=needed_lines[line_list[GeometryInfo<dim>::
- face_to_cell_lines(face,l)]]->index();
- orientation[l]=true;
- }
- else
- {
- face_line_list[l]=needed_lines[inverse_line_list[GeometryInfo<dim>::
- face_to_cell_lines(face,l)]]->index();
- orientation[l]=false;
- }
-
-
- internal::Triangulation::TriaObject<2>
- quad(face_line_list[0],
- face_line_list[1],
- face_line_list[2],
- face_line_list[3]);
-
- // insert quad, with
- // invalid iterator
- //
- // if quad already exists,
- // then nothing bad happens
- // here, as this will then
- // simply become an
- // interior face of the
- // triangulation. however,
- // we will run into major
- // trouble if the face was
- // already inserted in the
- // opposite
- // direction. there are
- // really only two
- // orientations for a face
- // to be in, since the edge
- // directions are already
- // set. thus, vertex 0 is
- // the one from which two
- // edges originate, and
- // vertex 3 is the one to
- // which they converge. we
- // are then left with
- // orientations 0-1-2-3 and
- // 2-3-0-1 for the order of
- // lines. the
- // corresponding quad can
- // be easily constructed by
- // exchanging lines. we do
- // so here, just to check
- // that that flipped quad
- // isn't already in the
- // triangulation. if it is,
- // then don't insert the
- // new one and instead
- // later set the
- // face_orientation flag
- const internal::Triangulation::TriaObject<2>
- test_quad_1(quad.face(2), quad.face(3),
- quad.face(0), quad.face(1)),//face_orientation=false, face_flip=false, face_rotation=false
- test_quad_2(quad.face(0), quad.face(1),
- quad.face(3), quad.face(2)),//face_orientation=false, face_flip=false, face_rotation=true
- test_quad_3(quad.face(3), quad.face(2),
- quad.face(1), quad.face(0)),//face_orientation=false, face_flip=true, face_rotation=false
- test_quad_4(quad.face(1), quad.face(0),
- quad.face(2), quad.face(3)),//face_orientation=false, face_flip=true, face_rotation=true
- test_quad_5(quad.face(2), quad.face(3),
- quad.face(1), quad.face(0)),//face_orientation=true, face_flip=false, face_rotation=true
- test_quad_6(quad.face(1), quad.face(0),
- quad.face(3), quad.face(2)),//face_orientation=true, face_flip=true, face_rotation=false
- test_quad_7(quad.face(3), quad.face(2),
- quad.face(0), quad.face(1));//face_orientation=true, face_flip=true, face_rotation=true
- if (needed_quads.find (test_quad_1) == needed_quads.end() &&
- needed_quads.find (test_quad_2) == needed_quads.end() &&
- needed_quads.find (test_quad_3) == needed_quads.end() &&
- needed_quads.find (test_quad_4) == needed_quads.end() &&
- needed_quads.find (test_quad_5) == needed_quads.end() &&
- needed_quads.find (test_quad_6) == needed_quads.end() &&
- needed_quads.find (test_quad_7) == needed_quads.end())
- needed_quads[quad] = std::make_pair(triangulation.end_quad(),orientation);
- }
- }
-
-
- /////////////////////////////////
- // enter the resulting quads into
- // the arrays of the Triangulation
- //
- // first reserve enough space
- triangulation.faces->quads.reserve_space (0,needed_quads.size());
-
- {
- typename Triangulation<dim,spacedim>::raw_quad_iterator
- quad = triangulation.begin_raw_quad();
- typename std::map<internal::Triangulation::TriaObject<2>,
- std::pair<typename Triangulation<dim,spacedim>::quad_iterator,
- std_cxx1x::array<bool,GeometryInfo<dim>::lines_per_face> >,
- QuadComparator>
- ::iterator q;
- for (q = needed_quads.begin(); quad!=triangulation.end_quad(); ++quad, ++q)
- {
- quad->set (q->first);
- quad->set_used_flag ();
- quad->clear_user_flag ();
- quad->clear_user_data ();
- // set the line orientation
- quad->set_line_orientation(0,q->second.second[0]);
- quad->set_line_orientation(1,q->second.second[1]);
- quad->set_line_orientation(2,q->second.second[2]);
- quad->set_line_orientation(3,q->second.second[3]);
-
-
- // now set the iterator for
- // this quad
- q->second.first = quad;
- }
- }
-
- /////////////////////////////////
- // finally create the cells
- triangulation.levels[0]->cells.reserve_space (cells.size());
-
- // store for each quad index the
- // adjacent cells
- std::map<int,std::vector<typename Triangulation<dim,spacedim>::cell_iterator> >
- adjacent_cells;
-
- // finally make up cells
- {
- typename Triangulation<dim,spacedim>::raw_cell_iterator
- cell = triangulation.begin_raw_hex();
- for (unsigned int c=0; c<cells.size(); ++c, ++cell)
- {
- // first find for each of
- // the cells the quad
- // iterator of the
- // respective faces.
- //
- // to this end, set up the
- // lines of this cell and
- // find the quads that are
- // bounded by these lines;
- // these are then the faces
- // of the present cell
- std::pair<int,int> line_list[GeometryInfo<dim>::lines_per_cell],
- inverse_line_list[GeometryInfo<dim>::lines_per_cell];
- unsigned int face_line_list[4];
- for (unsigned int line=0; line<GeometryInfo<dim>::lines_per_cell; ++line)
- {
- line_list[line]=std::make_pair(
- cells[c].vertices[GeometryInfo<dim>::line_to_cell_vertices(line, 0)],
- cells[c].vertices[GeometryInfo<dim>::line_to_cell_vertices(line, 1)]);
- inverse_line_list[line]=std::pair<int,int> (
- cells[c].vertices[GeometryInfo<dim>::line_to_cell_vertices(line, 1)],
- cells[c].vertices[GeometryInfo<dim>::line_to_cell_vertices(line, 0)]);
- }
-
- // get the iterators
- // corresponding to the
- // faces. also store
- // whether they are
- // reversed or not
- typename Triangulation<dim,spacedim>::quad_iterator
- face_iterator[GeometryInfo<dim>::faces_per_cell];
- bool face_orientation[GeometryInfo<dim>::faces_per_cell];
- bool face_flip[GeometryInfo<dim>::faces_per_cell];
- bool face_rotation[GeometryInfo<dim>::faces_per_cell];
- for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
- {
- for (unsigned int l=0; l<GeometryInfo<dim>::lines_per_face; ++l)
- if (needed_lines.find (inverse_line_list[GeometryInfo<dim>::
- face_to_cell_lines(face,l)]) == needed_lines.end())
- face_line_list[l]=needed_lines[line_list[GeometryInfo<dim>::
- face_to_cell_lines(face,l)]]->index();
- else
- face_line_list[l]=needed_lines[inverse_line_list[GeometryInfo<dim>::
- face_to_cell_lines(face,l)]]->index();
-
- internal::Triangulation::TriaObject<2>
- quad(face_line_list[0],
- face_line_list[1],
- face_line_list[2],
- face_line_list[3]);
-
- if (needed_quads.find (quad) != needed_quads.end())
- {
- // face is in standard
- // orientation (and not
- // flipped or rotated). this
- // must be true for at least
- // one of the two cells
- // containing this face
- // (i.e. for the cell which
- // originally inserted the
- // face)
- face_iterator[face] = needed_quads[quad].first;
- face_orientation[face] = true;
- face_flip[face]=false;
- face_rotation[face]=false;
- }
- else
- {
- // face must be available in
- // reverse order
- // then. construct all
- // possibilities and check
- // them one after the other
- const internal::Triangulation::TriaObject<2>
- test_quad_1(quad.face(2), quad.face(3),
- quad.face(0), quad.face(1)),//face_orientation=false, face_flip=false, face_rotation=false
- test_quad_2(quad.face(0), quad.face(1),
- quad.face(3), quad.face(2)),//face_orientation=false, face_flip=false, face_rotation=true
- test_quad_3(quad.face(3), quad.face(2),
- quad.face(1), quad.face(0)),//face_orientation=false, face_flip=true, face_rotation=false
- test_quad_4(quad.face(1), quad.face(0),
- quad.face(2), quad.face(3)),//face_orientation=false, face_flip=true, face_rotation=true
- test_quad_5(quad.face(2), quad.face(3),
- quad.face(1), quad.face(0)),//face_orientation=true, face_flip=false, face_rotation=true
- test_quad_6(quad.face(1), quad.face(0),
- quad.face(3), quad.face(2)),//face_orientation=true, face_flip=true, face_rotation=false
- test_quad_7(quad.face(3), quad.face(2),
- quad.face(0), quad.face(1));//face_orientation=true, face_flip=true, face_rotation=true
- if (needed_quads.find (test_quad_1) != needed_quads.end())
- {
- face_iterator[face] = needed_quads[test_quad_1].first;
- face_orientation[face] = false;
- face_flip[face]=false;
- face_rotation[face]=false;
- }
- else if (needed_quads.find (test_quad_2) != needed_quads.end())
- {
- face_iterator[face] = needed_quads[test_quad_2].first;
- face_orientation[face] = false;
- face_flip[face]=false;
- face_rotation[face]=true;
- }
- else if (needed_quads.find (test_quad_3) != needed_quads.end())
- {
- face_iterator[face] = needed_quads[test_quad_3].first;
- face_orientation[face] = false;
- face_flip[face]=true;
- face_rotation[face]=false;
- }
- else if (needed_quads.find (test_quad_4) != needed_quads.end())
- {
- face_iterator[face] = needed_quads[test_quad_4].first;
- face_orientation[face] = false;
- face_flip[face]=true;
- face_rotation[face]=true;
- }
- else if (needed_quads.find (test_quad_5) != needed_quads.end())
- {
- face_iterator[face] = needed_quads[test_quad_5].first;
- face_orientation[face] = true;
- face_flip[face]=false;
- face_rotation[face]=true;
- }
- else if (needed_quads.find (test_quad_6) != needed_quads.end())
- {
- face_iterator[face] = needed_quads[test_quad_6].first;
- face_orientation[face] = true;
- face_flip[face]=true;
- face_rotation[face]=false;
- }
- else if (needed_quads.find (test_quad_7) != needed_quads.end())
- {
- face_iterator[face] = needed_quads[test_quad_7].first;
- face_orientation[face] = true;
- face_flip[face]=true;
- face_rotation[face]=true;
- }
-
- else
- // we didn't find the
- // face in any direction,
- // so something went
- // wrong above
- Assert(false,ExcInternalError());
-
- }
- }// for all faces
-
- // make the cell out of
- // these iterators
- cell->set (internal::Triangulation
- ::TriaObject<3> (face_iterator[0]->index(),
- face_iterator[1]->index(),
- face_iterator[2]->index(),
- face_iterator[3]->index(),
- face_iterator[4]->index(),
- face_iterator[5]->index()));
-
- cell->set_used_flag ();
- cell->set_material_id (cells[c].material_id);
- cell->clear_user_flag ();
- cell->clear_user_data ();
- cell->set_subdomain_id (0);
-
- // set orientation flag for
- // each of the faces
- for (unsigned int quad=0; quad<GeometryInfo<dim>::faces_per_cell; ++quad)
- {
- cell->set_face_orientation (quad, face_orientation[quad]);
- cell->set_face_flip (quad, face_flip[quad]);
- cell->set_face_rotation (quad, face_rotation[quad]);
- }
-
-
- // note that this cell is
- // adjacent to the six
- // quads
- for (unsigned int quad=0; quad<GeometryInfo<dim>::faces_per_cell; ++quad)
- adjacent_cells[face_iterator[quad]->index()].push_back (cell);
+ struct QuadComparator
+ {
+ inline bool operator () (const internal::Triangulation::TriaObject<2> &q1,
+ const internal::Triangulation::TriaObject<2> &q2) const
+ {
+ // here is room to
+ // optimize the repeated
+ // equality test of the
+ // previous lines; the
+ // compiler will probably
+ // take care of most of
+ // it anyway
+ if ((q1.face(0) < q2.face(0)) ||
+ ((q1.face(0) == q2.face(0)) &&
+ (q1.face(1) < q2.face(1))) ||
+ ((q1.face(0) == q2.face(0)) &&
+ (q1.face(1) == q2.face(1)) &&
+ (q1.face(2) < q2.face(2))) ||
+ ((q1.face(0) == q2.face(0)) &&
+ (q1.face(1) == q2.face(1)) &&
+ (q1.face(2) == q2.face(2)) &&
+ (q1.face(3) < q2.face(3))))
+ return true;
+ else
+ return false;
+ }
+ };
+
+
+
+ template <int spacedim>
+ static
+ void
+ create_triangulation (const std::vector<Point<spacedim> > &v,
+ const std::vector<CellData<3> > &cells,
+ const SubCellData &subcelldata,
+ Triangulation<3,spacedim> &triangulation)
+ {
+ AssertThrow (v.size() > 0, ExcMessage ("No vertices given"));
+ AssertThrow (cells.size() > 0, ExcMessage ("No cells given"));
+
+ const unsigned int dim=3;
+
+ // copy vertices
+ triangulation.vertices = v;
+ triangulation.vertices_used = std::vector<bool> (v.size(), true);
+
+ // check that all cells have
+ // positive volume. if not call the
+ // invert_all_cells_of_negative_grid
+ // and reorder_cells function of
+ // GridReordering before creating
+ // the triangulation
+ for (unsigned int cell_no=0; cell_no<cells.size(); ++cell_no)
+ AssertThrow (dealii::GridTools::cell_measure(triangulation.vertices,
+ cells[cell_no].vertices) >= 0,
+ ExcGridHasInvalidCell(cell_no));
+
+ ///////////////////////////////////////
+ // first set up some collections of data
+ //
+ // make up a list of the needed
+ // lines
+ //
+ // each line is a pair of
+ // vertices. The list is kept
+ // sorted and it is guaranteed that
+ // each line is inserted only once.
+ // While the key of such an entry
+ // is the pair of vertices, the
+ // thing it points to is an
+ // iterator pointing to the line
+ // object itself. In the first run,
+ // these iterators are all invalid
+ // ones, but they are filled
+ // afterwards same applies for the
+ // quads
+ typename std::map<std::pair<int,int>,
+ typename Triangulation<dim,spacedim>::line_iterator> needed_lines;
+ for (unsigned int cell=0; cell<cells.size(); ++cell)
+ {
+ // check whether vertex indices
+ // are valid ones
+ for (unsigned int vertex=0; vertex<GeometryInfo<dim>::vertices_per_cell; ++vertex)
+ AssertThrow (cells[cell].vertices[vertex] < triangulation.vertices.size(),
+ ExcInvalidVertexIndex (cell, cells[cell].vertices[vertex],
+ triangulation.vertices.size()));
+
+ for (unsigned int line=0; line<GeometryInfo<dim>::lines_per_cell; ++line)
+ {
+ // given a line vertex number
+ // (0,1) on a specific line we
+ // get the cell vertex number
+ // (0-7) through the
+ // line_to_cell_vertices
+ // function
+ std::pair<int,int> line_vertices(
+ cells[cell].vertices[GeometryInfo<dim>::line_to_cell_vertices(line, 0)],
+ cells[cell].vertices[GeometryInfo<dim>::line_to_cell_vertices(line, 1)]);
+
+ // if that line was already inserted
+ // in reverse order do nothing, else
+ // insert the line
+ if ( (needed_lines.find(std::make_pair(line_vertices.second,
+ line_vertices.first))
+ ==
+ needed_lines.end()))
+ {
+ // insert line, with
+ // invalid iterator. if line
+ // already exists, then
+ // nothing bad happens here
+ needed_lines[line_vertices] = triangulation.end_line();
+ }
+ }
+ }
+
+
+ /////////////////////////////////
+ // now for some sanity-checks:
+ //
+ // check that every vertex has at
+ // least tree adjacent lines
+ {
+ std::vector<unsigned short int> vertex_touch_count (v.size(), 0);
+ typename std::map<std::pair<int,int>,
+ typename Triangulation<dim,spacedim>::line_iterator>::iterator i;
+ for (i=needed_lines.begin(); i!=needed_lines.end(); i++)
+ {
+ // touch the vertices of
+ // this line
+ ++vertex_touch_count[i->first.first];
+ ++vertex_touch_count[i->first.second];
+ }
+
+ // assert minimum touch count
+ // is at least three. if not so,
+ // then clean triangulation and
+ // exit with an exception
+ AssertThrow (* (std::min_element(vertex_touch_count.begin(),
+ vertex_touch_count.end())) >= 3,
+ ExcGridHasInvalidVertices());
+ }
+
+
+ ///////////////////////////////////
+ // actually set up data structures
+ // for the lines
+ // reserve enough space
+ triangulation.levels.push_back (new internal::Triangulation::TriaLevel<dim>);
+ triangulation.faces = new internal::Triangulation::TriaFaces<dim>;
+ triangulation.levels[0]->reserve_space (cells.size(), dim, spacedim);
+ triangulation.faces->lines.reserve_space (0,needed_lines.size());
+
+ // make up lines
+ {
+ typename Triangulation<dim,spacedim>::raw_line_iterator
+ line = triangulation.begin_raw_line();
+ typename std::map<std::pair<int,int>,
+ typename Triangulation<dim,spacedim>::line_iterator>::iterator i;
+ for (i = needed_lines.begin(); line!=triangulation.end_line(); ++line, ++i)
+ {
+ line->set (internal::Triangulation::TriaObject<1>(i->first.first,
+ i->first.second));
+ line->set_used_flag ();
+ line->clear_user_flag ();
+ line->clear_user_data ();
+
+ // now set the iterator for
+ // this line
+ i->second = line;
+ }
+ }
+
+
+ ///////////////////////////////////////////
+ // make up the quads of this triangulation
+ //
+ // same thing: the iterators are
+ // set to the invalid value at
+ // first, we only collect the data
+ // now
+
+ // the bool array stores, wether the lines
+ // are in the standard orientation or not
+
+ // note that QuadComparator is a
+ // class declared and defined in
+ // this file
+ std::map<internal::Triangulation::TriaObject<2>,
+ std::pair<typename Triangulation<dim,spacedim>::quad_iterator,
+ std_cxx1x::array<bool,GeometryInfo<dim>::lines_per_face> >,
+ QuadComparator>
+ needed_quads;
+ for (unsigned int cell=0; cell<cells.size(); ++cell)
+ {
+ // the faces are quads which
+ // consist of four numbers
+ // denoting the index of the
+ // four lines bounding the
+ // quad. we can get this index
+ // by asking @p{needed_lines}
+ // for an iterator to this
+ // line, dereferencing it and
+ // thus return an iterator into
+ // the @p{lines} array of the
+ // triangulation, which is
+ // already set up. we can then
+ // ask this iterator for its
+ // index within the present
+ // level (the level is zero, of
+ // course)
+ //
+ // to make things easier, we
+ // don't create the lines
+ // (pairs of their vertex
+ // indices) in place, but
+ // before they are really
+ // needed.
+ std::pair<int,int> line_list[GeometryInfo<dim>::lines_per_cell],
+ inverse_line_list[GeometryInfo<dim>::lines_per_cell];
+ unsigned int face_line_list[GeometryInfo<dim>::lines_per_face];
+ std_cxx1x::array<bool,GeometryInfo<dim>::lines_per_face> orientation;
+
+ for (unsigned int line=0; line<GeometryInfo<dim>::lines_per_cell; ++line)
+ {
+ line_list[line]=std::pair<int,int> (
+ cells[cell].vertices[GeometryInfo<dim>::line_to_cell_vertices(line, 0)],
+ cells[cell].vertices[GeometryInfo<dim>::line_to_cell_vertices(line, 1)]);
+ inverse_line_list[line]=std::pair<int,int> (
+ cells[cell].vertices[GeometryInfo<dim>::line_to_cell_vertices(line, 1)],
+ cells[cell].vertices[GeometryInfo<dim>::line_to_cell_vertices(line, 0)]);
+ }
+
+ for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
+ {
+ // set up a list of the lines to be
+ // used for this face. check the
+ // direction for each line
+ //
+ // given a face line number (0-3) on
+ // a specific face we get the cell
+ // line number (0-11) through the
+ // face_to_cell_lines function
+ for (unsigned int l=0; l<GeometryInfo<dim>::lines_per_face; ++l)
+ if (needed_lines.find (inverse_line_list[GeometryInfo<dim>::
+ face_to_cell_lines(face,l)]) == needed_lines.end())
+ {
+ face_line_list[l]=needed_lines[line_list[GeometryInfo<dim>::
+ face_to_cell_lines(face,l)]]->index();
+ orientation[l]=true;
+ }
+ else
+ {
+ face_line_list[l]=needed_lines[inverse_line_list[GeometryInfo<dim>::
+ face_to_cell_lines(face,l)]]->index();
+ orientation[l]=false;
+ }
+
+
+ internal::Triangulation::TriaObject<2>
+ quad(face_line_list[0],
+ face_line_list[1],
+ face_line_list[2],
+ face_line_list[3]);
+
+ // insert quad, with
+ // invalid iterator
+ //
+ // if quad already exists,
+ // then nothing bad happens
+ // here, as this will then
+ // simply become an
+ // interior face of the
+ // triangulation. however,
+ // we will run into major
+ // trouble if the face was
+ // already inserted in the
+ // opposite
+ // direction. there are
+ // really only two
+ // orientations for a face
+ // to be in, since the edge
+ // directions are already
+ // set. thus, vertex 0 is
+ // the one from which two
+ // edges originate, and
+ // vertex 3 is the one to
+ // which they converge. we
+ // are then left with
+ // orientations 0-1-2-3 and
+ // 2-3-0-1 for the order of
+ // lines. the
+ // corresponding quad can
+ // be easily constructed by
+ // exchanging lines. we do
+ // so here, just to check
+ // that that flipped quad
+ // isn't already in the
+ // triangulation. if it is,
+ // then don't insert the
+ // new one and instead
+ // later set the
+ // face_orientation flag
+ const internal::Triangulation::TriaObject<2>
+ test_quad_1(quad.face(2), quad.face(3),
+ quad.face(0), quad.face(1)),//face_orientation=false, face_flip=false, face_rotation=false
+ test_quad_2(quad.face(0), quad.face(1),
+ quad.face(3), quad.face(2)),//face_orientation=false, face_flip=false, face_rotation=true
+ test_quad_3(quad.face(3), quad.face(2),
+ quad.face(1), quad.face(0)),//face_orientation=false, face_flip=true, face_rotation=false
+ test_quad_4(quad.face(1), quad.face(0),
+ quad.face(2), quad.face(3)),//face_orientation=false, face_flip=true, face_rotation=true
+ test_quad_5(quad.face(2), quad.face(3),
+ quad.face(1), quad.face(0)),//face_orientation=true, face_flip=false, face_rotation=true
+ test_quad_6(quad.face(1), quad.face(0),
+ quad.face(3), quad.face(2)),//face_orientation=true, face_flip=true, face_rotation=false
+ test_quad_7(quad.face(3), quad.face(2),
+ quad.face(0), quad.face(1));//face_orientation=true, face_flip=true, face_rotation=true
+ if (needed_quads.find (test_quad_1) == needed_quads.end() &&
+ needed_quads.find (test_quad_2) == needed_quads.end() &&
+ needed_quads.find (test_quad_3) == needed_quads.end() &&
+ needed_quads.find (test_quad_4) == needed_quads.end() &&
+ needed_quads.find (test_quad_5) == needed_quads.end() &&
+ needed_quads.find (test_quad_6) == needed_quads.end() &&
+ needed_quads.find (test_quad_7) == needed_quads.end())
+ needed_quads[quad] = std::make_pair(triangulation.end_quad(),orientation);
+ }
+ }
+
+
+ /////////////////////////////////
+ // enter the resulting quads into
+ // the arrays of the Triangulation
+ //
+ // first reserve enough space
+ triangulation.faces->quads.reserve_space (0,needed_quads.size());
+
+ {
+ typename Triangulation<dim,spacedim>::raw_quad_iterator
+ quad = triangulation.begin_raw_quad();
+ typename std::map<internal::Triangulation::TriaObject<2>,
+ std::pair<typename Triangulation<dim,spacedim>::quad_iterator,
+ std_cxx1x::array<bool,GeometryInfo<dim>::lines_per_face> >,
+ QuadComparator>
+ ::iterator q;
+ for (q = needed_quads.begin(); quad!=triangulation.end_quad(); ++quad, ++q)
+ {
+ quad->set (q->first);
+ quad->set_used_flag ();
+ quad->clear_user_flag ();
+ quad->clear_user_data ();
+ // set the line orientation
+ quad->set_line_orientation(0,q->second.second[0]);
+ quad->set_line_orientation(1,q->second.second[1]);
+ quad->set_line_orientation(2,q->second.second[2]);
+ quad->set_line_orientation(3,q->second.second[3]);
+
+
+ // now set the iterator for
+ // this quad
+ q->second.first = quad;
+ }
+ }
+
+ /////////////////////////////////
+ // finally create the cells
+ triangulation.levels[0]->cells.reserve_space (cells.size());
+
+ // store for each quad index the
+ // adjacent cells
+ std::map<int,std::vector<typename Triangulation<dim,spacedim>::cell_iterator> >
+ adjacent_cells;
+
+ // finally make up cells
+ {
+ typename Triangulation<dim,spacedim>::raw_cell_iterator
+ cell = triangulation.begin_raw_hex();
+ for (unsigned int c=0; c<cells.size(); ++c, ++cell)
+ {
+ // first find for each of
+ // the cells the quad
+ // iterator of the
+ // respective faces.
+ //
+ // to this end, set up the
+ // lines of this cell and
+ // find the quads that are
+ // bounded by these lines;
+ // these are then the faces
+ // of the present cell
+ std::pair<int,int> line_list[GeometryInfo<dim>::lines_per_cell],
+ inverse_line_list[GeometryInfo<dim>::lines_per_cell];
+ unsigned int face_line_list[4];
+ for (unsigned int line=0; line<GeometryInfo<dim>::lines_per_cell; ++line)
+ {
+ line_list[line]=std::make_pair(
+ cells[c].vertices[GeometryInfo<dim>::line_to_cell_vertices(line, 0)],
+ cells[c].vertices[GeometryInfo<dim>::line_to_cell_vertices(line, 1)]);
+ inverse_line_list[line]=std::pair<int,int> (
+ cells[c].vertices[GeometryInfo<dim>::line_to_cell_vertices(line, 1)],
+ cells[c].vertices[GeometryInfo<dim>::line_to_cell_vertices(line, 0)]);
+ }
+
+ // get the iterators
+ // corresponding to the
+ // faces. also store
+ // whether they are
+ // reversed or not
+ typename Triangulation<dim,spacedim>::quad_iterator
+ face_iterator[GeometryInfo<dim>::faces_per_cell];
+ bool face_orientation[GeometryInfo<dim>::faces_per_cell];
+ bool face_flip[GeometryInfo<dim>::faces_per_cell];
+ bool face_rotation[GeometryInfo<dim>::faces_per_cell];
+ for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
+ {
+ for (unsigned int l=0; l<GeometryInfo<dim>::lines_per_face; ++l)
+ if (needed_lines.find (inverse_line_list[GeometryInfo<dim>::
+ face_to_cell_lines(face,l)]) == needed_lines.end())
+ face_line_list[l]=needed_lines[line_list[GeometryInfo<dim>::
+ face_to_cell_lines(face,l)]]->index();
+ else
+ face_line_list[l]=needed_lines[inverse_line_list[GeometryInfo<dim>::
+ face_to_cell_lines(face,l)]]->index();
+
+ internal::Triangulation::TriaObject<2>
+ quad(face_line_list[0],
+ face_line_list[1],
+ face_line_list[2],
+ face_line_list[3]);
+
+ if (needed_quads.find (quad) != needed_quads.end())
+ {
+ // face is in standard
+ // orientation (and not
+ // flipped or rotated). this
+ // must be true for at least
+ // one of the two cells
+ // containing this face
+ // (i.e. for the cell which
+ // originally inserted the
+ // face)
+ face_iterator[face] = needed_quads[quad].first;
+ face_orientation[face] = true;
+ face_flip[face]=false;
+ face_rotation[face]=false;
+ }
+ else
+ {
+ // face must be available in
+ // reverse order
+ // then. construct all
+ // possibilities and check
+ // them one after the other
+ const internal::Triangulation::TriaObject<2>
+ test_quad_1(quad.face(2), quad.face(3),
+ quad.face(0), quad.face(1)),//face_orientation=false, face_flip=false, face_rotation=false
+ test_quad_2(quad.face(0), quad.face(1),
+ quad.face(3), quad.face(2)),//face_orientation=false, face_flip=false, face_rotation=true
+ test_quad_3(quad.face(3), quad.face(2),
+ quad.face(1), quad.face(0)),//face_orientation=false, face_flip=true, face_rotation=false
+ test_quad_4(quad.face(1), quad.face(0),
+ quad.face(2), quad.face(3)),//face_orientation=false, face_flip=true, face_rotation=true
+ test_quad_5(quad.face(2), quad.face(3),
+ quad.face(1), quad.face(0)),//face_orientation=true, face_flip=false, face_rotation=true
+ test_quad_6(quad.face(1), quad.face(0),
+ quad.face(3), quad.face(2)),//face_orientation=true, face_flip=true, face_rotation=false
+ test_quad_7(quad.face(3), quad.face(2),
+ quad.face(0), quad.face(1));//face_orientation=true, face_flip=true, face_rotation=true
+ if (needed_quads.find (test_quad_1) != needed_quads.end())
+ {
+ face_iterator[face] = needed_quads[test_quad_1].first;
+ face_orientation[face] = false;
+ face_flip[face]=false;
+ face_rotation[face]=false;
+ }
+ else if (needed_quads.find (test_quad_2) != needed_quads.end())
+ {
+ face_iterator[face] = needed_quads[test_quad_2].first;
+ face_orientation[face] = false;
+ face_flip[face]=false;
+ face_rotation[face]=true;
+ }
+ else if (needed_quads.find (test_quad_3) != needed_quads.end())
+ {
+ face_iterator[face] = needed_quads[test_quad_3].first;
+ face_orientation[face] = false;
+ face_flip[face]=true;
+ face_rotation[face]=false;
+ }
+ else if (needed_quads.find (test_quad_4) != needed_quads.end())
+ {
+ face_iterator[face] = needed_quads[test_quad_4].first;
+ face_orientation[face] = false;
+ face_flip[face]=true;
+ face_rotation[face]=true;
+ }
+ else if (needed_quads.find (test_quad_5) != needed_quads.end())
+ {
+ face_iterator[face] = needed_quads[test_quad_5].first;
+ face_orientation[face] = true;
+ face_flip[face]=false;
+ face_rotation[face]=true;
+ }
+ else if (needed_quads.find (test_quad_6) != needed_quads.end())
+ {
+ face_iterator[face] = needed_quads[test_quad_6].first;
+ face_orientation[face] = true;
+ face_flip[face]=true;
+ face_rotation[face]=false;
+ }
+ else if (needed_quads.find (test_quad_7) != needed_quads.end())
+ {
+ face_iterator[face] = needed_quads[test_quad_7].first;
+ face_orientation[face] = true;
+ face_flip[face]=true;
+ face_rotation[face]=true;
+ }
+
+ else
+ // we didn't find the
+ // face in any direction,
+ // so something went
+ // wrong above
+ Assert(false,ExcInternalError());
+
+ }
+ }// for all faces
+
+ // make the cell out of
+ // these iterators
+ cell->set (internal::Triangulation
+ ::TriaObject<3> (face_iterator[0]->index(),
+ face_iterator[1]->index(),
+ face_iterator[2]->index(),
+ face_iterator[3]->index(),
+ face_iterator[4]->index(),
+ face_iterator[5]->index()));
+
+ cell->set_used_flag ();
+ cell->set_material_id (cells[c].material_id);
+ cell->clear_user_flag ();
+ cell->clear_user_data ();
+ cell->set_subdomain_id (0);
+
+ // set orientation flag for
+ // each of the faces
+ for (unsigned int quad=0; quad<GeometryInfo<dim>::faces_per_cell; ++quad)
+ {
+ cell->set_face_orientation (quad, face_orientation[quad]);
+ cell->set_face_flip (quad, face_flip[quad]);
+ cell->set_face_rotation (quad, face_rotation[quad]);
+ }
+
+
+ // note that this cell is
+ // adjacent to the six
+ // quads
+ for (unsigned int quad=0; quad<GeometryInfo<dim>::faces_per_cell; ++quad)
+ adjacent_cells[face_iterator[quad]->index()].push_back (cell);
#ifdef DEBUG
- // make some checks on the
- // lines and their
- // ordering
-
- // first map all cell lines
- // to the two face lines
- // which should
- // coincide. all face lines
- // are included with a cell
- // line number (0-11)
- // key. At the end all keys
- // will be included twice
- // (for each of the two
- // coinciding lines once)
- std::multimap<unsigned int, std::pair<unsigned int, unsigned int> >
- cell_to_face_lines;
- for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
- for (unsigned int line=0; line<GeometryInfo<dim>::lines_per_face; ++line)
- cell_to_face_lines.insert(
- std::pair<unsigned int, std::pair<unsigned int, unsigned int> > (
- GeometryInfo<dim>::face_to_cell_lines(face,line),
- std::pair<unsigned int, unsigned int> (face,line)));
- std::multimap<unsigned int, std::pair<unsigned int, unsigned int> >::const_iterator
- map_iter=cell_to_face_lines.begin();
-
- for (; map_iter!=cell_to_face_lines.end(); ++map_iter)
- {
- const unsigned int cell_line=map_iter->first;
- const unsigned int face1=map_iter->second.first;
- const unsigned int line1=map_iter->second.second;
- ++map_iter;
- Assert(map_iter!=cell_to_face_lines.end(), ExcInternalErrorOnCell(c));
- Assert(map_iter->first==cell_line, ExcInternalErrorOnCell(c));
- const unsigned int face2=map_iter->second.first;
- const unsigned int line2=map_iter->second.second;
-
- // check that the pair
- // of lines really
- // coincide. Take care
- // about the face
- // orientation;
- Assert (face_iterator[face1]->line(GeometryInfo<dim>::standard_to_real_face_line(
- line1,
- face_orientation[face1],
- face_flip[face1],
- face_rotation[face1])) ==
- face_iterator[face2]->line(GeometryInfo<dim>::standard_to_real_face_line(
- line2,
- face_orientation[face2],
- face_flip[face2],
- face_rotation[face2])),
- ExcInternalErrorOnCell(c));
- }
+ // make some checks on the
+ // lines and their
+ // ordering
+
+ // first map all cell lines
+ // to the two face lines
+ // which should
+ // coincide. all face lines
+ // are included with a cell
+ // line number (0-11)
+ // key. At the end all keys
+ // will be included twice
+ // (for each of the two
+ // coinciding lines once)
+ std::multimap<unsigned int, std::pair<unsigned int, unsigned int> >
+ cell_to_face_lines;
+ for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
+ for (unsigned int line=0; line<GeometryInfo<dim>::lines_per_face; ++line)
+ cell_to_face_lines.insert(
+ std::pair<unsigned int, std::pair<unsigned int, unsigned int> > (
+ GeometryInfo<dim>::face_to_cell_lines(face,line),
+ std::pair<unsigned int, unsigned int> (face,line)));
+ std::multimap<unsigned int, std::pair<unsigned int, unsigned int> >::const_iterator
+ map_iter=cell_to_face_lines.begin();
+
+ for (; map_iter!=cell_to_face_lines.end(); ++map_iter)
+ {
+ const unsigned int cell_line=map_iter->first;
+ const unsigned int face1=map_iter->second.first;
+ const unsigned int line1=map_iter->second.second;
+ ++map_iter;
+ Assert(map_iter!=cell_to_face_lines.end(), ExcInternalErrorOnCell(c));
+ Assert(map_iter->first==cell_line, ExcInternalErrorOnCell(c));
+ const unsigned int face2=map_iter->second.first;
+ const unsigned int line2=map_iter->second.second;
+
+ // check that the pair
+ // of lines really
+ // coincide. Take care
+ // about the face
+ // orientation;
+ Assert (face_iterator[face1]->line(GeometryInfo<dim>::standard_to_real_face_line(
+ line1,
+ face_orientation[face1],
+ face_flip[face1],
+ face_rotation[face1])) ==
+ face_iterator[face2]->line(GeometryInfo<dim>::standard_to_real_face_line(
+ line2,
+ face_orientation[face2],
+ face_flip[face2],
+ face_rotation[face2])),
+ ExcInternalErrorOnCell(c));
+ }
#endif
- }
- }
-
-
- /////////////////////////////////////////
- // find those quads which are at the
- // boundary and mark them appropriately
- for (typename Triangulation<dim,spacedim>::quad_iterator
- quad=triangulation.begin_quad(); quad!=triangulation.end_quad(); ++quad)
- {
- const unsigned int n_adj_cells = adjacent_cells[quad->index()].size();
- // assert that every quad has
- // one or two adjacent cells
- AssertThrow ((n_adj_cells >= 1) &&
- (n_adj_cells <= 2),
- ExcInternalError());
-
- // if only one cell: quad is at
- // boundary -> give it the
- // boundary indicator zero by
- // default
- if (n_adj_cells == 1)
- quad->set_boundary_indicator (0);
- else
- // interior quad -> types::internal_face_boundary_id
- quad->set_boundary_indicator (types::internal_face_boundary_id);
- }
-
- /////////////////////////////////////////
- // next find those lines which are at
- // the boundary and mark all others as
- // interior ones
- //
- // for this: first mark all lines
- // as interior
- for (typename Triangulation<dim,spacedim>::line_iterator
- line=triangulation.begin_line(); line!=triangulation.end_line(); ++line)
- line->set_boundary_indicator (types::internal_face_boundary_id);
- // next reset all lines bounding
- // boundary quads as on the
- // boundary also. note that since
- // we are in 3d, there are cases
- // where one or more lines of a
- // quad that is not on the
- // boundary, are actually boundary
- // lines. they will not be marked
- // when visiting this
- // face. however, since we do not
- // support dim-2 dimensional
- // boundaries (i.e. internal lines
- // constituting boundaries), every
- // such line is also part of a face
- // that is actually on the
- // boundary, so sooner or later we
- // get to mark that line for being
- // on the boundary
- for (typename Triangulation<dim,spacedim>::quad_iterator
- quad=triangulation.begin_quad(); quad!=triangulation.end_quad(); ++quad)
- if (quad->at_boundary())
- for (unsigned int l=0; l<4; ++l)
- quad->line(l)->set_boundary_indicator (0);
-
- ///////////////////////////////////////
- // now set boundary indicators
- // where given
- //
- // first do so for lines
- std::vector<CellData<1> >::const_iterator boundary_line
- = subcelldata.boundary_lines.begin();
- std::vector<CellData<1> >::const_iterator end_boundary_line
- = subcelldata.boundary_lines.end();
- for (; boundary_line!=end_boundary_line; ++boundary_line)
- {
- typename Triangulation<dim,spacedim>::line_iterator line;
- std::pair <int, int> line_vertices(std::make_pair(boundary_line->vertices[0],
- boundary_line->vertices[1]));
- if (needed_lines.find(line_vertices) != needed_lines.end())
- // line found in this
- // direction
- line = needed_lines[line_vertices];
-
- else
- {
- // look wether it exists in
- // reverse direction
- std::swap (line_vertices.first, line_vertices.second);
- if (needed_lines.find(line_vertices) != needed_lines.end())
- line = needed_lines[line_vertices];
- else
- // line does not exist
- AssertThrow (false, ExcLineInexistant(line_vertices.first,
- line_vertices.second));
- }
- // Assert that only exterior
- // lines are given a boundary
- // indicator
- AssertThrow (line->at_boundary(),
- ExcInteriorLineCantBeBoundary());
-
- // and make sure that we don't
- // attempt to reset the
- // boundary indicator to a
- // different than the
- // previously set value
- if (line->boundary_indicator() != 0)
- AssertThrow (line->boundary_indicator() == boundary_line->boundary_id,
- ExcMessage ("Duplicate boundary lines are only allowed "
- "if they carry the same boundary indicator."));
-
- line->set_boundary_indicator (boundary_line->boundary_id);
- }
-
-
- // now go on with boundary faces
- std::vector<CellData<2> >::const_iterator boundary_quad
- = subcelldata.boundary_quads.begin();
- std::vector<CellData<2> >::const_iterator end_boundary_quad
- = subcelldata.boundary_quads.end();
- for (; boundary_quad!=end_boundary_quad; ++boundary_quad)
- {
- typename Triangulation<dim,spacedim>::quad_iterator quad;
- typename Triangulation<dim,spacedim>::line_iterator line[4];
-
- // first find the lines that
- // are made up of the given
- // vertices, then build up a
- // quad from these lines
- // finally use the find
- // function of the map template
- // to find the quad
- for (unsigned int i=0; i<4; ++i)
- {
- std::pair<int, int> line_vertices(
- boundary_quad->vertices[GeometryInfo<dim-1>::line_to_cell_vertices(i,0)],
- boundary_quad->vertices[GeometryInfo<dim-1>::line_to_cell_vertices(i,1)]);
-
- // check whether line
- // already exists
- if (needed_lines.find(line_vertices) != needed_lines.end())
- line[i] = needed_lines[line_vertices];
- else
- // look wether it exists
- // in reverse direction
- {
- std::swap (line_vertices.first, line_vertices.second);
- if (needed_lines.find(line_vertices) != needed_lines.end())
- line[i] = needed_lines[line_vertices];
- else
- // line does
- // not exist
- AssertThrow (false, ExcLineInexistant(line_vertices.first,
- line_vertices.second));
- }
- }
-
-
- // Set up 2 quads that are
- // built up from the lines for
- // reasons of comparison to
- // needed_quads. The second
- // quad is the reversed version
- // of the first quad in order
- // find the quad regardless of
- // its orientation. This is
- // introduced for convenience
- // and because boundary quad
- // orientation does not carry
- // any information.
- internal::Triangulation::TriaObject<2>
- quad_compare_1(line[0]->index(), line[1]->index(),
- line[2]->index(), line[3]->index());
- internal::Triangulation::TriaObject<2>
- quad_compare_2(line[2]->index(), line[3]->index(),
- line[0]->index(), line[1]->index());
-
- // try to find the quad with
- // lines situated as
- // constructed above. if it
- // could not be found, rotate
- // the boundary lines 3 times
- // until it is found or it does
- // not exist.
-
- // mapping from counterclock to
- // lexicographic ordering of
- // quad lines
- static const unsigned int lex2cclock[4]={3,1,0,2};
- // copy lines from
- // lexicographic to
- // counterclock ordering, as
- // rotation is much simpler in
- // counterclock ordering
- typename Triangulation<dim,spacedim>::line_iterator
- line_counterclock[4];
- for (unsigned int i=0; i<4; ++i)
- line_counterclock[lex2cclock[i]]=line[i];
- unsigned int n_rotations=0;
- bool not_found_quad_1;
- while ( (not_found_quad_1=(needed_quads.find(quad_compare_1) == needed_quads.end())) &&
- ( needed_quads.find(quad_compare_2) == needed_quads.end()) &&
- (n_rotations<4))
- {
- // use the rotate defined
- // in <algorithms>
- rotate(line_counterclock, line_counterclock+1, line_counterclock+4);
- // update the quads with
- // rotated lines (i runs in
- // lexicographic ordering)
- for (unsigned int i=0; i<4; ++i)
- {
- quad_compare_1.set_face(i, line_counterclock[lex2cclock[i]]->index());
- quad_compare_2.set_face((i+2)%4, line_counterclock[lex2cclock[i]]->index());
- }
-
- ++n_rotations;
- }
-
- AssertThrow (n_rotations!=4,
- ExcQuadInexistant(line[0]->index(), line[1]->index(),
- line[2]->index(), line[3]->index()));
-
- if (not_found_quad_1)
- quad = needed_quads[quad_compare_2].first;
- else
- quad = needed_quads[quad_compare_1].first;
-
- // check whether this face is
- // really an exterior one
- AssertThrow (quad->at_boundary(),
- ExcInteriorQuadCantBeBoundary());
-
- // and make sure that we don't
- // attempt to reset the
- // boundary indicator to a
- // different than the
- // previously set value
- if (quad->boundary_indicator() != 0)
- AssertThrow (quad->boundary_indicator() == boundary_quad->boundary_id,
- ExcMessage ("Duplicate boundary quads are only allowed "
- "if they carry the same boundary indicator."));
-
- quad->set_boundary_indicator (boundary_quad->boundary_id);
- }
-
-
- /////////////////////////////////////////
- // finally update neighborship info
- for (typename Triangulation<dim,spacedim>::cell_iterator
- cell=triangulation.begin(); cell!=triangulation.end(); ++cell)
- for (unsigned int face=0; face<6; ++face)
- if (adjacent_cells[cell->quad(face)->index()][0] == cell)
- // first adjacent cell is
- // this one
- {
- if (adjacent_cells[cell->quad(face)->index()].size() == 2)
- // there is another
- // adjacent cell
- cell->set_neighbor (face,
- adjacent_cells[cell->quad(face)->index()][1]);
- }
- // first adjacent cell is not this
- // one, -> it must be the neighbor
- // we are looking for
- else
- cell->set_neighbor (face,
- adjacent_cells[cell->quad(face)->index()][0]);
- }
-
-
- /**
- * Distort a 1d triangulation in
- * some random way.
- */
- template <int spacedim>
- static
- void
- distort_random (const double factor,
- const bool keep_boundary,
- Triangulation<1,spacedim> &triangulation)
- {
- const unsigned int dim = 1;
-
- // if spacedim>1 we need to
- // make sure that we perturb
- // points but keep them on
- // the manifold
- Assert (spacedim == 1,
- ExcNotImplemented());
-
- // this function is mostly
- // equivalent to that for the
- // general dimensional case the
- // only difference being the
- // correction for split faces which
- // is not necessary in 1D
-
- // find the smallest length of the
- // lines adjacent to the
- // vertex. take the initial value
- // to be larger than anything that
- // might be found: the diameter of
- // the triangulation, here computed
- // by adding up the diameters of
- // the coarse grid cells.
- double almost_infinite_length = 0;
- for (typename Triangulation<dim,spacedim>::cell_iterator
- cell=triangulation.begin(0); cell!=triangulation.end(0); ++cell)
- almost_infinite_length += cell->diameter();
-
- std::vector<double> minimal_length (triangulation.vertices.size(),
- almost_infinite_length);
- // also note if a vertex is at
- // the boundary
- std::vector<bool> at_boundary (triangulation.vertices.size(), false);
-
- for (typename Triangulation<dim,spacedim>::active_line_iterator
- line=triangulation.begin_active_line();
- line != triangulation.end_line(); ++line)
- {
- if (keep_boundary && line->at_boundary())
- {
- at_boundary[line->vertex_index(0)] = true;
- at_boundary[line->vertex_index(1)] = true;
- }
-
- minimal_length[line->vertex_index(0)]
- = std::min(line->diameter(),
- minimal_length[line->vertex_index(0)]);
- minimal_length[line->vertex_index(1)]
- = std::min(line->diameter(),
- minimal_length[line->vertex_index(1)]);
- }
-
-
- const unsigned int n_vertices = triangulation.vertices.size();
- Point<spacedim> shift_vector;
-
- for (unsigned int vertex=0; vertex<n_vertices; ++vertex)
- {
- // ignore this vertex if we
- // whall keep the boundary and
- // this vertex *is* at the
- // boundary
- if (keep_boundary && at_boundary[vertex])
- continue;
-
- // first compute a random shift
- // vector
- for (unsigned int d=0; d<spacedim; ++d)
- shift_vector(d) = std::rand()*1.0/RAND_MAX;
-
- shift_vector *= factor * minimal_length[vertex] /
- std::sqrt(shift_vector.square());
-
- // finally move the vertex
- triangulation.vertices[vertex] += shift_vector;
- }
- }
-
-
- /**
- * Distort a triangulation in
- * some random way. This is the
- * function taken for the case
- * dim>1.
- */
- template <int dim, int spacedim>
- static
- void
- distort_random (const double factor,
- const bool keep_boundary,
- Triangulation<dim,spacedim> &triangulation)
- {
+ }
+ }
+
+
+ /////////////////////////////////////////
+ // find those quads which are at the
+ // boundary and mark them appropriately
+ for (typename Triangulation<dim,spacedim>::quad_iterator
+ quad=triangulation.begin_quad(); quad!=triangulation.end_quad(); ++quad)
+ {
+ const unsigned int n_adj_cells = adjacent_cells[quad->index()].size();
+ // assert that every quad has
+ // one or two adjacent cells
+ AssertThrow ((n_adj_cells >= 1) &&
+ (n_adj_cells <= 2),
+ ExcInternalError());
+
+ // if only one cell: quad is at
+ // boundary -> give it the
+ // boundary indicator zero by
+ // default
+ if (n_adj_cells == 1)
+ quad->set_boundary_indicator (0);
+ else
+ // interior quad -> types::internal_face_boundary_id
+ quad->set_boundary_indicator (types::internal_face_boundary_id);
+ }
+
+ /////////////////////////////////////////
+ // next find those lines which are at
+ // the boundary and mark all others as
+ // interior ones
+ //
+ // for this: first mark all lines
+ // as interior
+ for (typename Triangulation<dim,spacedim>::line_iterator
+ line=triangulation.begin_line(); line!=triangulation.end_line(); ++line)
+ line->set_boundary_indicator (types::internal_face_boundary_id);
+ // next reset all lines bounding
+ // boundary quads as on the
+ // boundary also. note that since
+ // we are in 3d, there are cases
+ // where one or more lines of a
+ // quad that is not on the
+ // boundary, are actually boundary
+ // lines. they will not be marked
+ // when visiting this
+ // face. however, since we do not
+ // support dim-2 dimensional
+ // boundaries (i.e. internal lines
+ // constituting boundaries), every
+ // such line is also part of a face
+ // that is actually on the
+ // boundary, so sooner or later we
+ // get to mark that line for being
+ // on the boundary
+ for (typename Triangulation<dim,spacedim>::quad_iterator
+ quad=triangulation.begin_quad(); quad!=triangulation.end_quad(); ++quad)
+ if (quad->at_boundary())
+ for (unsigned int l=0; l<4; ++l)
+ quad->line(l)->set_boundary_indicator (0);
+
+ ///////////////////////////////////////
+ // now set boundary indicators
+ // where given
+ //
+ // first do so for lines
+ std::vector<CellData<1> >::const_iterator boundary_line
+ = subcelldata.boundary_lines.begin();
+ std::vector<CellData<1> >::const_iterator end_boundary_line
+ = subcelldata.boundary_lines.end();
+ for (; boundary_line!=end_boundary_line; ++boundary_line)
+ {
+ typename Triangulation<dim,spacedim>::line_iterator line;
+ std::pair <int, int> line_vertices(std::make_pair(boundary_line->vertices[0],
+ boundary_line->vertices[1]));
+ if (needed_lines.find(line_vertices) != needed_lines.end())
+ // line found in this
+ // direction
+ line = needed_lines[line_vertices];
+
+ else
+ {
+ // look wether it exists in
+ // reverse direction
+ std::swap (line_vertices.first, line_vertices.second);
+ if (needed_lines.find(line_vertices) != needed_lines.end())
+ line = needed_lines[line_vertices];
+ else
+ // line does not exist
+ AssertThrow (false, ExcLineInexistant(line_vertices.first,
+ line_vertices.second));
+ }
+ // Assert that only exterior
+ // lines are given a boundary
+ // indicator
+ AssertThrow (line->at_boundary(),
+ ExcInteriorLineCantBeBoundary());
+
+ // and make sure that we don't
+ // attempt to reset the
+ // boundary indicator to a
+ // different than the
+ // previously set value
+ if (line->boundary_indicator() != 0)
+ AssertThrow (line->boundary_indicator() == boundary_line->boundary_id,
+ ExcMessage ("Duplicate boundary lines are only allowed "
+ "if they carry the same boundary indicator."));
+
+ line->set_boundary_indicator (boundary_line->boundary_id);
+ }
+
+
+ // now go on with boundary faces
+ std::vector<CellData<2> >::const_iterator boundary_quad
+ = subcelldata.boundary_quads.begin();
+ std::vector<CellData<2> >::const_iterator end_boundary_quad
+ = subcelldata.boundary_quads.end();
+ for (; boundary_quad!=end_boundary_quad; ++boundary_quad)
+ {
+ typename Triangulation<dim,spacedim>::quad_iterator quad;
+ typename Triangulation<dim,spacedim>::line_iterator line[4];
+
+ // first find the lines that
+ // are made up of the given
+ // vertices, then build up a
+ // quad from these lines
+ // finally use the find
+ // function of the map template
+ // to find the quad
+ for (unsigned int i=0; i<4; ++i)
+ {
+ std::pair<int, int> line_vertices(
+ boundary_quad->vertices[GeometryInfo<dim-1>::line_to_cell_vertices(i,0)],
+ boundary_quad->vertices[GeometryInfo<dim-1>::line_to_cell_vertices(i,1)]);
+
+ // check whether line
+ // already exists
+ if (needed_lines.find(line_vertices) != needed_lines.end())
+ line[i] = needed_lines[line_vertices];
+ else
+ // look wether it exists
+ // in reverse direction
+ {
+ std::swap (line_vertices.first, line_vertices.second);
+ if (needed_lines.find(line_vertices) != needed_lines.end())
+ line[i] = needed_lines[line_vertices];
+ else
+ // line does
+ // not exist
+ AssertThrow (false, ExcLineInexistant(line_vertices.first,
+ line_vertices.second));
+ }
+ }
+
+
+ // Set up 2 quads that are
+ // built up from the lines for
+ // reasons of comparison to
+ // needed_quads. The second
+ // quad is the reversed version
+ // of the first quad in order
+ // find the quad regardless of
+ // its orientation. This is
+ // introduced for convenience
+ // and because boundary quad
+ // orientation does not carry
+ // any information.
+ internal::Triangulation::TriaObject<2>
+ quad_compare_1(line[0]->index(), line[1]->index(),
+ line[2]->index(), line[3]->index());
+ internal::Triangulation::TriaObject<2>
+ quad_compare_2(line[2]->index(), line[3]->index(),
+ line[0]->index(), line[1]->index());
+
+ // try to find the quad with
+ // lines situated as
+ // constructed above. if it
+ // could not be found, rotate
+ // the boundary lines 3 times
+ // until it is found or it does
+ // not exist.
+
+ // mapping from counterclock to
+ // lexicographic ordering of
+ // quad lines
+ static const unsigned int lex2cclock[4]={3,1,0,2};
+ // copy lines from
+ // lexicographic to
+ // counterclock ordering, as
+ // rotation is much simpler in
+ // counterclock ordering
+ typename Triangulation<dim,spacedim>::line_iterator
+ line_counterclock[4];
+ for (unsigned int i=0; i<4; ++i)
+ line_counterclock[lex2cclock[i]]=line[i];
+ unsigned int n_rotations=0;
+ bool not_found_quad_1;
+ while ( (not_found_quad_1=(needed_quads.find(quad_compare_1) == needed_quads.end())) &&
+ ( needed_quads.find(quad_compare_2) == needed_quads.end()) &&
+ (n_rotations<4))
+ {
+ // use the rotate defined
+ // in <algorithms>
+ rotate(line_counterclock, line_counterclock+1, line_counterclock+4);
+ // update the quads with
+ // rotated lines (i runs in
+ // lexicographic ordering)
+ for (unsigned int i=0; i<4; ++i)
+ {
+ quad_compare_1.set_face(i, line_counterclock[lex2cclock[i]]->index());
+ quad_compare_2.set_face((i+2)%4, line_counterclock[lex2cclock[i]]->index());
+ }
+
+ ++n_rotations;
+ }
+
+ AssertThrow (n_rotations!=4,
+ ExcQuadInexistant(line[0]->index(), line[1]->index(),
+ line[2]->index(), line[3]->index()));
+
+ if (not_found_quad_1)
+ quad = needed_quads[quad_compare_2].first;
+ else
+ quad = needed_quads[quad_compare_1].first;
+
+ // check whether this face is
+ // really an exterior one
+ AssertThrow (quad->at_boundary(),
+ ExcInteriorQuadCantBeBoundary());
+
+ // and make sure that we don't
+ // attempt to reset the
+ // boundary indicator to a
+ // different than the
+ // previously set value
+ if (quad->boundary_indicator() != 0)
+ AssertThrow (quad->boundary_indicator() == boundary_quad->boundary_id,
+ ExcMessage ("Duplicate boundary quads are only allowed "
+ "if they carry the same boundary indicator."));
+
+ quad->set_boundary_indicator (boundary_quad->boundary_id);
+ }
+
+
+ /////////////////////////////////////////
+ // finally update neighborship info
+ for (typename Triangulation<dim,spacedim>::cell_iterator
+ cell=triangulation.begin(); cell!=triangulation.end(); ++cell)
+ for (unsigned int face=0; face<6; ++face)
+ if (adjacent_cells[cell->quad(face)->index()][0] == cell)
+ // first adjacent cell is
+ // this one
+ {
+ if (adjacent_cells[cell->quad(face)->index()].size() == 2)
+ // there is another
+ // adjacent cell
+ cell->set_neighbor (face,
+ adjacent_cells[cell->quad(face)->index()][1]);
+ }
+ // first adjacent cell is not this
+ // one, -> it must be the neighbor
+ // we are looking for
+ else
+ cell->set_neighbor (face,
+ adjacent_cells[cell->quad(face)->index()][0]);
+ }
+
+
+ /**
+ * Distort a 1d triangulation in
+ * some random way.
+ */
+ template <int spacedim>
+ static
+ void
+ distort_random (const double factor,
+ const bool keep_boundary,
+ Triangulation<1,spacedim> &triangulation)
+ {
+ const unsigned int dim = 1;
+
+ // if spacedim>1 we need to
+ // make sure that we perturb
+ // points but keep them on
+ // the manifold
+ Assert (spacedim == 1,
+ ExcNotImplemented());
+
+ // this function is mostly
+ // equivalent to that for the
+ // general dimensional case the
+ // only difference being the
+ // correction for split faces which
+ // is not necessary in 1D
+
+ // find the smallest length of the
+ // lines adjacent to the
+ // vertex. take the initial value
+ // to be larger than anything that
+ // might be found: the diameter of
+ // the triangulation, here computed
+ // by adding up the diameters of
+ // the coarse grid cells.
+ double almost_infinite_length = 0;
+ for (typename Triangulation<dim,spacedim>::cell_iterator
+ cell=triangulation.begin(0); cell!=triangulation.end(0); ++cell)
+ almost_infinite_length += cell->diameter();
+
+ std::vector<double> minimal_length (triangulation.vertices.size(),
+ almost_infinite_length);
+ // also note if a vertex is at
+ // the boundary
+ std::vector<bool> at_boundary (triangulation.vertices.size(), false);
+
+ for (typename Triangulation<dim,spacedim>::active_line_iterator
+ line=triangulation.begin_active_line();
+ line != triangulation.end_line(); ++line)
+ {
+ if (keep_boundary && line->at_boundary())
+ {
+ at_boundary[line->vertex_index(0)] = true;
+ at_boundary[line->vertex_index(1)] = true;
+ }
+
+ minimal_length[line->vertex_index(0)]
+ = std::min(line->diameter(),
+ minimal_length[line->vertex_index(0)]);
+ minimal_length[line->vertex_index(1)]
+ = std::min(line->diameter(),
+ minimal_length[line->vertex_index(1)]);
+ }
+
+
+ const unsigned int n_vertices = triangulation.vertices.size();
+ Point<spacedim> shift_vector;
+
+ for (unsigned int vertex=0; vertex<n_vertices; ++vertex)
+ {
+ // ignore this vertex if we
+ // whall keep the boundary and
+ // this vertex *is* at the
+ // boundary
+ if (keep_boundary && at_boundary[vertex])
+ continue;
+
+ // first compute a random shift
+ // vector
+ for (unsigned int d=0; d<spacedim; ++d)
+ shift_vector(d) = std::rand()*1.0/RAND_MAX;
+
+ shift_vector *= factor * minimal_length[vertex] /
+ std::sqrt(shift_vector.square());
+
+ // finally move the vertex
+ triangulation.vertices[vertex] += shift_vector;
+ }
+ }
+
+
+ /**
+ * Distort a triangulation in
+ * some random way. This is the
+ * function taken for the case
+ * dim>1.
+ */
+ template <int dim, int spacedim>
+ static
+ void
+ distort_random (const double factor,
+ const bool keep_boundary,
+ Triangulation<dim,spacedim> &triangulation)
+ {
//TODO:[?]Implement the random distortion in Triangulation for hanging nodes as well
// Hanging nodes need to be reset to the correct mean value
// at the end, which is simple for 2D but difficult for 3D. Maybe take
// a look at how we get to the original location of the point in the
// execute_refinement function and copy the relevant lines.
- // this function is mostly
- // equivalent to that for the
- // general dimensional case the
- // only difference being the
- // correction for split faces which
- // is not necessary in 1D
- //
- // if you change something here,
- // don't forget to do so there as
- // well
-
- // find the smallest length of the
- // lines adjacent to the
- // vertex. take the initial value
- // to be larger than anything that
- // might be found: the diameter of
- // the triangulation, here
- // estimated by adding up the
- // diameters of the coarse grid
- // cells.
- double almost_infinite_length = 0;
- for (typename Triangulation<dim,spacedim>::cell_iterator
- cell=triangulation.begin(0); cell!=triangulation.end(0); ++cell)
- almost_infinite_length += cell->diameter();
-
- std::vector<double> minimal_length (triangulation.vertices.size(),
- almost_infinite_length);
-
- // also note if a vertex is at the
- // boundary
- std::vector<bool> at_boundary (triangulation.vertices.size(), false);
-
- for (typename Triangulation<dim,spacedim>::active_line_iterator
- line=triangulation.begin_active_line();
- line != triangulation.end_line(); ++line)
- {
- if (keep_boundary && line->at_boundary())
- {
- at_boundary[line->vertex_index(0)] = true;
- at_boundary[line->vertex_index(1)] = true;
- }
-
- minimal_length[line->vertex_index(0)]
- = std::min(line->diameter(),
- minimal_length[line->vertex_index(0)]);
- minimal_length[line->vertex_index(1)]
- = std::min(line->diameter(),
- minimal_length[line->vertex_index(1)]);
- }
-
-
- const unsigned int n_vertices = triangulation.vertices.size();
- Point<spacedim> shift_vector;
-
- for (unsigned int vertex=0; vertex<n_vertices; ++vertex)
- {
- // ignore this vertex if we
- // whall keep the boundary and
- // this vertex *is* at the
- // boundary
- if (keep_boundary && at_boundary[vertex])
- continue;
-
- // first compute a random shift
- // vector
- for (unsigned int d=0; d<spacedim; ++d)
- shift_vector(d) = std::rand()*1.0/RAND_MAX;
-
- shift_vector *= factor * minimal_length[vertex] /
- std::sqrt(shift_vector.square());
-
- // finally move the vertex
- triangulation.vertices[vertex] += shift_vector;
- }
-
-
- // finally correct hanging nodes
- // again. The following is not
- // necessary for 1D
- typename Triangulation<dim,spacedim>::active_cell_iterator
- cell = triangulation.begin_active(),
- endc = triangulation.end();
- for (; cell!=endc; ++cell)
- for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
- if (cell->face(face)->has_children() &&
- !cell->face(face)->at_boundary())
- // this lines has children,
- // thus there are restricted
- // nodes
- {
- // not implemented at
- // present for dim=3 or
- // higher
- Assert (dim<=2, ExcNotImplemented());
-
- // compute where the common
- // point of the two child
- // lines will lie and reset
- // it to the correct value
- triangulation.vertices[cell->face(face)->child(0)->vertex_index(1)]
- = (cell->face(face)->vertex(0) +
- cell->face(face)->vertex(1)) / 2;
- }
- }
-
-
- /**
- * Actually delete a cell, or rather all
- * its children, which is the main step for
- * the coarsening process. This is the
- * dimension dependent part of @p
- * execute_coarsening. The second argument
- * is a vector which gives for each line
- * index the number of cells containing
- * this line. This information is needed to
- * decide whether a refined line may be
- * coarsened or not in 3D. In 1D and 2D
- * this argument is not needed and thus
- * ignored. The same applies for the last
- * argument and quads instead of lines.
- */
- template <int spacedim>
- static
- void
- delete_children (Triangulation<1,spacedim> &triangulation,
- typename Triangulation<1,spacedim>::cell_iterator &cell,
- std::vector<unsigned int> &,
- std::vector<unsigned int> &)
- {
- const unsigned int dim = 1;
-
- // first we need to reset the
- // neighbor pointers of the
- // neighbors of this cell's
- // children to this cell. This is
- // different for one dimension,
- // since there neighbors can have a
- // refinement level differing from
- // that of this cell's children by
- // more than one level.
-
- Assert (!cell->child(0)->has_children() && !cell->child(1)->has_children(),
- ExcInternalError());
-
- // first do it for the cells to the
- // left
- if (cell->neighbor(0).state() == IteratorState::valid)
- if (cell->neighbor(0)->has_children())
- {
- typename Triangulation<dim,spacedim>::cell_iterator
- neighbor = cell->neighbor(0);
- Assert (neighbor->level() == cell->level(), ExcInternalError());
-
- // right child
- neighbor = neighbor->child(1);
- while (1)
- {
- Assert (neighbor->neighbor(1) == cell->child(0),
- ExcInternalError());
- neighbor->set_neighbor (1, cell);
-
- // move on to further
- // children on the
- // boundary between this
- // cell and its neighbor
- if (neighbor->has_children())
- neighbor = neighbor->child(1);
- else
- break;
- }
- }
-
- // now do it for the cells to the
- // left
- if (cell->neighbor(1).state() == IteratorState::valid)
- if (cell->neighbor(1)->has_children())
- {
- typename Triangulation<dim,spacedim>::cell_iterator
- neighbor = cell->neighbor(1);
- Assert (neighbor->level() == cell->level(), ExcInternalError());
-
- // left child
- neighbor = neighbor->child(0);
- while (1)
- {
- Assert (neighbor->neighbor(0) == cell->child(1),
- ExcInternalError());
- neighbor->set_neighbor (0, cell);
-
- // move on to further
- // children on the
- // boundary between this
- // cell and its neighbor
- if (neighbor->has_children())
- neighbor = neighbor->child(0);
- else
- break;
- }
- }
-
-
- // delete the vertex which will not
- // be needed anymore. This vertex
- // is the second of the first child
- triangulation.vertices_used[cell->child(0)->vertex_index(1)] = false;
-
- // invalidate children. clear user
- // pointers, to avoid that they may
- // appear at unwanted places later
- // on...
- for (unsigned int child=0; child<cell->n_children(); ++child)
- {
- cell->child(child)->clear_user_data();
- cell->child(child)->clear_user_flag();
- cell->child(child)->clear_used_flag();
- }
-
-
- // delete pointer to children
- cell->clear_children ();
- cell->clear_user_flag();
- }
-
-
-
- template <int spacedim>
- static
- void
- delete_children (Triangulation<2,spacedim> &triangulation,
- typename Triangulation<2,spacedim>::cell_iterator &cell,
- std::vector<unsigned int> &line_cell_count,
- std::vector<unsigned int> &)
- {
- const unsigned int dim=2;
- const RefinementCase<dim> ref_case=cell->refinement_case();
-
- Assert(line_cell_count.size()==triangulation.n_raw_lines(), ExcInternalError());
-
- // vectors to hold all lines which
- // may be deleted
- std::vector<typename Triangulation<dim,spacedim>::line_iterator>
- lines_to_delete(0);
-
- lines_to_delete.reserve(4*2+4);
-
- // now we decrease the counters for
- // lines contained in the child
- // cells
- for (unsigned int c=0; c<cell->n_children(); ++c)
- {
- typename Triangulation<dim,spacedim>::cell_iterator
- child=cell->child(c);
- for (unsigned int l=0; l<GeometryInfo<dim>::lines_per_cell; ++l)
- --line_cell_count[child->line_index(l)];
- }
-
-
- // delete the vertex which will not
- // be needed anymore. This vertex
- // is the second of the second line
- // of the first child, if the cell
- // is refined with cut_xy, else there
- // is no inner vertex.
- // additionally delete unneeded inner
- // lines
- if (ref_case==RefinementCase<dim>::cut_xy)
- {
- triangulation.vertices_used[cell->child(0)->line(1)->vertex_index(1)] = false;
-
- lines_to_delete.push_back(cell->child(0)->line(1));
- lines_to_delete.push_back(cell->child(0)->line(3));
- lines_to_delete.push_back(cell->child(3)->line(0));
- lines_to_delete.push_back(cell->child(3)->line(2));
- }
- else
- {
- unsigned int inner_face_no=ref_case==RefinementCase<dim>::cut_x ? 1 : 3;
-
- // the inner line will not be
- // used any more
- lines_to_delete.push_back(cell->child(0)->line(inner_face_no));
- }
-
- // invalidate children
- for (unsigned int child=0; child<cell->n_children(); ++child)
- {
- cell->child(child)->clear_user_data();
- cell->child(child)->clear_user_flag();
- cell->child(child)->clear_used_flag();
- }
-
-
- // delete pointer to children
- cell->clear_children ();
- cell->clear_refinement_case();
- cell->clear_user_flag();
-
- // look at the refinement of outer
- // lines. if nobody needs those
- // anymore we can add them to the
- // list of lines to be deleted.
- for (unsigned int line_no=0; line_no<GeometryInfo<dim>::lines_per_cell; ++line_no)
- {
- typename Triangulation<dim,spacedim>::line_iterator
- line=cell->line(line_no);
-
- if (line->has_children())
- {
- // if one of the cell counters is
- // zero, the other has to be as well
-
- Assert((line_cell_count[line->child_index(0)] == 0 &&
- line_cell_count[line->child_index(1)] == 0) ||
- (line_cell_count[line->child_index(0)] > 0 &&
- line_cell_count[line->child_index(1)] > 0),
- ExcInternalError());
-
- if (line_cell_count[line->child_index(0)]==0)
- {
- for (unsigned int c=0; c<2; ++c)
- Assert (!line->child(c)->has_children(),
- ExcInternalError());
-
- // we may delete the line's
- // children and the middle vertex
- // as no cell references them
- // anymore
- triangulation.vertices_used[line->child(0)->vertex_index(1)] = false;
-
- lines_to_delete.push_back(line->child(0));
- lines_to_delete.push_back(line->child(1));
-
- line->clear_children();
- }
- }
- }
-
- // finally, delete unneeded lines
-
- // clear user pointers, to avoid that
- // they may appear at unwanted places
- // later on...
- // same for user flags, then finally
- // delete the lines
- typename std::vector<typename Triangulation<dim,spacedim>::line_iterator>::iterator
- line=lines_to_delete.begin(),
- endline=lines_to_delete.end();
- for (; line!=endline; ++line)
- {
- (*line)->clear_user_data();
- (*line)->clear_user_flag();
- (*line)->clear_used_flag();
- }
- }
-
-
-
- template <int spacedim>
- static
- void
- delete_children (Triangulation<3,spacedim> &triangulation,
- typename Triangulation<3,spacedim>::cell_iterator &cell,
- std::vector<unsigned int> &line_cell_count,
- std::vector<unsigned int> &quad_cell_count)
- {
- const unsigned int dim=3;
-
- Assert(line_cell_count.size()==triangulation.n_raw_lines(), ExcInternalError());
- Assert(quad_cell_count.size()==triangulation.n_raw_quads(), ExcInternalError());
-
- // first of all, we store the RefineCase of
- // this cell
- const RefinementCase<dim> ref_case=cell->refinement_case();
- // vectors to hold all lines and quads which
- // may be deleted
- std::vector<typename Triangulation<dim,spacedim>::line_iterator>
- lines_to_delete(0);
- std::vector<typename Triangulation<dim,spacedim>::quad_iterator>
- quads_to_delete(0);
-
- lines_to_delete.reserve(12*2+6*4+6);
- quads_to_delete.reserve(6*4+12);
-
- // now we decrease the counters for lines and
- // quads contained in the child cells
- for (unsigned int c=0; c<cell->n_children(); ++c)
- {
- typename Triangulation<dim,spacedim>::cell_iterator
- child=cell->child(c);
- for (unsigned int l=0; l<GeometryInfo<dim>::lines_per_cell; ++l)
- --line_cell_count[child->line_index(l)];
- for (unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell; ++f)
- --quad_cell_count[child->quad_index(f)];
- }
-
- ///////////////////////////////////////
- // delete interior quads and lines and the
- // interior vertex, depending on the
- // refinement case of the cell
- //
- // for append quads and lines: only append
- // them to the list of objects to be deleted
-
- switch (ref_case)
- {
- case RefinementCase<dim>::cut_x:
- quads_to_delete.push_back(cell->child(0)->face(1));
- break;
- case RefinementCase<dim>::cut_y:
- quads_to_delete.push_back(cell->child(0)->face(3));
- break;
- case RefinementCase<dim>::cut_z:
- quads_to_delete.push_back(cell->child(0)->face(5));
- break;
- case RefinementCase<dim>::cut_xy:
- quads_to_delete.push_back(cell->child(0)->face(1));
- quads_to_delete.push_back(cell->child(0)->face(3));
- quads_to_delete.push_back(cell->child(3)->face(0));
- quads_to_delete.push_back(cell->child(3)->face(2));
-
- lines_to_delete.push_back(cell->child(0)->line(11));
- break;
- case RefinementCase<dim>::cut_xz:
- quads_to_delete.push_back(cell->child(0)->face(1));
- quads_to_delete.push_back(cell->child(0)->face(5));
- quads_to_delete.push_back(cell->child(3)->face(0));
- quads_to_delete.push_back(cell->child(3)->face(4));
-
- lines_to_delete.push_back(cell->child(0)->line(5));
- break;
- case RefinementCase<dim>::cut_yz:
- quads_to_delete.push_back(cell->child(0)->face(3));
- quads_to_delete.push_back(cell->child(0)->face(5));
- quads_to_delete.push_back(cell->child(3)->face(2));
- quads_to_delete.push_back(cell->child(3)->face(4));
-
- lines_to_delete.push_back(cell->child(0)->line(7));
- break;
- case RefinementCase<dim>::cut_xyz:
- quads_to_delete.push_back(cell->child(0)->face(1));
- quads_to_delete.push_back(cell->child(2)->face(1));
- quads_to_delete.push_back(cell->child(4)->face(1));
- quads_to_delete.push_back(cell->child(6)->face(1));
-
- quads_to_delete.push_back(cell->child(0)->face(3));
- quads_to_delete.push_back(cell->child(1)->face(3));
- quads_to_delete.push_back(cell->child(4)->face(3));
- quads_to_delete.push_back(cell->child(5)->face(3));
-
- quads_to_delete.push_back(cell->child(0)->face(5));
- quads_to_delete.push_back(cell->child(1)->face(5));
- quads_to_delete.push_back(cell->child(2)->face(5));
- quads_to_delete.push_back(cell->child(3)->face(5));
-
- lines_to_delete.push_back(cell->child(0)->line(5));
- lines_to_delete.push_back(cell->child(0)->line(7));
- lines_to_delete.push_back(cell->child(0)->line(11));
- lines_to_delete.push_back(cell->child(7)->line(0));
- lines_to_delete.push_back(cell->child(7)->line(2));
- lines_to_delete.push_back(cell->child(7)->line(8));
- // delete the vertex which will not
- // be needed anymore. This vertex
- // is the vertex at the heart of
- // this cell, which is the sixth of
- // the first child
- triangulation.vertices_used[cell->child(0)->vertex_index(7)] = false;
- break;
- default:
- // only remaining case is
- // no_refinement, thus an error
- Assert(false, ExcInternalError());
- break;
- }
-
-
- // invalidate children
- for (unsigned int child=0; child<cell->n_children(); ++child)
- {
- cell->child(child)->clear_user_data();
- cell->child(child)->clear_user_flag();
-
- for (unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell; ++f)
- {
- // set flags denoting deviations from
- // standard orientation of faces back
- // to initialization values
- cell->child(child)->set_face_orientation (f, true);
- cell->child(child)->set_face_flip(f,false);
- cell->child(child)->set_face_rotation(f,false);
- }
-
- cell->child(child)->clear_used_flag();
- }
-
-
- // delete pointer to children
- cell->clear_children ();
- cell->clear_refinement_case ();
- cell->clear_user_flag();
-
- // so far we only looked at inner quads,
- // lines and vertices. Now we have to
- // consider outer ones as well. here, we have
- // to check, whether there are other cells
- // still needing these objects. oherwise we
- // can delete them. first for quads (and
- // their inner lines).
-
- for (unsigned int quad_no=0; quad_no<GeometryInfo<dim>::faces_per_cell; ++quad_no)
- {
- typename Triangulation<dim,spacedim>::quad_iterator
- quad=cell->face(quad_no);
-
- Assert((GeometryInfo<dim>::face_refinement_case(ref_case,quad_no) && quad->has_children()) ||
- GeometryInfo<dim>::face_refinement_case(ref_case,quad_no)==RefinementCase<dim-1>::no_refinement,
- ExcInternalError());
-
- switch (quad->refinement_case())
- {
- case RefinementCase<dim-1>::no_refinement:
- // nothing to do as the quad
- // is not refined
- break;
- case RefinementCase<dim-1>::cut_x:
- case RefinementCase<dim-1>::cut_y:
- {
- // if one of the cell counters is
- // zero, the other has to be as
- // well
- Assert((quad_cell_count[quad->child_index(0)] == 0 &&
- quad_cell_count[quad->child_index(1)] == 0) ||
- (quad_cell_count[quad->child_index(0)] > 0 &&
- quad_cell_count[quad->child_index(1)] > 0),
- ExcInternalError());
- // it might be, that the quad is
- // refined twice anisotropically,
- // first check, whether we may
- // delete possible grand_children
- unsigned int deleted_grandchildren=0;
- unsigned int number_of_child_refinements=0;
-
- for (unsigned int c=0; c<2; ++c)
- if (quad->child(c)->has_children())
- {
- ++number_of_child_refinements;
- // if one of the cell counters is
- // zero, the other has to be as
- // well
- Assert((quad_cell_count[quad->child(c)->child_index(0)] == 0 &&
- quad_cell_count[quad->child(c)->child_index(1)] == 0) ||
- (quad_cell_count[quad->child(c)->child_index(0)] > 0 &&
- quad_cell_count[quad->child(c)->child_index(1)] > 0),
- ExcInternalError());
- if (quad_cell_count[quad->child(c)->child_index(0)]==0)
- {
- // Assert, that the two
- // anisotropic
- // refinements add up to
- // isotropic refinement
- Assert(quad->refinement_case()+quad->child(c)->refinement_case()==RefinementCase<dim>::cut_xy,
- ExcInternalError());
- // we may delete the
- // quad's children and
- // the inner line as no
- // cell references them
- // anymore
- quads_to_delete.push_back(quad->child(c)->child(0));
- quads_to_delete.push_back(quad->child(c)->child(1));
- if (quad->child(c)->refinement_case()==RefinementCase<2>::cut_x)
- lines_to_delete.push_back(quad->child(c)->child(0)->line(1));
- else
- lines_to_delete.push_back(quad->child(c)->child(0)->line(3));
- quad->child(c)->clear_children();
- quad->child(c)->clear_refinement_case();
- ++deleted_grandchildren;
- }
- }
- // if no grandchildren are left, we
- // may as well delete the
- // refinement of the inner line
- // between our children and the
- // corresponding vertex
- if (number_of_child_refinements>0 &&
- deleted_grandchildren==number_of_child_refinements)
- {
- typename Triangulation<dim,spacedim>::line_iterator
- middle_line;
- if (quad->refinement_case()==RefinementCase<2>::cut_x)
- middle_line=quad->child(0)->line(1);
- else
- middle_line=quad->child(0)->line(3);
-
- lines_to_delete.push_back(middle_line->child(0));
- lines_to_delete.push_back(middle_line->child(1));
- triangulation.vertices_used[middle_vertex_index<dim,spacedim>(middle_line)]
- = false;
- middle_line->clear_children();
- }
-
- // now consider the direct children
- // of the given quad
- if (quad_cell_count[quad->child_index(0)]==0)
- {
- // we may delete the quad's
- // children and the inner line
- // as no cell references them
- // anymore
- quads_to_delete.push_back(quad->child(0));
- quads_to_delete.push_back(quad->child(1));
- if (quad->refinement_case()==RefinementCase<2>::cut_x)
- lines_to_delete.push_back(quad->child(0)->line(1));
- else
- lines_to_delete.push_back(quad->child(0)->line(3));
-
- // if the counters just dropped
- // to zero, otherwise the
- // children would have been
- // deleted earlier, then this
- // cell's children must have
- // contained the anisotropic
- // quad children. thus, if
- // those have again anisotropic
- // children, which are in
- // effect isotropic children of
- // the original quad, those are
- // still needed by a
- // neighboring cell and we
- // cannot delete them. instead,
- // we have to reset this quad's
- // refine case to isotropic and
- // set the children
- // accordingly.
- if (quad->child(0)->has_children())
- if (quad->refinement_case()==RefinementCase<2>::cut_x)
- {
- // now evereything is
- // quite complicated. we
- // have the children
- // numbered according to
- //
- // *---*---*
- // |n+1|m+1|
- // *---*---*
- // | n | m |
- // *---*---*
- //
- // from the original
- // anisotropic
- // refinement. we have to
- // reorder them as
- //
- // *---*---*
- // | m |m+1|
- // *---*---*
- // | n |n+1|
- // *---*---*
- //
- // for isotropic refinement.
- //
- // this is a bit ugly, of
- // course: loop over all
- // cells on all levels
- // and look for faces n+1
- // (switch_1) and m
- // (switch_2).
- const typename Triangulation<dim,spacedim>::quad_iterator
- switch_1=quad->child(0)->child(1),
- switch_2=quad->child(1)->child(0);
-
- Assert(!switch_1->has_children(), ExcInternalError());
- Assert(!switch_2->has_children(), ExcInternalError());
-
- const int switch_1_index=switch_1->index();
- const int switch_2_index=switch_2->index();
- for (unsigned int l=0; l<triangulation.levels.size(); ++l)
- for (unsigned int h=0; h<triangulation.levels[l]->cells.cells.size(); ++h)
- for (unsigned int q=0; q<GeometryInfo<dim>::faces_per_cell; ++q)
- {
- const int index=triangulation.levels[l]->cells.cells[h].face(q);
- if (index==switch_1_index)
- triangulation.levels[l]->cells.cells[h].set_face(q,switch_2_index);
- else if (index==switch_2_index)
- triangulation.levels[l]->cells.cells[h].set_face(q,switch_1_index);
- }
- // now we have to copy
- // all information of the
- // two quads
- const int switch_1_lines[4]=
- {switch_1->line_index(0),
- switch_1->line_index(1),
- switch_1->line_index(2),
- switch_1->line_index(3)};
- const bool switch_1_line_orientations[4]=
- {switch_1->line_orientation(0),
- switch_1->line_orientation(1),
- switch_1->line_orientation(2),
- switch_1->line_orientation(3)};
- const types::boundary_id_t switch_1_boundary_indicator=switch_1->boundary_indicator();
- const unsigned int switch_1_user_index=switch_1->user_index();
- const bool switch_1_user_flag=switch_1->user_flag_set();
-
- switch_1->set(internal::Triangulation::TriaObject<2>(switch_2->line_index(0),
- switch_2->line_index(1),
- switch_2->line_index(2),
- switch_2->line_index(3)));
- switch_1->set_line_orientation(0, switch_2->line_orientation(0));
- switch_1->set_line_orientation(1, switch_2->line_orientation(1));
- switch_1->set_line_orientation(2, switch_2->line_orientation(2));
- switch_1->set_line_orientation(3, switch_2->line_orientation(3));
- switch_1->set_boundary_indicator(switch_2->boundary_indicator());
- switch_1->set_user_index(switch_2->user_index());
- if (switch_2->user_flag_set())
- switch_1->set_user_flag();
- else
- switch_1->clear_user_flag();
-
- switch_2->set(internal::Triangulation::TriaObject<2>(switch_1_lines[0],
- switch_1_lines[1],
- switch_1_lines[2],
- switch_1_lines[3]));
- switch_2->set_line_orientation(0, switch_1_line_orientations[0]);
- switch_2->set_line_orientation(1, switch_1_line_orientations[1]);
- switch_2->set_line_orientation(2, switch_1_line_orientations[2]);
- switch_2->set_line_orientation(3, switch_1_line_orientations[3]);
- switch_2->set_boundary_indicator(switch_1_boundary_indicator);
- switch_2->set_user_index(switch_1_user_index);
- if (switch_1_user_flag)
- switch_2->set_user_flag();
- else
- switch_2->clear_user_flag();
-
- const unsigned int child_0=quad->child(0)->child_index(0);
- const unsigned int child_2=quad->child(1)->child_index(0);
- quad->clear_children();
- quad->clear_refinement_case();
- quad->set_refinement_case(RefinementCase<2>::cut_xy);
- quad->set_children(0,child_0);
- quad->set_children(2,child_2);
- std::swap(quad_cell_count[child_0+1],quad_cell_count[child_2]);
- }
- else
- {
- // the face was refined
- // with cut_y, thus the
- // children are already
- // in correct order. we
- // only have to set them
- // correctly, deleting
- // the indirection of two
- // anisotropic refinement
- // and going directly
- // from the quad to
- // isotropic children
- const unsigned int child_0=quad->child(0)->child_index(0);
- const unsigned int child_2=quad->child(1)->child_index(0);
- quad->clear_children();
- quad->clear_refinement_case();
- quad->set_refinement_case(RefinementCase<2>::cut_xy);
- quad->set_children(0,child_0);
- quad->set_children(2,child_2);
- }
- else
- {
- quad->clear_children();
- quad->clear_refinement_case();
- }
-
-
- }
- break;
- }
- case RefinementCase<dim-1>::cut_xy:
- {
- // if one of the cell counters is
- // zero, the others have to be as
- // well
-
- Assert((quad_cell_count[quad->child_index(0)] == 0 &&
- quad_cell_count[quad->child_index(1)] == 0 &&
- quad_cell_count[quad->child_index(2)] == 0 &&
- quad_cell_count[quad->child_index(3)] == 0) ||
- (quad_cell_count[quad->child_index(0)] > 0 &&
- quad_cell_count[quad->child_index(1)] > 0 &&
- quad_cell_count[quad->child_index(2)] > 0 &&
- quad_cell_count[quad->child_index(3)] > 0),
- ExcInternalError());
-
- if (quad_cell_count[quad->child_index(0)]==0)
- {
- // we may delete the quad's
- // children, the inner lines
- // and the middle vertex as no
- // cell references them anymore
- lines_to_delete.push_back(quad->child(0)->line(1));
- lines_to_delete.push_back(quad->child(3)->line(0));
- lines_to_delete.push_back(quad->child(0)->line(3));
- lines_to_delete.push_back(quad->child(3)->line(2));
-
- for (unsigned int child=0; child<quad->n_children(); ++child)
- quads_to_delete.push_back(quad->child(child));
-
- triangulation.vertices_used[quad->child(0)->vertex_index(3)] = false;
-
- quad->clear_children();
- quad->clear_refinement_case();
- }
- }
- break;
-
- default:
- Assert(false, ExcInternalError());
- break;
- }
-
- }
-
- // now we repeat a similar procedure
- // for the outer lines of this cell.
-
- // if in debug mode: check that each
- // of the lines for which we consider
- // deleting the children in fact has
- // children (the bits/coarsening_3d
- // test tripped over this initially)
- for (unsigned int line_no=0; line_no<GeometryInfo<dim>::lines_per_cell; ++line_no)
- {
- typename Triangulation<dim,spacedim>::line_iterator
- line=cell->line(line_no);
-
- Assert((GeometryInfo<dim>::line_refinement_case(ref_case,line_no) && line->has_children()) ||
- GeometryInfo<dim>::line_refinement_case(ref_case,line_no)==RefinementCase<1>::no_refinement,
- ExcInternalError());
-
- if (line->has_children())
- {
- // if one of the cell counters is
- // zero, the other has to be as well
-
- Assert((line_cell_count[line->child_index(0)] == 0 &&
- line_cell_count[line->child_index(1)] == 0) ||
- (line_cell_count[line->child_index(0)] > 0 &&
- line_cell_count[line->child_index(1)] > 0),
- ExcInternalError());
-
- if (line_cell_count[line->child_index(0)]==0)
- {
- for (unsigned int c=0; c<2; ++c)
- Assert (!line->child(c)->has_children(),
- ExcInternalError());
-
- // we may delete the line's
- // children and the middle vertex
- // as no cell references them
- // anymore
- triangulation.vertices_used[line->child(0)->vertex_index(1)] = false;
-
- lines_to_delete.push_back(line->child(0));
- lines_to_delete.push_back(line->child(1));
-
- line->clear_children();
- }
- }
- }
-
- // finally, delete unneeded quads and lines
-
- // clear user pointers, to avoid that
- // they may appear at unwanted places
- // later on...
- // same for user flags, then finally
- // delete the quads and lines
- typename std::vector<typename Triangulation<dim,spacedim>::line_iterator>::iterator
- line=lines_to_delete.begin(),
- endline=lines_to_delete.end();
- for (; line!=endline; ++line)
- {
- (*line)->clear_user_data();
- (*line)->clear_user_flag();
- (*line)->clear_used_flag();
- }
-
- typename std::vector<typename Triangulation<dim,spacedim>::quad_iterator>::iterator
- quad=quads_to_delete.begin(),
- endquad=quads_to_delete.end();
- for (; quad!=endquad; ++quad)
- {
- (*quad)->clear_user_data();
- (*quad)->clear_children();
- (*quad)->clear_refinement_case();
- (*quad)->clear_user_flag();
- (*quad)->clear_used_flag();
- }
- }
-
-
- /**
- * Create the children of a 2d
- * cell. The arguments indicate
- * the next free spots in the
- * vertices, lines, and cells
- * arrays.
- *
- * The faces of the cell have to
- * be refined already, whereas
- * the inner lines in 2D will be
- * created in this
- * function. Therefore iterator
- * pointers into the vectors of
- * lines, quads and cells have to
- * be passed, which point at (or
- * "before") the reserved space.
- */
- template <int spacedim>
- static
- void
- create_children (Triangulation<2,spacedim> &triangulation,
- unsigned int &next_unused_vertex,
- typename Triangulation<2,spacedim>::raw_line_iterator &next_unused_line,
- typename Triangulation<2,spacedim>::raw_cell_iterator &next_unused_cell,
- typename Triangulation<2,spacedim>::cell_iterator &cell)
- {
- const unsigned int dim=2;
- // clear refinement flag
- const RefinementCase<dim> ref_case=cell->refine_flag_set();
- cell->clear_refine_flag ();
+ // this function is mostly
+ // equivalent to that for the
+ // general dimensional case the
+ // only difference being the
+ // correction for split faces which
+ // is not necessary in 1D
+ //
+ // if you change something here,
+ // don't forget to do so there as
+ // well
+
+ // find the smallest length of the
+ // lines adjacent to the
+ // vertex. take the initial value
+ // to be larger than anything that
+ // might be found: the diameter of
+ // the triangulation, here
+ // estimated by adding up the
+ // diameters of the coarse grid
+ // cells.
+ double almost_infinite_length = 0;
+ for (typename Triangulation<dim,spacedim>::cell_iterator
+ cell=triangulation.begin(0); cell!=triangulation.end(0); ++cell)
+ almost_infinite_length += cell->diameter();
+
+ std::vector<double> minimal_length (triangulation.vertices.size(),
+ almost_infinite_length);
+
+ // also note if a vertex is at the
+ // boundary
+ std::vector<bool> at_boundary (triangulation.vertices.size(), false);
+
+ for (typename Triangulation<dim,spacedim>::active_line_iterator
+ line=triangulation.begin_active_line();
+ line != triangulation.end_line(); ++line)
+ {
+ if (keep_boundary && line->at_boundary())
+ {
+ at_boundary[line->vertex_index(0)] = true;
+ at_boundary[line->vertex_index(1)] = true;
+ }
+
+ minimal_length[line->vertex_index(0)]
+ = std::min(line->diameter(),
+ minimal_length[line->vertex_index(0)]);
+ minimal_length[line->vertex_index(1)]
+ = std::min(line->diameter(),
+ minimal_length[line->vertex_index(1)]);
+ }
+
+
+ const unsigned int n_vertices = triangulation.vertices.size();
+ Point<spacedim> shift_vector;
+
+ for (unsigned int vertex=0; vertex<n_vertices; ++vertex)
+ {
+ // ignore this vertex if we
+ // whall keep the boundary and
+ // this vertex *is* at the
+ // boundary
+ if (keep_boundary && at_boundary[vertex])
+ continue;
+
+ // first compute a random shift
+ // vector
+ for (unsigned int d=0; d<spacedim; ++d)
+ shift_vector(d) = std::rand()*1.0/RAND_MAX;
+
+ shift_vector *= factor * minimal_length[vertex] /
+ std::sqrt(shift_vector.square());
+
+ // finally move the vertex
+ triangulation.vertices[vertex] += shift_vector;
+ }
+
+
+ // finally correct hanging nodes
+ // again. The following is not
+ // necessary for 1D
+ typename Triangulation<dim,spacedim>::active_cell_iterator
+ cell = triangulation.begin_active(),
+ endc = triangulation.end();
+ for (; cell!=endc; ++cell)
+ for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
+ if (cell->face(face)->has_children() &&
+ !cell->face(face)->at_boundary())
+ // this lines has children,
+ // thus there are restricted
+ // nodes
+ {
+ // not implemented at
+ // present for dim=3 or
+ // higher
+ Assert (dim<=2, ExcNotImplemented());
+
+ // compute where the common
+ // point of the two child
+ // lines will lie and reset
+ // it to the correct value
+ triangulation.vertices[cell->face(face)->child(0)->vertex_index(1)]
+ = (cell->face(face)->vertex(0) +
+ cell->face(face)->vertex(1)) / 2;
+ }
+ }
+
+
+ /**
+ * Actually delete a cell, or rather all
+ * its children, which is the main step for
+ * the coarsening process. This is the
+ * dimension dependent part of @p
+ * execute_coarsening. The second argument
+ * is a vector which gives for each line
+ * index the number of cells containing
+ * this line. This information is needed to
+ * decide whether a refined line may be
+ * coarsened or not in 3D. In 1D and 2D
+ * this argument is not needed and thus
+ * ignored. The same applies for the last
+ * argument and quads instead of lines.
+ */
+ template <int spacedim>
+ static
+ void
+ delete_children (Triangulation<1,spacedim> &triangulation,
+ typename Triangulation<1,spacedim>::cell_iterator &cell,
+ std::vector<unsigned int> &,
+ std::vector<unsigned int> &)
+ {
+ const unsigned int dim = 1;
+
+ // first we need to reset the
+ // neighbor pointers of the
+ // neighbors of this cell's
+ // children to this cell. This is
+ // different for one dimension,
+ // since there neighbors can have a
+ // refinement level differing from
+ // that of this cell's children by
+ // more than one level.
+
+ Assert (!cell->child(0)->has_children() && !cell->child(1)->has_children(),
+ ExcInternalError());
+
+ // first do it for the cells to the
+ // left
+ if (cell->neighbor(0).state() == IteratorState::valid)
+ if (cell->neighbor(0)->has_children())
+ {
+ typename Triangulation<dim,spacedim>::cell_iterator
+ neighbor = cell->neighbor(0);
+ Assert (neighbor->level() == cell->level(), ExcInternalError());
+
+ // right child
+ neighbor = neighbor->child(1);
+ while (1)
+ {
+ Assert (neighbor->neighbor(1) == cell->child(0),
+ ExcInternalError());
+ neighbor->set_neighbor (1, cell);
+
+ // move on to further
+ // children on the
+ // boundary between this
+ // cell and its neighbor
+ if (neighbor->has_children())
+ neighbor = neighbor->child(1);
+ else
+ break;
+ }
+ }
+
+ // now do it for the cells to the
+ // left
+ if (cell->neighbor(1).state() == IteratorState::valid)
+ if (cell->neighbor(1)->has_children())
+ {
+ typename Triangulation<dim,spacedim>::cell_iterator
+ neighbor = cell->neighbor(1);
+ Assert (neighbor->level() == cell->level(), ExcInternalError());
+
+ // left child
+ neighbor = neighbor->child(0);
+ while (1)
+ {
+ Assert (neighbor->neighbor(0) == cell->child(1),
+ ExcInternalError());
+ neighbor->set_neighbor (0, cell);
+
+ // move on to further
+ // children on the
+ // boundary between this
+ // cell and its neighbor
+ if (neighbor->has_children())
+ neighbor = neighbor->child(0);
+ else
+ break;
+ }
+ }
+
+
+ // delete the vertex which will not
+ // be needed anymore. This vertex
+ // is the second of the first child
+ triangulation.vertices_used[cell->child(0)->vertex_index(1)] = false;
+
+ // invalidate children. clear user
+ // pointers, to avoid that they may
+ // appear at unwanted places later
+ // on...
+ for (unsigned int child=0; child<cell->n_children(); ++child)
+ {
+ cell->child(child)->clear_user_data();
+ cell->child(child)->clear_user_flag();
+ cell->child(child)->clear_used_flag();
+ }
+
+
+ // delete pointer to children
+ cell->clear_children ();
+ cell->clear_user_flag();
+ }
+
+
+
+ template <int spacedim>
+ static
+ void
+ delete_children (Triangulation<2,spacedim> &triangulation,
+ typename Triangulation<2,spacedim>::cell_iterator &cell,
+ std::vector<unsigned int> &line_cell_count,
+ std::vector<unsigned int> &)
+ {
+ const unsigned int dim=2;
+ const RefinementCase<dim> ref_case=cell->refinement_case();
+
+ Assert(line_cell_count.size()==triangulation.n_raw_lines(), ExcInternalError());
+
+ // vectors to hold all lines which
+ // may be deleted
+ std::vector<typename Triangulation<dim,spacedim>::line_iterator>
+ lines_to_delete(0);
+
+ lines_to_delete.reserve(4*2+4);
+
+ // now we decrease the counters for
+ // lines contained in the child
+ // cells
+ for (unsigned int c=0; c<cell->n_children(); ++c)
+ {
+ typename Triangulation<dim,spacedim>::cell_iterator
+ child=cell->child(c);
+ for (unsigned int l=0; l<GeometryInfo<dim>::lines_per_cell; ++l)
+ --line_cell_count[child->line_index(l)];
+ }
+
+
+ // delete the vertex which will not
+ // be needed anymore. This vertex
+ // is the second of the second line
+ // of the first child, if the cell
+ // is refined with cut_xy, else there
+ // is no inner vertex.
+ // additionally delete unneeded inner
+ // lines
+ if (ref_case==RefinementCase<dim>::cut_xy)
+ {
+ triangulation.vertices_used[cell->child(0)->line(1)->vertex_index(1)] = false;
+
+ lines_to_delete.push_back(cell->child(0)->line(1));
+ lines_to_delete.push_back(cell->child(0)->line(3));
+ lines_to_delete.push_back(cell->child(3)->line(0));
+ lines_to_delete.push_back(cell->child(3)->line(2));
+ }
+ else
+ {
+ unsigned int inner_face_no=ref_case==RefinementCase<dim>::cut_x ? 1 : 3;
+
+ // the inner line will not be
+ // used any more
+ lines_to_delete.push_back(cell->child(0)->line(inner_face_no));
+ }
+
+ // invalidate children
+ for (unsigned int child=0; child<cell->n_children(); ++child)
+ {
+ cell->child(child)->clear_user_data();
+ cell->child(child)->clear_user_flag();
+ cell->child(child)->clear_used_flag();
+ }
+
+
+ // delete pointer to children
+ cell->clear_children ();
+ cell->clear_refinement_case();
+ cell->clear_user_flag();
+
+ // look at the refinement of outer
+ // lines. if nobody needs those
+ // anymore we can add them to the
+ // list of lines to be deleted.
+ for (unsigned int line_no=0; line_no<GeometryInfo<dim>::lines_per_cell; ++line_no)
+ {
+ typename Triangulation<dim,spacedim>::line_iterator
+ line=cell->line(line_no);
+
+ if (line->has_children())
+ {
+ // if one of the cell counters is
+ // zero, the other has to be as well
+
+ Assert((line_cell_count[line->child_index(0)] == 0 &&
+ line_cell_count[line->child_index(1)] == 0) ||
+ (line_cell_count[line->child_index(0)] > 0 &&
+ line_cell_count[line->child_index(1)] > 0),
+ ExcInternalError());
+
+ if (line_cell_count[line->child_index(0)]==0)
+ {
+ for (unsigned int c=0; c<2; ++c)
+ Assert (!line->child(c)->has_children(),
+ ExcInternalError());
+
+ // we may delete the line's
+ // children and the middle vertex
+ // as no cell references them
+ // anymore
+ triangulation.vertices_used[line->child(0)->vertex_index(1)] = false;
+
+ lines_to_delete.push_back(line->child(0));
+ lines_to_delete.push_back(line->child(1));
+
+ line->clear_children();
+ }
+ }
+ }
+
+ // finally, delete unneeded lines
+
+ // clear user pointers, to avoid that
+ // they may appear at unwanted places
+ // later on...
+ // same for user flags, then finally
+ // delete the lines
+ typename std::vector<typename Triangulation<dim,spacedim>::line_iterator>::iterator
+ line=lines_to_delete.begin(),
+ endline=lines_to_delete.end();
+ for (; line!=endline; ++line)
+ {
+ (*line)->clear_user_data();
+ (*line)->clear_user_flag();
+ (*line)->clear_used_flag();
+ }
+ }
+
+
+
+ template <int spacedim>
+ static
+ void
+ delete_children (Triangulation<3,spacedim> &triangulation,
+ typename Triangulation<3,spacedim>::cell_iterator &cell,
+ std::vector<unsigned int> &line_cell_count,
+ std::vector<unsigned int> &quad_cell_count)
+ {
+ const unsigned int dim=3;
+
+ Assert(line_cell_count.size()==triangulation.n_raw_lines(), ExcInternalError());
+ Assert(quad_cell_count.size()==triangulation.n_raw_quads(), ExcInternalError());
+
+ // first of all, we store the RefineCase of
+ // this cell
+ const RefinementCase<dim> ref_case=cell->refinement_case();
+ // vectors to hold all lines and quads which
+ // may be deleted
+ std::vector<typename Triangulation<dim,spacedim>::line_iterator>
+ lines_to_delete(0);
+ std::vector<typename Triangulation<dim,spacedim>::quad_iterator>
+ quads_to_delete(0);
+
+ lines_to_delete.reserve(12*2+6*4+6);
+ quads_to_delete.reserve(6*4+12);
+
+ // now we decrease the counters for lines and
+ // quads contained in the child cells
+ for (unsigned int c=0; c<cell->n_children(); ++c)
+ {
+ typename Triangulation<dim,spacedim>::cell_iterator
+ child=cell->child(c);
+ for (unsigned int l=0; l<GeometryInfo<dim>::lines_per_cell; ++l)
+ --line_cell_count[child->line_index(l)];
+ for (unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell; ++f)
+ --quad_cell_count[child->quad_index(f)];
+ }
+
+ ///////////////////////////////////////
+ // delete interior quads and lines and the
+ // interior vertex, depending on the
+ // refinement case of the cell
+ //
+ // for append quads and lines: only append
+ // them to the list of objects to be deleted
+
+ switch (ref_case)
+ {
+ case RefinementCase<dim>::cut_x:
+ quads_to_delete.push_back(cell->child(0)->face(1));
+ break;
+ case RefinementCase<dim>::cut_y:
+ quads_to_delete.push_back(cell->child(0)->face(3));
+ break;
+ case RefinementCase<dim>::cut_z:
+ quads_to_delete.push_back(cell->child(0)->face(5));
+ break;
+ case RefinementCase<dim>::cut_xy:
+ quads_to_delete.push_back(cell->child(0)->face(1));
+ quads_to_delete.push_back(cell->child(0)->face(3));
+ quads_to_delete.push_back(cell->child(3)->face(0));
+ quads_to_delete.push_back(cell->child(3)->face(2));
+
+ lines_to_delete.push_back(cell->child(0)->line(11));
+ break;
+ case RefinementCase<dim>::cut_xz:
+ quads_to_delete.push_back(cell->child(0)->face(1));
+ quads_to_delete.push_back(cell->child(0)->face(5));
+ quads_to_delete.push_back(cell->child(3)->face(0));
+ quads_to_delete.push_back(cell->child(3)->face(4));
+
+ lines_to_delete.push_back(cell->child(0)->line(5));
+ break;
+ case RefinementCase<dim>::cut_yz:
+ quads_to_delete.push_back(cell->child(0)->face(3));
+ quads_to_delete.push_back(cell->child(0)->face(5));
+ quads_to_delete.push_back(cell->child(3)->face(2));
+ quads_to_delete.push_back(cell->child(3)->face(4));
+
+ lines_to_delete.push_back(cell->child(0)->line(7));
+ break;
+ case RefinementCase<dim>::cut_xyz:
+ quads_to_delete.push_back(cell->child(0)->face(1));
+ quads_to_delete.push_back(cell->child(2)->face(1));
+ quads_to_delete.push_back(cell->child(4)->face(1));
+ quads_to_delete.push_back(cell->child(6)->face(1));
+
+ quads_to_delete.push_back(cell->child(0)->face(3));
+ quads_to_delete.push_back(cell->child(1)->face(3));
+ quads_to_delete.push_back(cell->child(4)->face(3));
+ quads_to_delete.push_back(cell->child(5)->face(3));
+
+ quads_to_delete.push_back(cell->child(0)->face(5));
+ quads_to_delete.push_back(cell->child(1)->face(5));
+ quads_to_delete.push_back(cell->child(2)->face(5));
+ quads_to_delete.push_back(cell->child(3)->face(5));
+
+ lines_to_delete.push_back(cell->child(0)->line(5));
+ lines_to_delete.push_back(cell->child(0)->line(7));
+ lines_to_delete.push_back(cell->child(0)->line(11));
+ lines_to_delete.push_back(cell->child(7)->line(0));
+ lines_to_delete.push_back(cell->child(7)->line(2));
+ lines_to_delete.push_back(cell->child(7)->line(8));
+ // delete the vertex which will not
+ // be needed anymore. This vertex
+ // is the vertex at the heart of
+ // this cell, which is the sixth of
+ // the first child
+ triangulation.vertices_used[cell->child(0)->vertex_index(7)] = false;
+ break;
+ default:
+ // only remaining case is
+ // no_refinement, thus an error
+ Assert(false, ExcInternalError());
+ break;
+ }
+
+
+ // invalidate children
+ for (unsigned int child=0; child<cell->n_children(); ++child)
+ {
+ cell->child(child)->clear_user_data();
+ cell->child(child)->clear_user_flag();
+
+ for (unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell; ++f)
+ {
+ // set flags denoting deviations from
+ // standard orientation of faces back
+ // to initialization values
+ cell->child(child)->set_face_orientation (f, true);
+ cell->child(child)->set_face_flip(f,false);
+ cell->child(child)->set_face_rotation(f,false);
+ }
+
+ cell->child(child)->clear_used_flag();
+ }
+
+
+ // delete pointer to children
+ cell->clear_children ();
+ cell->clear_refinement_case ();
+ cell->clear_user_flag();
+
+ // so far we only looked at inner quads,
+ // lines and vertices. Now we have to
+ // consider outer ones as well. here, we have
+ // to check, whether there are other cells
+ // still needing these objects. oherwise we
+ // can delete them. first for quads (and
+ // their inner lines).
+
+ for (unsigned int quad_no=0; quad_no<GeometryInfo<dim>::faces_per_cell; ++quad_no)
+ {
+ typename Triangulation<dim,spacedim>::quad_iterator
+ quad=cell->face(quad_no);
+
+ Assert((GeometryInfo<dim>::face_refinement_case(ref_case,quad_no) && quad->has_children()) ||
+ GeometryInfo<dim>::face_refinement_case(ref_case,quad_no)==RefinementCase<dim-1>::no_refinement,
+ ExcInternalError());
+
+ switch (quad->refinement_case())
+ {
+ case RefinementCase<dim-1>::no_refinement:
+ // nothing to do as the quad
+ // is not refined
+ break;
+ case RefinementCase<dim-1>::cut_x:
+ case RefinementCase<dim-1>::cut_y:
+ {
+ // if one of the cell counters is
+ // zero, the other has to be as
+ // well
+ Assert((quad_cell_count[quad->child_index(0)] == 0 &&
+ quad_cell_count[quad->child_index(1)] == 0) ||
+ (quad_cell_count[quad->child_index(0)] > 0 &&
+ quad_cell_count[quad->child_index(1)] > 0),
+ ExcInternalError());
+ // it might be, that the quad is
+ // refined twice anisotropically,
+ // first check, whether we may
+ // delete possible grand_children
+ unsigned int deleted_grandchildren=0;
+ unsigned int number_of_child_refinements=0;
+
+ for (unsigned int c=0; c<2; ++c)
+ if (quad->child(c)->has_children())
+ {
+ ++number_of_child_refinements;
+ // if one of the cell counters is
+ // zero, the other has to be as
+ // well
+ Assert((quad_cell_count[quad->child(c)->child_index(0)] == 0 &&
+ quad_cell_count[quad->child(c)->child_index(1)] == 0) ||
+ (quad_cell_count[quad->child(c)->child_index(0)] > 0 &&
+ quad_cell_count[quad->child(c)->child_index(1)] > 0),
+ ExcInternalError());
+ if (quad_cell_count[quad->child(c)->child_index(0)]==0)
+ {
+ // Assert, that the two
+ // anisotropic
+ // refinements add up to
+ // isotropic refinement
+ Assert(quad->refinement_case()+quad->child(c)->refinement_case()==RefinementCase<dim>::cut_xy,
+ ExcInternalError());
+ // we may delete the
+ // quad's children and
+ // the inner line as no
+ // cell references them
+ // anymore
+ quads_to_delete.push_back(quad->child(c)->child(0));
+ quads_to_delete.push_back(quad->child(c)->child(1));
+ if (quad->child(c)->refinement_case()==RefinementCase<2>::cut_x)
+ lines_to_delete.push_back(quad->child(c)->child(0)->line(1));
+ else
+ lines_to_delete.push_back(quad->child(c)->child(0)->line(3));
+ quad->child(c)->clear_children();
+ quad->child(c)->clear_refinement_case();
+ ++deleted_grandchildren;
+ }
+ }
+ // if no grandchildren are left, we
+ // may as well delete the
+ // refinement of the inner line
+ // between our children and the
+ // corresponding vertex
+ if (number_of_child_refinements>0 &&
+ deleted_grandchildren==number_of_child_refinements)
+ {
+ typename Triangulation<dim,spacedim>::line_iterator
+ middle_line;
+ if (quad->refinement_case()==RefinementCase<2>::cut_x)
+ middle_line=quad->child(0)->line(1);
+ else
+ middle_line=quad->child(0)->line(3);
+
+ lines_to_delete.push_back(middle_line->child(0));
+ lines_to_delete.push_back(middle_line->child(1));
+ triangulation.vertices_used[middle_vertex_index<dim,spacedim>(middle_line)]
+ = false;
+ middle_line->clear_children();
+ }
+
+ // now consider the direct children
+ // of the given quad
+ if (quad_cell_count[quad->child_index(0)]==0)
+ {
+ // we may delete the quad's
+ // children and the inner line
+ // as no cell references them
+ // anymore
+ quads_to_delete.push_back(quad->child(0));
+ quads_to_delete.push_back(quad->child(1));
+ if (quad->refinement_case()==RefinementCase<2>::cut_x)
+ lines_to_delete.push_back(quad->child(0)->line(1));
+ else
+ lines_to_delete.push_back(quad->child(0)->line(3));
+
+ // if the counters just dropped
+ // to zero, otherwise the
+ // children would have been
+ // deleted earlier, then this
+ // cell's children must have
+ // contained the anisotropic
+ // quad children. thus, if
+ // those have again anisotropic
+ // children, which are in
+ // effect isotropic children of
+ // the original quad, those are
+ // still needed by a
+ // neighboring cell and we
+ // cannot delete them. instead,
+ // we have to reset this quad's
+ // refine case to isotropic and
+ // set the children
+ // accordingly.
+ if (quad->child(0)->has_children())
+ if (quad->refinement_case()==RefinementCase<2>::cut_x)
+ {
+ // now evereything is
+ // quite complicated. we
+ // have the children
+ // numbered according to
+ //
+ // *---*---*
+ // |n+1|m+1|
+ // *---*---*
+ // | n | m |
+ // *---*---*
+ //
+ // from the original
+ // anisotropic
+ // refinement. we have to
+ // reorder them as
+ //
+ // *---*---*
+ // | m |m+1|
+ // *---*---*
+ // | n |n+1|
+ // *---*---*
+ //
+ // for isotropic refinement.
+ //
+ // this is a bit ugly, of
+ // course: loop over all
+ // cells on all levels
+ // and look for faces n+1
+ // (switch_1) and m
+ // (switch_2).
+ const typename Triangulation<dim,spacedim>::quad_iterator
+ switch_1=quad->child(0)->child(1),
+ switch_2=quad->child(1)->child(0);
+
+ Assert(!switch_1->has_children(), ExcInternalError());
+ Assert(!switch_2->has_children(), ExcInternalError());
+
+ const int switch_1_index=switch_1->index();
+ const int switch_2_index=switch_2->index();
+ for (unsigned int l=0; l<triangulation.levels.size(); ++l)
+ for (unsigned int h=0; h<triangulation.levels[l]->cells.cells.size(); ++h)
+ for (unsigned int q=0; q<GeometryInfo<dim>::faces_per_cell; ++q)
+ {
+ const int index=triangulation.levels[l]->cells.cells[h].face(q);
+ if (index==switch_1_index)
+ triangulation.levels[l]->cells.cells[h].set_face(q,switch_2_index);
+ else if (index==switch_2_index)
+ triangulation.levels[l]->cells.cells[h].set_face(q,switch_1_index);
+ }
+ // now we have to copy
+ // all information of the
+ // two quads
+ const int switch_1_lines[4]=
+ {switch_1->line_index(0),
+ switch_1->line_index(1),
+ switch_1->line_index(2),
+ switch_1->line_index(3)};
+ const bool switch_1_line_orientations[4]=
+ {switch_1->line_orientation(0),
+ switch_1->line_orientation(1),
+ switch_1->line_orientation(2),
+ switch_1->line_orientation(3)};
+ const types::boundary_id_t switch_1_boundary_indicator=switch_1->boundary_indicator();
+ const unsigned int switch_1_user_index=switch_1->user_index();
+ const bool switch_1_user_flag=switch_1->user_flag_set();
+
+ switch_1->set(internal::Triangulation::TriaObject<2>(switch_2->line_index(0),
+ switch_2->line_index(1),
+ switch_2->line_index(2),
+ switch_2->line_index(3)));
+ switch_1->set_line_orientation(0, switch_2->line_orientation(0));
+ switch_1->set_line_orientation(1, switch_2->line_orientation(1));
+ switch_1->set_line_orientation(2, switch_2->line_orientation(2));
+ switch_1->set_line_orientation(3, switch_2->line_orientation(3));
+ switch_1->set_boundary_indicator(switch_2->boundary_indicator());
+ switch_1->set_user_index(switch_2->user_index());
+ if (switch_2->user_flag_set())
+ switch_1->set_user_flag();
+ else
+ switch_1->clear_user_flag();
+
+ switch_2->set(internal::Triangulation::TriaObject<2>(switch_1_lines[0],
+ switch_1_lines[1],
+ switch_1_lines[2],
+ switch_1_lines[3]));
+ switch_2->set_line_orientation(0, switch_1_line_orientations[0]);
+ switch_2->set_line_orientation(1, switch_1_line_orientations[1]);
+ switch_2->set_line_orientation(2, switch_1_line_orientations[2]);
+ switch_2->set_line_orientation(3, switch_1_line_orientations[3]);
+ switch_2->set_boundary_indicator(switch_1_boundary_indicator);
+ switch_2->set_user_index(switch_1_user_index);
+ if (switch_1_user_flag)
+ switch_2->set_user_flag();
+ else
+ switch_2->clear_user_flag();
+
+ const unsigned int child_0=quad->child(0)->child_index(0);
+ const unsigned int child_2=quad->child(1)->child_index(0);
+ quad->clear_children();
+ quad->clear_refinement_case();
+ quad->set_refinement_case(RefinementCase<2>::cut_xy);
+ quad->set_children(0,child_0);
+ quad->set_children(2,child_2);
+ std::swap(quad_cell_count[child_0+1],quad_cell_count[child_2]);
+ }
+ else
+ {
+ // the face was refined
+ // with cut_y, thus the
+ // children are already
+ // in correct order. we
+ // only have to set them
+ // correctly, deleting
+ // the indirection of two
+ // anisotropic refinement
+ // and going directly
+ // from the quad to
+ // isotropic children
+ const unsigned int child_0=quad->child(0)->child_index(0);
+ const unsigned int child_2=quad->child(1)->child_index(0);
+ quad->clear_children();
+ quad->clear_refinement_case();
+ quad->set_refinement_case(RefinementCase<2>::cut_xy);
+ quad->set_children(0,child_0);
+ quad->set_children(2,child_2);
+ }
+ else
+ {
+ quad->clear_children();
+ quad->clear_refinement_case();
+ }
+
+
+ }
+ break;
+ }
+ case RefinementCase<dim-1>::cut_xy:
+ {
+ // if one of the cell counters is
+ // zero, the others have to be as
+ // well
+
+ Assert((quad_cell_count[quad->child_index(0)] == 0 &&
+ quad_cell_count[quad->child_index(1)] == 0 &&
+ quad_cell_count[quad->child_index(2)] == 0 &&
+ quad_cell_count[quad->child_index(3)] == 0) ||
+ (quad_cell_count[quad->child_index(0)] > 0 &&
+ quad_cell_count[quad->child_index(1)] > 0 &&
+ quad_cell_count[quad->child_index(2)] > 0 &&
+ quad_cell_count[quad->child_index(3)] > 0),
+ ExcInternalError());
+
+ if (quad_cell_count[quad->child_index(0)]==0)
+ {
+ // we may delete the quad's
+ // children, the inner lines
+ // and the middle vertex as no
+ // cell references them anymore
+ lines_to_delete.push_back(quad->child(0)->line(1));
+ lines_to_delete.push_back(quad->child(3)->line(0));
+ lines_to_delete.push_back(quad->child(0)->line(3));
+ lines_to_delete.push_back(quad->child(3)->line(2));
+
+ for (unsigned int child=0; child<quad->n_children(); ++child)
+ quads_to_delete.push_back(quad->child(child));
+
+ triangulation.vertices_used[quad->child(0)->vertex_index(3)] = false;
+
+ quad->clear_children();
+ quad->clear_refinement_case();
+ }
+ }
+ break;
+
+ default:
+ Assert(false, ExcInternalError());
+ break;
+ }
+
+ }
+
+ // now we repeat a similar procedure
+ // for the outer lines of this cell.
+
+ // if in debug mode: check that each
+ // of the lines for which we consider
+ // deleting the children in fact has
+ // children (the bits/coarsening_3d
+ // test tripped over this initially)
+ for (unsigned int line_no=0; line_no<GeometryInfo<dim>::lines_per_cell; ++line_no)
+ {
+ typename Triangulation<dim,spacedim>::line_iterator
+ line=cell->line(line_no);
+
+ Assert((GeometryInfo<dim>::line_refinement_case(ref_case,line_no) && line->has_children()) ||
+ GeometryInfo<dim>::line_refinement_case(ref_case,line_no)==RefinementCase<1>::no_refinement,
+ ExcInternalError());
+
+ if (line->has_children())
+ {
+ // if one of the cell counters is
+ // zero, the other has to be as well
+
+ Assert((line_cell_count[line->child_index(0)] == 0 &&
+ line_cell_count[line->child_index(1)] == 0) ||
+ (line_cell_count[line->child_index(0)] > 0 &&
+ line_cell_count[line->child_index(1)] > 0),
+ ExcInternalError());
+
+ if (line_cell_count[line->child_index(0)]==0)
+ {
+ for (unsigned int c=0; c<2; ++c)
+ Assert (!line->child(c)->has_children(),
+ ExcInternalError());
+
+ // we may delete the line's
+ // children and the middle vertex
+ // as no cell references them
+ // anymore
+ triangulation.vertices_used[line->child(0)->vertex_index(1)] = false;
+
+ lines_to_delete.push_back(line->child(0));
+ lines_to_delete.push_back(line->child(1));
+
+ line->clear_children();
+ }
+ }
+ }
+
+ // finally, delete unneeded quads and lines
+
+ // clear user pointers, to avoid that
+ // they may appear at unwanted places
+ // later on...
+ // same for user flags, then finally
+ // delete the quads and lines
+ typename std::vector<typename Triangulation<dim,spacedim>::line_iterator>::iterator
+ line=lines_to_delete.begin(),
+ endline=lines_to_delete.end();
+ for (; line!=endline; ++line)
+ {
+ (*line)->clear_user_data();
+ (*line)->clear_user_flag();
+ (*line)->clear_used_flag();
+ }
+
+ typename std::vector<typename Triangulation<dim,spacedim>::quad_iterator>::iterator
+ quad=quads_to_delete.begin(),
+ endquad=quads_to_delete.end();
+ for (; quad!=endquad; ++quad)
+ {
+ (*quad)->clear_user_data();
+ (*quad)->clear_children();
+ (*quad)->clear_refinement_case();
+ (*quad)->clear_user_flag();
+ (*quad)->clear_used_flag();
+ }
+ }
+
+
+ /**
+ * Create the children of a 2d
+ * cell. The arguments indicate
+ * the next free spots in the
+ * vertices, lines, and cells
+ * arrays.
+ *
+ * The faces of the cell have to
+ * be refined already, whereas
+ * the inner lines in 2D will be
+ * created in this
+ * function. Therefore iterator
+ * pointers into the vectors of
+ * lines, quads and cells have to
+ * be passed, which point at (or
+ * "before") the reserved space.
+ */
+ template <int spacedim>
+ static
+ void
+ create_children (Triangulation<2,spacedim> &triangulation,
+ unsigned int &next_unused_vertex,
+ typename Triangulation<2,spacedim>::raw_line_iterator &next_unused_line,
+ typename Triangulation<2,spacedim>::raw_cell_iterator &next_unused_cell,
+ typename Triangulation<2,spacedim>::cell_iterator &cell)
+ {
+ const unsigned int dim=2;
+ // clear refinement flag
+ const RefinementCase<dim> ref_case=cell->refine_flag_set();
+ cell->clear_refine_flag ();
/* For the refinement process: since we go the levels up from the lowest, there
are (unlike above) only two possibilities: a neighbor cell is on the same
|0 | 1|
.--.--.
*/
- // collect the
- // indices of the
- // eight
- // surrounding
- // vertices
- // 2--7--3
- // | | |
- // 4--9--5
- // | | |
- // 0--6--1
- int new_vertices[9];
- for (unsigned int vertex_no=0; vertex_no<4; ++vertex_no)
- new_vertices[vertex_no]=cell->vertex_index(vertex_no);
- for (unsigned int line_no=0; line_no<4; ++line_no)
- if (cell->line(line_no)->has_children())
- new_vertices[4+line_no]=cell->line(line_no)->child(0)->vertex_index(1);
-
- if (ref_case==RefinementCase<dim>::cut_xy)
- {
-
- // find the next
- // unused vertex and
- // allocate it for
- // the new vertex we
- // need here
- while (triangulation.vertices_used[next_unused_vertex] == true)
- ++next_unused_vertex;
- Assert (next_unused_vertex < triangulation.vertices.size(),
- ExcTooFewVerticesAllocated());
- triangulation.vertices_used[next_unused_vertex] = true;
-
- new_vertices[8] = next_unused_vertex;
-
- // if this quad lives
- // in 2d, then we can
- // compute the new
- // central vertex
- // location just from
- // the surrounding
- // ones. If this is
- // not the case, then
- // we need to ask a
- // boundary object
- if (dim == spacedim)
- {
- // in a first
- // step, compute
- // the location
- // of central
- // vertex as the
- // average of the
- // 8 surrounding
- // vertices
- Point<spacedim> new_point;
- for (unsigned int i=0; i<8; ++i)
- new_point += triangulation.vertices[new_vertices[i]];
- new_point /= 8.0;
-
- triangulation.vertices[next_unused_vertex] = new_point;
-
- // if the user_flag is set, i.e. if the
- // cell is at the boundary, use a
- // different calculation of the middle
- // vertex here. this is of advantage, if
- // the boundary is strongly curved and
- // the cell has a high aspect ratio. this
- // can happen for example, if it was
- // refined anisotropically before.
- if (cell->user_flag_set())
- {
- // first reset the user_flag
- cell->clear_user_flag();
- // the user flag indicates: at least
- // one face is at the boundary. if it
- // is only one, set the new middle
- // vertex in a different way to avoid
- // some mis-shaped elements if the
- // new point on the boundary is not
- // where we expect it, especially if
- // it is to far inside the current
- // cell
- unsigned int boundary_face=GeometryInfo<dim>::faces_per_cell;
- for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
- if (cell->face(face)->at_boundary())
- {
- if (boundary_face == GeometryInfo<dim>::faces_per_cell)
- // no boundary face found so
- // far, so set it now
- boundary_face=face;
- else
- // there is another boundary
- // face, so reset boundary_face to
- // invalid value as a flag to
- // do nothing in the following
- boundary_face=GeometryInfo<dim>::faces_per_cell+1;
- }
-
- if (boundary_face<GeometryInfo<dim>::faces_per_cell)
- // reset the cell's middle vertex
- // to the middle of the straight
- // connection between the new
- // points on this face and on the
- // opposite face
- triangulation.vertices[next_unused_vertex]
- = 0.5*(cell->face(boundary_face)
- ->child(0)->vertex(1)+
- cell->face(GeometryInfo<dim>
- ::opposite_face[boundary_face])
- ->child(0)->vertex(1));
- }
- }
- else
- {
- // if this quad
- // lives in a
- // higher
- // dimensional
- // space then we
- // don't need to
- // worry if it is
- // at the
- // boundary of
- // the manifold
- // -- we always
- // have to use
- // the boundary
- // object anyway;
- // so ignore
- // whether the
- // user flag is
- // set or not
- cell->clear_user_flag();
-
-
-
- // An assert to make sure that the
- // static_cast in the next line has
- // the chance to give reasonable results.
- Assert(cell->material_id()<= std::numeric_limits<types::material_id_t>::max(),
- ExcIndexRange(cell->material_id(),0,std::numeric_limits<types::material_id_t>::max()));
-
- // new vertex is
- // placed on the
- // surface according
- // to the information
- // stored in the
- // boundary class
- triangulation.vertices[next_unused_vertex] =
- triangulation.get_boundary(static_cast<types::boundary_id_t>(cell->material_id()))
- .get_new_point_on_quad (cell);
- }
- }
-
-
- // Now the lines:
- typename Triangulation<dim,spacedim>::raw_line_iterator new_lines[12];
- unsigned int lmin=8;
- unsigned int lmax=12;
- if (ref_case!=RefinementCase<dim>::cut_xy)
- {
- lmin=6;
- lmax=7;
- }
-
- for (unsigned int l=lmin; l<lmax; ++l)
- {
- while (next_unused_line->used() == true)
- ++next_unused_line;
- new_lines[l] = next_unused_line;
- ++next_unused_line;
-
- Assert (new_lines[l]->used() == false,
- ExcCellShouldBeUnused());
- }
-
- if (ref_case==RefinementCase<dim>::cut_xy)
- {
- // .-6-.-7-.
- // 1 9 3
- // .-10.11-.
- // 0 8 2
- // .-4-.-5-.
-
- // lines 0-7 already
- // exist, create only
- // the four interior
- // lines 8-11
- unsigned int l=0;
- for (unsigned int face_no=0; face_no<GeometryInfo<dim>::faces_per_cell; ++face_no)
- for (unsigned int c=0; c<2; ++c, ++l)
- new_lines[l]=cell->line(face_no)->child(c);
- Assert(l==8, ExcInternalError());
-
- new_lines[8] ->set (internal::Triangulation::
- TriaObject<1>(new_vertices[6], new_vertices[8]));
- new_lines[9] ->set (internal::Triangulation::
- TriaObject<1>(new_vertices[8], new_vertices[7]));
- new_lines[10]->set (internal::Triangulation::
- TriaObject<1>(new_vertices[4], new_vertices[8]));
- new_lines[11]->set (internal::Triangulation::
- TriaObject<1>(new_vertices[8], new_vertices[5]));
- }
- else if (ref_case==RefinementCase<dim>::cut_x)
- {
- // .-4-.-5-.
- // | | |
- // 0 6 1
- // | | |
- // .-2-.-3-.
- new_lines[0]=cell->line(0);
- new_lines[1]=cell->line(1);
- new_lines[2]=cell->line(2)->child(0);
- new_lines[3]=cell->line(2)->child(1);
- new_lines[4]=cell->line(3)->child(0);
- new_lines[5]=cell->line(3)->child(1);
- new_lines[6]->set (internal::Triangulation::
- TriaObject<1>(new_vertices[6], new_vertices[7]));
- }
- else
- {
- Assert(ref_case==RefinementCase<dim>::cut_y, ExcInternalError());
- // .---5---.
- // 1 3
- // .---6---.
- // 0 2
- // .---4---.
- new_lines[0]=cell->line(0)->child(0);
- new_lines[1]=cell->line(0)->child(1);
- new_lines[2]=cell->line(1)->child(0);
- new_lines[3]=cell->line(1)->child(1);
- new_lines[4]=cell->line(2);
- new_lines[5]=cell->line(3);
- new_lines[6]->set (internal::Triangulation::
- TriaObject<1>(new_vertices[4], new_vertices[5]));
- }
-
- for (unsigned int l=lmin; l<lmax; ++l)
- {
- new_lines[l]->set_used_flag();
- new_lines[l]->clear_user_flag();
- new_lines[l]->clear_user_data();
- new_lines[l]->clear_children();
- // interior line
- new_lines[l]->set_boundary_indicator(types::internal_face_boundary_id);
- }
-
- // Now add the four (two)
- // new cells!
- typename Triangulation<dim,spacedim>::raw_cell_iterator
- subcells[GeometryInfo<dim>::max_children_per_cell];
- while (next_unused_cell->used() == true)
- ++next_unused_cell;
-
- const unsigned int n_children=
- GeometryInfo<dim>::n_children(ref_case);
- for (unsigned int i=0; i<n_children; ++i)
- {
- Assert (next_unused_cell->used() == false,
- ExcCellShouldBeUnused());
- subcells[i] = next_unused_cell;
- ++next_unused_cell;
- if (i%2==1 && i<n_children-1)
- while (next_unused_cell->used() == true)
- ++next_unused_cell;
- }
-
- if (ref_case==RefinementCase<dim>::cut_xy)
- {
- // children:
- // .--.--.
- // |2 . 3|
- // .--.--.
- // |0 | 1|
- // .--.--.
- // lines:
- // .-6-.-7-.
- // 1 9 3
- // .-10.11-.
- // 0 8 2
- // .-4-.-5-.
- subcells[0]->set (internal::Triangulation::
- TriaObject<2>(new_lines[0]->index(),
- new_lines[8]->index(),
- new_lines[4]->index(),
- new_lines[10]->index()));
- subcells[1]->set (internal::Triangulation::
- TriaObject<2>(new_lines[8]->index(),
- new_lines[2]->index(),
- new_lines[5]->index(),
- new_lines[11]->index()));
- subcells[2]->set (internal::Triangulation::
- TriaObject<2>(new_lines[1]->index(),
- new_lines[9]->index(),
- new_lines[10]->index(),
- new_lines[6]->index()));
- subcells[3]->set (internal::Triangulation::
- TriaObject<2>(new_lines[9]->index(),
- new_lines[3]->index(),
- new_lines[11]->index(),
- new_lines[7]->index()));
- }
- else if (ref_case==RefinementCase<dim>::cut_x)
- {
- // children:
- // .--.--.
- // | . |
- // .0 . 1.
- // | | |
- // .--.--.
- // lines:
- // .-4-.-5-.
- // | | |
- // 0 6 1
- // | | |
- // .-2-.-3-.
- subcells[0]->set (internal::Triangulation::
- TriaObject<2>(new_lines[0]->index(),
- new_lines[6]->index(),
- new_lines[2]->index(),
- new_lines[4]->index()));
- subcells[1]->set (internal::Triangulation::
- TriaObject<2>(new_lines[6]->index(),
- new_lines[1]->index(),
- new_lines[3]->index(),
- new_lines[5]->index()));
- }
- else
- {
- Assert(ref_case==RefinementCase<dim>::cut_y, ExcInternalError());
- // children:
- // .-----.
- // | 1 |
- // .-----.
- // | 0 |
- // .-----.
- // lines:
- // .---5---.
- // 1 3
- // .---6---.
- // 0 2
- // .---4---.
- subcells[0]->set (internal::Triangulation::
- TriaObject<2>(new_lines[0]->index(),
- new_lines[2]->index(),
- new_lines[4]->index(),
- new_lines[6]->index()));
- subcells[1]->set (internal::Triangulation::
- TriaObject<2>(new_lines[1]->index(),
- new_lines[3]->index(),
- new_lines[6]->index(),
- new_lines[5]->index()));
- }
-
-
- for (unsigned int i=0; i<n_children; ++i)
- {
- subcells[i]->set_used_flag();
- subcells[i]->clear_refine_flag();
- subcells[i]->clear_user_flag();
- subcells[i]->clear_user_data();
- subcells[i]->clear_children();
- // inherit material
- // properties
- subcells[i]->set_material_id (cell->material_id());
- subcells[i]->set_subdomain_id (cell->subdomain_id());
-
- if (i%2==0)
- subcells[i]->set_parent (cell->index ());
- }
-
-
-
- // set child index for
- // even children children
- // i=0,2 (0)
- for (unsigned int i=0; i<n_children/2; ++i)
- cell->set_children (2*i, subcells[2*i]->index());
- // set the refine case
- cell->set_refinement_case(ref_case);
-
- // note that the
- // refinement flag was
- // already cleared at the
- // beginning of this function
-
- if (dim < spacedim)
- for (unsigned int c=0; c<n_children; ++c)
- cell->child(c)->set_direction_flag (cell->direction_flag());
-
- }
-
-
-
- /**
- * A function that performs the
- * refinement of a triangulation in 1d.
- */
- template <int spacedim>
- static
- typename Triangulation<1,spacedim>::DistortedCellList
- execute_refinement (Triangulation<1,spacedim> &triangulation,
- const bool /*check_for_distorted_cells*/)
- {
- const unsigned int dim = 1;
-
- // check whether a new level is
- // needed we have to check for this
- // on the highest level only (on
- // this, all used cells are also
- // active, so we only have to check
- // for this)
- {
- typename Triangulation<dim,spacedim>::raw_cell_iterator
- cell = triangulation.begin_active (triangulation.levels.size()-1),
- endc = triangulation.end();
- for (; cell != endc; ++cell)
- if (cell->used())
- if (cell->refine_flag_set())
- {
- triangulation.levels
- .push_back (new internal::Triangulation::TriaLevel<dim>);
- break;
- }
- }
-
-
- // check how much space is needed
- // on every level we need not check
- // the highest level since either -
- // on the highest level no cells
- // are flagged for refinement -
- // there are, but
- // prepare_refinement added another
- // empty level
- unsigned int needed_vertices = 0;
- for (int level=triangulation.levels.size()-2; level>=0; --level)
- {
- // count number of flagged
- // cells on this level
- unsigned int flagged_cells = 0;
- typename Triangulation<dim,spacedim>::active_cell_iterator
- acell = triangulation.begin_active(level),
- aendc = triangulation.begin_active(level+1);
- for (; acell!=aendc; ++acell)
- if (acell->refine_flag_set())
- ++flagged_cells;
-
- // count number of used cells
- // on the next higher level
- const unsigned int used_cells
- = std::count_if (triangulation.levels[level+1]->cells.used.begin(),
- triangulation.levels[level+1]->cells.used.end(),
- std::bind2nd (std::equal_to<bool>(), true));
-
- // reserve space for the
- // used_cells cells already
- // existing on the next higher
- // level as well as for the
- // 2*flagged_cells that will be
- // created on that level
- triangulation.levels[level+1]
- ->reserve_space(used_cells+
- GeometryInfo<1>::max_children_per_cell *
- flagged_cells,
- 1,
- spacedim);
- // reserve space for
- // 2*flagged_cells new lines on
- // the next higher level
- triangulation.levels[level+1]->cells
- .reserve_space (GeometryInfo<1>::max_children_per_cell *
- flagged_cells,
- 0);
-
- needed_vertices += flagged_cells;
- }
-
- // add to needed vertices how many
- // vertices are already in use
- needed_vertices += std::count_if (triangulation.vertices_used.begin(),
- triangulation.vertices_used.end(),
- std::bind2nd (std::equal_to<bool>(),
- true));
- // if we need more vertices: create
- // them, if not: leave the array as
- // is, since shrinking is not
- // really possible because some of
- // the vertices at the end may be
- // in use
- if (needed_vertices > triangulation.vertices.size())
- {
- triangulation.vertices.resize (needed_vertices,
- Point<spacedim>());
- triangulation.vertices_used.resize (needed_vertices, false);
- }
-
-
- // Do REFINEMENT
- // on every level; exclude highest
- // level as above
-
- // index of next unused vertex
- unsigned int next_unused_vertex = 0;
-
- for (int level=triangulation.levels.size()-2; level>=0; --level)
- {
- typename Triangulation<dim,spacedim>::active_cell_iterator
- cell = triangulation.begin_active(level),
- endc = triangulation.begin_active(level+1);
-
- typename Triangulation<dim,spacedim>::raw_cell_iterator
- next_unused_cell = triangulation.begin_raw (level+1);
-
- for (; (cell!=endc) && (cell->level()==level); ++cell)
- if (cell->refine_flag_set())
- {
- // clear refinement flag
- cell->clear_refine_flag ();
-
- // search for next unused
- // vertex
- while (triangulation.vertices_used[next_unused_vertex] == true)
- ++next_unused_vertex;
- Assert (next_unused_vertex < triangulation.vertices.size(),
- ExcTooFewVerticesAllocated());
-
- // first insert new
- // vertex. if dim==spacedim
- // then simply use the
- // midpoint; otherwise we
- // have to ask the manifold
- // object
- if (dim == spacedim)
- triangulation.vertices[next_unused_vertex] =
- (cell->vertex(0) + cell->vertex(1)) / 2;
- else
- triangulation.vertices[next_unused_vertex] =
- triangulation.get_boundary(static_cast<types::boundary_id_t>(cell->material_id()))
- .get_new_point_on_line(cell);
- triangulation.vertices_used[next_unused_vertex] = true;
-
- // search for next two
- // unused cell (++ takes
- // care of the end of the
- // vector)
- typename Triangulation<dim,spacedim>::raw_cell_iterator
- first_child,
- second_child;
- while (next_unused_cell->used() == true)
- ++next_unused_cell;
- first_child = next_unused_cell;
- first_child->set_used_flag ();
- first_child->clear_user_data ();
- ++next_unused_cell;
- Assert (next_unused_cell->used() == false,
- ExcCellShouldBeUnused());
- second_child = next_unused_cell;
- second_child->set_used_flag ();
- second_child->clear_user_data ();
-
- // insert first child
- cell->set_children (0, first_child->index());
- first_child->clear_children ();
- first_child->set (internal::Triangulation
- ::TriaObject<1> (cell->vertex_index(0),
- next_unused_vertex));
- first_child->set_material_id (cell->material_id());
- first_child->set_subdomain_id (cell->subdomain_id());
- first_child->set_direction_flag (cell->direction_flag());
-
- first_child->set_parent (cell->index ());
-
- // reset neighborship info (refer
- // to
- // internal::Triangulation::TriaLevel<0>
- // for details)
- first_child->set_neighbor (1, second_child);
- if (cell->neighbor(0).state() != IteratorState::valid)
- first_child->set_neighbor (0, cell->neighbor(0));
- else
- if (cell->neighbor(0)->active())
- {
- // since the
- // neighbors level
- // is always
- // <=level, if the
- // cell is active,
- // then there are
- // no cells to the
- // left which may
- // want to know
- // about this new
- // child cell.
- Assert (cell->neighbor(0)->level() <= cell->level(),
- ExcInternalError());
- first_child->set_neighbor (0, cell->neighbor(0));
- }
- else
- // left neighbor is
- // refined
- {
- // set neighbor to
- // cell on same
- // level
- const unsigned int nbnb = cell->neighbor_of_neighbor (0);
- first_child->set_neighbor (0, cell->neighbor(0)->child(nbnb));
-
- // reset neighbor
- // info of all
- // right descendant
- // of the left
- // neighbor of cell
- typename Triangulation<dim,spacedim>::cell_iterator
- left_neighbor = cell->neighbor(0);
- while (left_neighbor->has_children())
- {
- left_neighbor = left_neighbor->child(nbnb);
- left_neighbor->set_neighbor (nbnb, first_child);
- }
- }
-
- // insert second child
- second_child->clear_children ();
- second_child->set (internal::Triangulation
- ::TriaObject<1>(next_unused_vertex,
- cell->vertex_index(1)));
- second_child->set_neighbor (0, first_child);
- second_child->set_material_id (cell->material_id());
- second_child->set_subdomain_id (cell->subdomain_id());
- second_child->set_direction_flag (cell->direction_flag());
-
- if (cell->neighbor(1).state() != IteratorState::valid)
- second_child->set_neighbor (1, cell->neighbor(1));
- else
- if (cell->neighbor(1)->active())
- {
- Assert (cell->neighbor(1)->level() <= cell->level(),
- ExcInternalError());
- second_child->set_neighbor (1, cell->neighbor(1));
- }
- else
- // right neighbor is
- // refined same as
- // above
- {
- const unsigned int nbnb = cell->neighbor_of_neighbor (1);
- second_child->set_neighbor (1, cell->neighbor(1)->child(nbnb));
-
- typename Triangulation<dim,spacedim>::cell_iterator
- right_neighbor = cell->neighbor(1);
- while (right_neighbor->has_children())
- {
- right_neighbor = right_neighbor->child(nbnb);
- right_neighbor->set_neighbor (nbnb, second_child);
- }
- }
- }
- }
-
- // in 1d, we can not have
- // distorted children
- // unless the parent was
- // already distorted
- // (that is because we
- // don't use boundary
- // information for 1d
- // triangulations). so
- // return an empty list
- return typename Triangulation<1,spacedim>::DistortedCellList();
- }
-
-
- /**
- * A function that performs the
- * refinement of a triangulation in 2d.
- */
- template <int spacedim>
- static
- typename Triangulation<2,spacedim>::DistortedCellList
- execute_refinement (Triangulation<2,spacedim> &triangulation,
- const bool check_for_distorted_cells)
- {
- const unsigned int dim = 2;
-
- // check whether a new level is
- // needed we have to check for this
- // on the highest level only (on
- // this, all used cells are also
- // active, so we only have to check
- // for this)
- if (true)
- {
- typename Triangulation<dim,spacedim>::raw_cell_iterator
- cell = triangulation.begin_active (triangulation.levels.size()-1),
- endc = triangulation.end();
- for (; cell != endc; ++cell)
- if (cell->used())
- if (cell->refine_flag_set())
- {
- triangulation.levels.push_back (new internal::Triangulation::TriaLevel<dim>);
- break;
- }
- }
-
-
- // first clear user flags and
- // pointers of lines; we're going
- // to use them to flag which lines
- // need refinement
- for (typename Triangulation<dim,spacedim>::line_iterator
- line=triangulation.begin_line(); line!=triangulation.end_line(); ++line)
- {
- line->clear_user_flag();
- line->clear_user_data();
- }
- // running over all cells and lines
- // count the number
- // n_single_lines of lines
- // which can be stored as
- // single lines, e.g. inner lines
- unsigned int n_single_lines=0;
- // New lines to be created:
- // number lines which are
- // stored in pairs (the
- // children of lines must be
- // stored in pairs)
- unsigned int n_lines_in_pairs = 0;
-
- // check how much space is needed
- // on every level we need not check
- // the highest level since either
- // - on the highest level no cells
- // are flagged for refinement
- // - there are, but prepare_refinement
- // added another empty level
- unsigned int needed_vertices = 0;
- for (int level=triangulation.levels.size()-2; level>=0; --level)
- {
- // count number of flagged
- // cells on this level and
- // compute how many new
- // vertices and new lines will
- // be needed
- unsigned int needed_cells = 0;
-
- typename Triangulation<dim,spacedim>::active_cell_iterator
- cell = triangulation.begin_active(level),
- endc = triangulation.begin_active(level+1);
- for (; cell!=endc; ++cell)
- if (cell->refine_flag_set())
- {
- if (cell->refine_flag_set()==RefinementCase<dim>::cut_xy)
- {
- needed_cells += 4;
-
- // new vertex at
- // center of cell is
- // needed in any case
- ++needed_vertices;
- // the four inner
- // lines can be
- // stored as singles
- n_single_lines += 4;
- }
- else // cut_x || cut_y
- {
- // set the flag showing that
- // anisotropic refinement is
- // used for at least one cell
- triangulation.anisotropic_refinement = true;
-
- needed_cells += 2;
- // no vertex at center
-
- // the inner line can
- // be stored as
- // single
- n_single_lines += 1;
-
- }
-
- // mark all faces
- // (lines) for
- // refinement;
- // checking locally
- // whether the
- // neighbor would
- // also like to
- // refine them is
- // rather difficult
- // for lines so we
- // only flag them and
- // after visiting all
- // cells, we decide
- // which lines need
- // refinement;
- for (unsigned int line_no=0; line_no<GeometryInfo<dim>::faces_per_cell;
- ++line_no)
- {
- if (GeometryInfo<dim>::face_refinement_case(
- cell->refine_flag_set(), line_no)==RefinementCase<1>::cut_x)
- {
- typename Triangulation<dim,spacedim>::line_iterator
- line = cell->line(line_no);
- if (line->has_children() == false)
- {
- line->set_user_flag ();
+ // collect the
+ // indices of the
+ // eight
+ // surrounding
+ // vertices
+ // 2--7--3
+ // | | |
+ // 4--9--5
+ // | | |
+ // 0--6--1
+ int new_vertices[9];
+ for (unsigned int vertex_no=0; vertex_no<4; ++vertex_no)
+ new_vertices[vertex_no]=cell->vertex_index(vertex_no);
+ for (unsigned int line_no=0; line_no<4; ++line_no)
+ if (cell->line(line_no)->has_children())
+ new_vertices[4+line_no]=cell->line(line_no)->child(0)->vertex_index(1);
+
+ if (ref_case==RefinementCase<dim>::cut_xy)
+ {
+
+ // find the next
+ // unused vertex and
+ // allocate it for
+ // the new vertex we
+ // need here
+ while (triangulation.vertices_used[next_unused_vertex] == true)
+ ++next_unused_vertex;
+ Assert (next_unused_vertex < triangulation.vertices.size(),
+ ExcTooFewVerticesAllocated());
+ triangulation.vertices_used[next_unused_vertex] = true;
+
+ new_vertices[8] = next_unused_vertex;
+
+ // if this quad lives
+ // in 2d, then we can
+ // compute the new
+ // central vertex
+ // location just from
+ // the surrounding
+ // ones. If this is
+ // not the case, then
+ // we need to ask a
+ // boundary object
+ if (dim == spacedim)
+ {
+ // in a first
+ // step, compute
+ // the location
+ // of central
+ // vertex as the
+ // average of the
+ // 8 surrounding
+ // vertices
+ Point<spacedim> new_point;
+ for (unsigned int i=0; i<8; ++i)
+ new_point += triangulation.vertices[new_vertices[i]];
+ new_point /= 8.0;
+
+ triangulation.vertices[next_unused_vertex] = new_point;
+
+ // if the user_flag is set, i.e. if the
+ // cell is at the boundary, use a
+ // different calculation of the middle
+ // vertex here. this is of advantage, if
+ // the boundary is strongly curved and
+ // the cell has a high aspect ratio. this
+ // can happen for example, if it was
+ // refined anisotropically before.
+ if (cell->user_flag_set())
+ {
+ // first reset the user_flag
+ cell->clear_user_flag();
+ // the user flag indicates: at least
+ // one face is at the boundary. if it
+ // is only one, set the new middle
+ // vertex in a different way to avoid
+ // some mis-shaped elements if the
+ // new point on the boundary is not
+ // where we expect it, especially if
+ // it is to far inside the current
+ // cell
+ unsigned int boundary_face=GeometryInfo<dim>::faces_per_cell;
+ for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
+ if (cell->face(face)->at_boundary())
+ {
+ if (boundary_face == GeometryInfo<dim>::faces_per_cell)
+ // no boundary face found so
+ // far, so set it now
+ boundary_face=face;
+ else
+ // there is another boundary
+ // face, so reset boundary_face to
+ // invalid value as a flag to
+ // do nothing in the following
+ boundary_face=GeometryInfo<dim>::faces_per_cell+1;
+ }
+
+ if (boundary_face<GeometryInfo<dim>::faces_per_cell)
+ // reset the cell's middle vertex
+ // to the middle of the straight
+ // connection between the new
+ // points on this face and on the
+ // opposite face
+ triangulation.vertices[next_unused_vertex]
+ = 0.5*(cell->face(boundary_face)
+ ->child(0)->vertex(1)+
+ cell->face(GeometryInfo<dim>
+ ::opposite_face[boundary_face])
+ ->child(0)->vertex(1));
+ }
+ }
+ else
+ {
+ // if this quad
+ // lives in a
+ // higher
+ // dimensional
+ // space then we
+ // don't need to
+ // worry if it is
+ // at the
+ // boundary of
+ // the manifold
+ // -- we always
+ // have to use
+ // the boundary
+ // object anyway;
+ // so ignore
+ // whether the
+ // user flag is
+ // set or not
+ cell->clear_user_flag();
+
+
+
+ // An assert to make sure that the
+ // static_cast in the next line has
+ // the chance to give reasonable results.
+ Assert(cell->material_id()<= std::numeric_limits<types::material_id_t>::max(),
+ ExcIndexRange(cell->material_id(),0,std::numeric_limits<types::material_id_t>::max()));
+
+ // new vertex is
+ // placed on the
+ // surface according
+ // to the information
+ // stored in the
+ // boundary class
+ triangulation.vertices[next_unused_vertex] =
+ triangulation.get_boundary(static_cast<types::boundary_id_t>(cell->material_id()))
+ .get_new_point_on_quad (cell);
+ }
+ }
+
+
+ // Now the lines:
+ typename Triangulation<dim,spacedim>::raw_line_iterator new_lines[12];
+ unsigned int lmin=8;
+ unsigned int lmax=12;
+ if (ref_case!=RefinementCase<dim>::cut_xy)
+ {
+ lmin=6;
+ lmax=7;
+ }
+
+ for (unsigned int l=lmin; l<lmax; ++l)
+ {
+ while (next_unused_line->used() == true)
+ ++next_unused_line;
+ new_lines[l] = next_unused_line;
+ ++next_unused_line;
+
+ Assert (new_lines[l]->used() == false,
+ ExcCellShouldBeUnused());
+ }
+
+ if (ref_case==RefinementCase<dim>::cut_xy)
+ {
+ // .-6-.-7-.
+ // 1 9 3
+ // .-10.11-.
+ // 0 8 2
+ // .-4-.-5-.
+
+ // lines 0-7 already
+ // exist, create only
+ // the four interior
+ // lines 8-11
+ unsigned int l=0;
+ for (unsigned int face_no=0; face_no<GeometryInfo<dim>::faces_per_cell; ++face_no)
+ for (unsigned int c=0; c<2; ++c, ++l)
+ new_lines[l]=cell->line(face_no)->child(c);
+ Assert(l==8, ExcInternalError());
+
+ new_lines[8] ->set (internal::Triangulation::
+ TriaObject<1>(new_vertices[6], new_vertices[8]));
+ new_lines[9] ->set (internal::Triangulation::
+ TriaObject<1>(new_vertices[8], new_vertices[7]));
+ new_lines[10]->set (internal::Triangulation::
+ TriaObject<1>(new_vertices[4], new_vertices[8]));
+ new_lines[11]->set (internal::Triangulation::
+ TriaObject<1>(new_vertices[8], new_vertices[5]));
+ }
+ else if (ref_case==RefinementCase<dim>::cut_x)
+ {
+ // .-4-.-5-.
+ // | | |
+ // 0 6 1
+ // | | |
+ // .-2-.-3-.
+ new_lines[0]=cell->line(0);
+ new_lines[1]=cell->line(1);
+ new_lines[2]=cell->line(2)->child(0);
+ new_lines[3]=cell->line(2)->child(1);
+ new_lines[4]=cell->line(3)->child(0);
+ new_lines[5]=cell->line(3)->child(1);
+ new_lines[6]->set (internal::Triangulation::
+ TriaObject<1>(new_vertices[6], new_vertices[7]));
+ }
+ else
+ {
+ Assert(ref_case==RefinementCase<dim>::cut_y, ExcInternalError());
+ // .---5---.
+ // 1 3
+ // .---6---.
+ // 0 2
+ // .---4---.
+ new_lines[0]=cell->line(0)->child(0);
+ new_lines[1]=cell->line(0)->child(1);
+ new_lines[2]=cell->line(1)->child(0);
+ new_lines[3]=cell->line(1)->child(1);
+ new_lines[4]=cell->line(2);
+ new_lines[5]=cell->line(3);
+ new_lines[6]->set (internal::Triangulation::
+ TriaObject<1>(new_vertices[4], new_vertices[5]));
+ }
+
+ for (unsigned int l=lmin; l<lmax; ++l)
+ {
+ new_lines[l]->set_used_flag();
+ new_lines[l]->clear_user_flag();
+ new_lines[l]->clear_user_data();
+ new_lines[l]->clear_children();
+ // interior line
+ new_lines[l]->set_boundary_indicator(types::internal_face_boundary_id);
+ }
+
+ // Now add the four (two)
+ // new cells!
+ typename Triangulation<dim,spacedim>::raw_cell_iterator
+ subcells[GeometryInfo<dim>::max_children_per_cell];
+ while (next_unused_cell->used() == true)
+ ++next_unused_cell;
+
+ const unsigned int n_children=
+ GeometryInfo<dim>::n_children(ref_case);
+ for (unsigned int i=0; i<n_children; ++i)
+ {
+ Assert (next_unused_cell->used() == false,
+ ExcCellShouldBeUnused());
+ subcells[i] = next_unused_cell;
+ ++next_unused_cell;
+ if (i%2==1 && i<n_children-1)
+ while (next_unused_cell->used() == true)
+ ++next_unused_cell;
+ }
+
+ if (ref_case==RefinementCase<dim>::cut_xy)
+ {
+ // children:
+ // .--.--.
+ // |2 . 3|
+ // .--.--.
+ // |0 | 1|
+ // .--.--.
+ // lines:
+ // .-6-.-7-.
+ // 1 9 3
+ // .-10.11-.
+ // 0 8 2
+ // .-4-.-5-.
+ subcells[0]->set (internal::Triangulation::
+ TriaObject<2>(new_lines[0]->index(),
+ new_lines[8]->index(),
+ new_lines[4]->index(),
+ new_lines[10]->index()));
+ subcells[1]->set (internal::Triangulation::
+ TriaObject<2>(new_lines[8]->index(),
+ new_lines[2]->index(),
+ new_lines[5]->index(),
+ new_lines[11]->index()));
+ subcells[2]->set (internal::Triangulation::
+ TriaObject<2>(new_lines[1]->index(),
+ new_lines[9]->index(),
+ new_lines[10]->index(),
+ new_lines[6]->index()));
+ subcells[3]->set (internal::Triangulation::
+ TriaObject<2>(new_lines[9]->index(),
+ new_lines[3]->index(),
+ new_lines[11]->index(),
+ new_lines[7]->index()));
+ }
+ else if (ref_case==RefinementCase<dim>::cut_x)
+ {
+ // children:
+ // .--.--.
+ // | . |
+ // .0 . 1.
+ // | | |
+ // .--.--.
+ // lines:
+ // .-4-.-5-.
+ // | | |
+ // 0 6 1
+ // | | |
+ // .-2-.-3-.
+ subcells[0]->set (internal::Triangulation::
+ TriaObject<2>(new_lines[0]->index(),
+ new_lines[6]->index(),
+ new_lines[2]->index(),
+ new_lines[4]->index()));
+ subcells[1]->set (internal::Triangulation::
+ TriaObject<2>(new_lines[6]->index(),
+ new_lines[1]->index(),
+ new_lines[3]->index(),
+ new_lines[5]->index()));
+ }
+ else
+ {
+ Assert(ref_case==RefinementCase<dim>::cut_y, ExcInternalError());
+ // children:
+ // .-----.
+ // | 1 |
+ // .-----.
+ // | 0 |
+ // .-----.
+ // lines:
+ // .---5---.
+ // 1 3
+ // .---6---.
+ // 0 2
+ // .---4---.
+ subcells[0]->set (internal::Triangulation::
+ TriaObject<2>(new_lines[0]->index(),
+ new_lines[2]->index(),
+ new_lines[4]->index(),
+ new_lines[6]->index()));
+ subcells[1]->set (internal::Triangulation::
+ TriaObject<2>(new_lines[1]->index(),
+ new_lines[3]->index(),
+ new_lines[6]->index(),
+ new_lines[5]->index()));
+ }
+
+
+ for (unsigned int i=0; i<n_children; ++i)
+ {
+ subcells[i]->set_used_flag();
+ subcells[i]->clear_refine_flag();
+ subcells[i]->clear_user_flag();
+ subcells[i]->clear_user_data();
+ subcells[i]->clear_children();
+ // inherit material
+ // properties
+ subcells[i]->set_material_id (cell->material_id());
+ subcells[i]->set_subdomain_id (cell->subdomain_id());
+
+ if (i%2==0)
+ subcells[i]->set_parent (cell->index ());
+ }
+
+
+
+ // set child index for
+ // even children children
+ // i=0,2 (0)
+ for (unsigned int i=0; i<n_children/2; ++i)
+ cell->set_children (2*i, subcells[2*i]->index());
+ // set the refine case
+ cell->set_refinement_case(ref_case);
+
+ // note that the
+ // refinement flag was
+ // already cleared at the
+ // beginning of this function
+
+ if (dim < spacedim)
+ for (unsigned int c=0; c<n_children; ++c)
+ cell->child(c)->set_direction_flag (cell->direction_flag());
+
+ }
+
+
+
+ /**
+ * A function that performs the
+ * refinement of a triangulation in 1d.
+ */
+ template <int spacedim>
+ static
+ typename Triangulation<1,spacedim>::DistortedCellList
+ execute_refinement (Triangulation<1,spacedim> &triangulation,
+ const bool /*check_for_distorted_cells*/)
+ {
+ const unsigned int dim = 1;
+
+ // check whether a new level is
+ // needed we have to check for this
+ // on the highest level only (on
+ // this, all used cells are also
+ // active, so we only have to check
+ // for this)
+ {
+ typename Triangulation<dim,spacedim>::raw_cell_iterator
+ cell = triangulation.begin_active (triangulation.levels.size()-1),
+ endc = triangulation.end();
+ for (; cell != endc; ++cell)
+ if (cell->used())
+ if (cell->refine_flag_set())
+ {
+ triangulation.levels
+ .push_back (new internal::Triangulation::TriaLevel<dim>);
+ break;
+ }
+ }
+
+
+ // check how much space is needed
+ // on every level we need not check
+ // the highest level since either -
+ // on the highest level no cells
+ // are flagged for refinement -
+ // there are, but
+ // prepare_refinement added another
+ // empty level
+ unsigned int needed_vertices = 0;
+ for (int level=triangulation.levels.size()-2; level>=0; --level)
+ {
+ // count number of flagged
+ // cells on this level
+ unsigned int flagged_cells = 0;
+ typename Triangulation<dim,spacedim>::active_cell_iterator
+ acell = triangulation.begin_active(level),
+ aendc = triangulation.begin_active(level+1);
+ for (; acell!=aendc; ++acell)
+ if (acell->refine_flag_set())
+ ++flagged_cells;
+
+ // count number of used cells
+ // on the next higher level
+ const unsigned int used_cells
+ = std::count_if (triangulation.levels[level+1]->cells.used.begin(),
+ triangulation.levels[level+1]->cells.used.end(),
+ std::bind2nd (std::equal_to<bool>(), true));
+
+ // reserve space for the
+ // used_cells cells already
+ // existing on the next higher
+ // level as well as for the
+ // 2*flagged_cells that will be
+ // created on that level
+ triangulation.levels[level+1]
+ ->reserve_space(used_cells+
+ GeometryInfo<1>::max_children_per_cell *
+ flagged_cells,
+ 1,
+ spacedim);
+ // reserve space for
+ // 2*flagged_cells new lines on
+ // the next higher level
+ triangulation.levels[level+1]->cells
+ .reserve_space (GeometryInfo<1>::max_children_per_cell *
+ flagged_cells,
+ 0);
+
+ needed_vertices += flagged_cells;
+ }
+
+ // add to needed vertices how many
+ // vertices are already in use
+ needed_vertices += std::count_if (triangulation.vertices_used.begin(),
+ triangulation.vertices_used.end(),
+ std::bind2nd (std::equal_to<bool>(),
+ true));
+ // if we need more vertices: create
+ // them, if not: leave the array as
+ // is, since shrinking is not
+ // really possible because some of
+ // the vertices at the end may be
+ // in use
+ if (needed_vertices > triangulation.vertices.size())
+ {
+ triangulation.vertices.resize (needed_vertices,
+ Point<spacedim>());
+ triangulation.vertices_used.resize (needed_vertices, false);
+ }
+
+
+ // Do REFINEMENT
+ // on every level; exclude highest
+ // level as above
+
+ // index of next unused vertex
+ unsigned int next_unused_vertex = 0;
+
+ for (int level=triangulation.levels.size()-2; level>=0; --level)
+ {
+ typename Triangulation<dim,spacedim>::active_cell_iterator
+ cell = triangulation.begin_active(level),
+ endc = triangulation.begin_active(level+1);
+
+ typename Triangulation<dim,spacedim>::raw_cell_iterator
+ next_unused_cell = triangulation.begin_raw (level+1);
+
+ for (; (cell!=endc) && (cell->level()==level); ++cell)
+ if (cell->refine_flag_set())
+ {
+ // clear refinement flag
+ cell->clear_refine_flag ();
+
+ // search for next unused
+ // vertex
+ while (triangulation.vertices_used[next_unused_vertex] == true)
+ ++next_unused_vertex;
+ Assert (next_unused_vertex < triangulation.vertices.size(),
+ ExcTooFewVerticesAllocated());
+
+ // first insert new
+ // vertex. if dim==spacedim
+ // then simply use the
+ // midpoint; otherwise we
+ // have to ask the manifold
+ // object
+ if (dim == spacedim)
+ triangulation.vertices[next_unused_vertex] =
+ (cell->vertex(0) + cell->vertex(1)) / 2;
+ else
+ triangulation.vertices[next_unused_vertex] =
+ triangulation.get_boundary(static_cast<types::boundary_id_t>(cell->material_id()))
+ .get_new_point_on_line(cell);
+ triangulation.vertices_used[next_unused_vertex] = true;
+
+ // search for next two
+ // unused cell (++ takes
+ // care of the end of the
+ // vector)
+ typename Triangulation<dim,spacedim>::raw_cell_iterator
+ first_child,
+ second_child;
+ while (next_unused_cell->used() == true)
+ ++next_unused_cell;
+ first_child = next_unused_cell;
+ first_child->set_used_flag ();
+ first_child->clear_user_data ();
+ ++next_unused_cell;
+ Assert (next_unused_cell->used() == false,
+ ExcCellShouldBeUnused());
+ second_child = next_unused_cell;
+ second_child->set_used_flag ();
+ second_child->clear_user_data ();
+
+ // insert first child
+ cell->set_children (0, first_child->index());
+ first_child->clear_children ();
+ first_child->set (internal::Triangulation
+ ::TriaObject<1> (cell->vertex_index(0),
+ next_unused_vertex));
+ first_child->set_material_id (cell->material_id());
+ first_child->set_subdomain_id (cell->subdomain_id());
+ first_child->set_direction_flag (cell->direction_flag());
+
+ first_child->set_parent (cell->index ());
+
+ // reset neighborship info (refer
+ // to
+ // internal::Triangulation::TriaLevel<0>
+ // for details)
+ first_child->set_neighbor (1, second_child);
+ if (cell->neighbor(0).state() != IteratorState::valid)
+ first_child->set_neighbor (0, cell->neighbor(0));
+ else
+ if (cell->neighbor(0)->active())
+ {
+ // since the
+ // neighbors level
+ // is always
+ // <=level, if the
+ // cell is active,
+ // then there are
+ // no cells to the
+ // left which may
+ // want to know
+ // about this new
+ // child cell.
+ Assert (cell->neighbor(0)->level() <= cell->level(),
+ ExcInternalError());
+ first_child->set_neighbor (0, cell->neighbor(0));
+ }
+ else
+ // left neighbor is
+ // refined
+ {
+ // set neighbor to
+ // cell on same
+ // level
+ const unsigned int nbnb = cell->neighbor_of_neighbor (0);
+ first_child->set_neighbor (0, cell->neighbor(0)->child(nbnb));
+
+ // reset neighbor
+ // info of all
+ // right descendant
+ // of the left
+ // neighbor of cell
+ typename Triangulation<dim,spacedim>::cell_iterator
+ left_neighbor = cell->neighbor(0);
+ while (left_neighbor->has_children())
+ {
+ left_neighbor = left_neighbor->child(nbnb);
+ left_neighbor->set_neighbor (nbnb, first_child);
+ }
+ }
+
+ // insert second child
+ second_child->clear_children ();
+ second_child->set (internal::Triangulation
+ ::TriaObject<1>(next_unused_vertex,
+ cell->vertex_index(1)));
+ second_child->set_neighbor (0, first_child);
+ second_child->set_material_id (cell->material_id());
+ second_child->set_subdomain_id (cell->subdomain_id());
+ second_child->set_direction_flag (cell->direction_flag());
+
+ if (cell->neighbor(1).state() != IteratorState::valid)
+ second_child->set_neighbor (1, cell->neighbor(1));
+ else
+ if (cell->neighbor(1)->active())
+ {
+ Assert (cell->neighbor(1)->level() <= cell->level(),
+ ExcInternalError());
+ second_child->set_neighbor (1, cell->neighbor(1));
+ }
+ else
+ // right neighbor is
+ // refined same as
+ // above
+ {
+ const unsigned int nbnb = cell->neighbor_of_neighbor (1);
+ second_child->set_neighbor (1, cell->neighbor(1)->child(nbnb));
+
+ typename Triangulation<dim,spacedim>::cell_iterator
+ right_neighbor = cell->neighbor(1);
+ while (right_neighbor->has_children())
+ {
+ right_neighbor = right_neighbor->child(nbnb);
+ right_neighbor->set_neighbor (nbnb, second_child);
+ }
+ }
+ }
+ }
+
+ // in 1d, we can not have
+ // distorted children
+ // unless the parent was
+ // already distorted
+ // (that is because we
+ // don't use boundary
+ // information for 1d
+ // triangulations). so
+ // return an empty list
+ return typename Triangulation<1,spacedim>::DistortedCellList();
+ }
+
+
+ /**
+ * A function that performs the
+ * refinement of a triangulation in 2d.
+ */
+ template <int spacedim>
+ static
+ typename Triangulation<2,spacedim>::DistortedCellList
+ execute_refinement (Triangulation<2,spacedim> &triangulation,
+ const bool check_for_distorted_cells)
+ {
+ const unsigned int dim = 2;
+
+ // check whether a new level is
+ // needed we have to check for this
+ // on the highest level only (on
+ // this, all used cells are also
+ // active, so we only have to check
+ // for this)
+ if (true)
+ {
+ typename Triangulation<dim,spacedim>::raw_cell_iterator
+ cell = triangulation.begin_active (triangulation.levels.size()-1),
+ endc = triangulation.end();
+ for (; cell != endc; ++cell)
+ if (cell->used())
+ if (cell->refine_flag_set())
+ {
+ triangulation.levels.push_back (new internal::Triangulation::TriaLevel<dim>);
+ break;
+ }
+ }
+
+
+ // first clear user flags and
+ // pointers of lines; we're going
+ // to use them to flag which lines
+ // need refinement
+ for (typename Triangulation<dim,spacedim>::line_iterator
+ line=triangulation.begin_line(); line!=triangulation.end_line(); ++line)
+ {
+ line->clear_user_flag();
+ line->clear_user_data();
+ }
+ // running over all cells and lines
+ // count the number
+ // n_single_lines of lines
+ // which can be stored as
+ // single lines, e.g. inner lines
+ unsigned int n_single_lines=0;
+ // New lines to be created:
+ // number lines which are
+ // stored in pairs (the
+ // children of lines must be
+ // stored in pairs)
+ unsigned int n_lines_in_pairs = 0;
+
+ // check how much space is needed
+ // on every level we need not check
+ // the highest level since either
+ // - on the highest level no cells
+ // are flagged for refinement
+ // - there are, but prepare_refinement
+ // added another empty level
+ unsigned int needed_vertices = 0;
+ for (int level=triangulation.levels.size()-2; level>=0; --level)
+ {
+ // count number of flagged
+ // cells on this level and
+ // compute how many new
+ // vertices and new lines will
+ // be needed
+ unsigned int needed_cells = 0;
+
+ typename Triangulation<dim,spacedim>::active_cell_iterator
+ cell = triangulation.begin_active(level),
+ endc = triangulation.begin_active(level+1);
+ for (; cell!=endc; ++cell)
+ if (cell->refine_flag_set())
+ {
+ if (cell->refine_flag_set()==RefinementCase<dim>::cut_xy)
+ {
+ needed_cells += 4;
+
+ // new vertex at
+ // center of cell is
+ // needed in any case
+ ++needed_vertices;
+ // the four inner
+ // lines can be
+ // stored as singles
+ n_single_lines += 4;
+ }
+ else // cut_x || cut_y
+ {
+ // set the flag showing that
+ // anisotropic refinement is
+ // used for at least one cell
+ triangulation.anisotropic_refinement = true;
+
+ needed_cells += 2;
+ // no vertex at center
+
+ // the inner line can
+ // be stored as
+ // single
+ n_single_lines += 1;
+
+ }
+
+ // mark all faces
+ // (lines) for
+ // refinement;
+ // checking locally
+ // whether the
+ // neighbor would
+ // also like to
+ // refine them is
+ // rather difficult
+ // for lines so we
+ // only flag them and
+ // after visiting all
+ // cells, we decide
+ // which lines need
+ // refinement;
+ for (unsigned int line_no=0; line_no<GeometryInfo<dim>::faces_per_cell;
+ ++line_no)
+ {
+ if (GeometryInfo<dim>::face_refinement_case(
+ cell->refine_flag_set(), line_no)==RefinementCase<1>::cut_x)
+ {
+ typename Triangulation<dim,spacedim>::line_iterator
+ line = cell->line(line_no);
+ if (line->has_children() == false)
+ {
+ line->set_user_flag ();
//TODO[WB]: we overwrite the user_index here because we later on need
// to find out which boundary object we have to ask to refine this
// line. we can't use the boundary_indicator field because that can
// only be used for lines at the boundary of the domain, but we also
// need a domain description for interior lines in the codim-1 case
- if (spacedim > dim)
- {
- if (line->at_boundary())
- // if
- // possible
- // honor
- // boundary
- // indicator
- line->set_user_index(line->boundary_indicator());
- else
- // otherwise
- // take
- // manifold
- // description
- // from
- // the
- // adjacent
- // cell
- line->set_user_index(cell->material_id());
- }
- }
- }
- }
- }
-
-
- // count number of used cells
- // on the next higher level
- const unsigned int used_cells
- = std::count_if (triangulation.levels[level+1]->cells.used.begin(),
- triangulation.levels[level+1]->cells.used.end(),
- std::bind2nd (std::equal_to<bool>(), true));
-
-
- // reserve space for the
- // used_cells cells already
- // existing on the next higher
- // level as well as for the
- // needed_cells that will be
- // created on that level
- triangulation.levels[level+1]
- ->reserve_space (used_cells+needed_cells, 2, spacedim);
-
- // reserve space for
- // needed_cells
- // new quads on the next higher
- // level
- triangulation.levels[level+1]->cells.
- reserve_space (needed_cells,0);
- }
-
- // now count the lines which
- // were flagged for refinement
- for (typename Triangulation<dim,spacedim>::line_iterator
- line=triangulation.begin_line(); line!=triangulation.end_line(); ++line)
- if (line->user_flag_set())
- {
- Assert (line->has_children() == false, ExcInternalError());
- n_lines_in_pairs += 2;
- needed_vertices += 1;
- }
- // reserve space for
- // n_lines_in_pairs new lines.
- // note, that we can't reserve space
- // for the single lines here as well,
- // as all the space reserved for lines
- // in pairs would be counted as unused
- // and we would end up with too little
- // space to store all lines. memory
- // reservation for n_single_lines can
- // only be done AFTER we refined the lines
- // of the current cells
- triangulation.faces->lines.
- reserve_space (n_lines_in_pairs, 0);
-
- // add to needed vertices how many
- // vertices are already in use
- needed_vertices += std::count_if (triangulation.vertices_used.begin(), triangulation.vertices_used.end(),
- std::bind2nd (std::equal_to<bool>(), true));
- // if we need more vertices: create
- // them, if not: leave the array as
- // is, since shrinking is not
- // really possible because some of
- // the vertices at the end may be
- // in use
- if (needed_vertices > triangulation.vertices.size())
- {
- triangulation.vertices.resize (needed_vertices, Point<spacedim>());
- triangulation.vertices_used.resize (needed_vertices, false);
- }
-
-
- // Do REFINEMENT
- // on every level; exclude highest
- // level as above
-
- // index of next unused vertex
- unsigned int next_unused_vertex = 0;
-
- // first the refinement of lines.
- // children are stored pairwise
- if (true)
- {
- // only active objects can be
- // refined further
- typename Triangulation<dim,spacedim>::active_line_iterator
- line = triangulation.begin_active_line(),
- endl = triangulation.end_line();
- typename Triangulation<dim,spacedim>::raw_line_iterator
- next_unused_line = triangulation.begin_raw_line ();
-
- for (; line!=endl; ++line)
- if (line->user_flag_set())
- {
- // this line needs to be
- // refined
-
- // find the next unused
- // vertex and set it
- // appropriately
- while (triangulation.vertices_used[next_unused_vertex] == true)
- ++next_unused_vertex;
- Assert (next_unused_vertex < triangulation.vertices.size(),
- ExcTooFewVerticesAllocated());
- triangulation.vertices_used[next_unused_vertex] = true;
-
- if (spacedim == dim)
- {
- // for the case of a domain
- // in an equal-dimensional
- // space we only have to
- // treat boundary lines
- // differently; for interior
- // lines we can compute the
- // midpoint as the mean of
- // the two vertices:
- if (line->at_boundary())
- triangulation.vertices[next_unused_vertex]
- = triangulation.get_boundary(line->boundary_indicator())
- .get_new_point_on_line (line);
- else
- triangulation.vertices[next_unused_vertex]
- = (line->vertex(0) + line->vertex(1)) / 2;
- }
- else
- // however, if spacedim>dim, we
- // always have to ask the
- // boundary object for its
- // answer
- triangulation.vertices[next_unused_vertex]
- = triangulation.get_boundary(line->user_index()).get_new_point_on_line (line);
-
- // now that we created
- // the right point, make
- // up the two child
- // lines. To this end,
- // find a pair of unused
- // lines
- bool pair_found=false;
- for (; next_unused_line!=endl; ++next_unused_line)
- if (!next_unused_line->used() &&
- !(++next_unused_line)->used())
- {
- // go back to the
- // first of the two
- // unused lines
- --next_unused_line;
- pair_found=true;
- break;
- }
- Assert (pair_found, ExcInternalError());
-
- // there are now two
- // consecutive unused
- // lines, such that the
- // children of a line
- // will be consecutive.
- // then set the child
- // pointer of the present
- // line
- line->set_children (0, next_unused_line->index());
-
- // set the two new lines
- const typename Triangulation<dim,spacedim>::raw_line_iterator
- children[2] = { next_unused_line,
- ++next_unused_line };
- // some tests; if any of
- // the iterators should
- // be invalid, then
- // already dereferencing
- // will fail
- Assert (children[0]->used() == false, ExcCellShouldBeUnused());
- Assert (children[1]->used() == false, ExcCellShouldBeUnused());
-
- children[0]->set (internal::Triangulation
- ::TriaObject<1>(line->vertex_index(0),
- next_unused_vertex));
- children[1]->set (internal::Triangulation
- ::TriaObject<1>(next_unused_vertex,
- line->vertex_index(1)));
-
- children[0]->set_used_flag();
- children[1]->set_used_flag();
- children[0]->clear_children();
- children[1]->clear_children();
- children[0]->clear_user_data();
- children[1]->clear_user_data();
- children[0]->clear_user_flag();
- children[1]->clear_user_flag();
-
- children[0]->set_boundary_indicator (line->boundary_indicator());
- children[1]->set_boundary_indicator (line->boundary_indicator());
-
- // finally clear flag
- // indicating the need
- // for refinement
- line->clear_user_flag ();
- }
- }
-
-
- // Now set up the new cells
-
- // reserve space for inner
- // lines (can be stored as
- // single lines)
- triangulation.faces->lines.
- reserve_space (0,n_single_lines);
-
- typename Triangulation<2,spacedim>::DistortedCellList
- cells_with_distorted_children;
-
- // reset next_unused_line, as
- // now also single empty places
- // in the vector can be used
- typename Triangulation<dim,spacedim>::raw_line_iterator
- next_unused_line = triangulation.begin_raw_line ();
-
- for (int level=0; level<static_cast<int>(triangulation.levels.size())-1; ++level)
- {
-
- // Remember: as we don't operate
- // on the finest level, begin_*(level+1)
- // is allowed
- typename Triangulation<dim,spacedim>::active_cell_iterator
- cell = triangulation.begin_active(level),
- endc = triangulation.begin_active(level+1);
-
- typename Triangulation<dim,spacedim>::raw_cell_iterator
- next_unused_cell = triangulation.begin_raw (level+1);
-
- for (; cell!=endc; ++cell)
- if (cell->refine_flag_set())
- {
- // set the user flag to
- // indicate, that at least one
- // line is at the boundary
-
- // TODO[Tobias Leicht] find a
- // better place to set this flag,
- // so that we do not need so much
- // time to check each cell here
- if (cell->at_boundary())
- cell->set_user_flag();
-
- // actually set up the children and
- // update neighbor information
- create_children (triangulation,
- next_unused_vertex,
- next_unused_line,
- next_unused_cell,
- cell);
-
- if ((check_for_distorted_cells == true)
- &&
- has_distorted_children (cell,
- internal::int2type<dim>(),
- internal::int2type<spacedim>()))
- cells_with_distorted_children.distorted_cells.push_back (cell);
- }
- }
-
- return cells_with_distorted_children;
- }
-
-
- /**
- * A function that performs the
- * refinement of a triangulation in 3d.
- */
- template <int spacedim>
- static
- typename Triangulation<3,spacedim>::DistortedCellList
- execute_refinement (Triangulation<3,spacedim> &triangulation,
- const bool check_for_distorted_cells)
- {
- const unsigned int dim = 3;
-
- // this function probably
- // also works for spacedim>3
- // but it isn't tested. it
- // will probably be necessary
- // to pull new vertices onto
- // the manifold just as we do
- // for the other functions
- // above.
- Assert (spacedim == 3, ExcNotImplemented());
-
- // check whether a new level is
- // needed we have to check for this
- // on the highest level only (on
- // this, all used cells are also
- // active, so we only have to check
- // for this)
- if (true)
- {
- typename Triangulation<dim,spacedim>::raw_cell_iterator
- cell = triangulation.begin_active (triangulation.levels.size()-1),
- endc = triangulation.end();
- for (; cell != endc; ++cell)
- if (cell->used())
- if (cell->refine_flag_set())
- {
- triangulation.levels.push_back (new internal::Triangulation::TriaLevel<dim>);
- break;
- }
- }
-
-
- // first clear user flags for quads
- // and lines; we're going to use them
- // to flag which lines and quads
- // need refinement
- triangulation.faces->quads.clear_user_data();
-
- for (typename Triangulation<dim,spacedim>::line_iterator
- line=triangulation.begin_line(); line!=triangulation.end_line(); ++line)
- line->clear_user_flag();
- for (typename Triangulation<dim,spacedim>::quad_iterator
- quad=triangulation.begin_quad(); quad!=triangulation.end_quad(); ++quad)
- quad->clear_user_flag();
-
- // create an array of face refine cases. User
- // indices of faces will be set to values
- // corresponding with indices in this array.
- const RefinementCase<dim-1> face_refinement_cases[4]=
- {RefinementCase<dim-1>::no_refinement,
- RefinementCase<dim-1>::cut_x,
- RefinementCase<dim-1>::cut_y,
- RefinementCase<dim-1>::cut_xy};
-
- // check how much space is needed
- // on every level
- // we need not check the highest
- // level since either
- // - on the highest level no cells
- // are flagged for refinement
- // - there are, but prepare_refinement
- // added another empty level which
- // then is the highest level
-
- // variables to hold the number of newly to
- // be created vertices, lines and quads. as
- // these are stored globally, declare them
- // outside the loop over al levels. we need
- // lines and quads in pairs for refinement of
- // old ones and lines and quads, that can be
- // stored as single ones, as they are newly
- // created in the inside of an existing cell
- unsigned int needed_vertices = 0;
- unsigned int needed_lines_single = 0;
- unsigned int needed_quads_single = 0;
- unsigned int needed_lines_pair = 0;
- unsigned int needed_quads_pair = 0;
- for (int level=triangulation.levels.size()-2; level>=0; --level)
- {
- // count number of flagged
- // cells on this level and
- // compute how many new
- // vertices and new lines will
- // be needed
- unsigned int new_cells = 0;
-
- typename Triangulation<dim,spacedim>::active_cell_iterator
- acell = triangulation.begin_active(level),
- aendc = triangulation.begin_active(level+1);
- for (; acell!=aendc; ++acell)
- if (acell->refine_flag_set())
- {
- RefinementCase<dim> ref_case=acell->refine_flag_set();
-
- // now for interior vertices, lines
- // and quads, which are needed in
- // any case
- if (ref_case==RefinementCase<dim>::cut_x ||
- ref_case==RefinementCase<dim>::cut_y ||
- ref_case==RefinementCase<dim>::cut_z)
- {
- ++needed_quads_single;
- new_cells+=2;
- triangulation.anisotropic_refinement=true;
- }
- else if (ref_case==RefinementCase<dim>::cut_xy ||
- ref_case==RefinementCase<dim>::cut_xz ||
- ref_case==RefinementCase<dim>::cut_yz)
- {
- ++needed_lines_single;
- needed_quads_single += 4;
- new_cells+=4;
- triangulation.anisotropic_refinement=true;
- }
- else if (ref_case==RefinementCase<dim>::cut_xyz)
- {
- ++needed_vertices;
- needed_lines_single += 6;
- needed_quads_single += 12;
- new_cells+=8;
- }
- else
- {
- // we should never get here
- Assert(false, ExcInternalError());
- }
-
- // mark all faces for refinement;
- // checking locally
- // if and how the neighbor
- // would like to
- // refine these is
- // difficult so
- // we only flag them and
- // after visiting all
- // cells, we decide which
- // faces need which refinement;
- for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell;
- ++face)
- {
- typename Triangulation<dim,spacedim>::face_iterator
- aface = acell->face(face);
- // get the RefineCase this
- // faces has for the given
- // RefineCase of the cell
- RefinementCase<dim-1> face_ref_case=
- GeometryInfo<dim>::face_refinement_case(ref_case,
- face,
- acell->face_orientation(face),
- acell->face_flip(face),
- acell->face_rotation(face));
- // only do something, if this
- // face has to be refined
- if (face_ref_case)
- {
- if (face_ref_case==RefinementCase<dim-1>::isotropic_refinement)
- {
- if (aface->number_of_children()<4)
- // we use user_flags to
- // denote needed isotropic
- // refinement
- aface->set_user_flag();
- }
- else if (aface->refinement_case()!=face_ref_case)
- // we use user_indices
- // to denote needed
- // anisotropic
- // refinement. note, that
- // we can have at most
- // one anisotropic
- // refinement case for
- // this face, as
- // otherwise
- // prepare_refinement()
- // would have changed one
- // of the cells to yield
- // isotropic refinement
- // at this
- // face. therefore we set
- // the user_index
- // uniquely
- {
- Assert(aface->refinement_case()==RefinementCase<dim-1>::isotropic_refinement ||
- aface->refinement_case()==RefinementCase<dim-1>::no_refinement,
- ExcInternalError());
- aface->set_user_index(face_ref_case);
- }
- }
- }// for all faces
-
- // flag all lines, that have to be
- // refined
- for (unsigned int line=0; line<GeometryInfo<dim>::lines_per_cell; ++line)
- if (GeometryInfo<dim>::line_refinement_case(ref_case,line) &&
- !acell->line(line)->has_children())
- acell->line(line)->set_user_flag();
-
- }// if refine_flag set and for all cells on this level
-
-
- // count number of used cells on
- // the next higher level
- const unsigned int used_cells
- = std::count_if (triangulation.levels[level+1]->cells.used.begin(),
- triangulation.levels[level+1]->cells.used.end(),
- std::bind2nd (std::equal_to<bool>(), true));
-
-
- // reserve space for the
- // used_cells cells already
- // existing on the next higher
- // level as well as for the
- // 8*flagged_cells that will be
- // created on that level
- triangulation.levels[level+1]
- ->reserve_space (used_cells+new_cells, 3, spacedim);
- // reserve space for
- // 8*flagged_cells
- // new hexes on the next higher
- // level
- triangulation.levels[level+1]->cells.reserve_space (new_cells);
- }// for all levels
- // now count the quads and
- // lines which were flagged for
- // refinement
- for (typename Triangulation<dim,spacedim>::quad_iterator
- quad=triangulation.begin_quad(); quad!=triangulation.end_quad(); ++quad)
- {
- if (quad->user_flag_set())
- {
- // isotropic refinement: 1 interior
- // vertex, 4 quads and 4 interior
- // lines. we store the interior lines
- // in pairs in case the face is
- // already or will be refined
- // anisotropically
- needed_quads_pair += 4;
- needed_lines_pair += 4;
- needed_vertices += 1;
- }
- if (quad->user_index())
- {
- // anisotropic refinement: 1 interior
- // line and two quads
- needed_quads_pair += 2;
- needed_lines_single += 1;
- // there is a kind of complicated
- // situation here which requires our
- // attention. if the quad is refined
- // isotropcally, two of the interior
- // lines will get a new mother line -
- // the interior line of our
- // anisotropically refined quad. if
- // those two lines are not
- // consecutive, we cannot do so and
- // have to replace them by two lines
- // that are consecutive. we try to
- // avoid that situation, but it may
- // happen nevertheless throug
- // repeated refinement and
- // coarsening. thus we have to check
- // here, as we will need some
- // additional space to store those
- // new lines in case we need them...
- if (quad->has_children())
- {
- Assert(quad->refinement_case()==RefinementCase<dim-1>::isotropic_refinement, ExcInternalError());
- if ((face_refinement_cases[quad->user_index()]==RefinementCase<dim-1>::cut_x
- && (quad->child(0)->line_index(1)+1!=quad->child(2)->line_index(1))) ||
- (face_refinement_cases[quad->user_index()]==RefinementCase<dim-1>::cut_y
- && (quad->child(0)->line_index(3)+1!=quad->child(1)->line_index(3))))
- needed_lines_pair +=2;
- }
- }
- }
-
- for (typename Triangulation<dim,spacedim>::line_iterator
- line=triangulation.begin_line(); line!=triangulation.end_line(); ++line)
- if (line->user_flag_set())
- {
- needed_lines_pair += 2;
- needed_vertices += 1;
- }
-
- // reserve space for
- // needed_lines new lines
- // stored in pairs
- triangulation.faces->lines.
- reserve_space (needed_lines_pair,needed_lines_single);
- // reserve space for
- // needed_quads new quads
- // stored in pairs
- triangulation.faces->quads.
- reserve_space (needed_quads_pair,needed_quads_single);
-
-
- // add to needed vertices how many
- // vertices are already in use
- needed_vertices += std::count_if (triangulation.vertices_used.begin(), triangulation.vertices_used.end(),
- std::bind2nd (std::equal_to<bool>(), true));
- // if we need more vertices: create
- // them, if not: leave the array as
- // is, since shrinking is not
- // really possible because some of
- // the vertices at the end may be
- // in use
- if (needed_vertices > triangulation.vertices.size())
- {
- triangulation.vertices.resize (needed_vertices, Point<spacedim>());
- triangulation.vertices_used.resize (needed_vertices, false);
- }
-
-
- ///////////////////////////////////////////
- // Before we start with the actual
- // refinement, we do some sanity
- // checks if in debug
- // mode. especially, we try to
- // catch the notorious problem with
- // lines being twice refined,
- // i.e. there are cells adjacent at
- // one line ("around the edge", but
- // not at a face), with two cells
- // differing by more than one
- // refinement level
- //
- // this check is very simple to
- // implement here, since we have
- // all lines flagged if they shall
- // be refined
+ if (spacedim > dim)
+ {
+ if (line->at_boundary())
+ // if
+ // possible
+ // honor
+ // boundary
+ // indicator
+ line->set_user_index(line->boundary_indicator());
+ else
+ // otherwise
+ // take
+ // manifold
+ // description
+ // from
+ // the
+ // adjacent
+ // cell
+ line->set_user_index(cell->material_id());
+ }
+ }
+ }
+ }
+ }
+
+
+ // count number of used cells
+ // on the next higher level
+ const unsigned int used_cells
+ = std::count_if (triangulation.levels[level+1]->cells.used.begin(),
+ triangulation.levels[level+1]->cells.used.end(),
+ std::bind2nd (std::equal_to<bool>(), true));
+
+
+ // reserve space for the
+ // used_cells cells already
+ // existing on the next higher
+ // level as well as for the
+ // needed_cells that will be
+ // created on that level
+ triangulation.levels[level+1]
+ ->reserve_space (used_cells+needed_cells, 2, spacedim);
+
+ // reserve space for
+ // needed_cells
+ // new quads on the next higher
+ // level
+ triangulation.levels[level+1]->cells.
+ reserve_space (needed_cells,0);
+ }
+
+ // now count the lines which
+ // were flagged for refinement
+ for (typename Triangulation<dim,spacedim>::line_iterator
+ line=triangulation.begin_line(); line!=triangulation.end_line(); ++line)
+ if (line->user_flag_set())
+ {
+ Assert (line->has_children() == false, ExcInternalError());
+ n_lines_in_pairs += 2;
+ needed_vertices += 1;
+ }
+ // reserve space for
+ // n_lines_in_pairs new lines.
+ // note, that we can't reserve space
+ // for the single lines here as well,
+ // as all the space reserved for lines
+ // in pairs would be counted as unused
+ // and we would end up with too little
+ // space to store all lines. memory
+ // reservation for n_single_lines can
+ // only be done AFTER we refined the lines
+ // of the current cells
+ triangulation.faces->lines.
+ reserve_space (n_lines_in_pairs, 0);
+
+ // add to needed vertices how many
+ // vertices are already in use
+ needed_vertices += std::count_if (triangulation.vertices_used.begin(), triangulation.vertices_used.end(),
+ std::bind2nd (std::equal_to<bool>(), true));
+ // if we need more vertices: create
+ // them, if not: leave the array as
+ // is, since shrinking is not
+ // really possible because some of
+ // the vertices at the end may be
+ // in use
+ if (needed_vertices > triangulation.vertices.size())
+ {
+ triangulation.vertices.resize (needed_vertices, Point<spacedim>());
+ triangulation.vertices_used.resize (needed_vertices, false);
+ }
+
+
+ // Do REFINEMENT
+ // on every level; exclude highest
+ // level as above
+
+ // index of next unused vertex
+ unsigned int next_unused_vertex = 0;
+
+ // first the refinement of lines.
+ // children are stored pairwise
+ if (true)
+ {
+ // only active objects can be
+ // refined further
+ typename Triangulation<dim,spacedim>::active_line_iterator
+ line = triangulation.begin_active_line(),
+ endl = triangulation.end_line();
+ typename Triangulation<dim,spacedim>::raw_line_iterator
+ next_unused_line = triangulation.begin_raw_line ();
+
+ for (; line!=endl; ++line)
+ if (line->user_flag_set())
+ {
+ // this line needs to be
+ // refined
+
+ // find the next unused
+ // vertex and set it
+ // appropriately
+ while (triangulation.vertices_used[next_unused_vertex] == true)
+ ++next_unused_vertex;
+ Assert (next_unused_vertex < triangulation.vertices.size(),
+ ExcTooFewVerticesAllocated());
+ triangulation.vertices_used[next_unused_vertex] = true;
+
+ if (spacedim == dim)
+ {
+ // for the case of a domain
+ // in an equal-dimensional
+ // space we only have to
+ // treat boundary lines
+ // differently; for interior
+ // lines we can compute the
+ // midpoint as the mean of
+ // the two vertices:
+ if (line->at_boundary())
+ triangulation.vertices[next_unused_vertex]
+ = triangulation.get_boundary(line->boundary_indicator())
+ .get_new_point_on_line (line);
+ else
+ triangulation.vertices[next_unused_vertex]
+ = (line->vertex(0) + line->vertex(1)) / 2;
+ }
+ else
+ // however, if spacedim>dim, we
+ // always have to ask the
+ // boundary object for its
+ // answer
+ triangulation.vertices[next_unused_vertex]
+ = triangulation.get_boundary(line->user_index()).get_new_point_on_line (line);
+
+ // now that we created
+ // the right point, make
+ // up the two child
+ // lines. To this end,
+ // find a pair of unused
+ // lines
+ bool pair_found=false;
+ for (; next_unused_line!=endl; ++next_unused_line)
+ if (!next_unused_line->used() &&
+ !(++next_unused_line)->used())
+ {
+ // go back to the
+ // first of the two
+ // unused lines
+ --next_unused_line;
+ pair_found=true;
+ break;
+ }
+ Assert (pair_found, ExcInternalError());
+
+ // there are now two
+ // consecutive unused
+ // lines, such that the
+ // children of a line
+ // will be consecutive.
+ // then set the child
+ // pointer of the present
+ // line
+ line->set_children (0, next_unused_line->index());
+
+ // set the two new lines
+ const typename Triangulation<dim,spacedim>::raw_line_iterator
+ children[2] = { next_unused_line,
+ ++next_unused_line };
+ // some tests; if any of
+ // the iterators should
+ // be invalid, then
+ // already dereferencing
+ // will fail
+ Assert (children[0]->used() == false, ExcCellShouldBeUnused());
+ Assert (children[1]->used() == false, ExcCellShouldBeUnused());
+
+ children[0]->set (internal::Triangulation
+ ::TriaObject<1>(line->vertex_index(0),
+ next_unused_vertex));
+ children[1]->set (internal::Triangulation
+ ::TriaObject<1>(next_unused_vertex,
+ line->vertex_index(1)));
+
+ children[0]->set_used_flag();
+ children[1]->set_used_flag();
+ children[0]->clear_children();
+ children[1]->clear_children();
+ children[0]->clear_user_data();
+ children[1]->clear_user_data();
+ children[0]->clear_user_flag();
+ children[1]->clear_user_flag();
+
+ children[0]->set_boundary_indicator (line->boundary_indicator());
+ children[1]->set_boundary_indicator (line->boundary_indicator());
+
+ // finally clear flag
+ // indicating the need
+ // for refinement
+ line->clear_user_flag ();
+ }
+ }
+
+
+ // Now set up the new cells
+
+ // reserve space for inner
+ // lines (can be stored as
+ // single lines)
+ triangulation.faces->lines.
+ reserve_space (0,n_single_lines);
+
+ typename Triangulation<2,spacedim>::DistortedCellList
+ cells_with_distorted_children;
+
+ // reset next_unused_line, as
+ // now also single empty places
+ // in the vector can be used
+ typename Triangulation<dim,spacedim>::raw_line_iterator
+ next_unused_line = triangulation.begin_raw_line ();
+
+ for (int level=0; level<static_cast<int>(triangulation.levels.size())-1; ++level)
+ {
+
+ // Remember: as we don't operate
+ // on the finest level, begin_*(level+1)
+ // is allowed
+ typename Triangulation<dim,spacedim>::active_cell_iterator
+ cell = triangulation.begin_active(level),
+ endc = triangulation.begin_active(level+1);
+
+ typename Triangulation<dim,spacedim>::raw_cell_iterator
+ next_unused_cell = triangulation.begin_raw (level+1);
+
+ for (; cell!=endc; ++cell)
+ if (cell->refine_flag_set())
+ {
+ // set the user flag to
+ // indicate, that at least one
+ // line is at the boundary
+
+ // TODO[Tobias Leicht] find a
+ // better place to set this flag,
+ // so that we do not need so much
+ // time to check each cell here
+ if (cell->at_boundary())
+ cell->set_user_flag();
+
+ // actually set up the children and
+ // update neighbor information
+ create_children (triangulation,
+ next_unused_vertex,
+ next_unused_line,
+ next_unused_cell,
+ cell);
+
+ if ((check_for_distorted_cells == true)
+ &&
+ has_distorted_children (cell,
+ internal::int2type<dim>(),
+ internal::int2type<spacedim>()))
+ cells_with_distorted_children.distorted_cells.push_back (cell);
+ }
+ }
+
+ return cells_with_distorted_children;
+ }
+
+
+ /**
+ * A function that performs the
+ * refinement of a triangulation in 3d.
+ */
+ template <int spacedim>
+ static
+ typename Triangulation<3,spacedim>::DistortedCellList
+ execute_refinement (Triangulation<3,spacedim> &triangulation,
+ const bool check_for_distorted_cells)
+ {
+ const unsigned int dim = 3;
+
+ // this function probably
+ // also works for spacedim>3
+ // but it isn't tested. it
+ // will probably be necessary
+ // to pull new vertices onto
+ // the manifold just as we do
+ // for the other functions
+ // above.
+ Assert (spacedim == 3, ExcNotImplemented());
+
+ // check whether a new level is
+ // needed we have to check for this
+ // on the highest level only (on
+ // this, all used cells are also
+ // active, so we only have to check
+ // for this)
+ if (true)
+ {
+ typename Triangulation<dim,spacedim>::raw_cell_iterator
+ cell = triangulation.begin_active (triangulation.levels.size()-1),
+ endc = triangulation.end();
+ for (; cell != endc; ++cell)
+ if (cell->used())
+ if (cell->refine_flag_set())
+ {
+ triangulation.levels.push_back (new internal::Triangulation::TriaLevel<dim>);
+ break;
+ }
+ }
+
+
+ // first clear user flags for quads
+ // and lines; we're going to use them
+ // to flag which lines and quads
+ // need refinement
+ triangulation.faces->quads.clear_user_data();
+
+ for (typename Triangulation<dim,spacedim>::line_iterator
+ line=triangulation.begin_line(); line!=triangulation.end_line(); ++line)
+ line->clear_user_flag();
+ for (typename Triangulation<dim,spacedim>::quad_iterator
+ quad=triangulation.begin_quad(); quad!=triangulation.end_quad(); ++quad)
+ quad->clear_user_flag();
+
+ // create an array of face refine cases. User
+ // indices of faces will be set to values
+ // corresponding with indices in this array.
+ const RefinementCase<dim-1> face_refinement_cases[4]=
+ {RefinementCase<dim-1>::no_refinement,
+ RefinementCase<dim-1>::cut_x,
+ RefinementCase<dim-1>::cut_y,
+ RefinementCase<dim-1>::cut_xy};
+
+ // check how much space is needed
+ // on every level
+ // we need not check the highest
+ // level since either
+ // - on the highest level no cells
+ // are flagged for refinement
+ // - there are, but prepare_refinement
+ // added another empty level which
+ // then is the highest level
+
+ // variables to hold the number of newly to
+ // be created vertices, lines and quads. as
+ // these are stored globally, declare them
+ // outside the loop over al levels. we need
+ // lines and quads in pairs for refinement of
+ // old ones and lines and quads, that can be
+ // stored as single ones, as they are newly
+ // created in the inside of an existing cell
+ unsigned int needed_vertices = 0;
+ unsigned int needed_lines_single = 0;
+ unsigned int needed_quads_single = 0;
+ unsigned int needed_lines_pair = 0;
+ unsigned int needed_quads_pair = 0;
+ for (int level=triangulation.levels.size()-2; level>=0; --level)
+ {
+ // count number of flagged
+ // cells on this level and
+ // compute how many new
+ // vertices and new lines will
+ // be needed
+ unsigned int new_cells = 0;
+
+ typename Triangulation<dim,spacedim>::active_cell_iterator
+ acell = triangulation.begin_active(level),
+ aendc = triangulation.begin_active(level+1);
+ for (; acell!=aendc; ++acell)
+ if (acell->refine_flag_set())
+ {
+ RefinementCase<dim> ref_case=acell->refine_flag_set();
+
+ // now for interior vertices, lines
+ // and quads, which are needed in
+ // any case
+ if (ref_case==RefinementCase<dim>::cut_x ||
+ ref_case==RefinementCase<dim>::cut_y ||
+ ref_case==RefinementCase<dim>::cut_z)
+ {
+ ++needed_quads_single;
+ new_cells+=2;
+ triangulation.anisotropic_refinement=true;
+ }
+ else if (ref_case==RefinementCase<dim>::cut_xy ||
+ ref_case==RefinementCase<dim>::cut_xz ||
+ ref_case==RefinementCase<dim>::cut_yz)
+ {
+ ++needed_lines_single;
+ needed_quads_single += 4;
+ new_cells+=4;
+ triangulation.anisotropic_refinement=true;
+ }
+ else if (ref_case==RefinementCase<dim>::cut_xyz)
+ {
+ ++needed_vertices;
+ needed_lines_single += 6;
+ needed_quads_single += 12;
+ new_cells+=8;
+ }
+ else
+ {
+ // we should never get here
+ Assert(false, ExcInternalError());
+ }
+
+ // mark all faces for refinement;
+ // checking locally
+ // if and how the neighbor
+ // would like to
+ // refine these is
+ // difficult so
+ // we only flag them and
+ // after visiting all
+ // cells, we decide which
+ // faces need which refinement;
+ for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell;
+ ++face)
+ {
+ typename Triangulation<dim,spacedim>::face_iterator
+ aface = acell->face(face);
+ // get the RefineCase this
+ // faces has for the given
+ // RefineCase of the cell
+ RefinementCase<dim-1> face_ref_case=
+ GeometryInfo<dim>::face_refinement_case(ref_case,
+ face,
+ acell->face_orientation(face),
+ acell->face_flip(face),
+ acell->face_rotation(face));
+ // only do something, if this
+ // face has to be refined
+ if (face_ref_case)
+ {
+ if (face_ref_case==RefinementCase<dim-1>::isotropic_refinement)
+ {
+ if (aface->number_of_children()<4)
+ // we use user_flags to
+ // denote needed isotropic
+ // refinement
+ aface->set_user_flag();
+ }
+ else if (aface->refinement_case()!=face_ref_case)
+ // we use user_indices
+ // to denote needed
+ // anisotropic
+ // refinement. note, that
+ // we can have at most
+ // one anisotropic
+ // refinement case for
+ // this face, as
+ // otherwise
+ // prepare_refinement()
+ // would have changed one
+ // of the cells to yield
+ // isotropic refinement
+ // at this
+ // face. therefore we set
+ // the user_index
+ // uniquely
+ {
+ Assert(aface->refinement_case()==RefinementCase<dim-1>::isotropic_refinement ||
+ aface->refinement_case()==RefinementCase<dim-1>::no_refinement,
+ ExcInternalError());
+ aface->set_user_index(face_ref_case);
+ }
+ }
+ }// for all faces
+
+ // flag all lines, that have to be
+ // refined
+ for (unsigned int line=0; line<GeometryInfo<dim>::lines_per_cell; ++line)
+ if (GeometryInfo<dim>::line_refinement_case(ref_case,line) &&
+ !acell->line(line)->has_children())
+ acell->line(line)->set_user_flag();
+
+ }// if refine_flag set and for all cells on this level
+
+
+ // count number of used cells on
+ // the next higher level
+ const unsigned int used_cells
+ = std::count_if (triangulation.levels[level+1]->cells.used.begin(),
+ triangulation.levels[level+1]->cells.used.end(),
+ std::bind2nd (std::equal_to<bool>(), true));
+
+
+ // reserve space for the
+ // used_cells cells already
+ // existing on the next higher
+ // level as well as for the
+ // 8*flagged_cells that will be
+ // created on that level
+ triangulation.levels[level+1]
+ ->reserve_space (used_cells+new_cells, 3, spacedim);
+ // reserve space for
+ // 8*flagged_cells
+ // new hexes on the next higher
+ // level
+ triangulation.levels[level+1]->cells.reserve_space (new_cells);
+ }// for all levels
+ // now count the quads and
+ // lines which were flagged for
+ // refinement
+ for (typename Triangulation<dim,spacedim>::quad_iterator
+ quad=triangulation.begin_quad(); quad!=triangulation.end_quad(); ++quad)
+ {
+ if (quad->user_flag_set())
+ {
+ // isotropic refinement: 1 interior
+ // vertex, 4 quads and 4 interior
+ // lines. we store the interior lines
+ // in pairs in case the face is
+ // already or will be refined
+ // anisotropically
+ needed_quads_pair += 4;
+ needed_lines_pair += 4;
+ needed_vertices += 1;
+ }
+ if (quad->user_index())
+ {
+ // anisotropic refinement: 1 interior
+ // line and two quads
+ needed_quads_pair += 2;
+ needed_lines_single += 1;
+ // there is a kind of complicated
+ // situation here which requires our
+ // attention. if the quad is refined
+ // isotropcally, two of the interior
+ // lines will get a new mother line -
+ // the interior line of our
+ // anisotropically refined quad. if
+ // those two lines are not
+ // consecutive, we cannot do so and
+ // have to replace them by two lines
+ // that are consecutive. we try to
+ // avoid that situation, but it may
+ // happen nevertheless throug
+ // repeated refinement and
+ // coarsening. thus we have to check
+ // here, as we will need some
+ // additional space to store those
+ // new lines in case we need them...
+ if (quad->has_children())
+ {
+ Assert(quad->refinement_case()==RefinementCase<dim-1>::isotropic_refinement, ExcInternalError());
+ if ((face_refinement_cases[quad->user_index()]==RefinementCase<dim-1>::cut_x
+ && (quad->child(0)->line_index(1)+1!=quad->child(2)->line_index(1))) ||
+ (face_refinement_cases[quad->user_index()]==RefinementCase<dim-1>::cut_y
+ && (quad->child(0)->line_index(3)+1!=quad->child(1)->line_index(3))))
+ needed_lines_pair +=2;
+ }
+ }
+ }
+
+ for (typename Triangulation<dim,spacedim>::line_iterator
+ line=triangulation.begin_line(); line!=triangulation.end_line(); ++line)
+ if (line->user_flag_set())
+ {
+ needed_lines_pair += 2;
+ needed_vertices += 1;
+ }
+
+ // reserve space for
+ // needed_lines new lines
+ // stored in pairs
+ triangulation.faces->lines.
+ reserve_space (needed_lines_pair,needed_lines_single);
+ // reserve space for
+ // needed_quads new quads
+ // stored in pairs
+ triangulation.faces->quads.
+ reserve_space (needed_quads_pair,needed_quads_single);
+
+
+ // add to needed vertices how many
+ // vertices are already in use
+ needed_vertices += std::count_if (triangulation.vertices_used.begin(), triangulation.vertices_used.end(),
+ std::bind2nd (std::equal_to<bool>(), true));
+ // if we need more vertices: create
+ // them, if not: leave the array as
+ // is, since shrinking is not
+ // really possible because some of
+ // the vertices at the end may be
+ // in use
+ if (needed_vertices > triangulation.vertices.size())
+ {
+ triangulation.vertices.resize (needed_vertices, Point<spacedim>());
+ triangulation.vertices_used.resize (needed_vertices, false);
+ }
+
+
+ ///////////////////////////////////////////
+ // Before we start with the actual
+ // refinement, we do some sanity
+ // checks if in debug
+ // mode. especially, we try to
+ // catch the notorious problem with
+ // lines being twice refined,
+ // i.e. there are cells adjacent at
+ // one line ("around the edge", but
+ // not at a face), with two cells
+ // differing by more than one
+ // refinement level
+ //
+ // this check is very simple to
+ // implement here, since we have
+ // all lines flagged if they shall
+ // be refined
#ifdef DEBUG
- for (typename Triangulation<dim,spacedim>::active_cell_iterator
- cell=triangulation.begin_active(); cell!=triangulation.end(); ++cell)
- if (!cell->refine_flag_set())
- for (unsigned int line=0; line<GeometryInfo<dim>::lines_per_cell; ++line)
- if (cell->line(line)->has_children())
- for (unsigned int c=0; c<2; ++c)
- Assert (cell->line(line)->child(c)->user_flag_set() == false,
- ExcInternalError());
+ for (typename Triangulation<dim,spacedim>::active_cell_iterator
+ cell=triangulation.begin_active(); cell!=triangulation.end(); ++cell)
+ if (!cell->refine_flag_set())
+ for (unsigned int line=0; line<GeometryInfo<dim>::lines_per_cell; ++line)
+ if (cell->line(line)->has_children())
+ for (unsigned int c=0; c<2; ++c)
+ Assert (cell->line(line)->child(c)->user_flag_set() == false,
+ ExcInternalError());
#endif
- ///////////////////////////////////////////
- // Do refinement on every level
- //
- // To make life a bit easier, we
- // first refine those lines and
- // quads that were flagged for
- // refinement and then compose the
- // newly to be created cells.
- //
- // index of next unused vertex
- unsigned int next_unused_vertex = 0;
-
- // first for lines
- if (true)
- {
- // only active objects can be
- // refined further
- typename Triangulation<dim,spacedim>::active_line_iterator
- line = triangulation.begin_active_line(),
- endl = triangulation.end_line();
- typename Triangulation<dim,spacedim>::raw_line_iterator
- next_unused_line = triangulation.begin_raw_line ();
-
- for (; line!=endl; ++line)
- if (line->user_flag_set())
- {
- // this line needs to be
- // refined
-
- // find the next unused
- // vertex and set it
- // appropriately
- while (triangulation.vertices_used[next_unused_vertex] == true)
- ++next_unused_vertex;
- Assert (next_unused_vertex < triangulation.vertices.size(),
- ExcTooFewVerticesAllocated());
- triangulation.vertices_used[next_unused_vertex] = true;
-
- if (line->at_boundary())
- triangulation.vertices[next_unused_vertex]
- = triangulation.get_boundary(line->boundary_indicator()).get_new_point_on_line (line);
- else
- triangulation.vertices[next_unused_vertex]
- = (line->vertex(0) + line->vertex(1)) / 2;
-
- // now that we created
- // the right point, make
- // up the two child lines
- // (++ takes care of the
- // end of the vector)
- next_unused_line=triangulation.faces->lines.next_free_pair_line(triangulation);
- Assert(next_unused_line.state() == IteratorState::valid,
- ExcInternalError());
-
- // now we found
- // two consecutive unused
- // lines, such that the
- // children of a line
- // will be consecutive.
- // then set the child
- // pointer of the present
- // line
- line->set_children (0, next_unused_line->index());
-
- // set the two new lines
- const typename Triangulation<dim,spacedim>::raw_line_iterator
- children[2] = { next_unused_line,
- ++next_unused_line };
-
- // some tests; if any of
- // the iterators should
- // be invalid, then
- // already dereferencing
- // will fail
- Assert (children[0]->used() == false, ExcCellShouldBeUnused());
- Assert (children[1]->used() == false, ExcCellShouldBeUnused());
-
- children[0]->set (internal::Triangulation
- ::TriaObject<1>(line->vertex_index(0),
- next_unused_vertex));
- children[1]->set (internal::Triangulation
- ::TriaObject<1>(next_unused_vertex,
- line->vertex_index(1)));
-
- children[0]->set_used_flag();
- children[1]->set_used_flag();
- children[0]->clear_children();
- children[1]->clear_children();
- children[0]->clear_user_data();
- children[1]->clear_user_data();
- children[0]->clear_user_flag();
- children[1]->clear_user_flag();
-
- children[0]->set_boundary_indicator (line->boundary_indicator());
- children[1]->set_boundary_indicator (line->boundary_indicator());
-
- // finally clear flag
- // indicating the need
- // for refinement
- line->clear_user_flag ();
- }
- }
-
-
- ///////////////////////////////////////
- // now refine marked quads
- ///////////////////////////////////////
-
- // here we encounter several cases:
-
- // a) the quad is unrefined and shall be
- // refined isotropically
-
- // b) the quad is unrefined and shall be
- // refined anisotropically
-
- // c) the quad is unrefined and shall be
- // refined both anisotropically and
- // isotropically (this is reduced to case b)
- // and then case b) for the children again)
-
- // d) the quad is refined anisotropically and
- // shall be refined isotropically (this is
- // reduced to case b) for the anisotropic
- // children)
-
- // e) the quad is refined isotropically and
- // shall be refined anisotropically (this is
- // transformed to case c), however we might
- // have to renumber/rename children...)
-
- // we need a loop in cases c) and d), as the
- // anisotropic children migt have a lower
- // index than the mother quad
- for (unsigned int loop=0; loop<2; ++loop)
- {
- // usually, only active objects can be
- // refined further. however, in cases d)
- // and e) that is not true, so we have to
- // use 'normal' iterators here
- typename Triangulation<dim,spacedim>::quad_iterator
- quad = triangulation.begin_quad(),
- endq = triangulation.end_quad();
- typename Triangulation<dim,spacedim>::raw_line_iterator
- next_unused_line = triangulation.begin_raw_line ();
- typename Triangulation<dim,spacedim>::raw_quad_iterator
- next_unused_quad = triangulation.begin_raw_quad ();
-
- for (; quad!=endq; ++quad)
- {
- if (quad->user_index())
- {
- RefinementCase<dim-1> aniso_quad_ref_case=face_refinement_cases[quad->user_index()];
- // there is one unlikely event
- // here, where we already have
- // refind the face: if the face
- // was refined anisotropically
- // and we want to refine it
- // isotropically, both children
- // are flagged for anisotropic
- // refinement. however, if those
- // children were already flagged
- // for anisotropic refinement,
- // they might already be
- // processed and refined.
- if (aniso_quad_ref_case == quad->refinement_case())
- continue;
-
- Assert(quad->refinement_case()==RefinementCase<dim-1>::cut_xy ||
- quad->refinement_case()==RefinementCase<dim-1>::no_refinement,
- ExcInternalError());
-
- // this quad needs to be refined
- // anisotropically
- Assert(quad->user_index() == RefinementCase<dim-1>::cut_x ||
- quad->user_index() == RefinementCase<dim-1>::cut_y,
- ExcInternalError());
-
- // make the new line interior to
- // the quad
- typename Triangulation<dim,spacedim>::raw_line_iterator new_line;
-
- new_line=triangulation.faces->lines.next_free_single_line(triangulation);
- Assert (new_line->used() == false,
- ExcCellShouldBeUnused());
-
- // first collect the
- // indices of the vertices:
- // *--1--*
- // | | |
- // | | | cut_x
- // | | |
- // *--0--*
- //
- // *-----*
- // | |
- // 0-----1 cut_y
- // | |
- // *-----*
- unsigned int vertex_indices[2];
- if (aniso_quad_ref_case==RefinementCase<dim-1>::cut_x)
- {
- vertex_indices[0]=quad->line(2)->child(0)->vertex_index(1);
- vertex_indices[1]=quad->line(3)->child(0)->vertex_index(1);
- }
- else
- {
- vertex_indices[0]=quad->line(0)->child(0)->vertex_index(1);
- vertex_indices[1]=quad->line(1)->child(0)->vertex_index(1);
- }
-
- new_line->set (internal::Triangulation::
- TriaObject<1>(vertex_indices[0], vertex_indices[1]));
- new_line->set_used_flag();
- new_line->clear_user_flag();
- new_line->clear_user_data();
- new_line->clear_children();
- new_line->set_boundary_indicator(quad->boundary_indicator());
-
- // child 0 and 1 of a line are
- // switched if the line
- // orientation is false. set up a
- // miniature table, indicating
- // which child to take for line
- // orientations false and
- // true. first index: child index
- // in standard orientation,
- // second index: line orientation
- const unsigned int index[2][2]=
- {{1,0}, // child 0, line_orientation=false and true
- {0,1}}; // child 1, line_orientation=false and true
-
- // find some space (consecutive)
- // for the two newly to be
- // created quads.
- typename Triangulation<dim,spacedim>::raw_quad_iterator new_quads[2];
-
- next_unused_quad=triangulation.faces->quads.next_free_pair_quad(triangulation);
- new_quads[0] = next_unused_quad;
- Assert (new_quads[0]->used() == false, ExcCellShouldBeUnused());
-
- ++next_unused_quad;
- new_quads[1] = next_unused_quad;
- Assert (new_quads[1]->used() == false, ExcCellShouldBeUnused());
-
-
- if (aniso_quad_ref_case==RefinementCase<dim-1>::cut_x)
- {
- new_quads[0]->set (internal::Triangulation
- ::TriaObject<2>(quad->line_index(0),
- new_line->index(),
- quad->line(2)->child(index[0][quad->line_orientation(2)])->index(),
- quad->line(3)->child(index[0][quad->line_orientation(3)])->index()));
- new_quads[1]->set (internal::Triangulation
- ::TriaObject<2>(new_line->index(),
- quad->line_index(1),
- quad->line(2)->child(index[1][quad->line_orientation(2)])->index(),
- quad->line(3)->child(index[1][quad->line_orientation(3)])->index()));
- }
- else
- {
- new_quads[0]->set (internal::Triangulation
- ::TriaObject<2>(quad->line(0)->child(index[0][quad->line_orientation(0)])->index(),
- quad->line(1)->child(index[0][quad->line_orientation(1)])->index(),
- quad->line_index(2),
- new_line->index()));
- new_quads[1]->set (internal::Triangulation
- ::TriaObject<2>(quad->line(0)->child(index[1][quad->line_orientation(0)])->index(),
- quad->line(1)->child(index[1][quad->line_orientation(1)])->index(),
- new_line->index(),
- quad->line_index(3)));
- }
-
- for (unsigned int i=0; i<2; ++i)
- {
- new_quads[i]->set_used_flag();
- new_quads[i]->clear_user_flag();
- new_quads[i]->clear_user_data();
- new_quads[i]->clear_children();
- new_quads[i]->set_boundary_indicator (quad->boundary_indicator());
- // set all line orientations to
- // true, change this after the
- // loop, as we have to consider
- // different lines for each
- // child
- for (unsigned int j=0; j<GeometryInfo<dim>::lines_per_face; ++j)
- new_quads[i]->set_line_orientation(j,true);
- }
- // now set the line orientation of
- // children of outer lines
- // correctly, the lines in the
- // interior of the refined quad are
- // automatically oriented
- // conforming to the standard
- new_quads[0]->set_line_orientation(0,quad->line_orientation(0));
- new_quads[0]->set_line_orientation(2,quad->line_orientation(2));
- new_quads[1]->set_line_orientation(1,quad->line_orientation(1));
- new_quads[1]->set_line_orientation(3,quad->line_orientation(3));
- if (aniso_quad_ref_case==RefinementCase<dim-1>::cut_x)
- {
- new_quads[0]->set_line_orientation(3,quad->line_orientation(3));
- new_quads[1]->set_line_orientation(2,quad->line_orientation(2));
- }
- else
- {
- new_quads[0]->set_line_orientation(1,quad->line_orientation(1));
- new_quads[1]->set_line_orientation(0,quad->line_orientation(0));
- }
-
- // test, whether this face is
- // refined isotropically
- // already. if so, set the
- // correct children pointers.
- if (quad->refinement_case()==RefinementCase<dim-1>::cut_xy)
- {
- // we will put a new
- // refinemnt level of
- // anisotropic refinement
- // between the unrefined and
- // isotropically refined quad
- // ending up with the same
- // fine quads but introducing
- // anisotropically refined
- // ones as children of the
- // unrefined quad and mother
- // cells of the original fine
- // ones.
-
- // this process includes the
- // creation of a new middle
- // line which we will assign
- // as the mother line of two
- // of the existing inner
- // lines. If those inner
- // lines are not consecutive
- // in memory, we won't find
- // them later on, so we have
- // to create new ones instead
- // and replace all occurances
- // of the old ones with those
- // new ones. As this is kind
- // of ugly, we hope we don't
- // have to do it often...
- typename Triangulation<dim,spacedim>::line_iterator old_child[2];
- if (aniso_quad_ref_case==RefinementCase<dim-1>::cut_x)
- {
- old_child[0]=quad->child(0)->line(1);
- old_child[1]=quad->child(2)->line(1);
- }
- else
- {
- Assert(aniso_quad_ref_case==RefinementCase<dim-1>::cut_y, ExcInternalError());
-
- old_child[0]=quad->child(0)->line(3);
- old_child[1]=quad->child(1)->line(3);
- }
-
- if (old_child[0]->index()+1 != old_child[1]->index())
- {
- // this is exactly the
- // ugly case we taked
- // about. so, no
- // coimplaining, lets get
- // two new lines and copy
- // all info
- typename Triangulation<dim,spacedim>::raw_line_iterator new_child[2];
-
- new_child[0]=new_child[1]=triangulation.faces->lines.next_free_pair_line(triangulation);
- ++new_child[1];
-
- new_child[0]->set_used_flag();
- new_child[1]->set_used_flag();
-
- const int old_index_0=old_child[0]->index(),
- old_index_1=old_child[1]->index(),
- new_index_0=new_child[0]->index(),
- new_index_1=new_child[1]->index();
-
- // loop over all quads
- // and replace the old
- // lines
- for (unsigned int q=0; q<triangulation.faces->quads.cells.size(); ++q)
- for (unsigned int l=0; l<GeometryInfo<dim>::lines_per_face; ++l)
- {
- const int index=triangulation.faces->quads.cells[q].face(l);
- if (index==old_index_0)
- triangulation.faces->quads.cells[q].set_face(l,new_index_0);
- else if (index==old_index_1)
- triangulation.faces->quads.cells[q].set_face(l,new_index_1);
- }
- // now we have to copy
- // all information of the
- // two lines
- for (unsigned int i=0; i<2; ++i)
- {
- Assert(!old_child[i]->has_children(), ExcInternalError());
-
- new_child[i]->set(internal::Triangulation::TriaObject<1>(old_child[i]->vertex_index(0),
- old_child[i]->vertex_index(1)));
- new_child[i]->set_boundary_indicator(old_child[i]->boundary_indicator());
- new_child[i]->set_user_index(old_child[i]->user_index());
- if (old_child[i]->user_flag_set())
- new_child[i]->set_user_flag();
- else
- new_child[i]->clear_user_flag();
-
- new_child[i]->clear_children();
-
- old_child[i]->clear_user_flag();
- old_child[i]->clear_user_index();
- old_child[i]->clear_used_flag();
- }
- }
- // now that we cared
- // about the lines, go on
- // with the quads
- // themselves, where we
- // might encounter
- // similar situations...
- if (aniso_quad_ref_case==RefinementCase<dim-1>::cut_x)
- {
- new_line->set_children(0, quad->child(0)->line_index(1));
- Assert(new_line->child(1)==quad->child(2)->line(1),
- ExcInternalError());
- // now evereything is
- // quite complicated. we
- // have the children
- // numbered according to
- //
- // *---*---*
- // |n+2|n+3|
- // *---*---*
- // | n |n+1|
- // *---*---*
- //
- // from the original
- // isotropic
- // refinement. we have to
- // reorder them as
- //
- // *---*---*
- // |n+1|n+3|
- // *---*---*
- // | n |n+2|
- // *---*---*
- //
- // such that n and n+1
- // are consecutive
- // children of m and n+2
- // and n+3 are
- // consecutive children
- // of m+1, where m and
- // m+1 are given as in
- //
- // *---*---*
- // | | |
- // | m |m+1|
- // | | |
- // *---*---*
- //
- // this is a bit ugly, of
- // course: loop over all
- // cells on all levels
- // and look for faces n+1
- // (switch_1) and n+2
- // (switch_2).
- const typename Triangulation<dim,spacedim>::quad_iterator
- switch_1=quad->child(1),
- switch_2=quad->child(2);
- const int switch_1_index=switch_1->index();
- const int switch_2_index=switch_2->index();
- for (unsigned int l=0; l<triangulation.levels.size(); ++l)
- for (unsigned int h=0; h<triangulation.levels[l]->cells.cells.size(); ++h)
- for (unsigned int q=0; q<GeometryInfo<dim>::faces_per_cell; ++q)
- {
- const int index=triangulation.levels[l]->cells.cells[h].face(q);
- if (index==switch_1_index)
- triangulation.levels[l]->cells.cells[h].set_face(q,switch_2_index);
- else if (index==switch_2_index)
- triangulation.levels[l]->cells.cells[h].set_face(q,switch_1_index);
- }
- // now we have to copy
- // all information of the
- // two quads
- const int switch_1_lines[4]=
- {switch_1->line_index(0),
- switch_1->line_index(1),
- switch_1->line_index(2),
- switch_1->line_index(3)};
- const bool switch_1_line_orientations[4]=
- {switch_1->line_orientation(0),
- switch_1->line_orientation(1),
- switch_1->line_orientation(2),
- switch_1->line_orientation(3)};
- const types::boundary_id_t switch_1_boundary_indicator=switch_1->boundary_indicator();
- const unsigned int switch_1_user_index=switch_1->user_index();
- const bool switch_1_user_flag=switch_1->user_flag_set();
- const RefinementCase<dim-1> switch_1_refinement_case=switch_1->refinement_case();
- const int switch_1_first_child_pair=(switch_1_refinement_case ? switch_1->child_index(0) : -1);
- const int switch_1_second_child_pair=(switch_1_refinement_case==RefinementCase<dim-1>::cut_xy ? switch_1->child_index(2) : -1);
-
- switch_1->set(internal::Triangulation::TriaObject<2>(switch_2->line_index(0),
- switch_2->line_index(1),
- switch_2->line_index(2),
- switch_2->line_index(3)));
- switch_1->set_line_orientation(0, switch_2->line_orientation(0));
- switch_1->set_line_orientation(1, switch_2->line_orientation(1));
- switch_1->set_line_orientation(2, switch_2->line_orientation(2));
- switch_1->set_line_orientation(3, switch_2->line_orientation(3));
- switch_1->set_boundary_indicator(switch_2->boundary_indicator());
- switch_1->set_user_index(switch_2->user_index());
- if (switch_2->user_flag_set())
- switch_1->set_user_flag();
- else
- switch_1->clear_user_flag();
- switch_1->clear_refinement_case();
- switch_1->set_refinement_case(switch_2->refinement_case());
- switch_1->clear_children();
- if (switch_2->refinement_case())
- switch_1->set_children(0, switch_2->child_index(0));
- if (switch_2->refinement_case()==RefinementCase<dim-1>::cut_xy)
- switch_1->set_children(2, switch_2->child_index(2));
-
- switch_2->set(internal::Triangulation::TriaObject<2>(switch_1_lines[0],
- switch_1_lines[1],
- switch_1_lines[2],
- switch_1_lines[3]));
- switch_2->set_line_orientation(0, switch_1_line_orientations[0]);
- switch_2->set_line_orientation(1, switch_1_line_orientations[1]);
- switch_2->set_line_orientation(2, switch_1_line_orientations[2]);
- switch_2->set_line_orientation(3, switch_1_line_orientations[3]);
- switch_2->set_boundary_indicator(switch_1_boundary_indicator);
- switch_2->set_user_index(switch_1_user_index);
- if (switch_1_user_flag)
- switch_2->set_user_flag();
- else
- switch_2->clear_user_flag();
- switch_2->clear_refinement_case();
- switch_2->set_refinement_case(switch_1_refinement_case);
- switch_2->clear_children();
- switch_2->set_children(0, switch_1_first_child_pair);
- switch_2->set_children(2, switch_1_second_child_pair);
-
- new_quads[0]->set_refinement_case(RefinementCase<2>::cut_y);
- new_quads[0]->set_children(0, quad->child_index(0));
- new_quads[1]->set_refinement_case(RefinementCase<2>::cut_y);
- new_quads[1]->set_children(0, quad->child_index(2));
- }
- else
- {
- new_quads[0]->set_refinement_case(RefinementCase<2>::cut_x);
- new_quads[0]->set_children(0, quad->child_index(0));
- new_quads[1]->set_refinement_case(RefinementCase<2>::cut_x);
- new_quads[1]->set_children(0, quad->child_index(2));
- new_line->set_children(0, quad->child(0)->line_index(3));
- Assert(new_line->child(1)==quad->child(1)->line(3),
- ExcInternalError());
- }
- quad->clear_children();
- }
-
- // note these quads as children
- // to the present one
- quad->set_children (0, new_quads[0]->index());
-
- quad->set_refinement_case(aniso_quad_ref_case);
-
- // finally clear flag
- // indicating the need
- // for refinement
- quad->clear_user_data ();
- } // if (anisotropic refinement)
-
- if (quad->user_flag_set())
- {
- // this quad needs to be
- // refined isotropically
-
- // first of all: we only get here
- // in the first run of the loop
- Assert(loop==0,ExcInternalError());
-
- // find the next unused
- // vertex. we'll need this in any
- // case
- while (triangulation.vertices_used[next_unused_vertex] == true)
- ++next_unused_vertex;
- Assert (next_unused_vertex < triangulation.vertices.size(),
- ExcTooFewVerticesAllocated());
-
- // now: if the quad is refined
- // anisotropically already, set
- // the anisotropic refinement
- // flag for both
- // children. Additionally, we
- // have to refine the inner line,
- // as it is an outer line of the
- // two (anisotropic) children
- const RefinementCase<dim-1> quad_ref_case=quad->refinement_case();
-
- if (quad_ref_case==RefinementCase<dim-1>::cut_x ||
- quad_ref_case==RefinementCase<dim-1>::cut_y)
- {
- // set the 'opposite' refine case for children
- quad->child(0)->set_user_index(RefinementCase<dim-1>::cut_xy-quad_ref_case);
- quad->child(1)->set_user_index(RefinementCase<dim-1>::cut_xy-quad_ref_case);
- // refine the inner line
- typename Triangulation<dim,spacedim>::line_iterator middle_line;
- if (quad_ref_case==RefinementCase<dim-1>::cut_x)
- middle_line=quad->child(0)->line(1);
- else
- middle_line=quad->child(0)->line(3);
-
- // if the face has been
- // refined anisotropically in
- // the last refinement step
- // it might be, that it is
- // flagged already and that
- // the middle line is thus
- // refined already. if not
- // create children.
- if (!middle_line->has_children())
- {
- // set the middle vertex
- // appropriately. double
- // refinement of quads can only
- // happen in the interior of
- // the domain, so we need not
- // care about boundary quads
- // here
- triangulation.vertices[next_unused_vertex]
- = (middle_line->vertex(0) + middle_line->vertex(1)) / 2;
- triangulation.vertices_used[next_unused_vertex] = true;
-
- // now search a slot for the two
- // child lines
- next_unused_line=triangulation.faces->lines.next_free_pair_line(triangulation);
-
- // set the child
- // pointer of the present
- // line
- middle_line->set_children (0, next_unused_line->index());
-
- // set the two new lines
- const typename Triangulation<dim,spacedim>::raw_line_iterator
- children[2] = { next_unused_line,
- ++next_unused_line };
-
- // some tests; if any of
- // the iterators should
- // be invalid, then
- // already dereferencing
- // will fail
- Assert (children[0]->used() == false, ExcCellShouldBeUnused());
- Assert (children[1]->used() == false, ExcCellShouldBeUnused());
-
- children[0]->set (internal::Triangulation::
- TriaObject<1>(middle_line->vertex_index(0),
- next_unused_vertex));
- children[1]->set (internal::Triangulation::
- TriaObject<1>(next_unused_vertex,
- middle_line->vertex_index(1)));
-
- children[0]->set_used_flag();
- children[1]->set_used_flag();
- children[0]->clear_children();
- children[1]->clear_children();
- children[0]->clear_user_data();
- children[1]->clear_user_data();
- children[0]->clear_user_flag();
- children[1]->clear_user_flag();
-
- children[0]->set_boundary_indicator (middle_line->boundary_indicator());
- children[1]->set_boundary_indicator (middle_line->boundary_indicator());
- }
- // now remove the flag from the
- // quad and go to the next
- // quad, the actual refinement
- // of the quad takes place
- // later on in this pass of the
- // loop or in the next one
- quad->clear_user_flag();
- continue;
- } // if (several refinement cases)
-
- // if we got here, we have an
- // unrefined quad and have to do
- // the usual work like in an purely
- // isotropic refinement
- Assert(quad_ref_case==RefinementCase<dim-1>::no_refinement, ExcInternalError());
-
- // set the middle vertex
- // appropriately
- if (quad->at_boundary())
- triangulation.vertices[next_unused_vertex]
- = triangulation.get_boundary(quad->boundary_indicator()).get_new_point_on_quad (quad);
- else
- // it might be that the
- // quad itself is not
- // at the boundary, but
- // that one of its lines
- // actually is. in this
- // case, the newly
- // created vertices at
- // the centers of the
- // lines are not
- // necessarily the mean
- // values of the
- // adjacent vertices,
- // so do not compute
- // the new vertex as
- // the mean value of
- // the 4 vertices of
- // the face, but rather
- // as a weighted mean
- // value of the 8
- // vertices which we
- // already have (the
- // four old ones, and
- // the four ones
- // inserted as middle
- // points for the four
- // lines). summing up
- // some more points is
- // generally cheaper
- // than first asking
- // whether one of the
- // lines is at the
- // boundary
- //
- // note that the exact
- // weights are chosen
- // such as to minimize
- // the distortion of
- // the four new quads
- // from the optimal
- // shape; their
- // derivation and
- // values is copied
- // over from the
- // @p{MappingQ::set_laplace_on_vector}
- // function
- triangulation.vertices[next_unused_vertex]
- = (quad->vertex(0) + quad->vertex(1) +
- quad->vertex(2) + quad->vertex(3) +
- 3*(quad->line(0)->child(0)->vertex(1) +
- quad->line(1)->child(0)->vertex(1) +
- quad->line(2)->child(0)->vertex(1) +
- quad->line(3)->child(0)->vertex(1)) ) / 16;
-
- triangulation.vertices_used[next_unused_vertex] = true;
-
- // now that we created
- // the right point, make
- // up the four lines
- // interior to the quad
- // (++ takes care of the
- // end of the vector)
- typename Triangulation<dim,spacedim>::raw_line_iterator new_lines[4];
-
- for (unsigned int i=0; i<4; ++i)
- {
- if (i%2==0)
- // search a free pair of
- // lines for 0. and 2. line,
- // so that two of them end up
- // together, which is
- // necessary if later on we
- // want to refine the quad
- // anisotropically and the
- // two lines end up as
- // children of new line
- next_unused_line=triangulation.faces->lines.next_free_pair_line(triangulation);
-
- new_lines[i] = next_unused_line;
- ++next_unused_line;
-
- Assert (new_lines[i]->used() == false,
- ExcCellShouldBeUnused());
- }
-
- // set the data of the
- // four lines.
- // first collect the
- // indices of the five
- // vertices:
- // *--3--*
- // | | |
- // 0--4--1
- // | | |
- // *--2--*
- // the lines are numbered
- // as follows:
- // *--*--*
- // | 1 |
- // *2-*-3*
- // | 0 |
- // *--*--*
-
- const unsigned int vertex_indices[5]
- = { quad->line(0)->child(0)->vertex_index(1),
- quad->line(1)->child(0)->vertex_index(1),
- quad->line(2)->child(0)->vertex_index(1),
- quad->line(3)->child(0)->vertex_index(1),
- next_unused_vertex
- };
-
- new_lines[0]->set (internal::Triangulation::
- TriaObject<1>(vertex_indices[2], vertex_indices[4]));
- new_lines[1]->set (internal::Triangulation::
- TriaObject<1>(vertex_indices[4], vertex_indices[3]));
- new_lines[2]->set (internal::Triangulation::
- TriaObject<1>(vertex_indices[0], vertex_indices[4]));
- new_lines[3]->set (internal::Triangulation::
- TriaObject<1>(vertex_indices[4], vertex_indices[1]));
-
- for (unsigned int i=0; i<4; ++i)
- {
- new_lines[i]->set_used_flag();
- new_lines[i]->clear_user_flag();
- new_lines[i]->clear_user_data();
- new_lines[i]->clear_children();
- new_lines[i]->set_boundary_indicator(quad->boundary_indicator());
- }
-
- // now for the
- // quads. again, first
- // collect some data
- // about the indices of
- // the lines, with the
- // following numbering:
- // .-6-.-7-.
- // 1 9 3
- // .-10.11-.
- // 0 8 2
- // .-4-.-5-.
-
- // child 0 and 1 of a line are
- // switched if the line orientation
- // is false. set up a miniature
- // table, indicating which child to
- // take for line orientations false
- // and true. first index: child
- // index in standard orientation,
- // second index: line orientation
- const unsigned int index[2][2]=
- {{1,0}, // child 0, line_orientation=false and true
- {0,1}}; // child 1, line_orientation=false and true
-
- const unsigned int line_indices[12]
- = { quad->line(0)->child(index[0][quad->line_orientation(0)])->index(),
- quad->line(0)->child(index[1][quad->line_orientation(0)])->index(),
- quad->line(1)->child(index[0][quad->line_orientation(1)])->index(),
- quad->line(1)->child(index[1][quad->line_orientation(1)])->index(),
- quad->line(2)->child(index[0][quad->line_orientation(2)])->index(),
- quad->line(2)->child(index[1][quad->line_orientation(2)])->index(),
- quad->line(3)->child(index[0][quad->line_orientation(3)])->index(),
- quad->line(3)->child(index[1][quad->line_orientation(3)])->index(),
- new_lines[0]->index(),
- new_lines[1]->index(),
- new_lines[2]->index(),
- new_lines[3]->index()
- };
-
- // find some space (consecutive)
- // for the first two newly to be
- // created quads.
- typename Triangulation<dim,spacedim>::raw_quad_iterator new_quads[4];
-
- next_unused_quad=triangulation.faces->quads.next_free_pair_quad(triangulation);
-
- new_quads[0] = next_unused_quad;
- Assert (new_quads[0]->used() == false, ExcCellShouldBeUnused());
-
- ++next_unused_quad;
- new_quads[1] = next_unused_quad;
- Assert (new_quads[1]->used() == false, ExcCellShouldBeUnused());
-
- next_unused_quad=triangulation.faces->quads.next_free_pair_quad(triangulation);
- new_quads[2] = next_unused_quad;
- Assert (new_quads[2]->used() == false, ExcCellShouldBeUnused());
-
- ++next_unused_quad;
- new_quads[3] = next_unused_quad;
- Assert (new_quads[3]->used() == false, ExcCellShouldBeUnused());
-
- // note these quads as
- // children to the
- // present one
- quad->set_children (0, new_quads[0]->index());
- quad->set_children (2, new_quads[2]->index());
- new_quads[0]->set (internal::Triangulation
- ::TriaObject<2>(line_indices[0],
- line_indices[8],
- line_indices[4],
- line_indices[10]));
-
- quad->set_refinement_case(RefinementCase<2>::cut_xy);
-
- new_quads[0]->set (internal::Triangulation
- ::TriaObject<2>(line_indices[0],
- line_indices[8],
- line_indices[4],
- line_indices[10]));
- new_quads[1]->set (internal::Triangulation
- ::TriaObject<2>(line_indices[8],
- line_indices[2],
- line_indices[5],
- line_indices[11]));
- new_quads[2]->set (internal::Triangulation
- ::TriaObject<2>(line_indices[1],
- line_indices[9],
- line_indices[10],
- line_indices[6]));
- new_quads[3]->set (internal::Triangulation
- ::TriaObject<2>(line_indices[9],
- line_indices[3],
- line_indices[11],
- line_indices[7]));
- for (unsigned int i=0; i<4; ++i)
- {
- new_quads[i]->set_used_flag();
- new_quads[i]->clear_user_flag();
- new_quads[i]->clear_user_data();
- new_quads[i]->clear_children();
- new_quads[i]->set_boundary_indicator (quad->boundary_indicator());
- // set all line orientations to
- // true, change this after the
- // loop, as we have to consider
- // different lines for each
- // child
- for (unsigned int j=0; j<GeometryInfo<dim>::lines_per_face; ++j)
- new_quads[i]->set_line_orientation(j,true);
- }
- // now set the line orientation of
- // children of outer lines
- // correctly, the lines in the
- // interior of the refined quad are
- // automatically oriented
- // conforming to the standard
- new_quads[0]->set_line_orientation(0,quad->line_orientation(0));
- new_quads[0]->set_line_orientation(2,quad->line_orientation(2));
- new_quads[1]->set_line_orientation(1,quad->line_orientation(1));
- new_quads[1]->set_line_orientation(2,quad->line_orientation(2));
- new_quads[2]->set_line_orientation(0,quad->line_orientation(0));
- new_quads[2]->set_line_orientation(3,quad->line_orientation(3));
- new_quads[3]->set_line_orientation(1,quad->line_orientation(1));
- new_quads[3]->set_line_orientation(3,quad->line_orientation(3));
-
- // finally clear flag
- // indicating the need
- // for refinement
- quad->clear_user_flag ();
- } // if (isotropic refinement)
- } // for all quads
- } // looped two times over all quads, all quads refined now
-
- ///////////////////////////////////
- // Now, finally, set up the new
- // cells
- ///////////////////////////////////
-
- typename Triangulation<3,spacedim>::DistortedCellList
- cells_with_distorted_children;
-
- for (unsigned int level=0; level!=triangulation.levels.size()-1; ++level)
- {
- // only active objects can be
- // refined further; remember
- // that we won't operate on the
- // finest level, so
- // triangulation.begin_*(level+1) is allowed
- typename Triangulation<dim,spacedim>::active_hex_iterator
- hex = triangulation.begin_active_hex(level),
- endh = triangulation.begin_active_hex(level+1);
- typename Triangulation<dim,spacedim>::raw_hex_iterator
- next_unused_hex = triangulation.begin_raw_hex (level+1);
-
- for (; hex!=endh; ++hex)
- if (hex->refine_flag_set())
- {
- // this hex needs to be
- // refined
-
- // clear flag indicating
- // the need for
- // refinement. do it here
- // already, since we
- // can't do it anymore
- // once the cell has
- // children
- const RefinementCase<dim> ref_case=hex->refine_flag_set();
- hex->clear_refine_flag ();
- hex->set_refinement_case(ref_case);
-
- // depending on the refine case we
- // might have to create additional
- // vertices, lines and quads
- // interior of the hex before the
- // actual children can be set up.
-
- // in a first step: reserve the
- // needed space for lines, quads
- // and hexes and initialize them
- // correctly
-
- unsigned int n_new_lines=0;
- unsigned int n_new_quads=0;
- unsigned int n_new_hexes=0;
- switch (ref_case)
- {
- case RefinementCase<dim>::cut_x:
- case RefinementCase<dim>::cut_y:
- case RefinementCase<dim>::cut_z:
- n_new_lines=0;
- n_new_quads=1;
- n_new_hexes=2;
- break;
- case RefinementCase<dim>::cut_xy:
- case RefinementCase<dim>::cut_xz:
- case RefinementCase<dim>::cut_yz:
- n_new_lines=1;
- n_new_quads=4;
- n_new_hexes=4;
- break;
- case RefinementCase<dim>::cut_xyz:
- n_new_lines=6;
- n_new_quads=12;
- n_new_hexes=8;
- break;
- default:
- Assert(false, ExcInternalError());
- break;
- }
-
- // find some space for the newly to
- // be created interior lines and
- // initialize them.
- std::vector<typename Triangulation<dim,spacedim>::raw_line_iterator>
- new_lines(n_new_lines);
- for (unsigned int i=0; i<n_new_lines; ++i)
- {
- new_lines[i] = triangulation.faces->lines.next_free_single_line(triangulation);
-
- Assert (new_lines[i]->used() == false,
- ExcCellShouldBeUnused());
- new_lines[i]->set_used_flag();
- new_lines[i]->clear_user_flag();
- new_lines[i]->clear_user_data();
- new_lines[i]->clear_children();
- // interior line
- new_lines[i]->set_boundary_indicator(types::internal_face_boundary_id);
- }
-
- // find some space for the newly to
- // be created interior quads and
- // initialize them.
- std::vector<typename Triangulation<dim,spacedim>::raw_quad_iterator>
- new_quads(n_new_quads);
- for (unsigned int i=0; i<n_new_quads; ++i)
- {
- new_quads[i] = triangulation.faces->quads.next_free_single_quad(triangulation);
-
- Assert (new_quads[i]->used() == false,
- ExcCellShouldBeUnused());
- new_quads[i]->set_used_flag();
- new_quads[i]->clear_user_flag();
- new_quads[i]->clear_user_data();
- new_quads[i]->clear_children();
- // interior quad
- new_quads[i]->set_boundary_indicator (types::internal_face_boundary_id);
- // set all line orientation
- // flags to true by default,
- // change this afterwards, if
- // necessary
- for (unsigned int j=0; j<GeometryInfo<dim>::lines_per_face; ++j)
- new_quads[i]->set_line_orientation(j,true);
- }
-
- // find some space for the newly to
- // be created hexes and initialize
- // them.
- std::vector<typename Triangulation<dim,spacedim>::raw_hex_iterator>
- new_hexes(n_new_hexes);
- for (unsigned int i=0; i<n_new_hexes; ++i)
- {
- if (i%2==0)
- next_unused_hex=triangulation.levels[level+1]->cells.next_free_hex(triangulation,level+1);
-
- else
- ++next_unused_hex;
-
- new_hexes[i]=next_unused_hex;
-
- Assert (new_hexes[i]->used() == false,
- ExcCellShouldBeUnused());
- new_hexes[i]->set_used_flag();
- new_hexes[i]->clear_user_flag();
- new_hexes[i]->clear_user_data();
- new_hexes[i]->clear_children();
- // inherit material
- // properties
- new_hexes[i]->set_material_id (hex->material_id());
- new_hexes[i]->set_subdomain_id (hex->subdomain_id());
-
- if (i%2)
- new_hexes[i]->set_parent (hex->index ());
- // set the face_orientation
- // flag to true for all faces
- // initially, as this is the
- // default value which is true
- // for all faces interior to
- // the hex. later on go the
- // other way round and reset
- // faces that are at the
- // boundary of the mother cube
- //
- // the same is true for the
- // face_flip and face_rotation
- // flags. however, the latter
- // two are set to false by
- // default as this is the
- // standard value
- for (unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell; ++f)
- {
- new_hexes[i]->set_face_orientation(f, true);
- new_hexes[i]->set_face_flip(f, false);
- new_hexes[i]->set_face_rotation(f, false);
- }
- }
- // note these hexes as
- // children to the
- // present cell
- for (unsigned int i=0; i<n_new_hexes/2; ++i)
- hex->set_children (2*i, new_hexes[2*i]->index());
-
- // we have to take into account
- // whether the different faces are
- // oriented correctly or in the
- // opposite direction, so store
- // that up front
-
- // face_orientation
- const bool f_or[6]
- = { hex->face_orientation (0),
- hex->face_orientation (1),
- hex->face_orientation (2),
- hex->face_orientation (3),
- hex->face_orientation (4),
- hex->face_orientation (5) };
-
- // face_flip
- const bool f_fl[6]
- = { hex->face_flip (0),
- hex->face_flip (1),
- hex->face_flip (2),
- hex->face_flip (3),
- hex->face_flip (4),
- hex->face_flip (5) };
-
- // face_rotation
- const bool f_ro[6]
- = { hex->face_rotation (0),
- hex->face_rotation (1),
- hex->face_rotation (2),
- hex->face_rotation (3),
- hex->face_rotation (4),
- hex->face_rotation (5) };
-
- // some commonly used fields which
- // have varying size
- const unsigned int *vertex_indices=0;
- const typename Triangulation<dim,spacedim>::raw_line_iterator
- *lines=0;
- const unsigned int *line_indices=0;
- const bool *line_orientation=0;
- const unsigned int *quad_indices=0;
-
- // little helper table, indicating,
- // whether the child with index 0
- // or with index 1 can be found at
- // the standard origin of an
- // anisotropically refined quads in
- // real orientation
- // index 1: (RefineCase - 1)
- // index 2: face_flip
-
- // index 3: face rotation
- // note: face orientation has no influence
- const unsigned int child_at_origin[2][2][2]=
- { { { 0, 0 }, // RefinementCase<dim>::cut_x, face_flip=false, face_rotation=false and true
- { 1, 1 }}, // RefinementCase<dim>::cut_x, face_flip=true, face_rotation=false and true
- { { 0, 1 }, // RefinementCase<dim>::cut_y, face_flip=false, face_rotation=false and true
- { 1, 0 }}};// RefinementCase<dim>::cut_y, face_flip=true, face_rotation=false and true
-
- ///////////////////////////////////////
- //
- // in the following we will do the
- // same thing for each refinement
- // case: create a new vertex (if
- // needed), create new interior
- // lines (if needed), create new
- // interior quads and afterwards
- // build the children hexes out of
- // these and the existing subfaces
- // of the outer quads (which have
- // been created above). However,
- // even if the steps are quite
- // similar, the actual work
- // strongly depends on the actual
- // refinement case. therefore, we
- // use seperate blocks of code for
- // each of these cases, which
- // hopefully increases the
- // readability to some extend.
-
- switch (ref_case)
- {
- case RefinementCase<dim>::cut_x:
- {
- //////////////////////////////
- //
- // RefinementCase<dim>::cut_x
- //
- // the refined cube will look
- // like this:
- //
- // *----*----*
- // / / /|
- // / / / |
- // / / / |
- // *----*----* |
- // | | | |
- // | | | *
- // | | | /
- // | | | /
- // | | |/
- // *----*----*
- //
- // again, first
- // collect some data
- // about the indices of
- // the lines, with the
- // following numbering:
-
- // face 2: front plane
- // (note: x,y exchanged)
- // *---*---*
- // | | |
- // | 0 |
- // | | |
- // *---*---*
- // m0
- // face 3: back plane
- // (note: x,y exchanged)
- // m1
- // *---*---*
- // | | |
- // | 1 |
- // | | |
- // *---*---*
- // face 4: bottom plane
- // *---*---*
- // / / /
- // / 2 /
- // / / /
- // *---*---*
- // m0
- // face 5: top plane
- // m1
- // *---*---*
- // / / /
- // / 3 /
- // / / /
- // *---*---*
-
- // set up a list of line iterators
- // first. from this, construct
- // lists of line_indices and
- // line orientations later on
- const typename Triangulation<dim,spacedim>::raw_line_iterator
- lines_x[4]
- = {
- hex->face(2)->child(0)
- ->line((hex->face(2)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3), //0
- hex->face(3)->child(0)
- ->line((hex->face(3)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3), //1
- hex->face(4)->child(0)
- ->line((hex->face(4)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3), //2
- hex->face(5)->child(0)
- ->line((hex->face(5)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3) //3
- };
-
- lines=&lines_x[0];
-
- unsigned int line_indices_x[4];
-
- for (unsigned int i=0; i<4; ++i)
- line_indices_x[i]=lines[i]->index();
- line_indices=&line_indices_x[0];
-
- // the orientation of lines for the
- // inner quads is quite tricky. as
- // these lines are newly created
- // ones and thus have no parents,
- // they cannot inherit this
- // property. set up an array and
- // fill it with the respective
- // values
- bool line_orientation_x[4];
-
- // the middle vertice marked
- // as m0 above is the start
- // vertex for lines 0 and 2
- // in standard orientation,
- // whereas m1 is the end
- // vertex of lines 1 and 3 in
- // standard orientation
- const unsigned int middle_vertices[2]=
- {
- hex->line(2)->child(0)->vertex_index(1),
- hex->line(7)->child(0)->vertex_index(1)
- };
-
- for (unsigned int i=0; i<4; ++i)
- if (lines[i]->vertex_index(i%2)==middle_vertices[i%2])
- line_orientation_x[i]=true;
- else
- {
- // it must be the other
- // way round then
- Assert(lines[i]->vertex_index((i+1)%2)==middle_vertices[i%2],
- ExcInternalError());
- line_orientation_x[i]=false;
- }
-
- line_orientation=&line_orientation_x[0];
-
- // set up the new quad, line
- // numbering is as indicated
- // above
- new_quads[0]->set (internal::Triangulation
- ::TriaObject<2>(line_indices[0],
- line_indices[1],
- line_indices[2],
- line_indices[3]));
-
- new_quads[0]->set_line_orientation(0,line_orientation[0]);
- new_quads[0]->set_line_orientation(1,line_orientation[1]);
- new_quads[0]->set_line_orientation(2,line_orientation[2]);
- new_quads[0]->set_line_orientation(3,line_orientation[3]);
-
- // the quads are
- // numbered as follows:
- //
- // planes in the interior
- // of the old hex:
- // *
- // /|
- // / | x
- // / | *-------* *---------*
- // * | | | / /
- // | 0 | | | / /
- // | * | | / /
- // | / *-------*y *---------*x
- // | /
- // |/
- // *
- //
- // children of the faces
- // of the old hex
- // *---*---* *---*---*
- // /| | | / / /|
- // / | | | / 9 / 10/ |
- // / | 5 | 6 | / / / |
- // * | | | *---*---* |
- // | 1 *---*---* | | | 2 *
- // | / / / | | | /
- // | / 7 / 8 / | 3 | 4 | /
- // |/ / / | | |/
- // *---*---* *---*---*
- //
- // note that we have to
- // take care of the
- // orientation of
- // faces.
- const unsigned int quad_indices_x[11]
- = {
- new_quads[0]->index(), //0
-
- hex->face(0)->index(), //1
-
- hex->face(1)->index(), //2
-
- hex->face(2)->child_index( child_at_origin[hex->face(2)->refinement_case()-1][f_fl[2]][f_ro[2]]), //3
- hex->face(2)->child_index(1-child_at_origin[hex->face(2)->refinement_case()-1][f_fl[2]][f_ro[2]]),
-
- hex->face(3)->child_index( child_at_origin[hex->face(3)->refinement_case()-1][f_fl[3]][f_ro[3]]), //5
- hex->face(3)->child_index(1-child_at_origin[hex->face(3)->refinement_case()-1][f_fl[3]][f_ro[3]]),
-
- hex->face(4)->child_index( child_at_origin[hex->face(4)->refinement_case()-1][f_fl[4]][f_ro[4]]), //7
- hex->face(4)->child_index(1-child_at_origin[hex->face(4)->refinement_case()-1][f_fl[4]][f_ro[4]]),
-
- hex->face(5)->child_index( child_at_origin[hex->face(5)->refinement_case()-1][f_fl[5]][f_ro[5]]), //9
- hex->face(5)->child_index(1-child_at_origin[hex->face(5)->refinement_case()-1][f_fl[5]][f_ro[5]])
-
- };
- quad_indices=&quad_indices_x[0];
-
- new_hexes[0]->set (internal::Triangulation
- ::TriaObject<3>(quad_indices[1],
- quad_indices[0],
- quad_indices[3],
- quad_indices[5],
- quad_indices[7],
- quad_indices[9]));
- new_hexes[1]->set (internal::Triangulation
- ::TriaObject<3>(quad_indices[0],
- quad_indices[2],
- quad_indices[4],
- quad_indices[6],
- quad_indices[8],
- quad_indices[10]));
- break;
- }
- case RefinementCase<dim>::cut_y:
- {
- //////////////////////////////
- //
- // RefinementCase<dim>::cut_y
- //
- // the refined cube will look
- // like this:
- //
- // *---------*
- // / /|
- // *---------* |
- // / /| |
- // *---------* | |
- // | | | |
- // | | | *
- // | | |/
- // | | *
- // | |/
- // *---------*
- //
- // again, first
- // collect some data
- // about the indices of
- // the lines, with the
- // following numbering:
-
- // face 0: left plane
- // *
- // /|
- // * |
- // /| |
- // * | |
- // | 0 |
- // | | *
- // | |/
- // | *m0
- // |/
- // *
- // face 1: right plane
- // *
- // /|
- // m1* |
- // /| |
- // * | |
- // | 1 |
- // | | *
- // | |/
- // | *
- // |/
- // *
- // face 4: bottom plane
- // *-------*
- // / /
- // m0*---2---*
- // / /
- // *-------*
- // face 5: top plane
- // *-------*
- // / /
- // *---3---*m1
- // / /
- // *-------*
-
- // set up a list of line iterators
- // first. from this, construct
- // lists of line_indices and
- // line orientations later on
- const typename Triangulation<dim,spacedim>::raw_line_iterator
- lines_y[4]
- = {
- hex->face(0)->child(0)
- ->line((hex->face(0)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3), //0
- hex->face(1)->child(0)
- ->line((hex->face(1)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3), //1
- hex->face(4)->child(0)
- ->line((hex->face(4)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3), //2
- hex->face(5)->child(0)
- ->line((hex->face(5)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3) //3
- };
-
- lines=&lines_y[0];
-
- unsigned int line_indices_y[4];
-
- for (unsigned int i=0; i<4; ++i)
- line_indices_y[i]=lines[i]->index();
- line_indices=&line_indices_y[0];
-
- // the orientation of lines for the
- // inner quads is quite tricky. as
- // these lines are newly created
- // ones and thus have no parents,
- // they cannot inherit this
- // property. set up an array and
- // fill it with the respective
- // values
- bool line_orientation_y[4];
-
- // the middle vertice marked
- // as m0 above is the start
- // vertex for lines 0 and 2
- // in standard orientation,
- // whereas m1 is the end
- // vertex of lines 1 and 3 in
- // standard orientation
- const unsigned int middle_vertices[2]=
- {
- hex->line(0)->child(0)->vertex_index(1),
- hex->line(5)->child(0)->vertex_index(1)
- };
-
- for (unsigned int i=0; i<4; ++i)
- if (lines[i]->vertex_index(i%2)==middle_vertices[i%2])
- line_orientation_y[i]=true;
- else
- {
- // it must be the other way round then
- Assert(lines[i]->vertex_index((i+1)%2)==middle_vertices[i%2],
- ExcInternalError());
- line_orientation_y[i]=false;
- }
-
- line_orientation=&line_orientation_y[0];
-
- // set up the new quad, line
- // numbering is as indicated
- // above
- new_quads[0]->set (internal::Triangulation
- ::TriaObject<2>(line_indices[2],
- line_indices[3],
- line_indices[0],
- line_indices[1]));
-
- new_quads[0]->set_line_orientation(0,line_orientation[2]);
- new_quads[0]->set_line_orientation(1,line_orientation[3]);
- new_quads[0]->set_line_orientation(2,line_orientation[0]);
- new_quads[0]->set_line_orientation(3,line_orientation[1]);
-
- // the quads are
- // numbered as follows:
- //
- // planes in the interior
- // of the old hex:
- // *
- // /|
- // / | x
- // / | *-------* *---------*
- // * | | | / /
- // | | | 0 | / /
- // | * | | / /
- // | / *-------*y *---------*x
- // | /
- // |/
- // *
- //
- // children of the faces
- // of the old hex
- // *-------* *-------*
- // /| | / 10 /|
- // * | | *-------* |
- // /| | 6 | / 9 /| |
- // * |2| | *-------* |4|
- // | | *-------* | | | *
- // |1|/ 8 / | |3|/
- // | *-------* | 5 | *
- // |/ 7 / | |/
- // *-------* *-------*
- //
- // note that we have to
- // take care of the
- // orientation of
- // faces.
- const unsigned int quad_indices_y[11]
- = {
- new_quads[0]->index(), //0
-
- hex->face(0)->child_index( child_at_origin[hex->face(0)->refinement_case()-1][f_fl[0]][f_ro[0]]), //1
- hex->face(0)->child_index(1-child_at_origin[hex->face(0)->refinement_case()-1][f_fl[0]][f_ro[0]]),
-
- hex->face(1)->child_index( child_at_origin[hex->face(1)->refinement_case()-1][f_fl[1]][f_ro[1]]), //3
- hex->face(1)->child_index(1-child_at_origin[hex->face(1)->refinement_case()-1][f_fl[1]][f_ro[1]]),
-
- hex->face(2)->index(), //5
-
- hex->face(3)->index(), //6
-
- hex->face(4)->child_index( child_at_origin[hex->face(4)->refinement_case()-1][f_fl[4]][f_ro[4]]), //7
- hex->face(4)->child_index(1-child_at_origin[hex->face(4)->refinement_case()-1][f_fl[4]][f_ro[4]]),
-
- hex->face(5)->child_index( child_at_origin[hex->face(5)->refinement_case()-1][f_fl[5]][f_ro[5]]), //9
- hex->face(5)->child_index(1-child_at_origin[hex->face(5)->refinement_case()-1][f_fl[5]][f_ro[5]])
-
- };
- quad_indices=&quad_indices_y[0];
-
- new_hexes[0]->set (internal::Triangulation
- ::TriaObject<3>(quad_indices[1],
- quad_indices[3],
- quad_indices[5],
- quad_indices[0],
- quad_indices[7],
- quad_indices[9]));
- new_hexes[1]->set (internal::Triangulation
- ::TriaObject<3>(quad_indices[2],
- quad_indices[4],
- quad_indices[0],
- quad_indices[6],
- quad_indices[8],
- quad_indices[10]));
- break;
- }
- case RefinementCase<dim>::cut_z:
- {
- //////////////////////////////
- //
- // RefinementCase<dim>::cut_z
- //
- // the refined cube will look
- // like this:
- //
- // *---------*
- // / /|
- // / / |
- // / / *
- // *---------* /|
- // | | / |
- // | |/ *
- // *---------* /
- // | | /
- // | |/
- // *---------*
- //
- // again, first
- // collect some data
- // about the indices of
- // the lines, with the
- // following numbering:
-
- // face 0: left plane
- // *
- // /|
- // / |
- // / *
- // * /|
- // | 0 |
- // |/ *
- // m0* /
- // | /
- // |/
- // *
- // face 1: right plane
- // *
- // /|
- // / |
- // / *m1
- // * /|
- // | 1 |
- // |/ *
- // * /
- // | /
- // |/
- // *
- // face 2: front plane
- // (note: x,y exchanged)
- // *-------*
- // | |
- // m0*---2---*
- // | |
- // *-------*
- // face 3: back plane
- // (note: x,y exchanged)
- // *-------*
- // | |
- // *---3---*m1
- // | |
- // *-------*
-
- // set up a list of line iterators
- // first. from this, construct
- // lists of line_indices and
- // line orientations later on
- const typename Triangulation<dim,spacedim>::raw_line_iterator
- lines_z[4]
- = {
- hex->face(0)->child(0)
- ->line((hex->face(0)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3), //0
- hex->face(1)->child(0)
- ->line((hex->face(1)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3), //1
- hex->face(2)->child(0)
- ->line((hex->face(2)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3), //2
- hex->face(3)->child(0)
- ->line((hex->face(3)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3) //3
- };
-
- lines=&lines_z[0];
-
- unsigned int line_indices_z[4];
-
- for (unsigned int i=0; i<4; ++i)
- line_indices_z[i]=lines[i]->index();
- line_indices=&line_indices_z[0];
-
- // the orientation of lines for the
- // inner quads is quite tricky. as
- // these lines are newly created
- // ones and thus have no parents,
- // they cannot inherit this
- // property. set up an array and
- // fill it with the respective
- // values
- bool line_orientation_z[4];
-
- // the middle vertex marked
- // as m0 above is the start
- // vertex for lines 0 and 2
- // in standard orientation,
- // whereas m1 is the end
- // vertex of lines 1 and 3 in
- // standard orientation
- const unsigned int middle_vertices[2]=
- {
- middle_vertex_index<dim,spacedim>(hex->line(8)),
- middle_vertex_index<dim,spacedim>(hex->line(11))
- };
-
- for (unsigned int i=0; i<4; ++i)
- if (lines[i]->vertex_index(i%2)==middle_vertices[i%2])
- line_orientation_z[i]=true;
- else
- {
- // it must be the other way round then
- Assert(lines[i]->vertex_index((i+1)%2)==middle_vertices[i%2],
- ExcInternalError());
- line_orientation_z[i]=false;
- }
-
- line_orientation=&line_orientation_z[0];
-
- // set up the new quad, line
- // numbering is as indicated
- // above
- new_quads[0]->set (internal::Triangulation
- ::TriaObject<2>(line_indices[0],
- line_indices[1],
- line_indices[2],
- line_indices[3]));
-
- new_quads[0]->set_line_orientation(0,line_orientation[0]);
- new_quads[0]->set_line_orientation(1,line_orientation[1]);
- new_quads[0]->set_line_orientation(2,line_orientation[2]);
- new_quads[0]->set_line_orientation(3,line_orientation[3]);
-
- // the quads are
- // numbered as follows:
- //
- // planes in the interior
- // of the old hex:
- // *
- // /|
- // / | x
- // / | *-------* *---------*
- // * | | | / /
- // | | | | / 0 /
- // | * | | / /
- // | / *-------*y *---------*x
- // | /
- // |/
- // *
- //
- // children of the faces
- // of the old hex
- // *---*---* *-------*
- // /| 8 | / /|
- // / | | / 10 / |
- // / *-------* / / *
- // * 2/| | *-------* 4/|
- // | / | 7 | | 6 | / |
- // |/1 *-------* | |/3 *
- // * / / *-------* /
- // | / 9 / | | /
- // |/ / | 5 |/
- // *-------* *---*---*
- //
- // note that we have to
- // take care of the
- // orientation of
- // faces.
- const unsigned int quad_indices_z[11]
- = {
- new_quads[0]->index(), //0
-
- hex->face(0)->child_index( child_at_origin[hex->face(0)->refinement_case()-1][f_fl[0]][f_ro[0]]), //1
- hex->face(0)->child_index(1-child_at_origin[hex->face(0)->refinement_case()-1][f_fl[0]][f_ro[0]]),
-
- hex->face(1)->child_index( child_at_origin[hex->face(1)->refinement_case()-1][f_fl[1]][f_ro[1]]), //3
- hex->face(1)->child_index(1-child_at_origin[hex->face(1)->refinement_case()-1][f_fl[1]][f_ro[1]]),
-
- hex->face(2)->child_index( child_at_origin[hex->face(2)->refinement_case()-1][f_fl[2]][f_ro[2]]), //5
- hex->face(2)->child_index(1-child_at_origin[hex->face(2)->refinement_case()-1][f_fl[2]][f_ro[2]]),
-
- hex->face(3)->child_index( child_at_origin[hex->face(3)->refinement_case()-1][f_fl[3]][f_ro[3]]), //7
- hex->face(3)->child_index(1-child_at_origin[hex->face(3)->refinement_case()-1][f_fl[3]][f_ro[3]]),
-
- hex->face(4)->index(), //9
-
- hex->face(5)->index() //10
- };
- quad_indices=&quad_indices_z[0];
-
- new_hexes[0]->set (internal::Triangulation
- ::TriaObject<3>(quad_indices[1],
- quad_indices[3],
- quad_indices[5],
- quad_indices[7],
- quad_indices[9],
- quad_indices[0]));
- new_hexes[1]->set (internal::Triangulation
- ::TriaObject<3>(quad_indices[2],
- quad_indices[4],
- quad_indices[6],
- quad_indices[8],
- quad_indices[0],
- quad_indices[10]));
- break;
- }
- case RefinementCase<dim>::cut_xy:
- {
- //////////////////////////////
- //
- // RefinementCase<dim>::cut_xy
- //
- // the refined cube will look
- // like this:
- //
- // *----*----*
- // / / /|
- // *----*----* |
- // / / /| |
- // *----*----* | |
- // | | | | |
- // | | | | *
- // | | | |/
- // | | | *
- // | | |/
- // *----*----*
- //
-
- // first, create the new
- // internal line
- new_lines[0]->set (internal::Triangulation::
- TriaObject<1>(middle_vertex_index<dim,spacedim>(hex->face(4)),
- middle_vertex_index<dim,spacedim>(hex->face(5))));
-
- // again, first
- // collect some data
- // about the indices of
- // the lines, with the
- // following numbering:
-
- // face 0: left plane
- // *
- // /|
- // * |
- // /| |
- // * | |
- // | 0 |
- // | | *
- // | |/
- // | *
- // |/
- // *
- // face 1: right plane
- // *
- // /|
- // * |
- // /| |
- // * | |
- // | 1 |
- // | | *
- // | |/
- // | *
- // |/
- // *
- // face 2: front plane
- // (note: x,y exchanged)
- // *---*---*
- // | | |
- // | 2 |
- // | | |
- // *-------*
- // face 3: back plane
- // (note: x,y exchanged)
- // *---*---*
- // | | |
- // | 3 |
- // | | |
- // *---*---*
- // face 4: bottom plane
- // *---*---*
- // / 5 /
- // *-6-*-7-*
- // / 4 /
- // *---*---*
- // face 5: top plane
- // *---*---*
- // / 9 /
- // *10-*-11*
- // / 8 /
- // *---*---*
- // middle planes
- // *-------* *---*---*
- // / / | | |
- // / / | 12 |
- // / / | | |
- // *-------* *---*---*
-
- // set up a list of line iterators
- // first. from this, construct
- // lists of line_indices and
- // line orientations later on
- const typename Triangulation<dim,spacedim>::raw_line_iterator
- lines_xy[13]
- = {
- hex->face(0)->child(0)
- ->line((hex->face(0)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3), //0
- hex->face(1)->child(0)
- ->line((hex->face(1)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3), //1
- hex->face(2)->child(0)
- ->line((hex->face(2)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3), //2
- hex->face(3)->child(0)
- ->line((hex->face(3)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3), //3
-
- hex->face(4)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[4],f_fl[4],f_ro[4]))
- ->line(GeometryInfo<dim>::standard_to_real_face_line(1,f_or[4],f_fl[4],f_ro[4])), //4
- hex->face(4)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[4],f_fl[4],f_ro[4]))
- ->line(GeometryInfo<dim>::standard_to_real_face_line(0,f_or[4],f_fl[4],f_ro[4])), //5
- hex->face(4)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[4],f_fl[4],f_ro[4]))
- ->line(GeometryInfo<dim>::standard_to_real_face_line(3,f_or[4],f_fl[4],f_ro[4])), //6
- hex->face(4)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[4],f_fl[4],f_ro[4]))
- ->line(GeometryInfo<dim>::standard_to_real_face_line(2,f_or[4],f_fl[4],f_ro[4])), //7
-
- hex->face(5)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[5],f_fl[5],f_ro[5]))
- ->line(GeometryInfo<dim>::standard_to_real_face_line(1,f_or[5],f_fl[5],f_ro[5])), //8
- hex->face(5)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[5],f_fl[5],f_ro[5]))
- ->line(GeometryInfo<dim>::standard_to_real_face_line(0,f_or[5],f_fl[5],f_ro[5])), //9
- hex->face(5)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[5],f_fl[5],f_ro[5]))
- ->line(GeometryInfo<dim>::standard_to_real_face_line(3,f_or[5],f_fl[5],f_ro[5])), //10
- hex->face(5)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[5],f_fl[5],f_ro[5]))
- ->line(GeometryInfo<dim>::standard_to_real_face_line(2,f_or[5],f_fl[5],f_ro[5])), //11
-
- new_lines[0] //12
- };
-
- lines=&lines_xy[0];
-
- unsigned int line_indices_xy[13];
-
- for (unsigned int i=0; i<13; ++i)
- line_indices_xy[i]=lines[i]->index();
- line_indices=&line_indices_xy[0];
-
- // the orientation of lines for the
- // inner quads is quite tricky. as
- // these lines are newly created
- // ones and thus have no parents,
- // they cannot inherit this
- // property. set up an array and
- // fill it with the respective
- // values
- bool line_orientation_xy[13];
-
- // the middle vertices of the
- // lines of our bottom face
- const unsigned int middle_vertices[4]=
- {
- hex->line(0)->child(0)->vertex_index(1),
- hex->line(1)->child(0)->vertex_index(1),
- hex->line(2)->child(0)->vertex_index(1),
- hex->line(3)->child(0)->vertex_index(1),
- };
-
- // note: for lines 0 to 3 the
- // orientation of the line
- // is 'true', if vertex 0 is
- // on the bottom face
- for (unsigned int i=0; i<4; ++i)
- if (lines[i]->vertex_index(0)==middle_vertices[i])
- line_orientation_xy[i]=true;
- else
- {
- // it must be the other way round then
- Assert(lines[i]->vertex_index(1)==middle_vertices[i],
- ExcInternalError());
- line_orientation_xy[i]=false;
- }
-
- // note: for lines 4 to 11
- // (inner lines of the outer quads)
- // the following holds: the second
- // vertex of the even lines in
- // standard orientation is the
- // vertex in the middle of the
- // quad, whereas for odd lines the
- // first vertex is the same middle
- // vertex.
- for (unsigned int i=4; i<12; ++i)
- if (lines[i]->vertex_index((i+1)%2) ==
- middle_vertex_index<dim,spacedim>(hex->face(3+i/4)))
- line_orientation_xy[i]=true;
- else
- {
- // it must be the other way
- // round then
- Assert(lines[i]->vertex_index(i%2) ==
- (middle_vertex_index<dim,spacedim>(hex->face(3+i/4))),
- ExcInternalError());
- line_orientation_xy[i]=false;
- }
- // for the last line the line
- // orientation is always true,
- // since it was just constructed
- // that way
-
- line_orientation_xy[12]=true;
- line_orientation=&line_orientation_xy[0];
-
- // set up the 4 quads,
- // numbered as follows
- // (left quad numbering,
- // right line numbering
- // extracted from above)
- //
- // * *
- // /| 9|
- // * | * |
- // y/| | 8| 3
- // * |1| * | |
- // | | |x | 12|
- // |0| * | | *
- // | |/ 2 |5
- // | * | *
- // |/ |4
- // * *
- //
- // x
- // *---*---* *10-*-11*
- // | | | | | |
- // | 2 | 3 | 0 12 1
- // | | | | | |
- // *---*---*y *-6-*-7-*
-
- new_quads[0]->set (internal::Triangulation
- ::TriaObject<2>(line_indices[2],
- line_indices[12],
- line_indices[4],
- line_indices[8]));
- new_quads[1]->set (internal::Triangulation
- ::TriaObject<2>(line_indices[12],
- line_indices[3],
- line_indices[5],
- line_indices[9]));
- new_quads[2]->set (internal::Triangulation
- ::TriaObject<2>(line_indices[6],
- line_indices[10],
- line_indices[0],
- line_indices[12]));
- new_quads[3]->set (internal::Triangulation
- ::TriaObject<2>(line_indices[7],
- line_indices[11],
- line_indices[12],
- line_indices[1]));
-
- new_quads[0]->set_line_orientation(0,line_orientation[2]);
- new_quads[0]->set_line_orientation(2,line_orientation[4]);
- new_quads[0]->set_line_orientation(3,line_orientation[8]);
-
- new_quads[1]->set_line_orientation(1,line_orientation[3]);
- new_quads[1]->set_line_orientation(2,line_orientation[5]);
- new_quads[1]->set_line_orientation(3,line_orientation[9]);
-
- new_quads[2]->set_line_orientation(0,line_orientation[6]);
- new_quads[2]->set_line_orientation(1,line_orientation[10]);
- new_quads[2]->set_line_orientation(2,line_orientation[0]);
-
- new_quads[3]->set_line_orientation(0,line_orientation[7]);
- new_quads[3]->set_line_orientation(1,line_orientation[11]);
- new_quads[3]->set_line_orientation(3,line_orientation[1]);
-
- // the quads are
- // numbered as follows:
- //
- // planes in the interior
- // of the old hex:
- // *
- // /|
- // * | x
- // /| | *---*---* *---------*
- // * |1| | | | / /
- // | | | | 2 | 3 | / /
- // |0| * | | | / /
- // | |/ *---*---*y *---------*x
- // | *
- // |/
- // *
- //
- // children of the faces
- // of the old hex
- // *---*---* *---*---*
- // /| | | /18 / 19/|
- // * |10 | 11| /---/---* |
- // /| | | | /16 / 17/| |
- // * |5| | | *---*---* |7|
- // | | *---*---* | | | | *
- // |4|/14 / 15/ | | |6|/
- // | *---/---/ | 8 | 9 | *
- // |/12 / 13/ | | |/
- // *---*---* *---*---*
- //
- // note that we have to
- // take care of the
- // orientation of
- // faces.
- const unsigned int quad_indices_xy[20]
- = {
- new_quads[0]->index(), //0
- new_quads[1]->index(),
- new_quads[2]->index(),
- new_quads[3]->index(),
-
- hex->face(0)->child_index( child_at_origin[hex->face(0)->refinement_case()-1][f_fl[0]][f_ro[0]]), //4
- hex->face(0)->child_index(1-child_at_origin[hex->face(0)->refinement_case()-1][f_fl[0]][f_ro[0]]),
-
- hex->face(1)->child_index( child_at_origin[hex->face(1)->refinement_case()-1][f_fl[1]][f_ro[1]]), //6
- hex->face(1)->child_index(1-child_at_origin[hex->face(1)->refinement_case()-1][f_fl[1]][f_ro[1]]),
-
- hex->face(2)->child_index( child_at_origin[hex->face(2)->refinement_case()-1][f_fl[2]][f_ro[2]]), //8
- hex->face(2)->child_index(1-child_at_origin[hex->face(2)->refinement_case()-1][f_fl[2]][f_ro[2]]),
-
- hex->face(3)->child_index( child_at_origin[hex->face(3)->refinement_case()-1][f_fl[3]][f_ro[3]]), //10
- hex->face(3)->child_index(1-child_at_origin[hex->face(3)->refinement_case()-1][f_fl[3]][f_ro[3]]),
-
- hex->face(4)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[4],f_fl[4],f_ro[4])), //12
- hex->face(4)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(1,f_or[4],f_fl[4],f_ro[4])),
- hex->face(4)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(2,f_or[4],f_fl[4],f_ro[4])),
- hex->face(4)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[4],f_fl[4],f_ro[4])),
-
- hex->face(5)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[5],f_fl[5],f_ro[5])), //16
- hex->face(5)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(1,f_or[5],f_fl[5],f_ro[5])),
- hex->face(5)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(2,f_or[5],f_fl[5],f_ro[5])),
- hex->face(5)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[5],f_fl[5],f_ro[5]))
- };
- quad_indices=&quad_indices_xy[0];
-
- new_hexes[0]->set (internal::Triangulation
- ::TriaObject<3>(quad_indices[4],
- quad_indices[0],
- quad_indices[8],
- quad_indices[2],
- quad_indices[12],
- quad_indices[16]));
- new_hexes[1]->set (internal::Triangulation
- ::TriaObject<3>(quad_indices[0],
- quad_indices[6],
- quad_indices[9],
- quad_indices[3],
- quad_indices[13],
- quad_indices[17]));
- new_hexes[2]->set (internal::Triangulation
- ::TriaObject<3>(quad_indices[5],
- quad_indices[1],
- quad_indices[2],
- quad_indices[10],
- quad_indices[14],
- quad_indices[18]));
- new_hexes[3]->set (internal::Triangulation
- ::TriaObject<3>(quad_indices[1],
- quad_indices[7],
- quad_indices[3],
- quad_indices[11],
- quad_indices[15],
- quad_indices[19]));
- break;
- }
- case RefinementCase<dim>::cut_xz:
- {
- //////////////////////////////
- //
- // RefinementCase<dim>::cut_xz
- //
- // the refined cube will look
- // like this:
- //
- // *----*----*
- // / / /|
- // / / / |
- // / / / *
- // *----*----* /|
- // | | | / |
- // | | |/ *
- // *----*----* /
- // | | | /
- // | | |/
- // *----*----*
- //
-
- // first, create the new
- // internal line
- new_lines[0]->set (internal::Triangulation::
- TriaObject<1>(middle_vertex_index<dim,spacedim>(hex->face(2)),
- middle_vertex_index<dim,spacedim>(hex->face(3))));
-
- // again, first
- // collect some data
- // about the indices of
- // the lines, with the
- // following numbering:
-
- // face 0: left plane
- // *
- // /|
- // / |
- // / *
- // * /|
- // | 0 |
- // |/ *
- // * /
- // | /
- // |/
- // *
- // face 1: right plane
- // *
- // /|
- // / |
- // / *
- // * /|
- // | 1 |
- // |/ *
- // * /
- // | /
- // |/
- // *
- // face 2: front plane
- // (note: x,y exchanged)
- // *---*---*
- // | 5 |
- // *-6-*-7-*
- // | 4 |
- // *---*---*
- // face 3: back plane
- // (note: x,y exchanged)
- // *---*---*
- // | 9 |
- // *10-*-11*
- // | 8 |
- // *---*---*
- // face 4: bottom plane
- // *---*---*
- // / / /
- // / 2 /
- // / / /
- // *---*---*
- // face 5: top plane
- // *---*---*
- // / / /
- // / 3 /
- // / / /
- // *---*---*
- // middle planes
- // *---*---* *-------*
- // / / / | |
- // / 12 / | |
- // / / / | |
- // *---*---* *-------*
-
- // set up a list of line iterators
- // first. from this, construct
- // lists of line_indices and
- // line orientations later on
- const typename Triangulation<dim,spacedim>::raw_line_iterator
- lines_xz[13]
- = {
- hex->face(0)->child(0)
- ->line((hex->face(0)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3), //0
- hex->face(1)->child(0)
- ->line((hex->face(1)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3), //1
- hex->face(4)->child(0)
- ->line((hex->face(4)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3), //2
- hex->face(5)->child(0)
- ->line((hex->face(5)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3), //3
-
- hex->face(2)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[2],f_fl[2],f_ro[2]))
- ->line(GeometryInfo<dim>::standard_to_real_face_line(3,f_or[2],f_fl[2],f_ro[2])), //4
- hex->face(2)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[2],f_fl[2],f_ro[2]))
- ->line(GeometryInfo<dim>::standard_to_real_face_line(2,f_or[2],f_fl[2],f_ro[2])), //5
- hex->face(2)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[2],f_fl[2],f_ro[2]))
- ->line(GeometryInfo<dim>::standard_to_real_face_line(1,f_or[2],f_fl[2],f_ro[2])), //6
- hex->face(2)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[2],f_fl[2],f_ro[2]))
- ->line(GeometryInfo<dim>::standard_to_real_face_line(0,f_or[2],f_fl[2],f_ro[2])), //7
-
- hex->face(3)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[3],f_fl[3],f_ro[3]))
- ->line(GeometryInfo<dim>::standard_to_real_face_line(3,f_or[3],f_fl[3],f_ro[3])), //8
- hex->face(3)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[3],f_fl[3],f_ro[3]))
- ->line(GeometryInfo<dim>::standard_to_real_face_line(2,f_or[3],f_fl[3],f_ro[3])), //9
- hex->face(3)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[3],f_fl[3],f_ro[3]))
- ->line(GeometryInfo<dim>::standard_to_real_face_line(1,f_or[3],f_fl[3],f_ro[3])), //10
- hex->face(3)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[3],f_fl[3],f_ro[3]))
- ->line(GeometryInfo<dim>::standard_to_real_face_line(0,f_or[3],f_fl[3],f_ro[3])), //11
-
- new_lines[0] //12
- };
-
- lines=&lines_xz[0];
-
- unsigned int line_indices_xz[13];
-
- for (unsigned int i=0; i<13; ++i)
- line_indices_xz[i]=lines[i]->index();
- line_indices=&line_indices_xz[0];
-
- // the orientation of lines for the
- // inner quads is quite tricky. as
- // these lines are newly created
- // ones and thus have no parents,
- // they cannot inherit this
- // property. set up an array and
- // fill it with the respective
- // values
- bool line_orientation_xz[13];
-
- // the middle vertices of the
- // lines of our front face
- const unsigned int middle_vertices[4]=
- {
- hex->line(8)->child(0)->vertex_index(1),
- hex->line(9)->child(0)->vertex_index(1),
- hex->line(2)->child(0)->vertex_index(1),
- hex->line(6)->child(0)->vertex_index(1),
- };
-
- // note: for lines 0 to 3 the
- // orientation of the line
- // is 'true', if vertex 0 is
- // on the front
- for (unsigned int i=0; i<4; ++i)
- if (lines[i]->vertex_index(0)==middle_vertices[i])
- line_orientation_xz[i]=true;
- else
- {
- // it must be the other way round then
- Assert(lines[i]->vertex_index(1)==middle_vertices[i],
- ExcInternalError());
- line_orientation_xz[i]=false;
- }
-
- // note: for lines 4 to 11
- // (inner lines of the outer quads)
- // the following holds: the second
- // vertex of the even lines in
- // standard orientation is the
- // vertex in the middle of the
- // quad, whereas for odd lines the
- // first vertex is the same middle
- // vertex.
- for (unsigned int i=4; i<12; ++i)
- if (lines[i]->vertex_index((i+1)%2) ==
- middle_vertex_index<dim,spacedim>(hex->face(1+i/4)))
- line_orientation_xz[i]=true;
- else
- {
- // it must be the other way
- // round then
- Assert(lines[i]->vertex_index(i%2) ==
- (middle_vertex_index<dim,spacedim>(hex->face(1+i/4))),
- ExcInternalError());
- line_orientation_xz[i]=false;
- }
- // for the last line the line
- // orientation is always true,
- // since it was just constructed
- // that way
-
- line_orientation_xz[12]=true;
- line_orientation=&line_orientation_xz[0];
-
- // set up the 4 quads,
- // numbered as follows
- // (left quad numbering,
- // right line numbering
- // extracted from above),
- // the drawings denote
- // middle planes
- //
- // * *
- // /| /|
- // / | 3 9
- // y/ * / *
- // * 3/| * /|
- // | / |x 5 12|8
- // |/ * |/ *
- // * 2/ * /
- // | / 4 2
- // |/ |/
- // * *
- //
- // y
- // *----*----* *-10-*-11-*
- // / / / / / /
- // / 0 / 1 / 0 12 1
- // / / / / / /
- // *----*----*x *--6-*--7-*
-
- new_quads[0]->set (internal::Triangulation
- ::TriaObject<2>(line_indices[0],
- line_indices[12],
- line_indices[6],
- line_indices[10]));
- new_quads[1]->set (internal::Triangulation
- ::TriaObject<2>(line_indices[12],
- line_indices[1],
- line_indices[7],
- line_indices[11]));
- new_quads[2]->set (internal::Triangulation
- ::TriaObject<2>(line_indices[4],
- line_indices[8],
- line_indices[2],
- line_indices[12]));
- new_quads[3]->set (internal::Triangulation
- ::TriaObject<2>(line_indices[5],
- line_indices[9],
- line_indices[12],
- line_indices[3]));
-
- new_quads[0]->set_line_orientation(0,line_orientation[0]);
- new_quads[0]->set_line_orientation(2,line_orientation[6]);
- new_quads[0]->set_line_orientation(3,line_orientation[10]);
-
- new_quads[1]->set_line_orientation(1,line_orientation[1]);
- new_quads[1]->set_line_orientation(2,line_orientation[7]);
- new_quads[1]->set_line_orientation(3,line_orientation[11]);
-
- new_quads[2]->set_line_orientation(0,line_orientation[4]);
- new_quads[2]->set_line_orientation(1,line_orientation[8]);
- new_quads[2]->set_line_orientation(2,line_orientation[2]);
-
- new_quads[3]->set_line_orientation(0,line_orientation[5]);
- new_quads[3]->set_line_orientation(1,line_orientation[9]);
- new_quads[3]->set_line_orientation(3,line_orientation[3]);
-
- // the quads are
- // numbered as follows:
- //
- // planes in the interior
- // of the old hex:
- // *
- // /|
- // / | x
- // /3 * *-------* *----*----*
- // * /| | | / / /
- // | / | | | / 0 / 1 /
- // |/ * | | / / /
- // * 2/ *-------*y *----*----*x
- // | /
- // |/
- // *
- //
- // children of the faces
- // of the old hex
- // *---*---* *---*---*
- // /|13 | 15| / / /|
- // / | | | /18 / 19/ |
- // / *---*---* / / / *
- // * 5/| | | *---*---* 7/|
- // | / |12 | 14| | 9 | 11| / |
- // |/4 *---*---* | | |/6 *
- // * / / / *---*---* /
- // | /16 / 17/ | | | /
- // |/ / / | 8 | 10|/
- // *---*---* *---*---*
- //
- // note that we have to
- // take care of the
- // orientation of
- // faces.
- const unsigned int quad_indices_xz[20]
- = {
- new_quads[0]->index(), //0
- new_quads[1]->index(),
- new_quads[2]->index(),
- new_quads[3]->index(),
-
- hex->face(0)->child_index( child_at_origin[hex->face(0)->refinement_case()-1][f_fl[0]][f_ro[0]]), //4
- hex->face(0)->child_index(1-child_at_origin[hex->face(0)->refinement_case()-1][f_fl[0]][f_ro[0]]),
-
- hex->face(1)->child_index( child_at_origin[hex->face(1)->refinement_case()-1][f_fl[1]][f_ro[1]]), //6
- hex->face(1)->child_index(1-child_at_origin[hex->face(1)->refinement_case()-1][f_fl[1]][f_ro[1]]),
-
- hex->face(2)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[2],f_fl[2],f_ro[2])), //8
- hex->face(2)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(1,f_or[2],f_fl[2],f_ro[2])),
- hex->face(2)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(2,f_or[2],f_fl[2],f_ro[2])),
- hex->face(2)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[2],f_fl[2],f_ro[2])),
-
- hex->face(3)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[3],f_fl[3],f_ro[3])), //12
- hex->face(3)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(1,f_or[3],f_fl[3],f_ro[3])),
- hex->face(3)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(2,f_or[3],f_fl[3],f_ro[3])),
- hex->face(3)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[3],f_fl[3],f_ro[3])),
-
- hex->face(4)->child_index( child_at_origin[hex->face(4)->refinement_case()-1][f_fl[4]][f_ro[4]]), //16
- hex->face(4)->child_index(1-child_at_origin[hex->face(4)->refinement_case()-1][f_fl[4]][f_ro[4]]),
-
- hex->face(5)->child_index( child_at_origin[hex->face(5)->refinement_case()-1][f_fl[5]][f_ro[5]]), //18
- hex->face(5)->child_index(1-child_at_origin[hex->face(5)->refinement_case()-1][f_fl[5]][f_ro[5]])
- };
- quad_indices=&quad_indices_xz[0];
-
- // due to the exchange of x
- // and y for the front and
- // back face, we order the
- // children according to
- //
- // *---*---*
- // | 1 | 3 |
- // *---*---*
- // | 0 | 2 |
- // *---*---*
- new_hexes[0]->set (internal::Triangulation
- ::TriaObject<3>(quad_indices[4],
- quad_indices[2],
- quad_indices[8],
- quad_indices[12],
- quad_indices[16],
- quad_indices[0]));
- new_hexes[1]->set (internal::Triangulation
- ::TriaObject<3>(quad_indices[5],
- quad_indices[3],
- quad_indices[9],
- quad_indices[13],
- quad_indices[0],
- quad_indices[18]));
- new_hexes[2]->set (internal::Triangulation
- ::TriaObject<3>(quad_indices[2],
- quad_indices[6],
- quad_indices[10],
- quad_indices[14],
- quad_indices[17],
- quad_indices[1]));
- new_hexes[3]->set (internal::Triangulation
- ::TriaObject<3>(quad_indices[3],
- quad_indices[7],
- quad_indices[11],
- quad_indices[15],
- quad_indices[1],
- quad_indices[19]));
- break;
- }
- case RefinementCase<dim>::cut_yz:
- {
- //////////////////////////////
- //
- // RefinementCase<dim>::cut_yz
- //
- // the refined cube will look
- // like this:
- //
- // *---------*
- // / /|
- // *---------* |
- // / /| |
- // *---------* |/|
- // | | * |
- // | |/| *
- // *---------* |/
- // | | *
- // | |/
- // *---------*
- //
-
- // first, create the new
- // internal line
- new_lines[0]->set (internal::Triangulation::
- TriaObject<1>(middle_vertex_index<dim,spacedim>(hex->face(0)),
- middle_vertex_index<dim,spacedim>(hex->face(1))));
-
- // again, first
- // collect some data
- // about the indices of
- // the lines, with the
- // following numbering:
- // (note that face 0 and
- // 1 each are shown twice
- // for better
- // readability)
-
- // face 0: left plane
- // * *
- // /| /|
- // * | * |
- // /| * /| *
- // * 5/| * |7|
- // | * | | * |
- // |/| * |6| *
- // * 4/ * |/
- // | * | *
- // |/ |/
- // * *
- // face 1: right plane
- // * *
- // /| /|
- // * | * |
- // /| * /| *
- // * 9/| * |11
- // | * | | * |
- // |/| * |10 *
- // * 8/ * |/
- // | * | *
- // |/ |/
- // * *
- // face 2: front plane
- // (note: x,y exchanged)
- // *-------*
- // | |
- // *---0---*
- // | |
- // *-------*
- // face 3: back plane
- // (note: x,y exchanged)
- // *-------*
- // | |
- // *---1---*
- // | |
- // *-------*
- // face 4: bottom plane
- // *-------*
- // / /
- // *---2---*
- // / /
- // *-------*
- // face 5: top plane
- // *-------*
- // / /
- // *---3---*
- // / /
- // *-------*
- // middle planes
- // *-------* *-------*
- // / / | |
- // *---12--* | |
- // / / | |
- // *-------* *-------*
-
- // set up a list of line iterators
- // first. from this, construct
- // lists of line_indices and
- // line orientations later on
- const typename Triangulation<dim,spacedim>::raw_line_iterator
- lines_yz[13]
- = {
- hex->face(2)->child(0)
- ->line((hex->face(2)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3), //0
- hex->face(3)->child(0)
- ->line((hex->face(3)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3), //1
- hex->face(4)->child(0)
- ->line((hex->face(4)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3), //2
- hex->face(5)->child(0)
- ->line((hex->face(5)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3), //3
-
- hex->face(0)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[0],f_fl[0],f_ro[0]))
- ->line(GeometryInfo<dim>::standard_to_real_face_line(1,f_or[0],f_fl[0],f_ro[0])), //4
- hex->face(0)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[0],f_fl[0],f_ro[0]))
- ->line(GeometryInfo<dim>::standard_to_real_face_line(0,f_or[0],f_fl[0],f_ro[0])), //5
- hex->face(0)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[0],f_fl[0],f_ro[0]))
- ->line(GeometryInfo<dim>::standard_to_real_face_line(3,f_or[0],f_fl[0],f_ro[0])), //6
- hex->face(0)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[0],f_fl[0],f_ro[0]))
- ->line(GeometryInfo<dim>::standard_to_real_face_line(2,f_or[0],f_fl[0],f_ro[0])), //7
-
- hex->face(1)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[1],f_fl[1],f_ro[1]))
- ->line(GeometryInfo<dim>::standard_to_real_face_line(1,f_or[1],f_fl[1],f_ro[1])), //8
- hex->face(1)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[1],f_fl[1],f_ro[1]))
- ->line(GeometryInfo<dim>::standard_to_real_face_line(0,f_or[1],f_fl[1],f_ro[1])), //9
- hex->face(1)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[1],f_fl[1],f_ro[1]))
- ->line(GeometryInfo<dim>::standard_to_real_face_line(3,f_or[1],f_fl[1],f_ro[1])), //10
- hex->face(1)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[1],f_fl[1],f_ro[1]))
- ->line(GeometryInfo<dim>::standard_to_real_face_line(2,f_or[1],f_fl[1],f_ro[1])), //11
-
- new_lines[0] //12
- };
-
- lines=&lines_yz[0];
-
- unsigned int line_indices_yz[13];
-
- for (unsigned int i=0; i<13; ++i)
- line_indices_yz[i]=lines[i]->index();
- line_indices=&line_indices_yz[0];
-
- // the orientation of lines for the
- // inner quads is quite tricky. as
- // these lines are newly created
- // ones and thus have no parents,
- // they cannot inherit this
- // property. set up an array and
- // fill it with the respective
- // values
- bool line_orientation_yz[13];
-
- // the middle vertices of the
- // lines of our front face
- const unsigned int middle_vertices[4]=
- {
- hex->line(8)->child(0)->vertex_index(1),
- hex->line(10)->child(0)->vertex_index(1),
- hex->line(0)->child(0)->vertex_index(1),
- hex->line(4)->child(0)->vertex_index(1),
- };
-
- // note: for lines 0 to 3 the
- // orientation of the line
- // is 'true', if vertex 0 is
- // on the front
- for (unsigned int i=0; i<4; ++i)
- if (lines[i]->vertex_index(0)==middle_vertices[i])
- line_orientation_yz[i]=true;
- else
- {
- // it must be the other way round then
- Assert(lines[i]->vertex_index(1)==middle_vertices[i],
- ExcInternalError());
- line_orientation_yz[i]=false;
- }
-
- // note: for lines 4 to 11
- // (inner lines of the outer quads)
- // the following holds: the second
- // vertex of the even lines in
- // standard orientation is the
- // vertex in the middle of the
- // quad, whereas for odd lines the
- // first vertex is the same middle
- // vertex.
- for (unsigned int i=4; i<12; ++i)
- if (lines[i]->vertex_index((i+1)%2) ==
- middle_vertex_index<dim,spacedim>(hex->face(i/4-1)))
- line_orientation_yz[i]=true;
- else
- {
- // it must be the other way
- // round then
- Assert(lines[i]->vertex_index(i%2) ==
- (middle_vertex_index<dim,spacedim>(hex->face(i/4-1))),
- ExcInternalError());
- line_orientation_yz[i]=false;
- }
- // for the last line the line
- // orientation is always true,
- // since it was just constructed
- // that way
-
- line_orientation_yz[12]=true;
- line_orientation=&line_orientation_yz[0];
-
- // set up the 4 quads,
- // numbered as follows (left
- // quad numbering, right line
- // numbering extracted from
- // above)
- //
- // x
- // *-------* *---3---*
- // | 3 | 5 9
- // *-------* *---12--*
- // | 2 | 4 8
- // *-------*y *---2---*
- //
- // y
- // *---------* *----1----*
- // / 1 / 7 11
- // *---------* *----12---*
- // / 0 / 6 10
- // *---------*x *----0----*
-
- new_quads[0]->set (internal::Triangulation
- ::TriaObject<2>(line_indices[6],
- line_indices[10],
- line_indices[0],
- line_indices[12]));
- new_quads[1]->set (internal::Triangulation
- ::TriaObject<2>(line_indices[7],
- line_indices[11],
- line_indices[12],
- line_indices[1]));
- new_quads[2]->set (internal::Triangulation
- ::TriaObject<2>(line_indices[2],
- line_indices[12],
- line_indices[4],
- line_indices[8]));
- new_quads[3]->set (internal::Triangulation
- ::TriaObject<2>(line_indices[12],
- line_indices[3],
- line_indices[5],
- line_indices[9]));
-
- new_quads[0]->set_line_orientation(0,line_orientation[6]);
- new_quads[0]->set_line_orientation(1,line_orientation[10]);
- new_quads[0]->set_line_orientation(2,line_orientation[0]);
-
- new_quads[1]->set_line_orientation(0,line_orientation[7]);
- new_quads[1]->set_line_orientation(1,line_orientation[11]);
- new_quads[1]->set_line_orientation(3,line_orientation[1]);
-
- new_quads[2]->set_line_orientation(0,line_orientation[2]);
- new_quads[2]->set_line_orientation(2,line_orientation[4]);
- new_quads[2]->set_line_orientation(3,line_orientation[8]);
-
- new_quads[3]->set_line_orientation(1,line_orientation[3]);
- new_quads[3]->set_line_orientation(2,line_orientation[5]);
- new_quads[3]->set_line_orientation(3,line_orientation[9]);
-
- // the quads are
- // numbered as follows:
- //
- // planes in the interior
- // of the old hex:
- // *
- // /|
- // / | x
- // / | *-------* *---------*
- // * | | 3 | / 1 /
- // | | *-------* *---------*
- // | * | 2 | / 0 /
- // | / *-------*y *---------*x
- // | /
- // |/
- // *
- //
- // children of the faces
- // of the old hex
- // *-------* *-------*
- // /| | / 19 /|
- // * | 15 | *-------* |
- // /|7*-------* / 18 /|11
- // * |/| | *-------* |/|
- // |6* | 14 | | 10* |
- // |/|5*-------* | 13 |/|9*
- // * |/ 17 / *-------* |/
- // |4*-------* | |8*
- // |/ 16 / | 12 |/
- // *-------* *-------*
- //
- // note that we have to
- // take care of the
- // orientation of
- // faces.
- const unsigned int quad_indices_yz[20]
- = {
- new_quads[0]->index(), //0
- new_quads[1]->index(),
- new_quads[2]->index(),
- new_quads[3]->index(),
-
- hex->face(0)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[0],f_fl[0],f_ro[0])), //4
- hex->face(0)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(1,f_or[0],f_fl[0],f_ro[0])),
- hex->face(0)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(2,f_or[0],f_fl[0],f_ro[0])),
- hex->face(0)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[0],f_fl[0],f_ro[0])),
-
- hex->face(1)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[1],f_fl[1],f_ro[1])), //8
- hex->face(1)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(1,f_or[1],f_fl[1],f_ro[1])),
- hex->face(1)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(2,f_or[1],f_fl[1],f_ro[1])),
- hex->face(1)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[1],f_fl[1],f_ro[1])),
-
- hex->face(2)->child_index( child_at_origin[hex->face(2)->refinement_case()-1][f_fl[2]][f_ro[2]]), //12
- hex->face(2)->child_index(1-child_at_origin[hex->face(2)->refinement_case()-1][f_fl[2]][f_ro[2]]),
-
- hex->face(3)->child_index( child_at_origin[hex->face(3)->refinement_case()-1][f_fl[3]][f_ro[3]]), //14
- hex->face(3)->child_index(1-child_at_origin[hex->face(3)->refinement_case()-1][f_fl[3]][f_ro[3]]),
-
- hex->face(4)->child_index( child_at_origin[hex->face(4)->refinement_case()-1][f_fl[4]][f_ro[4]]), //16
- hex->face(4)->child_index(1-child_at_origin[hex->face(4)->refinement_case()-1][f_fl[4]][f_ro[4]]),
-
- hex->face(5)->child_index( child_at_origin[hex->face(5)->refinement_case()-1][f_fl[5]][f_ro[5]]), //18
- hex->face(5)->child_index(1-child_at_origin[hex->face(5)->refinement_case()-1][f_fl[5]][f_ro[5]])
- };
- quad_indices=&quad_indices_yz[0];
-
- new_hexes[0]->set (internal::Triangulation
- ::TriaObject<3>(quad_indices[4],
- quad_indices[8],
- quad_indices[12],
- quad_indices[2],
- quad_indices[16],
- quad_indices[0]));
- new_hexes[1]->set (internal::Triangulation
- ::TriaObject<3>(quad_indices[5],
- quad_indices[9],
- quad_indices[2],
- quad_indices[14],
- quad_indices[17],
- quad_indices[1]));
- new_hexes[2]->set (internal::Triangulation
- ::TriaObject<3>(quad_indices[6],
- quad_indices[10],
- quad_indices[13],
- quad_indices[3],
- quad_indices[0],
- quad_indices[18]));
- new_hexes[3]->set (internal::Triangulation
- ::TriaObject<3>(quad_indices[7],
- quad_indices[11],
- quad_indices[3],
- quad_indices[15],
- quad_indices[1],
- quad_indices[19]));
- break;
- }
- case RefinementCase<dim>::cut_xyz:
- {
- //////////////////////////////
- //
- // RefinementCase<dim>::cut_xyz
- // isotropic refinement
- //
- // the refined cube will look
- // like this:
- //
- // *----*----*
- // / / /|
- // *----*----* |
- // / / /| *
- // *----*----* |/|
- // | | | * |
- // | | |/| *
- // *----*----* |/
- // | | | *
- // | | |/
- // *----*----*
- //
-
- // find the next unused
- // vertex and set it
- // appropriately
- while (triangulation.vertices_used[next_unused_vertex] == true)
- ++next_unused_vertex;
- Assert (next_unused_vertex < triangulation.vertices.size(),
- ExcTooFewVerticesAllocated());
- triangulation.vertices_used[next_unused_vertex] = true;
-
- // the new vertex is
- // definitely in the
- // interior, so we need not
- // worry about the boundary.
- // let it be the average of
- // the 26 vertices
- // surrounding it. weight
- // these vertices in the same
- // way as they are weighted
- // in the
- // @p{MappingQ::set_laplace_on_hex_vector}
- // function, and like the new
- // vertex at the center of
- // the quad is weighted (see
- // above)
- triangulation.vertices[next_unused_vertex] = Point<dim>();
- // first add corners of hex
- for (unsigned int vertex=0;
- vertex<GeometryInfo<dim>::vertices_per_cell; ++vertex)
- triangulation.vertices[next_unused_vertex] += hex->vertex(vertex) / 128;
- // now add center of lines
- for (unsigned int line=0;
- line<GeometryInfo<dim>::lines_per_cell; ++line)
- triangulation.vertices[next_unused_vertex] += hex->line(line)->child(0)->vertex(1) *
- 7./192.;
- // finally add centers of
- // faces. note that vertex 3
- // of child 0 is an invariant
- // with respect to the face
- // orientation, flip and
- // rotation
- for (unsigned int face=0;
- face<GeometryInfo<dim>::faces_per_cell; ++face)
- triangulation.vertices[next_unused_vertex] += hex->face(face)->isotropic_child(0)->vertex(3) *
- 1./12.;
-
- // set the data of the
- // six lines. first
- // collect the indices of
- // the seven vertices
- // (consider the two
- // planes to be crossed
- // to form the planes
- // cutting the hex in two
- // vertically and
- // horizontally)
- // *--3--* *--5--*
- // / / / | | |
- // 0--6--1 0--6--1
- // / / / | | |
- // *--2--* *--4--*
- // the lines are numbered
- // as follows:
- // *--*--* *--*--*
- // / 1 / | 5 |
- // *2-*-3* *2-*-3*
- // / 0 / | 4 |
- // *--*--* *--*--*
- //
- const unsigned int vertex_indices_xyz[7]
- = { middle_vertex_index<dim,spacedim>(hex->face(0)),
- middle_vertex_index<dim,spacedim>(hex->face(1)),
- middle_vertex_index<dim,spacedim>(hex->face(2)),
- middle_vertex_index<dim,spacedim>(hex->face(3)),
- middle_vertex_index<dim,spacedim>(hex->face(4)),
- middle_vertex_index<dim,spacedim>(hex->face(5)),
- next_unused_vertex
- };
- vertex_indices=&vertex_indices_xyz[0];
-
- new_lines[0]->set (internal::Triangulation::
- TriaObject<1>(vertex_indices[2], vertex_indices[6]));
- new_lines[1]->set (internal::Triangulation::
- TriaObject<1>(vertex_indices[6], vertex_indices[3]));
- new_lines[2]->set (internal::Triangulation::
- TriaObject<1>(vertex_indices[0], vertex_indices[6]));
- new_lines[3]->set (internal::Triangulation::
- TriaObject<1>(vertex_indices[6], vertex_indices[1]));
- new_lines[4]->set (internal::Triangulation::
- TriaObject<1>(vertex_indices[4], vertex_indices[6]));
- new_lines[5]->set (internal::Triangulation::
- TriaObject<1>(vertex_indices[6], vertex_indices[5]));
-
- // again, first
- // collect some data
- // about the indices of
- // the lines, with the
- // following numbering:
- // (note that face 0 and
- // 1 each are shown twice
- // for better
- // readability)
-
- // face 0: left plane
- // * *
- // /| /|
- // * | * |
- // /| * /| *
- // * 1/| * |3|
- // | * | | * |
- // |/| * |2| *
- // * 0/ * |/
- // | * | *
- // |/ |/
- // * *
- // face 1: right plane
- // * *
- // /| /|
- // * | * |
- // /| * /| *
- // * 5/| * |7|
- // | * | | * |
- // |/| * |6| *
- // * 4/ * |/
- // | * | *
- // |/ |/
- // * *
- // face 2: front plane
- // (note: x,y exchanged)
- // *---*---*
- // | 11 |
- // *-8-*-9-*
- // | 10 |
- // *---*---*
- // face 3: back plane
- // (note: x,y exchanged)
- // *---*---*
- // | 15 |
- // *12-*-13*
- // | 14 |
- // *---*---*
- // face 4: bottom plane
- // *---*---*
- // / 17 /
- // *18-*-19*
- // / 16 /
- // *---*---*
- // face 5: top plane
- // *---*---*
- // / 21 /
- // *22-*-23*
- // / 20 /
- // *---*---*
- // middle planes
- // *---*---* *---*---*
- // / 25 / | 29 |
- // *26-*-27* *26-*-27*
- // / 24 / | 28 |
- // *---*---* *---*---*
-
- // set up a list of line iterators
- // first. from this, construct
- // lists of line_indices and
- // line orientations later on
- const typename Triangulation<dim,spacedim>::raw_line_iterator
- lines_xyz[30]
- = {
- hex->face(0)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[0],f_fl[0],f_ro[0]))
- ->line(GeometryInfo<dim>::standard_to_real_face_line(1,f_or[0],f_fl[0],f_ro[0])), //0
- hex->face(0)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[0],f_fl[0],f_ro[0]))
- ->line(GeometryInfo<dim>::standard_to_real_face_line(0,f_or[0],f_fl[0],f_ro[0])), //1
- hex->face(0)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[0],f_fl[0],f_ro[0]))
- ->line(GeometryInfo<dim>::standard_to_real_face_line(3,f_or[0],f_fl[0],f_ro[0])), //2
- hex->face(0)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[0],f_fl[0],f_ro[0]))
- ->line(GeometryInfo<dim>::standard_to_real_face_line(2,f_or[0],f_fl[0],f_ro[0])), //3
-
- hex->face(1)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[1],f_fl[1],f_ro[1]))
- ->line(GeometryInfo<dim>::standard_to_real_face_line(1,f_or[1],f_fl[1],f_ro[1])), //4
- hex->face(1)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[1],f_fl[1],f_ro[1]))
- ->line(GeometryInfo<dim>::standard_to_real_face_line(0,f_or[1],f_fl[1],f_ro[1])), //5
- hex->face(1)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[1],f_fl[1],f_ro[1]))
- ->line(GeometryInfo<dim>::standard_to_real_face_line(3,f_or[1],f_fl[1],f_ro[1])), //6
- hex->face(1)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[1],f_fl[1],f_ro[1]))
- ->line(GeometryInfo<dim>::standard_to_real_face_line(2,f_or[1],f_fl[1],f_ro[1])), //7
-
- hex->face(2)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[2],f_fl[2],f_ro[2]))
- ->line(GeometryInfo<dim>::standard_to_real_face_line(1,f_or[2],f_fl[2],f_ro[2])), //8
- hex->face(2)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[2],f_fl[2],f_ro[2]))
- ->line(GeometryInfo<dim>::standard_to_real_face_line(0,f_or[2],f_fl[2],f_ro[2])), //9
- hex->face(2)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[2],f_fl[2],f_ro[2]))
- ->line(GeometryInfo<dim>::standard_to_real_face_line(3,f_or[2],f_fl[2],f_ro[2])), //10
- hex->face(2)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[2],f_fl[2],f_ro[2]))
- ->line(GeometryInfo<dim>::standard_to_real_face_line(2,f_or[2],f_fl[2],f_ro[2])), //11
-
- hex->face(3)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[3],f_fl[3],f_ro[3]))
- ->line(GeometryInfo<dim>::standard_to_real_face_line(1,f_or[3],f_fl[3],f_ro[3])), //12
- hex->face(3)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[3],f_fl[3],f_ro[3]))
- ->line(GeometryInfo<dim>::standard_to_real_face_line(0,f_or[3],f_fl[3],f_ro[3])), //13
- hex->face(3)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[3],f_fl[3],f_ro[3]))
- ->line(GeometryInfo<dim>::standard_to_real_face_line(3,f_or[3],f_fl[3],f_ro[3])), //14
- hex->face(3)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[3],f_fl[3],f_ro[3]))
- ->line(GeometryInfo<dim>::standard_to_real_face_line(2,f_or[3],f_fl[3],f_ro[3])), //15
-
- hex->face(4)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[4],f_fl[4],f_ro[4]))
- ->line(GeometryInfo<dim>::standard_to_real_face_line(1,f_or[4],f_fl[4],f_ro[4])), //16
- hex->face(4)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[4],f_fl[4],f_ro[4]))
- ->line(GeometryInfo<dim>::standard_to_real_face_line(0,f_or[4],f_fl[4],f_ro[4])), //17
- hex->face(4)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[4],f_fl[4],f_ro[4]))
- ->line(GeometryInfo<dim>::standard_to_real_face_line(3,f_or[4],f_fl[4],f_ro[4])), //18
- hex->face(4)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[4],f_fl[4],f_ro[4]))
- ->line(GeometryInfo<dim>::standard_to_real_face_line(2,f_or[4],f_fl[4],f_ro[4])), //19
-
- hex->face(5)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[5],f_fl[5],f_ro[5]))
- ->line(GeometryInfo<dim>::standard_to_real_face_line(1,f_or[5],f_fl[5],f_ro[5])), //20
- hex->face(5)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[5],f_fl[5],f_ro[5]))
- ->line(GeometryInfo<dim>::standard_to_real_face_line(0,f_or[5],f_fl[5],f_ro[5])), //21
- hex->face(5)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[5],f_fl[5],f_ro[5]))
- ->line(GeometryInfo<dim>::standard_to_real_face_line(3,f_or[5],f_fl[5],f_ro[5])), //22
- hex->face(5)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[5],f_fl[5],f_ro[5]))
- ->line(GeometryInfo<dim>::standard_to_real_face_line(2,f_or[5],f_fl[5],f_ro[5])), //23
-
- new_lines[0], //24
- new_lines[1], //25
- new_lines[2], //26
- new_lines[3], //27
- new_lines[4], //28
- new_lines[5] //29
- };
-
- lines=&lines_xyz[0];
-
- unsigned int line_indices_xyz[30];
- for (unsigned int i=0; i<30; ++i)
- line_indices_xyz[i]=lines[i]->index();
- line_indices=&line_indices_xyz[0];
-
- // the orientation of lines for the
- // inner quads is quite tricky. as
- // these lines are newly created
- // ones and thus have no parents,
- // they cannot inherit this
- // property. set up an array and
- // fill it with the respective
- // values
- bool line_orientation_xyz[30];
-
- // note: for the first 24 lines
- // (inner lines of the outer quads)
- // the following holds: the second
- // vertex of the even lines in
- // standard orientation is the
- // vertex in the middle of the
- // quad, whereas for odd lines the
- // first vertex is the same middle
- // vertex.
- for (unsigned int i=0; i<24; ++i)
- if (lines[i]->vertex_index((i+1)%2)==vertex_indices[i/4])
- line_orientation_xyz[i]=true;
- else
- {
- // it must be the other way
- // round then
- Assert(lines[i]->vertex_index(i%2)==vertex_indices[i/4],
- ExcInternalError());
- line_orientation_xyz[i]=false;
- }
- // for the last 6 lines the line
- // orientation is always true,
- // since they were just constructed
- // that way
- for (unsigned int i=24; i<30; ++i)
- line_orientation_xyz[i]=true;
- line_orientation=&line_orientation_xyz[0];
-
- // set up the 12 quads,
- // numbered as follows
- // (left quad numbering,
- // right line numbering
- // extracted from above)
- //
- // * *
- // /| 21|
- // * | * 15
- // y/|3* 20| *
- // * |/| * |/|
- // |2* |x 11 * 14
- // |/|1* |/| *
- // * |/ * |17
- // |0* 10 *
- // |/ |16
- // * *
- //
- // x
- // *---*---* *22-*-23*
- // | 5 | 7 | 1 29 5
- // *---*---* *26-*-27*
- // | 4 | 6 | 0 28 4
- // *---*---*y *18-*-19*
- //
- // y
- // *----*----* *-12-*-13-*
- // / 10 / 11 / 3 25 7
- // *----*----* *-26-*-27-*
- // / 8 / 9 / 2 24 6
- // *----*----*x *--8-*--9-*
-
- new_quads[0]->set (internal::Triangulation
- ::TriaObject<2>(line_indices[10],
- line_indices[28],
- line_indices[16],
- line_indices[24]));
- new_quads[1]->set (internal::Triangulation
- ::TriaObject<2>(line_indices[28],
- line_indices[14],
- line_indices[17],
- line_indices[25]));
- new_quads[2]->set (internal::Triangulation
- ::TriaObject<2>(line_indices[11],
- line_indices[29],
- line_indices[24],
- line_indices[20]));
- new_quads[3]->set (internal::Triangulation
- ::TriaObject<2>(line_indices[29],
- line_indices[15],
- line_indices[25],
- line_indices[21]));
- new_quads[4]->set (internal::Triangulation
- ::TriaObject<2>(line_indices[18],
- line_indices[26],
- line_indices[0],
- line_indices[28]));
- new_quads[5]->set (internal::Triangulation
- ::TriaObject<2>(line_indices[26],
- line_indices[22],
- line_indices[1],
- line_indices[29]));
- new_quads[6]->set (internal::Triangulation
- ::TriaObject<2>(line_indices[19],
- line_indices[27],
- line_indices[28],
- line_indices[4]));
- new_quads[7]->set (internal::Triangulation
- ::TriaObject<2>(line_indices[27],
- line_indices[23],
- line_indices[29],
- line_indices[5]));
- new_quads[8]->set (internal::Triangulation
- ::TriaObject<2>(line_indices[2],
- line_indices[24],
- line_indices[8],
- line_indices[26]));
- new_quads[9]->set (internal::Triangulation
- ::TriaObject<2>(line_indices[24],
- line_indices[6],
- line_indices[9],
- line_indices[27]));
- new_quads[10]->set (internal::Triangulation
- ::TriaObject<2>(line_indices[3],
- line_indices[25],
- line_indices[26],
- line_indices[12]));
- new_quads[11]->set (internal::Triangulation
- ::TriaObject<2>(line_indices[25],
- line_indices[7],
- line_indices[27],
- line_indices[13]));
-
- // now reset the line_orientation
- // flags of outer lines as they
- // cannot be set in a loop (at
- // least not easily)
- new_quads[0]->set_line_orientation(0,line_orientation[10]);
- new_quads[0]->set_line_orientation(2,line_orientation[16]);
-
- new_quads[1]->set_line_orientation(1,line_orientation[14]);
- new_quads[1]->set_line_orientation(2,line_orientation[17]);
-
- new_quads[2]->set_line_orientation(0,line_orientation[11]);
- new_quads[2]->set_line_orientation(3,line_orientation[20]);
-
- new_quads[3]->set_line_orientation(1,line_orientation[15]);
- new_quads[3]->set_line_orientation(3,line_orientation[21]);
-
- new_quads[4]->set_line_orientation(0,line_orientation[18]);
- new_quads[4]->set_line_orientation(2,line_orientation[0]);
-
- new_quads[5]->set_line_orientation(1,line_orientation[22]);
- new_quads[5]->set_line_orientation(2,line_orientation[1]);
-
- new_quads[6]->set_line_orientation(0,line_orientation[19]);
- new_quads[6]->set_line_orientation(3,line_orientation[4]);
-
- new_quads[7]->set_line_orientation(1,line_orientation[23]);
- new_quads[7]->set_line_orientation(3,line_orientation[5]);
-
- new_quads[8]->set_line_orientation(0,line_orientation[2]);
- new_quads[8]->set_line_orientation(2,line_orientation[8]);
-
- new_quads[9]->set_line_orientation(1,line_orientation[6]);
- new_quads[9]->set_line_orientation(2,line_orientation[9]);
-
- new_quads[10]->set_line_orientation(0,line_orientation[3]);
- new_quads[10]->set_line_orientation(3,line_orientation[12]);
-
- new_quads[11]->set_line_orientation(1,line_orientation[7]);
- new_quads[11]->set_line_orientation(3,line_orientation[13]);
-
- /////////////////////////////////
- // create the eight new hexes
- //
- // again first collect
- // some data. here, we
- // need the indices of a
- // whole lotta
- // quads.
-
- // the quads are
- // numbered as follows:
- //
- // planes in the interior
- // of the old hex:
- // *
- // /|
- // * |
- // /|3* *---*---* *----*----*
- // * |/| | 5 | 7 | / 10 / 11 /
- // |2* | *---*---* *----*----*
- // |/|1* | 4 | 6 | / 8 / 9 /
- // * |/ *---*---*y *----*----*x
- // |0*
- // |/
- // *
- //
- // children of the faces
- // of the old hex
- // *-------* *-------*
- // /|25 27| /34 35/|
- // 15| | / /19
- // / | | /32 33/ |
- // * |24 26| *-------*18 |
- // 1413*-------* |21 23| 17*
- // | /30 31/ | | /
- // 12/ / | |16
- // |/28 29/ |20 22|/
- // *-------* *-------*
- //
- // note that we have to
- // take care of the
- // orientation of
- // faces.
- const unsigned int quad_indices_xyz[36]
- = {
- new_quads[0]->index(), //0
- new_quads[1]->index(),
- new_quads[2]->index(),
- new_quads[3]->index(),
- new_quads[4]->index(),
- new_quads[5]->index(),
- new_quads[6]->index(),
- new_quads[7]->index(),
- new_quads[8]->index(),
- new_quads[9]->index(),
- new_quads[10]->index(),
- new_quads[11]->index(), //11
-
- hex->face(0)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[0],f_fl[0],f_ro[0])), //12
- hex->face(0)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(1,f_or[0],f_fl[0],f_ro[0])),
- hex->face(0)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(2,f_or[0],f_fl[0],f_ro[0])),
- hex->face(0)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[0],f_fl[0],f_ro[0])),
-
- hex->face(1)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[1],f_fl[1],f_ro[1])), //16
- hex->face(1)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(1,f_or[1],f_fl[1],f_ro[1])),
- hex->face(1)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(2,f_or[1],f_fl[1],f_ro[1])),
- hex->face(1)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[1],f_fl[1],f_ro[1])),
-
- hex->face(2)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[2],f_fl[2],f_ro[2])), //20
- hex->face(2)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(1,f_or[2],f_fl[2],f_ro[2])),
- hex->face(2)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(2,f_or[2],f_fl[2],f_ro[2])),
- hex->face(2)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[2],f_fl[2],f_ro[2])),
-
- hex->face(3)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[3],f_fl[3],f_ro[3])), //24
- hex->face(3)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(1,f_or[3],f_fl[3],f_ro[3])),
- hex->face(3)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(2,f_or[3],f_fl[3],f_ro[3])),
- hex->face(3)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[3],f_fl[3],f_ro[3])),
-
- hex->face(4)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[4],f_fl[4],f_ro[4])), //28
- hex->face(4)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(1,f_or[4],f_fl[4],f_ro[4])),
- hex->face(4)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(2,f_or[4],f_fl[4],f_ro[4])),
- hex->face(4)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[4],f_fl[4],f_ro[4])),
-
- hex->face(5)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[5],f_fl[5],f_ro[5])), //32
- hex->face(5)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(1,f_or[5],f_fl[5],f_ro[5])),
- hex->face(5)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(2,f_or[5],f_fl[5],f_ro[5])),
- hex->face(5)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[5],f_fl[5],f_ro[5]))
- };
- quad_indices=&quad_indices_xyz[0];
-
- // bottom children
- new_hexes[0]->set (internal::Triangulation
- ::TriaObject<3>(quad_indices[12],
- quad_indices[0],
- quad_indices[20],
- quad_indices[4],
- quad_indices[28],
- quad_indices[8]));
- new_hexes[1]->set (internal::Triangulation
- ::TriaObject<3>(quad_indices[0],
- quad_indices[16],
- quad_indices[22],
- quad_indices[6],
- quad_indices[29],
- quad_indices[9]));
- new_hexes[2]->set (internal::Triangulation
- ::TriaObject<3>(quad_indices[13],
- quad_indices[1],
- quad_indices[4],
- quad_indices[24],
- quad_indices[30],
- quad_indices[10]));
- new_hexes[3]->set (internal::Triangulation
- ::TriaObject<3>(quad_indices[1],
- quad_indices[17],
- quad_indices[6],
- quad_indices[26],
- quad_indices[31],
- quad_indices[11]));
-
- // top children
- new_hexes[4]->set (internal::Triangulation
- ::TriaObject<3>(quad_indices[14],
- quad_indices[2],
- quad_indices[21],
- quad_indices[5],
- quad_indices[8],
- quad_indices[32]));
- new_hexes[5]->set (internal::Triangulation
- ::TriaObject<3>(quad_indices[2],
- quad_indices[18],
- quad_indices[23],
- quad_indices[7],
- quad_indices[9],
- quad_indices[33]));
- new_hexes[6]->set (internal::Triangulation
- ::TriaObject<3>(quad_indices[15],
- quad_indices[3],
- quad_indices[5],
- quad_indices[25],
- quad_indices[10],
- quad_indices[34]));
- new_hexes[7]->set (internal::Triangulation
- ::TriaObject<3>(quad_indices[3],
- quad_indices[19],
- quad_indices[7],
- quad_indices[27],
- quad_indices[11],
- quad_indices[35]));
- break;
- }
- default:
- // all refinement cases
- // have been treated,
- // there only remains
- // RefinementCase<dim>::no_refinement
- // as untreated
- // enumeration
- // value. However, in
- // that case we should
- // have aborted much
- // earlier. thus we
- // should never get here
- Assert(false, ExcInternalError());
- break;
- }//switch (ref_case)
-
- // and set face orientation
- // flags. note that new faces in
- // the interior of the mother cell
- // always have a correctly oriented
- // face, but the ones on the outer
- // faces will inherit this flag
- //
- // the flag have been set to true
- // for all faces initially, now go
- // the other way round and reset
- // faces that are at the boundary
- // of the mother cube
- //
- // the same is true for the
- // face_flip and face_rotation
- // flags. however, the latter two
- // are set to false by default as
- // this is the standard value
-
- // loop over all faces and all
- // (relevant) subfaces of that in
- // order to set the correct values
- // for face_orientation, face_flip
- // and face_rotation, which are
- // inherited from the corresponding
- // face of the mother cube
- for (unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell; ++f)
- for (unsigned int s=0;
- s<std::max(GeometryInfo<dim-1>::n_children(GeometryInfo<dim>::face_refinement_case(ref_case,f)),
- 1U);
- ++s)
- {
- const unsigned int current_child
- =GeometryInfo<dim>::child_cell_on_face(ref_case,
- f,
- s,
- f_or[f],
- f_fl[f],
- f_ro[f],
- GeometryInfo<dim>::face_refinement_case(ref_case,
- f,
- f_or[f],
- f_fl[f],
- f_ro[f]));
- new_hexes[current_child]->set_face_orientation (f, f_or[f]);
- new_hexes[current_child]->set_face_flip (f, f_fl[f]);
- new_hexes[current_child]->set_face_rotation (f, f_ro[f]);
- }
-
- // now see if
- // we have
- // created
- // cells that
- // are
- // distorted
- // and if so
- // add them to
- // our list
- if ((check_for_distorted_cells == true)
- &&
- has_distorted_children (hex,
- internal::int2type<dim>(),
- internal::int2type<spacedim>()))
- cells_with_distorted_children.distorted_cells.push_back (hex);
-
- // note that the
- // refinement flag was
- // already cleared at the
- // beginning of this loop
- }
- }
-
- // clear user data on quads. we used some of
- // this data to indicate anisotropic
- // refinemnt cases on faces. all data should
- // be cleared by now, but the information
- // whether we used indices or pointers is
- // still present. reset it now to enable the
- // user to use whichever he likes later on.
- triangulation.faces->quads.clear_user_data();
-
- // return the list with distorted children
- return cells_with_distorted_children;
- }
-
-
- /**
- * At the boundary of the domain, the new
- * point on the face may be far inside the
- * current cell, if the boundary has a
- * strong curvature. If we allow anisotropic
- * refinement here, the resulting cell may
- * be strongly distorted. To prevent this,
- * this function flags such cells for
- * isotropic refinement. It is called
- * automatically from
- * prepare_coarsening_and_refinement().
- *
- * This function does nothing in
- * 1d (therefore the
- * specialization).
- */
- template <int spacedim>
- static
- void
- prevent_distorted_boundary_cells (const Triangulation<1,spacedim> &);
-
-
- template <int dim, int spacedim>
- static
- void
- prevent_distorted_boundary_cells (Triangulation<dim,spacedim> &triangulation)
- {
- // If the codimension is
- // one, we cannot perform
- // this check yet.
- if(spacedim>dim) return;
-
- for (typename Triangulation<dim,spacedim>::cell_iterator
- cell=triangulation.begin(); cell!=triangulation.end(); ++cell)
- if (cell->at_boundary() &&
- cell->refine_flag_set() &&
- cell->refine_flag_set()!=RefinementCase<dim>::isotropic_refinement)
- {
- // The cell is at the boundary
- // and it is flagged for
- // anisotropic
- // refinement. Therefore, we have
- // a closer look
- const RefinementCase<dim> ref_case=cell->refine_flag_set();
- for (unsigned int face_no=0;
- face_no<GeometryInfo<dim>::faces_per_cell;
- ++face_no)
- if (cell->face(face_no)->at_boundary())
- {
- // this is the critical
- // face at the boundary.
- if (GeometryInfo<dim>::face_refinement_case(ref_case,face_no)
- !=RefinementCase<dim-1>::isotropic_refinement)
- {
- // up to now, we do not
- // want to refine this
- // cell along the face
- // under consideration
- // here.
- const typename Triangulation<dim,spacedim>::face_iterator
- face = cell->face(face_no);
- // the new point on the
- // boundary would be
- // this one.
- const Point<spacedim> new_bound
- = triangulation.get_boundary(face->boundary_indicator())
- .get_new_point_on_face (face);
- // to check it,
- // transform to the
- // unit cell with
- // Q1Mapping
- const Point<dim> new_unit
- = StaticMappingQ1<dim,spacedim>::mapping.
- transform_real_to_unit_cell(cell,
- new_bound);
-
- // Now, we have to
- // calculate the
- // distance from the
- // face in the unit
- // cell.
-
- // take the correct
- // coordinate direction (0
- // for faces 0 and 1, 1 for
- // faces 2 and 3, 2 for faces
- // 4 and 5) and substract the
- // correct boundary value of
- // the face (0 for faces 0,
- // 2, and 4; 1 for faces 1, 3
- // and 5)
- const double dist = std::fabs(new_unit[face_no/2] - face_no%2);
- // compare this with
- // the empirical value
- // allowed. if it is
- // too big, flag the
- // face for isotropic
- // refinement
- const double allowed=0.25;
-
- if (dist>allowed)
- cell->flag_for_face_refinement(face_no);
- }//if flagged for anistropic refinement
- }//if (cell->face(face)->at_boundary())
- }//for all cells
- }
-
-
- /**
- * Some dimension dependent stuff for
- * mesh smoothing.
- *
- * At present, this function does nothing
- * in 1d and 2D, but makes sure no two
- * cells with a level difference greater
- * than one share one line in 3D. This
- * is a requirement needed for the
- * interpolation of hanging nodes, since
- * otherwise to steps of interpolation
- * would be necessary. This would make
- * the processes implemented in the
- * @p ConstraintMatrix class much more
- * complex, since these two steps of
- * interpolation do not commute.
- */
- template <int dim, int spacedim>
- static
- void
- prepare_refinement_dim_dependent (const Triangulation<dim,spacedim> &)
- {
- Assert (dim < 3,
- ExcMessage ("Wrong function called -- there should "
- "be a specialization."));
- }
-
-
- template <int spacedim>
- static
- void
- prepare_refinement_dim_dependent (Triangulation<3,spacedim> &triangulation)
- {
- const unsigned int dim = 3;
-
- // first clear flags on lines,
- // since we need them to determine
- // which lines will be refined
- triangulation.clear_user_flags_line();
-
- // also clear flags on hexes, since we need
- // them to mark those cells which are to be
- // coarsened
- triangulation.clear_user_flags_hex();
-
- // variable to store whether the
- // mesh was changed in the present
- // loop and in the whole process
- bool mesh_changed = false;
-
- do
- {
- mesh_changed = false;
-
- // for this following, we need to know
- // which cells are going to be
- // coarsened, if we had to make a
- // decision. the following function
- // sets these flags:
- triangulation.fix_coarsen_flags ();
-
-
- // flag those lines that are refined and
- // will not be coarsened and those that
- // will be refined
- for (typename Triangulation<dim,spacedim>::cell_iterator
- cell=triangulation.begin(); cell!=triangulation.end(); ++cell)
- if (cell->refine_flag_set())
- {
- for (unsigned int line=0; line<GeometryInfo<dim>::lines_per_cell; ++line)
- if (GeometryInfo<dim>::line_refinement_case(cell->refine_flag_set(), line)
- ==RefinementCase<1>::cut_x)
- // flag a line, that will be
- // refined
- cell->line(line)->set_user_flag();
- }
- else if(cell->has_children() && !cell->child(0)->coarsen_flag_set())
- {
- for (unsigned int line=0; line<GeometryInfo<dim>::lines_per_cell; ++line)
- if (GeometryInfo<dim>::line_refinement_case(cell->refinement_case(), line)
- ==RefinementCase<1>::cut_x)
- // flag a line, that is refined
- // and will stay so
- cell->line(line)->set_user_flag();
- }
- else if(cell->has_children() && cell->child(0)->coarsen_flag_set())
- cell->set_user_flag();
-
-
- // now check whether there are
- // cells with lines that are
- // more than once refined or
- // that will be more than once
- // refined. The first thing
- // should never be the case, in
- // the second case we flag the
- // cell for refinement
- for (typename Triangulation<dim,spacedim>::active_cell_iterator
- cell=triangulation.last_active(); cell!=triangulation.end(); --cell)
- for (unsigned int line=0; line<GeometryInfo<dim>::lines_per_cell; ++line)
- {
- if (cell->line(line)->has_children())
- {
- // if this line is
- // refined, its
- // children should
- // not have further
- // children
- //
- // however, if any of
- // the children is
- // flagged for
- // further
- // refinement, we
- // need to refine
- // this cell also (at
- // least, if the cell
- // is not already
- // flagged)
- bool offending_line_found = false;
-
- for (unsigned int c=0; c<2; ++c)
- {
- Assert (cell->line(line)->child(c)->has_children() == false,
- ExcInternalError());
-
- if (cell->line(line)->child(c)->user_flag_set () &&
- (GeometryInfo<dim>::line_refinement_case(cell->refine_flag_set(),
- line)
- ==RefinementCase<1>::no_refinement))
- {
- // tag this
- // cell for
- // refinement
- cell->clear_coarsen_flag ();
- // if anisotropic
- // coarsening is
- // allowed: extend the
- // refine_flag in the
- // needed direction,
- // else set refine_flag
- // (isotropic)
- if (triangulation.smooth_grid &
- Triangulation<dim,spacedim>::allow_anisotropic_smoothing)
- cell->flag_for_line_refinement(line);
- else
- cell->set_refine_flag();
-
- for (unsigned int l=0; l<GeometryInfo<dim>::lines_per_cell; ++l)
- if (GeometryInfo<dim>::line_refinement_case(cell->refine_flag_set(), line)
- ==RefinementCase<1>::cut_x)
- // flag a line,
- // that will be
- // refined
- cell->line(l)->set_user_flag();
- // note that
- // we have
- // changed
- // the grid
- offending_line_found = true;
-
- // it may save us several
- // loop iterations if we
- // flag all lines of
- // this cell now (and not
- // at the outset of the
- // next iteration) for
- // refinement
- for (unsigned int line=0;
- line<GeometryInfo<dim>::lines_per_cell; ++line)
- if (!cell->line(line)->has_children() &&
- (GeometryInfo<dim>::line_refinement_case(cell->refine_flag_set(),
- line)
- !=RefinementCase<1>::no_refinement))
- cell->line(line)->set_user_flag();
-
- break;
- }
- }
-
- if (offending_line_found)
- {
- mesh_changed = true;
- break;
- }
- }
- }
-
-
- // there is another thing here:
- // if any of the lines will be
- // refined, then we may not
- // coarsen the present cell
- // similarly, if any of the lines
- // *is* already refined, we may
- // not coarsen the current
- // cell. however, there's a
- // catch: if the line is refined,
- // but the cell behind it is
- // going to be coarsened, then
- // the situation changes. if we
- // forget this second condition,
- // the refine_and_coarsen_3d test
- // will start to fail. note that
- // to know which cells are going
- // to be coarsened, the call for
- // fix_coarsen_flags above is
- // necessary
- for (typename Triangulation<dim,spacedim>::cell_iterator
- cell=triangulation.last(); cell!=triangulation.end(); --cell)
- {
- if (cell->user_flag_set())
- for (unsigned int line=0; line<GeometryInfo<dim>::lines_per_cell; ++line)
- if (cell->line(line)->has_children() &&
- (cell->line(line)->child(0)->user_flag_set() ||
- cell->line(line)->child(1)->user_flag_set()))
- {
- for (unsigned int c=0; c<cell->n_children(); ++c)
- cell->child(c)->clear_coarsen_flag ();
- cell->clear_user_flag();
- for (unsigned int l=0; l<GeometryInfo<dim>::lines_per_cell; ++l)
- if (GeometryInfo<dim>::line_refinement_case(cell->refinement_case(), l)
- ==RefinementCase<1>::cut_x)
- // flag a line, that is refined
- // and will stay so
- cell->line(l)->set_user_flag();
- mesh_changed = true;
- break;
- }
- }
- }
- while (mesh_changed == true);
- }
-
-
-
- /**
- * Helper function for
- * @p fix_coarsen_flags. Return wether
- * coarsening of this cell is allowed.
- * Coarsening can be forbidden if the
- * neighboring cells are or will be
- * refined twice along the common face.
- */
- template <int dim, int spacedim>
- static
- bool
- coarsening_allowed (const typename Triangulation<dim,spacedim>::cell_iterator& cell)
- {
- // in 1d, coarsening is
- // always allowed since we
- // don't enforce the 2:1
- // constraint there
- if (dim == 1)
- return true;
-
- const RefinementCase<dim> ref_case = cell->refinement_case();
- for (unsigned int n=0; n<GeometryInfo<dim>::faces_per_cell; ++n)
- {
- // if the cell is not refined
- // along that face, coarsening
- // will not change anything, so
- // do nothing. the same applies,
- // if the face is at the boandary
- const RefinementCase<dim-1> face_ref_case =
- GeometryInfo<dim>::face_refinement_case(cell->refinement_case(), n);
-
- const unsigned int n_subfaces
- = GeometryInfo<dim-1>::n_children(face_ref_case);
-
- if (n_subfaces == 0 || cell->at_boundary(n))
- continue;
- for (unsigned int c=0; c<n_subfaces; ++c)
- {
- const typename Triangulation<dim,spacedim>::cell_iterator
- child = cell->child(GeometryInfo<dim>::
- child_cell_on_face(ref_case,
- n,c));
-
- const typename Triangulation<dim,spacedim>::cell_iterator
- child_neighbor = child->neighbor(n);
- if (!child->neighbor_is_coarser(n))
- // in 2d, if the child's neighbor
- // is coarser, then it has no
- // children. however, in 3d it
- // might be otherwise. consider
- // for example, that our face
- // might be refined with cut_x,
- // but the neighbor is refined
- // with cut_xy at that face. then
- // the neighbor pointers of the
- // children of our cell will point
- // to the common neighbor cell,
- // not to its children. what we
- // really want to know in the
- // following is, wether the
- // neighbor cell is refined twice
- // with reference to our cell.
- // that only has to be asked, if
- // the child's neighbor is not a
- // coarser one.
- if ((child_neighbor->has_children() &&
- !child_neighbor->user_flag_set())||
- // neighbor has children, which
- // are further refined along
- // the face, otherwise
- // something went wrong in the
- // contruction of neighbor
- // pointers. then only allow
- // coarsening if this neighbor
- // will be coarsened as well
- // (user_pointer is set). the
- // same applies, if the
- // neighbors children are not
- // refined but will be after
- // refinement
- child_neighbor->refine_flag_set())
- return false;
- }
- }
- return true;
- }
+ ///////////////////////////////////////////
+ // Do refinement on every level
+ //
+ // To make life a bit easier, we
+ // first refine those lines and
+ // quads that were flagged for
+ // refinement and then compose the
+ // newly to be created cells.
+ //
+ // index of next unused vertex
+ unsigned int next_unused_vertex = 0;
+
+ // first for lines
+ if (true)
+ {
+ // only active objects can be
+ // refined further
+ typename Triangulation<dim,spacedim>::active_line_iterator
+ line = triangulation.begin_active_line(),
+ endl = triangulation.end_line();
+ typename Triangulation<dim,spacedim>::raw_line_iterator
+ next_unused_line = triangulation.begin_raw_line ();
+
+ for (; line!=endl; ++line)
+ if (line->user_flag_set())
+ {
+ // this line needs to be
+ // refined
+
+ // find the next unused
+ // vertex and set it
+ // appropriately
+ while (triangulation.vertices_used[next_unused_vertex] == true)
+ ++next_unused_vertex;
+ Assert (next_unused_vertex < triangulation.vertices.size(),
+ ExcTooFewVerticesAllocated());
+ triangulation.vertices_used[next_unused_vertex] = true;
+
+ if (line->at_boundary())
+ triangulation.vertices[next_unused_vertex]
+ = triangulation.get_boundary(line->boundary_indicator()).get_new_point_on_line (line);
+ else
+ triangulation.vertices[next_unused_vertex]
+ = (line->vertex(0) + line->vertex(1)) / 2;
+
+ // now that we created
+ // the right point, make
+ // up the two child lines
+ // (++ takes care of the
+ // end of the vector)
+ next_unused_line=triangulation.faces->lines.next_free_pair_line(triangulation);
+ Assert(next_unused_line.state() == IteratorState::valid,
+ ExcInternalError());
+
+ // now we found
+ // two consecutive unused
+ // lines, such that the
+ // children of a line
+ // will be consecutive.
+ // then set the child
+ // pointer of the present
+ // line
+ line->set_children (0, next_unused_line->index());
+
+ // set the two new lines
+ const typename Triangulation<dim,spacedim>::raw_line_iterator
+ children[2] = { next_unused_line,
+ ++next_unused_line };
+
+ // some tests; if any of
+ // the iterators should
+ // be invalid, then
+ // already dereferencing
+ // will fail
+ Assert (children[0]->used() == false, ExcCellShouldBeUnused());
+ Assert (children[1]->used() == false, ExcCellShouldBeUnused());
+
+ children[0]->set (internal::Triangulation
+ ::TriaObject<1>(line->vertex_index(0),
+ next_unused_vertex));
+ children[1]->set (internal::Triangulation
+ ::TriaObject<1>(next_unused_vertex,
+ line->vertex_index(1)));
+
+ children[0]->set_used_flag();
+ children[1]->set_used_flag();
+ children[0]->clear_children();
+ children[1]->clear_children();
+ children[0]->clear_user_data();
+ children[1]->clear_user_data();
+ children[0]->clear_user_flag();
+ children[1]->clear_user_flag();
+
+ children[0]->set_boundary_indicator (line->boundary_indicator());
+ children[1]->set_boundary_indicator (line->boundary_indicator());
+
+ // finally clear flag
+ // indicating the need
+ // for refinement
+ line->clear_user_flag ();
+ }
+ }
+
+
+ ///////////////////////////////////////
+ // now refine marked quads
+ ///////////////////////////////////////
+
+ // here we encounter several cases:
+
+ // a) the quad is unrefined and shall be
+ // refined isotropically
+
+ // b) the quad is unrefined and shall be
+ // refined anisotropically
+
+ // c) the quad is unrefined and shall be
+ // refined both anisotropically and
+ // isotropically (this is reduced to case b)
+ // and then case b) for the children again)
+
+ // d) the quad is refined anisotropically and
+ // shall be refined isotropically (this is
+ // reduced to case b) for the anisotropic
+ // children)
+
+ // e) the quad is refined isotropically and
+ // shall be refined anisotropically (this is
+ // transformed to case c), however we might
+ // have to renumber/rename children...)
+
+ // we need a loop in cases c) and d), as the
+ // anisotropic children migt have a lower
+ // index than the mother quad
+ for (unsigned int loop=0; loop<2; ++loop)
+ {
+ // usually, only active objects can be
+ // refined further. however, in cases d)
+ // and e) that is not true, so we have to
+ // use 'normal' iterators here
+ typename Triangulation<dim,spacedim>::quad_iterator
+ quad = triangulation.begin_quad(),
+ endq = triangulation.end_quad();
+ typename Triangulation<dim,spacedim>::raw_line_iterator
+ next_unused_line = triangulation.begin_raw_line ();
+ typename Triangulation<dim,spacedim>::raw_quad_iterator
+ next_unused_quad = triangulation.begin_raw_quad ();
+
+ for (; quad!=endq; ++quad)
+ {
+ if (quad->user_index())
+ {
+ RefinementCase<dim-1> aniso_quad_ref_case=face_refinement_cases[quad->user_index()];
+ // there is one unlikely event
+ // here, where we already have
+ // refind the face: if the face
+ // was refined anisotropically
+ // and we want to refine it
+ // isotropically, both children
+ // are flagged for anisotropic
+ // refinement. however, if those
+ // children were already flagged
+ // for anisotropic refinement,
+ // they might already be
+ // processed and refined.
+ if (aniso_quad_ref_case == quad->refinement_case())
+ continue;
+
+ Assert(quad->refinement_case()==RefinementCase<dim-1>::cut_xy ||
+ quad->refinement_case()==RefinementCase<dim-1>::no_refinement,
+ ExcInternalError());
+
+ // this quad needs to be refined
+ // anisotropically
+ Assert(quad->user_index() == RefinementCase<dim-1>::cut_x ||
+ quad->user_index() == RefinementCase<dim-1>::cut_y,
+ ExcInternalError());
+
+ // make the new line interior to
+ // the quad
+ typename Triangulation<dim,spacedim>::raw_line_iterator new_line;
+
+ new_line=triangulation.faces->lines.next_free_single_line(triangulation);
+ Assert (new_line->used() == false,
+ ExcCellShouldBeUnused());
+
+ // first collect the
+ // indices of the vertices:
+ // *--1--*
+ // | | |
+ // | | | cut_x
+ // | | |
+ // *--0--*
+ //
+ // *-----*
+ // | |
+ // 0-----1 cut_y
+ // | |
+ // *-----*
+ unsigned int vertex_indices[2];
+ if (aniso_quad_ref_case==RefinementCase<dim-1>::cut_x)
+ {
+ vertex_indices[0]=quad->line(2)->child(0)->vertex_index(1);
+ vertex_indices[1]=quad->line(3)->child(0)->vertex_index(1);
+ }
+ else
+ {
+ vertex_indices[0]=quad->line(0)->child(0)->vertex_index(1);
+ vertex_indices[1]=quad->line(1)->child(0)->vertex_index(1);
+ }
+
+ new_line->set (internal::Triangulation::
+ TriaObject<1>(vertex_indices[0], vertex_indices[1]));
+ new_line->set_used_flag();
+ new_line->clear_user_flag();
+ new_line->clear_user_data();
+ new_line->clear_children();
+ new_line->set_boundary_indicator(quad->boundary_indicator());
+
+ // child 0 and 1 of a line are
+ // switched if the line
+ // orientation is false. set up a
+ // miniature table, indicating
+ // which child to take for line
+ // orientations false and
+ // true. first index: child index
+ // in standard orientation,
+ // second index: line orientation
+ const unsigned int index[2][2]=
+ {{1,0}, // child 0, line_orientation=false and true
+ {0,1}}; // child 1, line_orientation=false and true
+
+ // find some space (consecutive)
+ // for the two newly to be
+ // created quads.
+ typename Triangulation<dim,spacedim>::raw_quad_iterator new_quads[2];
+
+ next_unused_quad=triangulation.faces->quads.next_free_pair_quad(triangulation);
+ new_quads[0] = next_unused_quad;
+ Assert (new_quads[0]->used() == false, ExcCellShouldBeUnused());
+
+ ++next_unused_quad;
+ new_quads[1] = next_unused_quad;
+ Assert (new_quads[1]->used() == false, ExcCellShouldBeUnused());
+
+
+ if (aniso_quad_ref_case==RefinementCase<dim-1>::cut_x)
+ {
+ new_quads[0]->set (internal::Triangulation
+ ::TriaObject<2>(quad->line_index(0),
+ new_line->index(),
+ quad->line(2)->child(index[0][quad->line_orientation(2)])->index(),
+ quad->line(3)->child(index[0][quad->line_orientation(3)])->index()));
+ new_quads[1]->set (internal::Triangulation
+ ::TriaObject<2>(new_line->index(),
+ quad->line_index(1),
+ quad->line(2)->child(index[1][quad->line_orientation(2)])->index(),
+ quad->line(3)->child(index[1][quad->line_orientation(3)])->index()));
+ }
+ else
+ {
+ new_quads[0]->set (internal::Triangulation
+ ::TriaObject<2>(quad->line(0)->child(index[0][quad->line_orientation(0)])->index(),
+ quad->line(1)->child(index[0][quad->line_orientation(1)])->index(),
+ quad->line_index(2),
+ new_line->index()));
+ new_quads[1]->set (internal::Triangulation
+ ::TriaObject<2>(quad->line(0)->child(index[1][quad->line_orientation(0)])->index(),
+ quad->line(1)->child(index[1][quad->line_orientation(1)])->index(),
+ new_line->index(),
+ quad->line_index(3)));
+ }
+
+ for (unsigned int i=0; i<2; ++i)
+ {
+ new_quads[i]->set_used_flag();
+ new_quads[i]->clear_user_flag();
+ new_quads[i]->clear_user_data();
+ new_quads[i]->clear_children();
+ new_quads[i]->set_boundary_indicator (quad->boundary_indicator());
+ // set all line orientations to
+ // true, change this after the
+ // loop, as we have to consider
+ // different lines for each
+ // child
+ for (unsigned int j=0; j<GeometryInfo<dim>::lines_per_face; ++j)
+ new_quads[i]->set_line_orientation(j,true);
+ }
+ // now set the line orientation of
+ // children of outer lines
+ // correctly, the lines in the
+ // interior of the refined quad are
+ // automatically oriented
+ // conforming to the standard
+ new_quads[0]->set_line_orientation(0,quad->line_orientation(0));
+ new_quads[0]->set_line_orientation(2,quad->line_orientation(2));
+ new_quads[1]->set_line_orientation(1,quad->line_orientation(1));
+ new_quads[1]->set_line_orientation(3,quad->line_orientation(3));
+ if (aniso_quad_ref_case==RefinementCase<dim-1>::cut_x)
+ {
+ new_quads[0]->set_line_orientation(3,quad->line_orientation(3));
+ new_quads[1]->set_line_orientation(2,quad->line_orientation(2));
+ }
+ else
+ {
+ new_quads[0]->set_line_orientation(1,quad->line_orientation(1));
+ new_quads[1]->set_line_orientation(0,quad->line_orientation(0));
+ }
+
+ // test, whether this face is
+ // refined isotropically
+ // already. if so, set the
+ // correct children pointers.
+ if (quad->refinement_case()==RefinementCase<dim-1>::cut_xy)
+ {
+ // we will put a new
+ // refinemnt level of
+ // anisotropic refinement
+ // between the unrefined and
+ // isotropically refined quad
+ // ending up with the same
+ // fine quads but introducing
+ // anisotropically refined
+ // ones as children of the
+ // unrefined quad and mother
+ // cells of the original fine
+ // ones.
+
+ // this process includes the
+ // creation of a new middle
+ // line which we will assign
+ // as the mother line of two
+ // of the existing inner
+ // lines. If those inner
+ // lines are not consecutive
+ // in memory, we won't find
+ // them later on, so we have
+ // to create new ones instead
+ // and replace all occurances
+ // of the old ones with those
+ // new ones. As this is kind
+ // of ugly, we hope we don't
+ // have to do it often...
+ typename Triangulation<dim,spacedim>::line_iterator old_child[2];
+ if (aniso_quad_ref_case==RefinementCase<dim-1>::cut_x)
+ {
+ old_child[0]=quad->child(0)->line(1);
+ old_child[1]=quad->child(2)->line(1);
+ }
+ else
+ {
+ Assert(aniso_quad_ref_case==RefinementCase<dim-1>::cut_y, ExcInternalError());
+
+ old_child[0]=quad->child(0)->line(3);
+ old_child[1]=quad->child(1)->line(3);
+ }
+
+ if (old_child[0]->index()+1 != old_child[1]->index())
+ {
+ // this is exactly the
+ // ugly case we taked
+ // about. so, no
+ // coimplaining, lets get
+ // two new lines and copy
+ // all info
+ typename Triangulation<dim,spacedim>::raw_line_iterator new_child[2];
+
+ new_child[0]=new_child[1]=triangulation.faces->lines.next_free_pair_line(triangulation);
+ ++new_child[1];
+
+ new_child[0]->set_used_flag();
+ new_child[1]->set_used_flag();
+
+ const int old_index_0=old_child[0]->index(),
+ old_index_1=old_child[1]->index(),
+ new_index_0=new_child[0]->index(),
+ new_index_1=new_child[1]->index();
+
+ // loop over all quads
+ // and replace the old
+ // lines
+ for (unsigned int q=0; q<triangulation.faces->quads.cells.size(); ++q)
+ for (unsigned int l=0; l<GeometryInfo<dim>::lines_per_face; ++l)
+ {
+ const int index=triangulation.faces->quads.cells[q].face(l);
+ if (index==old_index_0)
+ triangulation.faces->quads.cells[q].set_face(l,new_index_0);
+ else if (index==old_index_1)
+ triangulation.faces->quads.cells[q].set_face(l,new_index_1);
+ }
+ // now we have to copy
+ // all information of the
+ // two lines
+ for (unsigned int i=0; i<2; ++i)
+ {
+ Assert(!old_child[i]->has_children(), ExcInternalError());
+
+ new_child[i]->set(internal::Triangulation::TriaObject<1>(old_child[i]->vertex_index(0),
+ old_child[i]->vertex_index(1)));
+ new_child[i]->set_boundary_indicator(old_child[i]->boundary_indicator());
+ new_child[i]->set_user_index(old_child[i]->user_index());
+ if (old_child[i]->user_flag_set())
+ new_child[i]->set_user_flag();
+ else
+ new_child[i]->clear_user_flag();
+
+ new_child[i]->clear_children();
+
+ old_child[i]->clear_user_flag();
+ old_child[i]->clear_user_index();
+ old_child[i]->clear_used_flag();
+ }
+ }
+ // now that we cared
+ // about the lines, go on
+ // with the quads
+ // themselves, where we
+ // might encounter
+ // similar situations...
+ if (aniso_quad_ref_case==RefinementCase<dim-1>::cut_x)
+ {
+ new_line->set_children(0, quad->child(0)->line_index(1));
+ Assert(new_line->child(1)==quad->child(2)->line(1),
+ ExcInternalError());
+ // now evereything is
+ // quite complicated. we
+ // have the children
+ // numbered according to
+ //
+ // *---*---*
+ // |n+2|n+3|
+ // *---*---*
+ // | n |n+1|
+ // *---*---*
+ //
+ // from the original
+ // isotropic
+ // refinement. we have to
+ // reorder them as
+ //
+ // *---*---*
+ // |n+1|n+3|
+ // *---*---*
+ // | n |n+2|
+ // *---*---*
+ //
+ // such that n and n+1
+ // are consecutive
+ // children of m and n+2
+ // and n+3 are
+ // consecutive children
+ // of m+1, where m and
+ // m+1 are given as in
+ //
+ // *---*---*
+ // | | |
+ // | m |m+1|
+ // | | |
+ // *---*---*
+ //
+ // this is a bit ugly, of
+ // course: loop over all
+ // cells on all levels
+ // and look for faces n+1
+ // (switch_1) and n+2
+ // (switch_2).
+ const typename Triangulation<dim,spacedim>::quad_iterator
+ switch_1=quad->child(1),
+ switch_2=quad->child(2);
+ const int switch_1_index=switch_1->index();
+ const int switch_2_index=switch_2->index();
+ for (unsigned int l=0; l<triangulation.levels.size(); ++l)
+ for (unsigned int h=0; h<triangulation.levels[l]->cells.cells.size(); ++h)
+ for (unsigned int q=0; q<GeometryInfo<dim>::faces_per_cell; ++q)
+ {
+ const int index=triangulation.levels[l]->cells.cells[h].face(q);
+ if (index==switch_1_index)
+ triangulation.levels[l]->cells.cells[h].set_face(q,switch_2_index);
+ else if (index==switch_2_index)
+ triangulation.levels[l]->cells.cells[h].set_face(q,switch_1_index);
+ }
+ // now we have to copy
+ // all information of the
+ // two quads
+ const int switch_1_lines[4]=
+ {switch_1->line_index(0),
+ switch_1->line_index(1),
+ switch_1->line_index(2),
+ switch_1->line_index(3)};
+ const bool switch_1_line_orientations[4]=
+ {switch_1->line_orientation(0),
+ switch_1->line_orientation(1),
+ switch_1->line_orientation(2),
+ switch_1->line_orientation(3)};
+ const types::boundary_id_t switch_1_boundary_indicator=switch_1->boundary_indicator();
+ const unsigned int switch_1_user_index=switch_1->user_index();
+ const bool switch_1_user_flag=switch_1->user_flag_set();
+ const RefinementCase<dim-1> switch_1_refinement_case=switch_1->refinement_case();
+ const int switch_1_first_child_pair=(switch_1_refinement_case ? switch_1->child_index(0) : -1);
+ const int switch_1_second_child_pair=(switch_1_refinement_case==RefinementCase<dim-1>::cut_xy ? switch_1->child_index(2) : -1);
+
+ switch_1->set(internal::Triangulation::TriaObject<2>(switch_2->line_index(0),
+ switch_2->line_index(1),
+ switch_2->line_index(2),
+ switch_2->line_index(3)));
+ switch_1->set_line_orientation(0, switch_2->line_orientation(0));
+ switch_1->set_line_orientation(1, switch_2->line_orientation(1));
+ switch_1->set_line_orientation(2, switch_2->line_orientation(2));
+ switch_1->set_line_orientation(3, switch_2->line_orientation(3));
+ switch_1->set_boundary_indicator(switch_2->boundary_indicator());
+ switch_1->set_user_index(switch_2->user_index());
+ if (switch_2->user_flag_set())
+ switch_1->set_user_flag();
+ else
+ switch_1->clear_user_flag();
+ switch_1->clear_refinement_case();
+ switch_1->set_refinement_case(switch_2->refinement_case());
+ switch_1->clear_children();
+ if (switch_2->refinement_case())
+ switch_1->set_children(0, switch_2->child_index(0));
+ if (switch_2->refinement_case()==RefinementCase<dim-1>::cut_xy)
+ switch_1->set_children(2, switch_2->child_index(2));
+
+ switch_2->set(internal::Triangulation::TriaObject<2>(switch_1_lines[0],
+ switch_1_lines[1],
+ switch_1_lines[2],
+ switch_1_lines[3]));
+ switch_2->set_line_orientation(0, switch_1_line_orientations[0]);
+ switch_2->set_line_orientation(1, switch_1_line_orientations[1]);
+ switch_2->set_line_orientation(2, switch_1_line_orientations[2]);
+ switch_2->set_line_orientation(3, switch_1_line_orientations[3]);
+ switch_2->set_boundary_indicator(switch_1_boundary_indicator);
+ switch_2->set_user_index(switch_1_user_index);
+ if (switch_1_user_flag)
+ switch_2->set_user_flag();
+ else
+ switch_2->clear_user_flag();
+ switch_2->clear_refinement_case();
+ switch_2->set_refinement_case(switch_1_refinement_case);
+ switch_2->clear_children();
+ switch_2->set_children(0, switch_1_first_child_pair);
+ switch_2->set_children(2, switch_1_second_child_pair);
+
+ new_quads[0]->set_refinement_case(RefinementCase<2>::cut_y);
+ new_quads[0]->set_children(0, quad->child_index(0));
+ new_quads[1]->set_refinement_case(RefinementCase<2>::cut_y);
+ new_quads[1]->set_children(0, quad->child_index(2));
+ }
+ else
+ {
+ new_quads[0]->set_refinement_case(RefinementCase<2>::cut_x);
+ new_quads[0]->set_children(0, quad->child_index(0));
+ new_quads[1]->set_refinement_case(RefinementCase<2>::cut_x);
+ new_quads[1]->set_children(0, quad->child_index(2));
+ new_line->set_children(0, quad->child(0)->line_index(3));
+ Assert(new_line->child(1)==quad->child(1)->line(3),
+ ExcInternalError());
+ }
+ quad->clear_children();
+ }
+
+ // note these quads as children
+ // to the present one
+ quad->set_children (0, new_quads[0]->index());
+
+ quad->set_refinement_case(aniso_quad_ref_case);
+
+ // finally clear flag
+ // indicating the need
+ // for refinement
+ quad->clear_user_data ();
+ } // if (anisotropic refinement)
+
+ if (quad->user_flag_set())
+ {
+ // this quad needs to be
+ // refined isotropically
+
+ // first of all: we only get here
+ // in the first run of the loop
+ Assert(loop==0,ExcInternalError());
+
+ // find the next unused
+ // vertex. we'll need this in any
+ // case
+ while (triangulation.vertices_used[next_unused_vertex] == true)
+ ++next_unused_vertex;
+ Assert (next_unused_vertex < triangulation.vertices.size(),
+ ExcTooFewVerticesAllocated());
+
+ // now: if the quad is refined
+ // anisotropically already, set
+ // the anisotropic refinement
+ // flag for both
+ // children. Additionally, we
+ // have to refine the inner line,
+ // as it is an outer line of the
+ // two (anisotropic) children
+ const RefinementCase<dim-1> quad_ref_case=quad->refinement_case();
+
+ if (quad_ref_case==RefinementCase<dim-1>::cut_x ||
+ quad_ref_case==RefinementCase<dim-1>::cut_y)
+ {
+ // set the 'opposite' refine case for children
+ quad->child(0)->set_user_index(RefinementCase<dim-1>::cut_xy-quad_ref_case);
+ quad->child(1)->set_user_index(RefinementCase<dim-1>::cut_xy-quad_ref_case);
+ // refine the inner line
+ typename Triangulation<dim,spacedim>::line_iterator middle_line;
+ if (quad_ref_case==RefinementCase<dim-1>::cut_x)
+ middle_line=quad->child(0)->line(1);
+ else
+ middle_line=quad->child(0)->line(3);
+
+ // if the face has been
+ // refined anisotropically in
+ // the last refinement step
+ // it might be, that it is
+ // flagged already and that
+ // the middle line is thus
+ // refined already. if not
+ // create children.
+ if (!middle_line->has_children())
+ {
+ // set the middle vertex
+ // appropriately. double
+ // refinement of quads can only
+ // happen in the interior of
+ // the domain, so we need not
+ // care about boundary quads
+ // here
+ triangulation.vertices[next_unused_vertex]
+ = (middle_line->vertex(0) + middle_line->vertex(1)) / 2;
+ triangulation.vertices_used[next_unused_vertex] = true;
+
+ // now search a slot for the two
+ // child lines
+ next_unused_line=triangulation.faces->lines.next_free_pair_line(triangulation);
+
+ // set the child
+ // pointer of the present
+ // line
+ middle_line->set_children (0, next_unused_line->index());
+
+ // set the two new lines
+ const typename Triangulation<dim,spacedim>::raw_line_iterator
+ children[2] = { next_unused_line,
+ ++next_unused_line };
+
+ // some tests; if any of
+ // the iterators should
+ // be invalid, then
+ // already dereferencing
+ // will fail
+ Assert (children[0]->used() == false, ExcCellShouldBeUnused());
+ Assert (children[1]->used() == false, ExcCellShouldBeUnused());
+
+ children[0]->set (internal::Triangulation::
+ TriaObject<1>(middle_line->vertex_index(0),
+ next_unused_vertex));
+ children[1]->set (internal::Triangulation::
+ TriaObject<1>(next_unused_vertex,
+ middle_line->vertex_index(1)));
+
+ children[0]->set_used_flag();
+ children[1]->set_used_flag();
+ children[0]->clear_children();
+ children[1]->clear_children();
+ children[0]->clear_user_data();
+ children[1]->clear_user_data();
+ children[0]->clear_user_flag();
+ children[1]->clear_user_flag();
+
+ children[0]->set_boundary_indicator (middle_line->boundary_indicator());
+ children[1]->set_boundary_indicator (middle_line->boundary_indicator());
+ }
+ // now remove the flag from the
+ // quad and go to the next
+ // quad, the actual refinement
+ // of the quad takes place
+ // later on in this pass of the
+ // loop or in the next one
+ quad->clear_user_flag();
+ continue;
+ } // if (several refinement cases)
+
+ // if we got here, we have an
+ // unrefined quad and have to do
+ // the usual work like in an purely
+ // isotropic refinement
+ Assert(quad_ref_case==RefinementCase<dim-1>::no_refinement, ExcInternalError());
+
+ // set the middle vertex
+ // appropriately
+ if (quad->at_boundary())
+ triangulation.vertices[next_unused_vertex]
+ = triangulation.get_boundary(quad->boundary_indicator()).get_new_point_on_quad (quad);
+ else
+ // it might be that the
+ // quad itself is not
+ // at the boundary, but
+ // that one of its lines
+ // actually is. in this
+ // case, the newly
+ // created vertices at
+ // the centers of the
+ // lines are not
+ // necessarily the mean
+ // values of the
+ // adjacent vertices,
+ // so do not compute
+ // the new vertex as
+ // the mean value of
+ // the 4 vertices of
+ // the face, but rather
+ // as a weighted mean
+ // value of the 8
+ // vertices which we
+ // already have (the
+ // four old ones, and
+ // the four ones
+ // inserted as middle
+ // points for the four
+ // lines). summing up
+ // some more points is
+ // generally cheaper
+ // than first asking
+ // whether one of the
+ // lines is at the
+ // boundary
+ //
+ // note that the exact
+ // weights are chosen
+ // such as to minimize
+ // the distortion of
+ // the four new quads
+ // from the optimal
+ // shape; their
+ // derivation and
+ // values is copied
+ // over from the
+ // @p{MappingQ::set_laplace_on_vector}
+ // function
+ triangulation.vertices[next_unused_vertex]
+ = (quad->vertex(0) + quad->vertex(1) +
+ quad->vertex(2) + quad->vertex(3) +
+ 3*(quad->line(0)->child(0)->vertex(1) +
+ quad->line(1)->child(0)->vertex(1) +
+ quad->line(2)->child(0)->vertex(1) +
+ quad->line(3)->child(0)->vertex(1)) ) / 16;
+
+ triangulation.vertices_used[next_unused_vertex] = true;
+
+ // now that we created
+ // the right point, make
+ // up the four lines
+ // interior to the quad
+ // (++ takes care of the
+ // end of the vector)
+ typename Triangulation<dim,spacedim>::raw_line_iterator new_lines[4];
+
+ for (unsigned int i=0; i<4; ++i)
+ {
+ if (i%2==0)
+ // search a free pair of
+ // lines for 0. and 2. line,
+ // so that two of them end up
+ // together, which is
+ // necessary if later on we
+ // want to refine the quad
+ // anisotropically and the
+ // two lines end up as
+ // children of new line
+ next_unused_line=triangulation.faces->lines.next_free_pair_line(triangulation);
+
+ new_lines[i] = next_unused_line;
+ ++next_unused_line;
+
+ Assert (new_lines[i]->used() == false,
+ ExcCellShouldBeUnused());
+ }
+
+ // set the data of the
+ // four lines.
+ // first collect the
+ // indices of the five
+ // vertices:
+ // *--3--*
+ // | | |
+ // 0--4--1
+ // | | |
+ // *--2--*
+ // the lines are numbered
+ // as follows:
+ // *--*--*
+ // | 1 |
+ // *2-*-3*
+ // | 0 |
+ // *--*--*
+
+ const unsigned int vertex_indices[5]
+ = { quad->line(0)->child(0)->vertex_index(1),
+ quad->line(1)->child(0)->vertex_index(1),
+ quad->line(2)->child(0)->vertex_index(1),
+ quad->line(3)->child(0)->vertex_index(1),
+ next_unused_vertex
+ };
+
+ new_lines[0]->set (internal::Triangulation::
+ TriaObject<1>(vertex_indices[2], vertex_indices[4]));
+ new_lines[1]->set (internal::Triangulation::
+ TriaObject<1>(vertex_indices[4], vertex_indices[3]));
+ new_lines[2]->set (internal::Triangulation::
+ TriaObject<1>(vertex_indices[0], vertex_indices[4]));
+ new_lines[3]->set (internal::Triangulation::
+ TriaObject<1>(vertex_indices[4], vertex_indices[1]));
+
+ for (unsigned int i=0; i<4; ++i)
+ {
+ new_lines[i]->set_used_flag();
+ new_lines[i]->clear_user_flag();
+ new_lines[i]->clear_user_data();
+ new_lines[i]->clear_children();
+ new_lines[i]->set_boundary_indicator(quad->boundary_indicator());
+ }
+
+ // now for the
+ // quads. again, first
+ // collect some data
+ // about the indices of
+ // the lines, with the
+ // following numbering:
+ // .-6-.-7-.
+ // 1 9 3
+ // .-10.11-.
+ // 0 8 2
+ // .-4-.-5-.
+
+ // child 0 and 1 of a line are
+ // switched if the line orientation
+ // is false. set up a miniature
+ // table, indicating which child to
+ // take for line orientations false
+ // and true. first index: child
+ // index in standard orientation,
+ // second index: line orientation
+ const unsigned int index[2][2]=
+ {{1,0}, // child 0, line_orientation=false and true
+ {0,1}}; // child 1, line_orientation=false and true
+
+ const unsigned int line_indices[12]
+ = { quad->line(0)->child(index[0][quad->line_orientation(0)])->index(),
+ quad->line(0)->child(index[1][quad->line_orientation(0)])->index(),
+ quad->line(1)->child(index[0][quad->line_orientation(1)])->index(),
+ quad->line(1)->child(index[1][quad->line_orientation(1)])->index(),
+ quad->line(2)->child(index[0][quad->line_orientation(2)])->index(),
+ quad->line(2)->child(index[1][quad->line_orientation(2)])->index(),
+ quad->line(3)->child(index[0][quad->line_orientation(3)])->index(),
+ quad->line(3)->child(index[1][quad->line_orientation(3)])->index(),
+ new_lines[0]->index(),
+ new_lines[1]->index(),
+ new_lines[2]->index(),
+ new_lines[3]->index()
+ };
+
+ // find some space (consecutive)
+ // for the first two newly to be
+ // created quads.
+ typename Triangulation<dim,spacedim>::raw_quad_iterator new_quads[4];
+
+ next_unused_quad=triangulation.faces->quads.next_free_pair_quad(triangulation);
+
+ new_quads[0] = next_unused_quad;
+ Assert (new_quads[0]->used() == false, ExcCellShouldBeUnused());
+
+ ++next_unused_quad;
+ new_quads[1] = next_unused_quad;
+ Assert (new_quads[1]->used() == false, ExcCellShouldBeUnused());
+
+ next_unused_quad=triangulation.faces->quads.next_free_pair_quad(triangulation);
+ new_quads[2] = next_unused_quad;
+ Assert (new_quads[2]->used() == false, ExcCellShouldBeUnused());
+
+ ++next_unused_quad;
+ new_quads[3] = next_unused_quad;
+ Assert (new_quads[3]->used() == false, ExcCellShouldBeUnused());
+
+ // note these quads as
+ // children to the
+ // present one
+ quad->set_children (0, new_quads[0]->index());
+ quad->set_children (2, new_quads[2]->index());
+ new_quads[0]->set (internal::Triangulation
+ ::TriaObject<2>(line_indices[0],
+ line_indices[8],
+ line_indices[4],
+ line_indices[10]));
+
+ quad->set_refinement_case(RefinementCase<2>::cut_xy);
+
+ new_quads[0]->set (internal::Triangulation
+ ::TriaObject<2>(line_indices[0],
+ line_indices[8],
+ line_indices[4],
+ line_indices[10]));
+ new_quads[1]->set (internal::Triangulation
+ ::TriaObject<2>(line_indices[8],
+ line_indices[2],
+ line_indices[5],
+ line_indices[11]));
+ new_quads[2]->set (internal::Triangulation
+ ::TriaObject<2>(line_indices[1],
+ line_indices[9],
+ line_indices[10],
+ line_indices[6]));
+ new_quads[3]->set (internal::Triangulation
+ ::TriaObject<2>(line_indices[9],
+ line_indices[3],
+ line_indices[11],
+ line_indices[7]));
+ for (unsigned int i=0; i<4; ++i)
+ {
+ new_quads[i]->set_used_flag();
+ new_quads[i]->clear_user_flag();
+ new_quads[i]->clear_user_data();
+ new_quads[i]->clear_children();
+ new_quads[i]->set_boundary_indicator (quad->boundary_indicator());
+ // set all line orientations to
+ // true, change this after the
+ // loop, as we have to consider
+ // different lines for each
+ // child
+ for (unsigned int j=0; j<GeometryInfo<dim>::lines_per_face; ++j)
+ new_quads[i]->set_line_orientation(j,true);
+ }
+ // now set the line orientation of
+ // children of outer lines
+ // correctly, the lines in the
+ // interior of the refined quad are
+ // automatically oriented
+ // conforming to the standard
+ new_quads[0]->set_line_orientation(0,quad->line_orientation(0));
+ new_quads[0]->set_line_orientation(2,quad->line_orientation(2));
+ new_quads[1]->set_line_orientation(1,quad->line_orientation(1));
+ new_quads[1]->set_line_orientation(2,quad->line_orientation(2));
+ new_quads[2]->set_line_orientation(0,quad->line_orientation(0));
+ new_quads[2]->set_line_orientation(3,quad->line_orientation(3));
+ new_quads[3]->set_line_orientation(1,quad->line_orientation(1));
+ new_quads[3]->set_line_orientation(3,quad->line_orientation(3));
+
+ // finally clear flag
+ // indicating the need
+ // for refinement
+ quad->clear_user_flag ();
+ } // if (isotropic refinement)
+ } // for all quads
+ } // looped two times over all quads, all quads refined now
+
+ ///////////////////////////////////
+ // Now, finally, set up the new
+ // cells
+ ///////////////////////////////////
+
+ typename Triangulation<3,spacedim>::DistortedCellList
+ cells_with_distorted_children;
+
+ for (unsigned int level=0; level!=triangulation.levels.size()-1; ++level)
+ {
+ // only active objects can be
+ // refined further; remember
+ // that we won't operate on the
+ // finest level, so
+ // triangulation.begin_*(level+1) is allowed
+ typename Triangulation<dim,spacedim>::active_hex_iterator
+ hex = triangulation.begin_active_hex(level),
+ endh = triangulation.begin_active_hex(level+1);
+ typename Triangulation<dim,spacedim>::raw_hex_iterator
+ next_unused_hex = triangulation.begin_raw_hex (level+1);
+
+ for (; hex!=endh; ++hex)
+ if (hex->refine_flag_set())
+ {
+ // this hex needs to be
+ // refined
+
+ // clear flag indicating
+ // the need for
+ // refinement. do it here
+ // already, since we
+ // can't do it anymore
+ // once the cell has
+ // children
+ const RefinementCase<dim> ref_case=hex->refine_flag_set();
+ hex->clear_refine_flag ();
+ hex->set_refinement_case(ref_case);
+
+ // depending on the refine case we
+ // might have to create additional
+ // vertices, lines and quads
+ // interior of the hex before the
+ // actual children can be set up.
+
+ // in a first step: reserve the
+ // needed space for lines, quads
+ // and hexes and initialize them
+ // correctly
+
+ unsigned int n_new_lines=0;
+ unsigned int n_new_quads=0;
+ unsigned int n_new_hexes=0;
+ switch (ref_case)
+ {
+ case RefinementCase<dim>::cut_x:
+ case RefinementCase<dim>::cut_y:
+ case RefinementCase<dim>::cut_z:
+ n_new_lines=0;
+ n_new_quads=1;
+ n_new_hexes=2;
+ break;
+ case RefinementCase<dim>::cut_xy:
+ case RefinementCase<dim>::cut_xz:
+ case RefinementCase<dim>::cut_yz:
+ n_new_lines=1;
+ n_new_quads=4;
+ n_new_hexes=4;
+ break;
+ case RefinementCase<dim>::cut_xyz:
+ n_new_lines=6;
+ n_new_quads=12;
+ n_new_hexes=8;
+ break;
+ default:
+ Assert(false, ExcInternalError());
+ break;
+ }
+
+ // find some space for the newly to
+ // be created interior lines and
+ // initialize them.
+ std::vector<typename Triangulation<dim,spacedim>::raw_line_iterator>
+ new_lines(n_new_lines);
+ for (unsigned int i=0; i<n_new_lines; ++i)
+ {
+ new_lines[i] = triangulation.faces->lines.next_free_single_line(triangulation);
+
+ Assert (new_lines[i]->used() == false,
+ ExcCellShouldBeUnused());
+ new_lines[i]->set_used_flag();
+ new_lines[i]->clear_user_flag();
+ new_lines[i]->clear_user_data();
+ new_lines[i]->clear_children();
+ // interior line
+ new_lines[i]->set_boundary_indicator(types::internal_face_boundary_id);
+ }
+
+ // find some space for the newly to
+ // be created interior quads and
+ // initialize them.
+ std::vector<typename Triangulation<dim,spacedim>::raw_quad_iterator>
+ new_quads(n_new_quads);
+ for (unsigned int i=0; i<n_new_quads; ++i)
+ {
+ new_quads[i] = triangulation.faces->quads.next_free_single_quad(triangulation);
+
+ Assert (new_quads[i]->used() == false,
+ ExcCellShouldBeUnused());
+ new_quads[i]->set_used_flag();
+ new_quads[i]->clear_user_flag();
+ new_quads[i]->clear_user_data();
+ new_quads[i]->clear_children();
+ // interior quad
+ new_quads[i]->set_boundary_indicator (types::internal_face_boundary_id);
+ // set all line orientation
+ // flags to true by default,
+ // change this afterwards, if
+ // necessary
+ for (unsigned int j=0; j<GeometryInfo<dim>::lines_per_face; ++j)
+ new_quads[i]->set_line_orientation(j,true);
+ }
+
+ // find some space for the newly to
+ // be created hexes and initialize
+ // them.
+ std::vector<typename Triangulation<dim,spacedim>::raw_hex_iterator>
+ new_hexes(n_new_hexes);
+ for (unsigned int i=0; i<n_new_hexes; ++i)
+ {
+ if (i%2==0)
+ next_unused_hex=triangulation.levels[level+1]->cells.next_free_hex(triangulation,level+1);
+
+ else
+ ++next_unused_hex;
+
+ new_hexes[i]=next_unused_hex;
+
+ Assert (new_hexes[i]->used() == false,
+ ExcCellShouldBeUnused());
+ new_hexes[i]->set_used_flag();
+ new_hexes[i]->clear_user_flag();
+ new_hexes[i]->clear_user_data();
+ new_hexes[i]->clear_children();
+ // inherit material
+ // properties
+ new_hexes[i]->set_material_id (hex->material_id());
+ new_hexes[i]->set_subdomain_id (hex->subdomain_id());
+
+ if (i%2)
+ new_hexes[i]->set_parent (hex->index ());
+ // set the face_orientation
+ // flag to true for all faces
+ // initially, as this is the
+ // default value which is true
+ // for all faces interior to
+ // the hex. later on go the
+ // other way round and reset
+ // faces that are at the
+ // boundary of the mother cube
+ //
+ // the same is true for the
+ // face_flip and face_rotation
+ // flags. however, the latter
+ // two are set to false by
+ // default as this is the
+ // standard value
+ for (unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell; ++f)
+ {
+ new_hexes[i]->set_face_orientation(f, true);
+ new_hexes[i]->set_face_flip(f, false);
+ new_hexes[i]->set_face_rotation(f, false);
+ }
+ }
+ // note these hexes as
+ // children to the
+ // present cell
+ for (unsigned int i=0; i<n_new_hexes/2; ++i)
+ hex->set_children (2*i, new_hexes[2*i]->index());
+
+ // we have to take into account
+ // whether the different faces are
+ // oriented correctly or in the
+ // opposite direction, so store
+ // that up front
+
+ // face_orientation
+ const bool f_or[6]
+ = { hex->face_orientation (0),
+ hex->face_orientation (1),
+ hex->face_orientation (2),
+ hex->face_orientation (3),
+ hex->face_orientation (4),
+ hex->face_orientation (5) };
+
+ // face_flip
+ const bool f_fl[6]
+ = { hex->face_flip (0),
+ hex->face_flip (1),
+ hex->face_flip (2),
+ hex->face_flip (3),
+ hex->face_flip (4),
+ hex->face_flip (5) };
+
+ // face_rotation
+ const bool f_ro[6]
+ = { hex->face_rotation (0),
+ hex->face_rotation (1),
+ hex->face_rotation (2),
+ hex->face_rotation (3),
+ hex->face_rotation (4),
+ hex->face_rotation (5) };
+
+ // some commonly used fields which
+ // have varying size
+ const unsigned int *vertex_indices=0;
+ const typename Triangulation<dim,spacedim>::raw_line_iterator
+ *lines=0;
+ const unsigned int *line_indices=0;
+ const bool *line_orientation=0;
+ const unsigned int *quad_indices=0;
+
+ // little helper table, indicating,
+ // whether the child with index 0
+ // or with index 1 can be found at
+ // the standard origin of an
+ // anisotropically refined quads in
+ // real orientation
+ // index 1: (RefineCase - 1)
+ // index 2: face_flip
+
+ // index 3: face rotation
+ // note: face orientation has no influence
+ const unsigned int child_at_origin[2][2][2]=
+ { { { 0, 0 }, // RefinementCase<dim>::cut_x, face_flip=false, face_rotation=false and true
+ { 1, 1 }}, // RefinementCase<dim>::cut_x, face_flip=true, face_rotation=false and true
+ { { 0, 1 }, // RefinementCase<dim>::cut_y, face_flip=false, face_rotation=false and true
+ { 1, 0 }}};// RefinementCase<dim>::cut_y, face_flip=true, face_rotation=false and true
+
+ ///////////////////////////////////////
+ //
+ // in the following we will do the
+ // same thing for each refinement
+ // case: create a new vertex (if
+ // needed), create new interior
+ // lines (if needed), create new
+ // interior quads and afterwards
+ // build the children hexes out of
+ // these and the existing subfaces
+ // of the outer quads (which have
+ // been created above). However,
+ // even if the steps are quite
+ // similar, the actual work
+ // strongly depends on the actual
+ // refinement case. therefore, we
+ // use seperate blocks of code for
+ // each of these cases, which
+ // hopefully increases the
+ // readability to some extend.
+
+ switch (ref_case)
+ {
+ case RefinementCase<dim>::cut_x:
+ {
+ //////////////////////////////
+ //
+ // RefinementCase<dim>::cut_x
+ //
+ // the refined cube will look
+ // like this:
+ //
+ // *----*----*
+ // / / /|
+ // / / / |
+ // / / / |
+ // *----*----* |
+ // | | | |
+ // | | | *
+ // | | | /
+ // | | | /
+ // | | |/
+ // *----*----*
+ //
+ // again, first
+ // collect some data
+ // about the indices of
+ // the lines, with the
+ // following numbering:
+
+ // face 2: front plane
+ // (note: x,y exchanged)
+ // *---*---*
+ // | | |
+ // | 0 |
+ // | | |
+ // *---*---*
+ // m0
+ // face 3: back plane
+ // (note: x,y exchanged)
+ // m1
+ // *---*---*
+ // | | |
+ // | 1 |
+ // | | |
+ // *---*---*
+ // face 4: bottom plane
+ // *---*---*
+ // / / /
+ // / 2 /
+ // / / /
+ // *---*---*
+ // m0
+ // face 5: top plane
+ // m1
+ // *---*---*
+ // / / /
+ // / 3 /
+ // / / /
+ // *---*---*
+
+ // set up a list of line iterators
+ // first. from this, construct
+ // lists of line_indices and
+ // line orientations later on
+ const typename Triangulation<dim,spacedim>::raw_line_iterator
+ lines_x[4]
+ = {
+ hex->face(2)->child(0)
+ ->line((hex->face(2)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3), //0
+ hex->face(3)->child(0)
+ ->line((hex->face(3)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3), //1
+ hex->face(4)->child(0)
+ ->line((hex->face(4)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3), //2
+ hex->face(5)->child(0)
+ ->line((hex->face(5)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3) //3
+ };
+
+ lines=&lines_x[0];
+
+ unsigned int line_indices_x[4];
+
+ for (unsigned int i=0; i<4; ++i)
+ line_indices_x[i]=lines[i]->index();
+ line_indices=&line_indices_x[0];
+
+ // the orientation of lines for the
+ // inner quads is quite tricky. as
+ // these lines are newly created
+ // ones and thus have no parents,
+ // they cannot inherit this
+ // property. set up an array and
+ // fill it with the respective
+ // values
+ bool line_orientation_x[4];
+
+ // the middle vertice marked
+ // as m0 above is the start
+ // vertex for lines 0 and 2
+ // in standard orientation,
+ // whereas m1 is the end
+ // vertex of lines 1 and 3 in
+ // standard orientation
+ const unsigned int middle_vertices[2]=
+ {
+ hex->line(2)->child(0)->vertex_index(1),
+ hex->line(7)->child(0)->vertex_index(1)
+ };
+
+ for (unsigned int i=0; i<4; ++i)
+ if (lines[i]->vertex_index(i%2)==middle_vertices[i%2])
+ line_orientation_x[i]=true;
+ else
+ {
+ // it must be the other
+ // way round then
+ Assert(lines[i]->vertex_index((i+1)%2)==middle_vertices[i%2],
+ ExcInternalError());
+ line_orientation_x[i]=false;
+ }
+
+ line_orientation=&line_orientation_x[0];
+
+ // set up the new quad, line
+ // numbering is as indicated
+ // above
+ new_quads[0]->set (internal::Triangulation
+ ::TriaObject<2>(line_indices[0],
+ line_indices[1],
+ line_indices[2],
+ line_indices[3]));
+
+ new_quads[0]->set_line_orientation(0,line_orientation[0]);
+ new_quads[0]->set_line_orientation(1,line_orientation[1]);
+ new_quads[0]->set_line_orientation(2,line_orientation[2]);
+ new_quads[0]->set_line_orientation(3,line_orientation[3]);
+
+ // the quads are
+ // numbered as follows:
+ //
+ // planes in the interior
+ // of the old hex:
+ // *
+ // /|
+ // / | x
+ // / | *-------* *---------*
+ // * | | | / /
+ // | 0 | | | / /
+ // | * | | / /
+ // | / *-------*y *---------*x
+ // | /
+ // |/
+ // *
+ //
+ // children of the faces
+ // of the old hex
+ // *---*---* *---*---*
+ // /| | | / / /|
+ // / | | | / 9 / 10/ |
+ // / | 5 | 6 | / / / |
+ // * | | | *---*---* |
+ // | 1 *---*---* | | | 2 *
+ // | / / / | | | /
+ // | / 7 / 8 / | 3 | 4 | /
+ // |/ / / | | |/
+ // *---*---* *---*---*
+ //
+ // note that we have to
+ // take care of the
+ // orientation of
+ // faces.
+ const unsigned int quad_indices_x[11]
+ = {
+ new_quads[0]->index(), //0
+
+ hex->face(0)->index(), //1
+
+ hex->face(1)->index(), //2
+
+ hex->face(2)->child_index( child_at_origin[hex->face(2)->refinement_case()-1][f_fl[2]][f_ro[2]]), //3
+ hex->face(2)->child_index(1-child_at_origin[hex->face(2)->refinement_case()-1][f_fl[2]][f_ro[2]]),
+
+ hex->face(3)->child_index( child_at_origin[hex->face(3)->refinement_case()-1][f_fl[3]][f_ro[3]]), //5
+ hex->face(3)->child_index(1-child_at_origin[hex->face(3)->refinement_case()-1][f_fl[3]][f_ro[3]]),
+
+ hex->face(4)->child_index( child_at_origin[hex->face(4)->refinement_case()-1][f_fl[4]][f_ro[4]]), //7
+ hex->face(4)->child_index(1-child_at_origin[hex->face(4)->refinement_case()-1][f_fl[4]][f_ro[4]]),
+
+ hex->face(5)->child_index( child_at_origin[hex->face(5)->refinement_case()-1][f_fl[5]][f_ro[5]]), //9
+ hex->face(5)->child_index(1-child_at_origin[hex->face(5)->refinement_case()-1][f_fl[5]][f_ro[5]])
+
+ };
+ quad_indices=&quad_indices_x[0];
+
+ new_hexes[0]->set (internal::Triangulation
+ ::TriaObject<3>(quad_indices[1],
+ quad_indices[0],
+ quad_indices[3],
+ quad_indices[5],
+ quad_indices[7],
+ quad_indices[9]));
+ new_hexes[1]->set (internal::Triangulation
+ ::TriaObject<3>(quad_indices[0],
+ quad_indices[2],
+ quad_indices[4],
+ quad_indices[6],
+ quad_indices[8],
+ quad_indices[10]));
+ break;
+ }
+ case RefinementCase<dim>::cut_y:
+ {
+ //////////////////////////////
+ //
+ // RefinementCase<dim>::cut_y
+ //
+ // the refined cube will look
+ // like this:
+ //
+ // *---------*
+ // / /|
+ // *---------* |
+ // / /| |
+ // *---------* | |
+ // | | | |
+ // | | | *
+ // | | |/
+ // | | *
+ // | |/
+ // *---------*
+ //
+ // again, first
+ // collect some data
+ // about the indices of
+ // the lines, with the
+ // following numbering:
+
+ // face 0: left plane
+ // *
+ // /|
+ // * |
+ // /| |
+ // * | |
+ // | 0 |
+ // | | *
+ // | |/
+ // | *m0
+ // |/
+ // *
+ // face 1: right plane
+ // *
+ // /|
+ // m1* |
+ // /| |
+ // * | |
+ // | 1 |
+ // | | *
+ // | |/
+ // | *
+ // |/
+ // *
+ // face 4: bottom plane
+ // *-------*
+ // / /
+ // m0*---2---*
+ // / /
+ // *-------*
+ // face 5: top plane
+ // *-------*
+ // / /
+ // *---3---*m1
+ // / /
+ // *-------*
+
+ // set up a list of line iterators
+ // first. from this, construct
+ // lists of line_indices and
+ // line orientations later on
+ const typename Triangulation<dim,spacedim>::raw_line_iterator
+ lines_y[4]
+ = {
+ hex->face(0)->child(0)
+ ->line((hex->face(0)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3), //0
+ hex->face(1)->child(0)
+ ->line((hex->face(1)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3), //1
+ hex->face(4)->child(0)
+ ->line((hex->face(4)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3), //2
+ hex->face(5)->child(0)
+ ->line((hex->face(5)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3) //3
+ };
+
+ lines=&lines_y[0];
+
+ unsigned int line_indices_y[4];
+
+ for (unsigned int i=0; i<4; ++i)
+ line_indices_y[i]=lines[i]->index();
+ line_indices=&line_indices_y[0];
+
+ // the orientation of lines for the
+ // inner quads is quite tricky. as
+ // these lines are newly created
+ // ones and thus have no parents,
+ // they cannot inherit this
+ // property. set up an array and
+ // fill it with the respective
+ // values
+ bool line_orientation_y[4];
+
+ // the middle vertice marked
+ // as m0 above is the start
+ // vertex for lines 0 and 2
+ // in standard orientation,
+ // whereas m1 is the end
+ // vertex of lines 1 and 3 in
+ // standard orientation
+ const unsigned int middle_vertices[2]=
+ {
+ hex->line(0)->child(0)->vertex_index(1),
+ hex->line(5)->child(0)->vertex_index(1)
+ };
+
+ for (unsigned int i=0; i<4; ++i)
+ if (lines[i]->vertex_index(i%2)==middle_vertices[i%2])
+ line_orientation_y[i]=true;
+ else
+ {
+ // it must be the other way round then
+ Assert(lines[i]->vertex_index((i+1)%2)==middle_vertices[i%2],
+ ExcInternalError());
+ line_orientation_y[i]=false;
+ }
+
+ line_orientation=&line_orientation_y[0];
+
+ // set up the new quad, line
+ // numbering is as indicated
+ // above
+ new_quads[0]->set (internal::Triangulation
+ ::TriaObject<2>(line_indices[2],
+ line_indices[3],
+ line_indices[0],
+ line_indices[1]));
+
+ new_quads[0]->set_line_orientation(0,line_orientation[2]);
+ new_quads[0]->set_line_orientation(1,line_orientation[3]);
+ new_quads[0]->set_line_orientation(2,line_orientation[0]);
+ new_quads[0]->set_line_orientation(3,line_orientation[1]);
+
+ // the quads are
+ // numbered as follows:
+ //
+ // planes in the interior
+ // of the old hex:
+ // *
+ // /|
+ // / | x
+ // / | *-------* *---------*
+ // * | | | / /
+ // | | | 0 | / /
+ // | * | | / /
+ // | / *-------*y *---------*x
+ // | /
+ // |/
+ // *
+ //
+ // children of the faces
+ // of the old hex
+ // *-------* *-------*
+ // /| | / 10 /|
+ // * | | *-------* |
+ // /| | 6 | / 9 /| |
+ // * |2| | *-------* |4|
+ // | | *-------* | | | *
+ // |1|/ 8 / | |3|/
+ // | *-------* | 5 | *
+ // |/ 7 / | |/
+ // *-------* *-------*
+ //
+ // note that we have to
+ // take care of the
+ // orientation of
+ // faces.
+ const unsigned int quad_indices_y[11]
+ = {
+ new_quads[0]->index(), //0
+
+ hex->face(0)->child_index( child_at_origin[hex->face(0)->refinement_case()-1][f_fl[0]][f_ro[0]]), //1
+ hex->face(0)->child_index(1-child_at_origin[hex->face(0)->refinement_case()-1][f_fl[0]][f_ro[0]]),
+
+ hex->face(1)->child_index( child_at_origin[hex->face(1)->refinement_case()-1][f_fl[1]][f_ro[1]]), //3
+ hex->face(1)->child_index(1-child_at_origin[hex->face(1)->refinement_case()-1][f_fl[1]][f_ro[1]]),
+
+ hex->face(2)->index(), //5
+
+ hex->face(3)->index(), //6
+
+ hex->face(4)->child_index( child_at_origin[hex->face(4)->refinement_case()-1][f_fl[4]][f_ro[4]]), //7
+ hex->face(4)->child_index(1-child_at_origin[hex->face(4)->refinement_case()-1][f_fl[4]][f_ro[4]]),
+
+ hex->face(5)->child_index( child_at_origin[hex->face(5)->refinement_case()-1][f_fl[5]][f_ro[5]]), //9
+ hex->face(5)->child_index(1-child_at_origin[hex->face(5)->refinement_case()-1][f_fl[5]][f_ro[5]])
+
+ };
+ quad_indices=&quad_indices_y[0];
+
+ new_hexes[0]->set (internal::Triangulation
+ ::TriaObject<3>(quad_indices[1],
+ quad_indices[3],
+ quad_indices[5],
+ quad_indices[0],
+ quad_indices[7],
+ quad_indices[9]));
+ new_hexes[1]->set (internal::Triangulation
+ ::TriaObject<3>(quad_indices[2],
+ quad_indices[4],
+ quad_indices[0],
+ quad_indices[6],
+ quad_indices[8],
+ quad_indices[10]));
+ break;
+ }
+ case RefinementCase<dim>::cut_z:
+ {
+ //////////////////////////////
+ //
+ // RefinementCase<dim>::cut_z
+ //
+ // the refined cube will look
+ // like this:
+ //
+ // *---------*
+ // / /|
+ // / / |
+ // / / *
+ // *---------* /|
+ // | | / |
+ // | |/ *
+ // *---------* /
+ // | | /
+ // | |/
+ // *---------*
+ //
+ // again, first
+ // collect some data
+ // about the indices of
+ // the lines, with the
+ // following numbering:
+
+ // face 0: left plane
+ // *
+ // /|
+ // / |
+ // / *
+ // * /|
+ // | 0 |
+ // |/ *
+ // m0* /
+ // | /
+ // |/
+ // *
+ // face 1: right plane
+ // *
+ // /|
+ // / |
+ // / *m1
+ // * /|
+ // | 1 |
+ // |/ *
+ // * /
+ // | /
+ // |/
+ // *
+ // face 2: front plane
+ // (note: x,y exchanged)
+ // *-------*
+ // | |
+ // m0*---2---*
+ // | |
+ // *-------*
+ // face 3: back plane
+ // (note: x,y exchanged)
+ // *-------*
+ // | |
+ // *---3---*m1
+ // | |
+ // *-------*
+
+ // set up a list of line iterators
+ // first. from this, construct
+ // lists of line_indices and
+ // line orientations later on
+ const typename Triangulation<dim,spacedim>::raw_line_iterator
+ lines_z[4]
+ = {
+ hex->face(0)->child(0)
+ ->line((hex->face(0)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3), //0
+ hex->face(1)->child(0)
+ ->line((hex->face(1)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3), //1
+ hex->face(2)->child(0)
+ ->line((hex->face(2)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3), //2
+ hex->face(3)->child(0)
+ ->line((hex->face(3)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3) //3
+ };
+
+ lines=&lines_z[0];
+
+ unsigned int line_indices_z[4];
+
+ for (unsigned int i=0; i<4; ++i)
+ line_indices_z[i]=lines[i]->index();
+ line_indices=&line_indices_z[0];
+
+ // the orientation of lines for the
+ // inner quads is quite tricky. as
+ // these lines are newly created
+ // ones and thus have no parents,
+ // they cannot inherit this
+ // property. set up an array and
+ // fill it with the respective
+ // values
+ bool line_orientation_z[4];
+
+ // the middle vertex marked
+ // as m0 above is the start
+ // vertex for lines 0 and 2
+ // in standard orientation,
+ // whereas m1 is the end
+ // vertex of lines 1 and 3 in
+ // standard orientation
+ const unsigned int middle_vertices[2]=
+ {
+ middle_vertex_index<dim,spacedim>(hex->line(8)),
+ middle_vertex_index<dim,spacedim>(hex->line(11))
+ };
+
+ for (unsigned int i=0; i<4; ++i)
+ if (lines[i]->vertex_index(i%2)==middle_vertices[i%2])
+ line_orientation_z[i]=true;
+ else
+ {
+ // it must be the other way round then
+ Assert(lines[i]->vertex_index((i+1)%2)==middle_vertices[i%2],
+ ExcInternalError());
+ line_orientation_z[i]=false;
+ }
+
+ line_orientation=&line_orientation_z[0];
+
+ // set up the new quad, line
+ // numbering is as indicated
+ // above
+ new_quads[0]->set (internal::Triangulation
+ ::TriaObject<2>(line_indices[0],
+ line_indices[1],
+ line_indices[2],
+ line_indices[3]));
+
+ new_quads[0]->set_line_orientation(0,line_orientation[0]);
+ new_quads[0]->set_line_orientation(1,line_orientation[1]);
+ new_quads[0]->set_line_orientation(2,line_orientation[2]);
+ new_quads[0]->set_line_orientation(3,line_orientation[3]);
+
+ // the quads are
+ // numbered as follows:
+ //
+ // planes in the interior
+ // of the old hex:
+ // *
+ // /|
+ // / | x
+ // / | *-------* *---------*
+ // * | | | / /
+ // | | | | / 0 /
+ // | * | | / /
+ // | / *-------*y *---------*x
+ // | /
+ // |/
+ // *
+ //
+ // children of the faces
+ // of the old hex
+ // *---*---* *-------*
+ // /| 8 | / /|
+ // / | | / 10 / |
+ // / *-------* / / *
+ // * 2/| | *-------* 4/|
+ // | / | 7 | | 6 | / |
+ // |/1 *-------* | |/3 *
+ // * / / *-------* /
+ // | / 9 / | | /
+ // |/ / | 5 |/
+ // *-------* *---*---*
+ //
+ // note that we have to
+ // take care of the
+ // orientation of
+ // faces.
+ const unsigned int quad_indices_z[11]
+ = {
+ new_quads[0]->index(), //0
+
+ hex->face(0)->child_index( child_at_origin[hex->face(0)->refinement_case()-1][f_fl[0]][f_ro[0]]), //1
+ hex->face(0)->child_index(1-child_at_origin[hex->face(0)->refinement_case()-1][f_fl[0]][f_ro[0]]),
+
+ hex->face(1)->child_index( child_at_origin[hex->face(1)->refinement_case()-1][f_fl[1]][f_ro[1]]), //3
+ hex->face(1)->child_index(1-child_at_origin[hex->face(1)->refinement_case()-1][f_fl[1]][f_ro[1]]),
+
+ hex->face(2)->child_index( child_at_origin[hex->face(2)->refinement_case()-1][f_fl[2]][f_ro[2]]), //5
+ hex->face(2)->child_index(1-child_at_origin[hex->face(2)->refinement_case()-1][f_fl[2]][f_ro[2]]),
+
+ hex->face(3)->child_index( child_at_origin[hex->face(3)->refinement_case()-1][f_fl[3]][f_ro[3]]), //7
+ hex->face(3)->child_index(1-child_at_origin[hex->face(3)->refinement_case()-1][f_fl[3]][f_ro[3]]),
+
+ hex->face(4)->index(), //9
+
+ hex->face(5)->index() //10
+ };
+ quad_indices=&quad_indices_z[0];
+
+ new_hexes[0]->set (internal::Triangulation
+ ::TriaObject<3>(quad_indices[1],
+ quad_indices[3],
+ quad_indices[5],
+ quad_indices[7],
+ quad_indices[9],
+ quad_indices[0]));
+ new_hexes[1]->set (internal::Triangulation
+ ::TriaObject<3>(quad_indices[2],
+ quad_indices[4],
+ quad_indices[6],
+ quad_indices[8],
+ quad_indices[0],
+ quad_indices[10]));
+ break;
+ }
+ case RefinementCase<dim>::cut_xy:
+ {
+ //////////////////////////////
+ //
+ // RefinementCase<dim>::cut_xy
+ //
+ // the refined cube will look
+ // like this:
+ //
+ // *----*----*
+ // / / /|
+ // *----*----* |
+ // / / /| |
+ // *----*----* | |
+ // | | | | |
+ // | | | | *
+ // | | | |/
+ // | | | *
+ // | | |/
+ // *----*----*
+ //
+
+ // first, create the new
+ // internal line
+ new_lines[0]->set (internal::Triangulation::
+ TriaObject<1>(middle_vertex_index<dim,spacedim>(hex->face(4)),
+ middle_vertex_index<dim,spacedim>(hex->face(5))));
+
+ // again, first
+ // collect some data
+ // about the indices of
+ // the lines, with the
+ // following numbering:
+
+ // face 0: left plane
+ // *
+ // /|
+ // * |
+ // /| |
+ // * | |
+ // | 0 |
+ // | | *
+ // | |/
+ // | *
+ // |/
+ // *
+ // face 1: right plane
+ // *
+ // /|
+ // * |
+ // /| |
+ // * | |
+ // | 1 |
+ // | | *
+ // | |/
+ // | *
+ // |/
+ // *
+ // face 2: front plane
+ // (note: x,y exchanged)
+ // *---*---*
+ // | | |
+ // | 2 |
+ // | | |
+ // *-------*
+ // face 3: back plane
+ // (note: x,y exchanged)
+ // *---*---*
+ // | | |
+ // | 3 |
+ // | | |
+ // *---*---*
+ // face 4: bottom plane
+ // *---*---*
+ // / 5 /
+ // *-6-*-7-*
+ // / 4 /
+ // *---*---*
+ // face 5: top plane
+ // *---*---*
+ // / 9 /
+ // *10-*-11*
+ // / 8 /
+ // *---*---*
+ // middle planes
+ // *-------* *---*---*
+ // / / | | |
+ // / / | 12 |
+ // / / | | |
+ // *-------* *---*---*
+
+ // set up a list of line iterators
+ // first. from this, construct
+ // lists of line_indices and
+ // line orientations later on
+ const typename Triangulation<dim,spacedim>::raw_line_iterator
+ lines_xy[13]
+ = {
+ hex->face(0)->child(0)
+ ->line((hex->face(0)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3), //0
+ hex->face(1)->child(0)
+ ->line((hex->face(1)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3), //1
+ hex->face(2)->child(0)
+ ->line((hex->face(2)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3), //2
+ hex->face(3)->child(0)
+ ->line((hex->face(3)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3), //3
+
+ hex->face(4)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[4],f_fl[4],f_ro[4]))
+ ->line(GeometryInfo<dim>::standard_to_real_face_line(1,f_or[4],f_fl[4],f_ro[4])), //4
+ hex->face(4)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[4],f_fl[4],f_ro[4]))
+ ->line(GeometryInfo<dim>::standard_to_real_face_line(0,f_or[4],f_fl[4],f_ro[4])), //5
+ hex->face(4)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[4],f_fl[4],f_ro[4]))
+ ->line(GeometryInfo<dim>::standard_to_real_face_line(3,f_or[4],f_fl[4],f_ro[4])), //6
+ hex->face(4)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[4],f_fl[4],f_ro[4]))
+ ->line(GeometryInfo<dim>::standard_to_real_face_line(2,f_or[4],f_fl[4],f_ro[4])), //7
+
+ hex->face(5)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[5],f_fl[5],f_ro[5]))
+ ->line(GeometryInfo<dim>::standard_to_real_face_line(1,f_or[5],f_fl[5],f_ro[5])), //8
+ hex->face(5)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[5],f_fl[5],f_ro[5]))
+ ->line(GeometryInfo<dim>::standard_to_real_face_line(0,f_or[5],f_fl[5],f_ro[5])), //9
+ hex->face(5)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[5],f_fl[5],f_ro[5]))
+ ->line(GeometryInfo<dim>::standard_to_real_face_line(3,f_or[5],f_fl[5],f_ro[5])), //10
+ hex->face(5)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[5],f_fl[5],f_ro[5]))
+ ->line(GeometryInfo<dim>::standard_to_real_face_line(2,f_or[5],f_fl[5],f_ro[5])), //11
+
+ new_lines[0] //12
+ };
+
+ lines=&lines_xy[0];
+
+ unsigned int line_indices_xy[13];
+
+ for (unsigned int i=0; i<13; ++i)
+ line_indices_xy[i]=lines[i]->index();
+ line_indices=&line_indices_xy[0];
+
+ // the orientation of lines for the
+ // inner quads is quite tricky. as
+ // these lines are newly created
+ // ones and thus have no parents,
+ // they cannot inherit this
+ // property. set up an array and
+ // fill it with the respective
+ // values
+ bool line_orientation_xy[13];
+
+ // the middle vertices of the
+ // lines of our bottom face
+ const unsigned int middle_vertices[4]=
+ {
+ hex->line(0)->child(0)->vertex_index(1),
+ hex->line(1)->child(0)->vertex_index(1),
+ hex->line(2)->child(0)->vertex_index(1),
+ hex->line(3)->child(0)->vertex_index(1),
+ };
+
+ // note: for lines 0 to 3 the
+ // orientation of the line
+ // is 'true', if vertex 0 is
+ // on the bottom face
+ for (unsigned int i=0; i<4; ++i)
+ if (lines[i]->vertex_index(0)==middle_vertices[i])
+ line_orientation_xy[i]=true;
+ else
+ {
+ // it must be the other way round then
+ Assert(lines[i]->vertex_index(1)==middle_vertices[i],
+ ExcInternalError());
+ line_orientation_xy[i]=false;
+ }
+
+ // note: for lines 4 to 11
+ // (inner lines of the outer quads)
+ // the following holds: the second
+ // vertex of the even lines in
+ // standard orientation is the
+ // vertex in the middle of the
+ // quad, whereas for odd lines the
+ // first vertex is the same middle
+ // vertex.
+ for (unsigned int i=4; i<12; ++i)
+ if (lines[i]->vertex_index((i+1)%2) ==
+ middle_vertex_index<dim,spacedim>(hex->face(3+i/4)))
+ line_orientation_xy[i]=true;
+ else
+ {
+ // it must be the other way
+ // round then
+ Assert(lines[i]->vertex_index(i%2) ==
+ (middle_vertex_index<dim,spacedim>(hex->face(3+i/4))),
+ ExcInternalError());
+ line_orientation_xy[i]=false;
+ }
+ // for the last line the line
+ // orientation is always true,
+ // since it was just constructed
+ // that way
+
+ line_orientation_xy[12]=true;
+ line_orientation=&line_orientation_xy[0];
+
+ // set up the 4 quads,
+ // numbered as follows
+ // (left quad numbering,
+ // right line numbering
+ // extracted from above)
+ //
+ // * *
+ // /| 9|
+ // * | * |
+ // y/| | 8| 3
+ // * |1| * | |
+ // | | |x | 12|
+ // |0| * | | *
+ // | |/ 2 |5
+ // | * | *
+ // |/ |4
+ // * *
+ //
+ // x
+ // *---*---* *10-*-11*
+ // | | | | | |
+ // | 2 | 3 | 0 12 1
+ // | | | | | |
+ // *---*---*y *-6-*-7-*
+
+ new_quads[0]->set (internal::Triangulation
+ ::TriaObject<2>(line_indices[2],
+ line_indices[12],
+ line_indices[4],
+ line_indices[8]));
+ new_quads[1]->set (internal::Triangulation
+ ::TriaObject<2>(line_indices[12],
+ line_indices[3],
+ line_indices[5],
+ line_indices[9]));
+ new_quads[2]->set (internal::Triangulation
+ ::TriaObject<2>(line_indices[6],
+ line_indices[10],
+ line_indices[0],
+ line_indices[12]));
+ new_quads[3]->set (internal::Triangulation
+ ::TriaObject<2>(line_indices[7],
+ line_indices[11],
+ line_indices[12],
+ line_indices[1]));
+
+ new_quads[0]->set_line_orientation(0,line_orientation[2]);
+ new_quads[0]->set_line_orientation(2,line_orientation[4]);
+ new_quads[0]->set_line_orientation(3,line_orientation[8]);
+
+ new_quads[1]->set_line_orientation(1,line_orientation[3]);
+ new_quads[1]->set_line_orientation(2,line_orientation[5]);
+ new_quads[1]->set_line_orientation(3,line_orientation[9]);
+
+ new_quads[2]->set_line_orientation(0,line_orientation[6]);
+ new_quads[2]->set_line_orientation(1,line_orientation[10]);
+ new_quads[2]->set_line_orientation(2,line_orientation[0]);
+
+ new_quads[3]->set_line_orientation(0,line_orientation[7]);
+ new_quads[3]->set_line_orientation(1,line_orientation[11]);
+ new_quads[3]->set_line_orientation(3,line_orientation[1]);
+
+ // the quads are
+ // numbered as follows:
+ //
+ // planes in the interior
+ // of the old hex:
+ // *
+ // /|
+ // * | x
+ // /| | *---*---* *---------*
+ // * |1| | | | / /
+ // | | | | 2 | 3 | / /
+ // |0| * | | | / /
+ // | |/ *---*---*y *---------*x
+ // | *
+ // |/
+ // *
+ //
+ // children of the faces
+ // of the old hex
+ // *---*---* *---*---*
+ // /| | | /18 / 19/|
+ // * |10 | 11| /---/---* |
+ // /| | | | /16 / 17/| |
+ // * |5| | | *---*---* |7|
+ // | | *---*---* | | | | *
+ // |4|/14 / 15/ | | |6|/
+ // | *---/---/ | 8 | 9 | *
+ // |/12 / 13/ | | |/
+ // *---*---* *---*---*
+ //
+ // note that we have to
+ // take care of the
+ // orientation of
+ // faces.
+ const unsigned int quad_indices_xy[20]
+ = {
+ new_quads[0]->index(), //0
+ new_quads[1]->index(),
+ new_quads[2]->index(),
+ new_quads[3]->index(),
+
+ hex->face(0)->child_index( child_at_origin[hex->face(0)->refinement_case()-1][f_fl[0]][f_ro[0]]), //4
+ hex->face(0)->child_index(1-child_at_origin[hex->face(0)->refinement_case()-1][f_fl[0]][f_ro[0]]),
+
+ hex->face(1)->child_index( child_at_origin[hex->face(1)->refinement_case()-1][f_fl[1]][f_ro[1]]), //6
+ hex->face(1)->child_index(1-child_at_origin[hex->face(1)->refinement_case()-1][f_fl[1]][f_ro[1]]),
+
+ hex->face(2)->child_index( child_at_origin[hex->face(2)->refinement_case()-1][f_fl[2]][f_ro[2]]), //8
+ hex->face(2)->child_index(1-child_at_origin[hex->face(2)->refinement_case()-1][f_fl[2]][f_ro[2]]),
+
+ hex->face(3)->child_index( child_at_origin[hex->face(3)->refinement_case()-1][f_fl[3]][f_ro[3]]), //10
+ hex->face(3)->child_index(1-child_at_origin[hex->face(3)->refinement_case()-1][f_fl[3]][f_ro[3]]),
+
+ hex->face(4)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[4],f_fl[4],f_ro[4])), //12
+ hex->face(4)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(1,f_or[4],f_fl[4],f_ro[4])),
+ hex->face(4)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(2,f_or[4],f_fl[4],f_ro[4])),
+ hex->face(4)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[4],f_fl[4],f_ro[4])),
+
+ hex->face(5)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[5],f_fl[5],f_ro[5])), //16
+ hex->face(5)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(1,f_or[5],f_fl[5],f_ro[5])),
+ hex->face(5)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(2,f_or[5],f_fl[5],f_ro[5])),
+ hex->face(5)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[5],f_fl[5],f_ro[5]))
+ };
+ quad_indices=&quad_indices_xy[0];
+
+ new_hexes[0]->set (internal::Triangulation
+ ::TriaObject<3>(quad_indices[4],
+ quad_indices[0],
+ quad_indices[8],
+ quad_indices[2],
+ quad_indices[12],
+ quad_indices[16]));
+ new_hexes[1]->set (internal::Triangulation
+ ::TriaObject<3>(quad_indices[0],
+ quad_indices[6],
+ quad_indices[9],
+ quad_indices[3],
+ quad_indices[13],
+ quad_indices[17]));
+ new_hexes[2]->set (internal::Triangulation
+ ::TriaObject<3>(quad_indices[5],
+ quad_indices[1],
+ quad_indices[2],
+ quad_indices[10],
+ quad_indices[14],
+ quad_indices[18]));
+ new_hexes[3]->set (internal::Triangulation
+ ::TriaObject<3>(quad_indices[1],
+ quad_indices[7],
+ quad_indices[3],
+ quad_indices[11],
+ quad_indices[15],
+ quad_indices[19]));
+ break;
+ }
+ case RefinementCase<dim>::cut_xz:
+ {
+ //////////////////////////////
+ //
+ // RefinementCase<dim>::cut_xz
+ //
+ // the refined cube will look
+ // like this:
+ //
+ // *----*----*
+ // / / /|
+ // / / / |
+ // / / / *
+ // *----*----* /|
+ // | | | / |
+ // | | |/ *
+ // *----*----* /
+ // | | | /
+ // | | |/
+ // *----*----*
+ //
+
+ // first, create the new
+ // internal line
+ new_lines[0]->set (internal::Triangulation::
+ TriaObject<1>(middle_vertex_index<dim,spacedim>(hex->face(2)),
+ middle_vertex_index<dim,spacedim>(hex->face(3))));
+
+ // again, first
+ // collect some data
+ // about the indices of
+ // the lines, with the
+ // following numbering:
+
+ // face 0: left plane
+ // *
+ // /|
+ // / |
+ // / *
+ // * /|
+ // | 0 |
+ // |/ *
+ // * /
+ // | /
+ // |/
+ // *
+ // face 1: right plane
+ // *
+ // /|
+ // / |
+ // / *
+ // * /|
+ // | 1 |
+ // |/ *
+ // * /
+ // | /
+ // |/
+ // *
+ // face 2: front plane
+ // (note: x,y exchanged)
+ // *---*---*
+ // | 5 |
+ // *-6-*-7-*
+ // | 4 |
+ // *---*---*
+ // face 3: back plane
+ // (note: x,y exchanged)
+ // *---*---*
+ // | 9 |
+ // *10-*-11*
+ // | 8 |
+ // *---*---*
+ // face 4: bottom plane
+ // *---*---*
+ // / / /
+ // / 2 /
+ // / / /
+ // *---*---*
+ // face 5: top plane
+ // *---*---*
+ // / / /
+ // / 3 /
+ // / / /
+ // *---*---*
+ // middle planes
+ // *---*---* *-------*
+ // / / / | |
+ // / 12 / | |
+ // / / / | |
+ // *---*---* *-------*
+
+ // set up a list of line iterators
+ // first. from this, construct
+ // lists of line_indices and
+ // line orientations later on
+ const typename Triangulation<dim,spacedim>::raw_line_iterator
+ lines_xz[13]
+ = {
+ hex->face(0)->child(0)
+ ->line((hex->face(0)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3), //0
+ hex->face(1)->child(0)
+ ->line((hex->face(1)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3), //1
+ hex->face(4)->child(0)
+ ->line((hex->face(4)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3), //2
+ hex->face(5)->child(0)
+ ->line((hex->face(5)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3), //3
+
+ hex->face(2)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[2],f_fl[2],f_ro[2]))
+ ->line(GeometryInfo<dim>::standard_to_real_face_line(3,f_or[2],f_fl[2],f_ro[2])), //4
+ hex->face(2)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[2],f_fl[2],f_ro[2]))
+ ->line(GeometryInfo<dim>::standard_to_real_face_line(2,f_or[2],f_fl[2],f_ro[2])), //5
+ hex->face(2)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[2],f_fl[2],f_ro[2]))
+ ->line(GeometryInfo<dim>::standard_to_real_face_line(1,f_or[2],f_fl[2],f_ro[2])), //6
+ hex->face(2)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[2],f_fl[2],f_ro[2]))
+ ->line(GeometryInfo<dim>::standard_to_real_face_line(0,f_or[2],f_fl[2],f_ro[2])), //7
+
+ hex->face(3)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[3],f_fl[3],f_ro[3]))
+ ->line(GeometryInfo<dim>::standard_to_real_face_line(3,f_or[3],f_fl[3],f_ro[3])), //8
+ hex->face(3)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[3],f_fl[3],f_ro[3]))
+ ->line(GeometryInfo<dim>::standard_to_real_face_line(2,f_or[3],f_fl[3],f_ro[3])), //9
+ hex->face(3)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[3],f_fl[3],f_ro[3]))
+ ->line(GeometryInfo<dim>::standard_to_real_face_line(1,f_or[3],f_fl[3],f_ro[3])), //10
+ hex->face(3)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[3],f_fl[3],f_ro[3]))
+ ->line(GeometryInfo<dim>::standard_to_real_face_line(0,f_or[3],f_fl[3],f_ro[3])), //11
+
+ new_lines[0] //12
+ };
+
+ lines=&lines_xz[0];
+
+ unsigned int line_indices_xz[13];
+
+ for (unsigned int i=0; i<13; ++i)
+ line_indices_xz[i]=lines[i]->index();
+ line_indices=&line_indices_xz[0];
+
+ // the orientation of lines for the
+ // inner quads is quite tricky. as
+ // these lines are newly created
+ // ones and thus have no parents,
+ // they cannot inherit this
+ // property. set up an array and
+ // fill it with the respective
+ // values
+ bool line_orientation_xz[13];
+
+ // the middle vertices of the
+ // lines of our front face
+ const unsigned int middle_vertices[4]=
+ {
+ hex->line(8)->child(0)->vertex_index(1),
+ hex->line(9)->child(0)->vertex_index(1),
+ hex->line(2)->child(0)->vertex_index(1),
+ hex->line(6)->child(0)->vertex_index(1),
+ };
+
+ // note: for lines 0 to 3 the
+ // orientation of the line
+ // is 'true', if vertex 0 is
+ // on the front
+ for (unsigned int i=0; i<4; ++i)
+ if (lines[i]->vertex_index(0)==middle_vertices[i])
+ line_orientation_xz[i]=true;
+ else
+ {
+ // it must be the other way round then
+ Assert(lines[i]->vertex_index(1)==middle_vertices[i],
+ ExcInternalError());
+ line_orientation_xz[i]=false;
+ }
+
+ // note: for lines 4 to 11
+ // (inner lines of the outer quads)
+ // the following holds: the second
+ // vertex of the even lines in
+ // standard orientation is the
+ // vertex in the middle of the
+ // quad, whereas for odd lines the
+ // first vertex is the same middle
+ // vertex.
+ for (unsigned int i=4; i<12; ++i)
+ if (lines[i]->vertex_index((i+1)%2) ==
+ middle_vertex_index<dim,spacedim>(hex->face(1+i/4)))
+ line_orientation_xz[i]=true;
+ else
+ {
+ // it must be the other way
+ // round then
+ Assert(lines[i]->vertex_index(i%2) ==
+ (middle_vertex_index<dim,spacedim>(hex->face(1+i/4))),
+ ExcInternalError());
+ line_orientation_xz[i]=false;
+ }
+ // for the last line the line
+ // orientation is always true,
+ // since it was just constructed
+ // that way
+
+ line_orientation_xz[12]=true;
+ line_orientation=&line_orientation_xz[0];
+
+ // set up the 4 quads,
+ // numbered as follows
+ // (left quad numbering,
+ // right line numbering
+ // extracted from above),
+ // the drawings denote
+ // middle planes
+ //
+ // * *
+ // /| /|
+ // / | 3 9
+ // y/ * / *
+ // * 3/| * /|
+ // | / |x 5 12|8
+ // |/ * |/ *
+ // * 2/ * /
+ // | / 4 2
+ // |/ |/
+ // * *
+ //
+ // y
+ // *----*----* *-10-*-11-*
+ // / / / / / /
+ // / 0 / 1 / 0 12 1
+ // / / / / / /
+ // *----*----*x *--6-*--7-*
+
+ new_quads[0]->set (internal::Triangulation
+ ::TriaObject<2>(line_indices[0],
+ line_indices[12],
+ line_indices[6],
+ line_indices[10]));
+ new_quads[1]->set (internal::Triangulation
+ ::TriaObject<2>(line_indices[12],
+ line_indices[1],
+ line_indices[7],
+ line_indices[11]));
+ new_quads[2]->set (internal::Triangulation
+ ::TriaObject<2>(line_indices[4],
+ line_indices[8],
+ line_indices[2],
+ line_indices[12]));
+ new_quads[3]->set (internal::Triangulation
+ ::TriaObject<2>(line_indices[5],
+ line_indices[9],
+ line_indices[12],
+ line_indices[3]));
+
+ new_quads[0]->set_line_orientation(0,line_orientation[0]);
+ new_quads[0]->set_line_orientation(2,line_orientation[6]);
+ new_quads[0]->set_line_orientation(3,line_orientation[10]);
+
+ new_quads[1]->set_line_orientation(1,line_orientation[1]);
+ new_quads[1]->set_line_orientation(2,line_orientation[7]);
+ new_quads[1]->set_line_orientation(3,line_orientation[11]);
+
+ new_quads[2]->set_line_orientation(0,line_orientation[4]);
+ new_quads[2]->set_line_orientation(1,line_orientation[8]);
+ new_quads[2]->set_line_orientation(2,line_orientation[2]);
+
+ new_quads[3]->set_line_orientation(0,line_orientation[5]);
+ new_quads[3]->set_line_orientation(1,line_orientation[9]);
+ new_quads[3]->set_line_orientation(3,line_orientation[3]);
+
+ // the quads are
+ // numbered as follows:
+ //
+ // planes in the interior
+ // of the old hex:
+ // *
+ // /|
+ // / | x
+ // /3 * *-------* *----*----*
+ // * /| | | / / /
+ // | / | | | / 0 / 1 /
+ // |/ * | | / / /
+ // * 2/ *-------*y *----*----*x
+ // | /
+ // |/
+ // *
+ //
+ // children of the faces
+ // of the old hex
+ // *---*---* *---*---*
+ // /|13 | 15| / / /|
+ // / | | | /18 / 19/ |
+ // / *---*---* / / / *
+ // * 5/| | | *---*---* 7/|
+ // | / |12 | 14| | 9 | 11| / |
+ // |/4 *---*---* | | |/6 *
+ // * / / / *---*---* /
+ // | /16 / 17/ | | | /
+ // |/ / / | 8 | 10|/
+ // *---*---* *---*---*
+ //
+ // note that we have to
+ // take care of the
+ // orientation of
+ // faces.
+ const unsigned int quad_indices_xz[20]
+ = {
+ new_quads[0]->index(), //0
+ new_quads[1]->index(),
+ new_quads[2]->index(),
+ new_quads[3]->index(),
+
+ hex->face(0)->child_index( child_at_origin[hex->face(0)->refinement_case()-1][f_fl[0]][f_ro[0]]), //4
+ hex->face(0)->child_index(1-child_at_origin[hex->face(0)->refinement_case()-1][f_fl[0]][f_ro[0]]),
+
+ hex->face(1)->child_index( child_at_origin[hex->face(1)->refinement_case()-1][f_fl[1]][f_ro[1]]), //6
+ hex->face(1)->child_index(1-child_at_origin[hex->face(1)->refinement_case()-1][f_fl[1]][f_ro[1]]),
+
+ hex->face(2)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[2],f_fl[2],f_ro[2])), //8
+ hex->face(2)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(1,f_or[2],f_fl[2],f_ro[2])),
+ hex->face(2)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(2,f_or[2],f_fl[2],f_ro[2])),
+ hex->face(2)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[2],f_fl[2],f_ro[2])),
+
+ hex->face(3)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[3],f_fl[3],f_ro[3])), //12
+ hex->face(3)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(1,f_or[3],f_fl[3],f_ro[3])),
+ hex->face(3)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(2,f_or[3],f_fl[3],f_ro[3])),
+ hex->face(3)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[3],f_fl[3],f_ro[3])),
+
+ hex->face(4)->child_index( child_at_origin[hex->face(4)->refinement_case()-1][f_fl[4]][f_ro[4]]), //16
+ hex->face(4)->child_index(1-child_at_origin[hex->face(4)->refinement_case()-1][f_fl[4]][f_ro[4]]),
+
+ hex->face(5)->child_index( child_at_origin[hex->face(5)->refinement_case()-1][f_fl[5]][f_ro[5]]), //18
+ hex->face(5)->child_index(1-child_at_origin[hex->face(5)->refinement_case()-1][f_fl[5]][f_ro[5]])
+ };
+ quad_indices=&quad_indices_xz[0];
+
+ // due to the exchange of x
+ // and y for the front and
+ // back face, we order the
+ // children according to
+ //
+ // *---*---*
+ // | 1 | 3 |
+ // *---*---*
+ // | 0 | 2 |
+ // *---*---*
+ new_hexes[0]->set (internal::Triangulation
+ ::TriaObject<3>(quad_indices[4],
+ quad_indices[2],
+ quad_indices[8],
+ quad_indices[12],
+ quad_indices[16],
+ quad_indices[0]));
+ new_hexes[1]->set (internal::Triangulation
+ ::TriaObject<3>(quad_indices[5],
+ quad_indices[3],
+ quad_indices[9],
+ quad_indices[13],
+ quad_indices[0],
+ quad_indices[18]));
+ new_hexes[2]->set (internal::Triangulation
+ ::TriaObject<3>(quad_indices[2],
+ quad_indices[6],
+ quad_indices[10],
+ quad_indices[14],
+ quad_indices[17],
+ quad_indices[1]));
+ new_hexes[3]->set (internal::Triangulation
+ ::TriaObject<3>(quad_indices[3],
+ quad_indices[7],
+ quad_indices[11],
+ quad_indices[15],
+ quad_indices[1],
+ quad_indices[19]));
+ break;
+ }
+ case RefinementCase<dim>::cut_yz:
+ {
+ //////////////////////////////
+ //
+ // RefinementCase<dim>::cut_yz
+ //
+ // the refined cube will look
+ // like this:
+ //
+ // *---------*
+ // / /|
+ // *---------* |
+ // / /| |
+ // *---------* |/|
+ // | | * |
+ // | |/| *
+ // *---------* |/
+ // | | *
+ // | |/
+ // *---------*
+ //
+
+ // first, create the new
+ // internal line
+ new_lines[0]->set (internal::Triangulation::
+ TriaObject<1>(middle_vertex_index<dim,spacedim>(hex->face(0)),
+ middle_vertex_index<dim,spacedim>(hex->face(1))));
+
+ // again, first
+ // collect some data
+ // about the indices of
+ // the lines, with the
+ // following numbering:
+ // (note that face 0 and
+ // 1 each are shown twice
+ // for better
+ // readability)
+
+ // face 0: left plane
+ // * *
+ // /| /|
+ // * | * |
+ // /| * /| *
+ // * 5/| * |7|
+ // | * | | * |
+ // |/| * |6| *
+ // * 4/ * |/
+ // | * | *
+ // |/ |/
+ // * *
+ // face 1: right plane
+ // * *
+ // /| /|
+ // * | * |
+ // /| * /| *
+ // * 9/| * |11
+ // | * | | * |
+ // |/| * |10 *
+ // * 8/ * |/
+ // | * | *
+ // |/ |/
+ // * *
+ // face 2: front plane
+ // (note: x,y exchanged)
+ // *-------*
+ // | |
+ // *---0---*
+ // | |
+ // *-------*
+ // face 3: back plane
+ // (note: x,y exchanged)
+ // *-------*
+ // | |
+ // *---1---*
+ // | |
+ // *-------*
+ // face 4: bottom plane
+ // *-------*
+ // / /
+ // *---2---*
+ // / /
+ // *-------*
+ // face 5: top plane
+ // *-------*
+ // / /
+ // *---3---*
+ // / /
+ // *-------*
+ // middle planes
+ // *-------* *-------*
+ // / / | |
+ // *---12--* | |
+ // / / | |
+ // *-------* *-------*
+
+ // set up a list of line iterators
+ // first. from this, construct
+ // lists of line_indices and
+ // line orientations later on
+ const typename Triangulation<dim,spacedim>::raw_line_iterator
+ lines_yz[13]
+ = {
+ hex->face(2)->child(0)
+ ->line((hex->face(2)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3), //0
+ hex->face(3)->child(0)
+ ->line((hex->face(3)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3), //1
+ hex->face(4)->child(0)
+ ->line((hex->face(4)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3), //2
+ hex->face(5)->child(0)
+ ->line((hex->face(5)->refinement_case() == RefinementCase<2>::cut_x) ? 1 : 3), //3
+
+ hex->face(0)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[0],f_fl[0],f_ro[0]))
+ ->line(GeometryInfo<dim>::standard_to_real_face_line(1,f_or[0],f_fl[0],f_ro[0])), //4
+ hex->face(0)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[0],f_fl[0],f_ro[0]))
+ ->line(GeometryInfo<dim>::standard_to_real_face_line(0,f_or[0],f_fl[0],f_ro[0])), //5
+ hex->face(0)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[0],f_fl[0],f_ro[0]))
+ ->line(GeometryInfo<dim>::standard_to_real_face_line(3,f_or[0],f_fl[0],f_ro[0])), //6
+ hex->face(0)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[0],f_fl[0],f_ro[0]))
+ ->line(GeometryInfo<dim>::standard_to_real_face_line(2,f_or[0],f_fl[0],f_ro[0])), //7
+
+ hex->face(1)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[1],f_fl[1],f_ro[1]))
+ ->line(GeometryInfo<dim>::standard_to_real_face_line(1,f_or[1],f_fl[1],f_ro[1])), //8
+ hex->face(1)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[1],f_fl[1],f_ro[1]))
+ ->line(GeometryInfo<dim>::standard_to_real_face_line(0,f_or[1],f_fl[1],f_ro[1])), //9
+ hex->face(1)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[1],f_fl[1],f_ro[1]))
+ ->line(GeometryInfo<dim>::standard_to_real_face_line(3,f_or[1],f_fl[1],f_ro[1])), //10
+ hex->face(1)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[1],f_fl[1],f_ro[1]))
+ ->line(GeometryInfo<dim>::standard_to_real_face_line(2,f_or[1],f_fl[1],f_ro[1])), //11
+
+ new_lines[0] //12
+ };
+
+ lines=&lines_yz[0];
+
+ unsigned int line_indices_yz[13];
+
+ for (unsigned int i=0; i<13; ++i)
+ line_indices_yz[i]=lines[i]->index();
+ line_indices=&line_indices_yz[0];
+
+ // the orientation of lines for the
+ // inner quads is quite tricky. as
+ // these lines are newly created
+ // ones and thus have no parents,
+ // they cannot inherit this
+ // property. set up an array and
+ // fill it with the respective
+ // values
+ bool line_orientation_yz[13];
+
+ // the middle vertices of the
+ // lines of our front face
+ const unsigned int middle_vertices[4]=
+ {
+ hex->line(8)->child(0)->vertex_index(1),
+ hex->line(10)->child(0)->vertex_index(1),
+ hex->line(0)->child(0)->vertex_index(1),
+ hex->line(4)->child(0)->vertex_index(1),
+ };
+
+ // note: for lines 0 to 3 the
+ // orientation of the line
+ // is 'true', if vertex 0 is
+ // on the front
+ for (unsigned int i=0; i<4; ++i)
+ if (lines[i]->vertex_index(0)==middle_vertices[i])
+ line_orientation_yz[i]=true;
+ else
+ {
+ // it must be the other way round then
+ Assert(lines[i]->vertex_index(1)==middle_vertices[i],
+ ExcInternalError());
+ line_orientation_yz[i]=false;
+ }
+
+ // note: for lines 4 to 11
+ // (inner lines of the outer quads)
+ // the following holds: the second
+ // vertex of the even lines in
+ // standard orientation is the
+ // vertex in the middle of the
+ // quad, whereas for odd lines the
+ // first vertex is the same middle
+ // vertex.
+ for (unsigned int i=4; i<12; ++i)
+ if (lines[i]->vertex_index((i+1)%2) ==
+ middle_vertex_index<dim,spacedim>(hex->face(i/4-1)))
+ line_orientation_yz[i]=true;
+ else
+ {
+ // it must be the other way
+ // round then
+ Assert(lines[i]->vertex_index(i%2) ==
+ (middle_vertex_index<dim,spacedim>(hex->face(i/4-1))),
+ ExcInternalError());
+ line_orientation_yz[i]=false;
+ }
+ // for the last line the line
+ // orientation is always true,
+ // since it was just constructed
+ // that way
+
+ line_orientation_yz[12]=true;
+ line_orientation=&line_orientation_yz[0];
+
+ // set up the 4 quads,
+ // numbered as follows (left
+ // quad numbering, right line
+ // numbering extracted from
+ // above)
+ //
+ // x
+ // *-------* *---3---*
+ // | 3 | 5 9
+ // *-------* *---12--*
+ // | 2 | 4 8
+ // *-------*y *---2---*
+ //
+ // y
+ // *---------* *----1----*
+ // / 1 / 7 11
+ // *---------* *----12---*
+ // / 0 / 6 10
+ // *---------*x *----0----*
+
+ new_quads[0]->set (internal::Triangulation
+ ::TriaObject<2>(line_indices[6],
+ line_indices[10],
+ line_indices[0],
+ line_indices[12]));
+ new_quads[1]->set (internal::Triangulation
+ ::TriaObject<2>(line_indices[7],
+ line_indices[11],
+ line_indices[12],
+ line_indices[1]));
+ new_quads[2]->set (internal::Triangulation
+ ::TriaObject<2>(line_indices[2],
+ line_indices[12],
+ line_indices[4],
+ line_indices[8]));
+ new_quads[3]->set (internal::Triangulation
+ ::TriaObject<2>(line_indices[12],
+ line_indices[3],
+ line_indices[5],
+ line_indices[9]));
+
+ new_quads[0]->set_line_orientation(0,line_orientation[6]);
+ new_quads[0]->set_line_orientation(1,line_orientation[10]);
+ new_quads[0]->set_line_orientation(2,line_orientation[0]);
+
+ new_quads[1]->set_line_orientation(0,line_orientation[7]);
+ new_quads[1]->set_line_orientation(1,line_orientation[11]);
+ new_quads[1]->set_line_orientation(3,line_orientation[1]);
+
+ new_quads[2]->set_line_orientation(0,line_orientation[2]);
+ new_quads[2]->set_line_orientation(2,line_orientation[4]);
+ new_quads[2]->set_line_orientation(3,line_orientation[8]);
+
+ new_quads[3]->set_line_orientation(1,line_orientation[3]);
+ new_quads[3]->set_line_orientation(2,line_orientation[5]);
+ new_quads[3]->set_line_orientation(3,line_orientation[9]);
+
+ // the quads are
+ // numbered as follows:
+ //
+ // planes in the interior
+ // of the old hex:
+ // *
+ // /|
+ // / | x
+ // / | *-------* *---------*
+ // * | | 3 | / 1 /
+ // | | *-------* *---------*
+ // | * | 2 | / 0 /
+ // | / *-------*y *---------*x
+ // | /
+ // |/
+ // *
+ //
+ // children of the faces
+ // of the old hex
+ // *-------* *-------*
+ // /| | / 19 /|
+ // * | 15 | *-------* |
+ // /|7*-------* / 18 /|11
+ // * |/| | *-------* |/|
+ // |6* | 14 | | 10* |
+ // |/|5*-------* | 13 |/|9*
+ // * |/ 17 / *-------* |/
+ // |4*-------* | |8*
+ // |/ 16 / | 12 |/
+ // *-------* *-------*
+ //
+ // note that we have to
+ // take care of the
+ // orientation of
+ // faces.
+ const unsigned int quad_indices_yz[20]
+ = {
+ new_quads[0]->index(), //0
+ new_quads[1]->index(),
+ new_quads[2]->index(),
+ new_quads[3]->index(),
+
+ hex->face(0)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[0],f_fl[0],f_ro[0])), //4
+ hex->face(0)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(1,f_or[0],f_fl[0],f_ro[0])),
+ hex->face(0)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(2,f_or[0],f_fl[0],f_ro[0])),
+ hex->face(0)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[0],f_fl[0],f_ro[0])),
+
+ hex->face(1)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[1],f_fl[1],f_ro[1])), //8
+ hex->face(1)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(1,f_or[1],f_fl[1],f_ro[1])),
+ hex->face(1)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(2,f_or[1],f_fl[1],f_ro[1])),
+ hex->face(1)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[1],f_fl[1],f_ro[1])),
+
+ hex->face(2)->child_index( child_at_origin[hex->face(2)->refinement_case()-1][f_fl[2]][f_ro[2]]), //12
+ hex->face(2)->child_index(1-child_at_origin[hex->face(2)->refinement_case()-1][f_fl[2]][f_ro[2]]),
+
+ hex->face(3)->child_index( child_at_origin[hex->face(3)->refinement_case()-1][f_fl[3]][f_ro[3]]), //14
+ hex->face(3)->child_index(1-child_at_origin[hex->face(3)->refinement_case()-1][f_fl[3]][f_ro[3]]),
+
+ hex->face(4)->child_index( child_at_origin[hex->face(4)->refinement_case()-1][f_fl[4]][f_ro[4]]), //16
+ hex->face(4)->child_index(1-child_at_origin[hex->face(4)->refinement_case()-1][f_fl[4]][f_ro[4]]),
+
+ hex->face(5)->child_index( child_at_origin[hex->face(5)->refinement_case()-1][f_fl[5]][f_ro[5]]), //18
+ hex->face(5)->child_index(1-child_at_origin[hex->face(5)->refinement_case()-1][f_fl[5]][f_ro[5]])
+ };
+ quad_indices=&quad_indices_yz[0];
+
+ new_hexes[0]->set (internal::Triangulation
+ ::TriaObject<3>(quad_indices[4],
+ quad_indices[8],
+ quad_indices[12],
+ quad_indices[2],
+ quad_indices[16],
+ quad_indices[0]));
+ new_hexes[1]->set (internal::Triangulation
+ ::TriaObject<3>(quad_indices[5],
+ quad_indices[9],
+ quad_indices[2],
+ quad_indices[14],
+ quad_indices[17],
+ quad_indices[1]));
+ new_hexes[2]->set (internal::Triangulation
+ ::TriaObject<3>(quad_indices[6],
+ quad_indices[10],
+ quad_indices[13],
+ quad_indices[3],
+ quad_indices[0],
+ quad_indices[18]));
+ new_hexes[3]->set (internal::Triangulation
+ ::TriaObject<3>(quad_indices[7],
+ quad_indices[11],
+ quad_indices[3],
+ quad_indices[15],
+ quad_indices[1],
+ quad_indices[19]));
+ break;
+ }
+ case RefinementCase<dim>::cut_xyz:
+ {
+ //////////////////////////////
+ //
+ // RefinementCase<dim>::cut_xyz
+ // isotropic refinement
+ //
+ // the refined cube will look
+ // like this:
+ //
+ // *----*----*
+ // / / /|
+ // *----*----* |
+ // / / /| *
+ // *----*----* |/|
+ // | | | * |
+ // | | |/| *
+ // *----*----* |/
+ // | | | *
+ // | | |/
+ // *----*----*
+ //
+
+ // find the next unused
+ // vertex and set it
+ // appropriately
+ while (triangulation.vertices_used[next_unused_vertex] == true)
+ ++next_unused_vertex;
+ Assert (next_unused_vertex < triangulation.vertices.size(),
+ ExcTooFewVerticesAllocated());
+ triangulation.vertices_used[next_unused_vertex] = true;
+
+ // the new vertex is
+ // definitely in the
+ // interior, so we need not
+ // worry about the boundary.
+ // let it be the average of
+ // the 26 vertices
+ // surrounding it. weight
+ // these vertices in the same
+ // way as they are weighted
+ // in the
+ // @p{MappingQ::set_laplace_on_hex_vector}
+ // function, and like the new
+ // vertex at the center of
+ // the quad is weighted (see
+ // above)
+ triangulation.vertices[next_unused_vertex] = Point<dim>();
+ // first add corners of hex
+ for (unsigned int vertex=0;
+ vertex<GeometryInfo<dim>::vertices_per_cell; ++vertex)
+ triangulation.vertices[next_unused_vertex] += hex->vertex(vertex) / 128;
+ // now add center of lines
+ for (unsigned int line=0;
+ line<GeometryInfo<dim>::lines_per_cell; ++line)
+ triangulation.vertices[next_unused_vertex] += hex->line(line)->child(0)->vertex(1) *
+ 7./192.;
+ // finally add centers of
+ // faces. note that vertex 3
+ // of child 0 is an invariant
+ // with respect to the face
+ // orientation, flip and
+ // rotation
+ for (unsigned int face=0;
+ face<GeometryInfo<dim>::faces_per_cell; ++face)
+ triangulation.vertices[next_unused_vertex] += hex->face(face)->isotropic_child(0)->vertex(3) *
+ 1./12.;
+
+ // set the data of the
+ // six lines. first
+ // collect the indices of
+ // the seven vertices
+ // (consider the two
+ // planes to be crossed
+ // to form the planes
+ // cutting the hex in two
+ // vertically and
+ // horizontally)
+ // *--3--* *--5--*
+ // / / / | | |
+ // 0--6--1 0--6--1
+ // / / / | | |
+ // *--2--* *--4--*
+ // the lines are numbered
+ // as follows:
+ // *--*--* *--*--*
+ // / 1 / | 5 |
+ // *2-*-3* *2-*-3*
+ // / 0 / | 4 |
+ // *--*--* *--*--*
+ //
+ const unsigned int vertex_indices_xyz[7]
+ = { middle_vertex_index<dim,spacedim>(hex->face(0)),
+ middle_vertex_index<dim,spacedim>(hex->face(1)),
+ middle_vertex_index<dim,spacedim>(hex->face(2)),
+ middle_vertex_index<dim,spacedim>(hex->face(3)),
+ middle_vertex_index<dim,spacedim>(hex->face(4)),
+ middle_vertex_index<dim,spacedim>(hex->face(5)),
+ next_unused_vertex
+ };
+ vertex_indices=&vertex_indices_xyz[0];
+
+ new_lines[0]->set (internal::Triangulation::
+ TriaObject<1>(vertex_indices[2], vertex_indices[6]));
+ new_lines[1]->set (internal::Triangulation::
+ TriaObject<1>(vertex_indices[6], vertex_indices[3]));
+ new_lines[2]->set (internal::Triangulation::
+ TriaObject<1>(vertex_indices[0], vertex_indices[6]));
+ new_lines[3]->set (internal::Triangulation::
+ TriaObject<1>(vertex_indices[6], vertex_indices[1]));
+ new_lines[4]->set (internal::Triangulation::
+ TriaObject<1>(vertex_indices[4], vertex_indices[6]));
+ new_lines[5]->set (internal::Triangulation::
+ TriaObject<1>(vertex_indices[6], vertex_indices[5]));
+
+ // again, first
+ // collect some data
+ // about the indices of
+ // the lines, with the
+ // following numbering:
+ // (note that face 0 and
+ // 1 each are shown twice
+ // for better
+ // readability)
+
+ // face 0: left plane
+ // * *
+ // /| /|
+ // * | * |
+ // /| * /| *
+ // * 1/| * |3|
+ // | * | | * |
+ // |/| * |2| *
+ // * 0/ * |/
+ // | * | *
+ // |/ |/
+ // * *
+ // face 1: right plane
+ // * *
+ // /| /|
+ // * | * |
+ // /| * /| *
+ // * 5/| * |7|
+ // | * | | * |
+ // |/| * |6| *
+ // * 4/ * |/
+ // | * | *
+ // |/ |/
+ // * *
+ // face 2: front plane
+ // (note: x,y exchanged)
+ // *---*---*
+ // | 11 |
+ // *-8-*-9-*
+ // | 10 |
+ // *---*---*
+ // face 3: back plane
+ // (note: x,y exchanged)
+ // *---*---*
+ // | 15 |
+ // *12-*-13*
+ // | 14 |
+ // *---*---*
+ // face 4: bottom plane
+ // *---*---*
+ // / 17 /
+ // *18-*-19*
+ // / 16 /
+ // *---*---*
+ // face 5: top plane
+ // *---*---*
+ // / 21 /
+ // *22-*-23*
+ // / 20 /
+ // *---*---*
+ // middle planes
+ // *---*---* *---*---*
+ // / 25 / | 29 |
+ // *26-*-27* *26-*-27*
+ // / 24 / | 28 |
+ // *---*---* *---*---*
+
+ // set up a list of line iterators
+ // first. from this, construct
+ // lists of line_indices and
+ // line orientations later on
+ const typename Triangulation<dim,spacedim>::raw_line_iterator
+ lines_xyz[30]
+ = {
+ hex->face(0)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[0],f_fl[0],f_ro[0]))
+ ->line(GeometryInfo<dim>::standard_to_real_face_line(1,f_or[0],f_fl[0],f_ro[0])), //0
+ hex->face(0)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[0],f_fl[0],f_ro[0]))
+ ->line(GeometryInfo<dim>::standard_to_real_face_line(0,f_or[0],f_fl[0],f_ro[0])), //1
+ hex->face(0)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[0],f_fl[0],f_ro[0]))
+ ->line(GeometryInfo<dim>::standard_to_real_face_line(3,f_or[0],f_fl[0],f_ro[0])), //2
+ hex->face(0)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[0],f_fl[0],f_ro[0]))
+ ->line(GeometryInfo<dim>::standard_to_real_face_line(2,f_or[0],f_fl[0],f_ro[0])), //3
+
+ hex->face(1)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[1],f_fl[1],f_ro[1]))
+ ->line(GeometryInfo<dim>::standard_to_real_face_line(1,f_or[1],f_fl[1],f_ro[1])), //4
+ hex->face(1)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[1],f_fl[1],f_ro[1]))
+ ->line(GeometryInfo<dim>::standard_to_real_face_line(0,f_or[1],f_fl[1],f_ro[1])), //5
+ hex->face(1)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[1],f_fl[1],f_ro[1]))
+ ->line(GeometryInfo<dim>::standard_to_real_face_line(3,f_or[1],f_fl[1],f_ro[1])), //6
+ hex->face(1)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[1],f_fl[1],f_ro[1]))
+ ->line(GeometryInfo<dim>::standard_to_real_face_line(2,f_or[1],f_fl[1],f_ro[1])), //7
+
+ hex->face(2)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[2],f_fl[2],f_ro[2]))
+ ->line(GeometryInfo<dim>::standard_to_real_face_line(1,f_or[2],f_fl[2],f_ro[2])), //8
+ hex->face(2)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[2],f_fl[2],f_ro[2]))
+ ->line(GeometryInfo<dim>::standard_to_real_face_line(0,f_or[2],f_fl[2],f_ro[2])), //9
+ hex->face(2)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[2],f_fl[2],f_ro[2]))
+ ->line(GeometryInfo<dim>::standard_to_real_face_line(3,f_or[2],f_fl[2],f_ro[2])), //10
+ hex->face(2)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[2],f_fl[2],f_ro[2]))
+ ->line(GeometryInfo<dim>::standard_to_real_face_line(2,f_or[2],f_fl[2],f_ro[2])), //11
+
+ hex->face(3)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[3],f_fl[3],f_ro[3]))
+ ->line(GeometryInfo<dim>::standard_to_real_face_line(1,f_or[3],f_fl[3],f_ro[3])), //12
+ hex->face(3)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[3],f_fl[3],f_ro[3]))
+ ->line(GeometryInfo<dim>::standard_to_real_face_line(0,f_or[3],f_fl[3],f_ro[3])), //13
+ hex->face(3)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[3],f_fl[3],f_ro[3]))
+ ->line(GeometryInfo<dim>::standard_to_real_face_line(3,f_or[3],f_fl[3],f_ro[3])), //14
+ hex->face(3)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[3],f_fl[3],f_ro[3]))
+ ->line(GeometryInfo<dim>::standard_to_real_face_line(2,f_or[3],f_fl[3],f_ro[3])), //15
+
+ hex->face(4)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[4],f_fl[4],f_ro[4]))
+ ->line(GeometryInfo<dim>::standard_to_real_face_line(1,f_or[4],f_fl[4],f_ro[4])), //16
+ hex->face(4)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[4],f_fl[4],f_ro[4]))
+ ->line(GeometryInfo<dim>::standard_to_real_face_line(0,f_or[4],f_fl[4],f_ro[4])), //17
+ hex->face(4)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[4],f_fl[4],f_ro[4]))
+ ->line(GeometryInfo<dim>::standard_to_real_face_line(3,f_or[4],f_fl[4],f_ro[4])), //18
+ hex->face(4)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[4],f_fl[4],f_ro[4]))
+ ->line(GeometryInfo<dim>::standard_to_real_face_line(2,f_or[4],f_fl[4],f_ro[4])), //19
+
+ hex->face(5)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[5],f_fl[5],f_ro[5]))
+ ->line(GeometryInfo<dim>::standard_to_real_face_line(1,f_or[5],f_fl[5],f_ro[5])), //20
+ hex->face(5)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[5],f_fl[5],f_ro[5]))
+ ->line(GeometryInfo<dim>::standard_to_real_face_line(0,f_or[5],f_fl[5],f_ro[5])), //21
+ hex->face(5)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[5],f_fl[5],f_ro[5]))
+ ->line(GeometryInfo<dim>::standard_to_real_face_line(3,f_or[5],f_fl[5],f_ro[5])), //22
+ hex->face(5)->isotropic_child(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[5],f_fl[5],f_ro[5]))
+ ->line(GeometryInfo<dim>::standard_to_real_face_line(2,f_or[5],f_fl[5],f_ro[5])), //23
+
+ new_lines[0], //24
+ new_lines[1], //25
+ new_lines[2], //26
+ new_lines[3], //27
+ new_lines[4], //28
+ new_lines[5] //29
+ };
+
+ lines=&lines_xyz[0];
+
+ unsigned int line_indices_xyz[30];
+ for (unsigned int i=0; i<30; ++i)
+ line_indices_xyz[i]=lines[i]->index();
+ line_indices=&line_indices_xyz[0];
+
+ // the orientation of lines for the
+ // inner quads is quite tricky. as
+ // these lines are newly created
+ // ones and thus have no parents,
+ // they cannot inherit this
+ // property. set up an array and
+ // fill it with the respective
+ // values
+ bool line_orientation_xyz[30];
+
+ // note: for the first 24 lines
+ // (inner lines of the outer quads)
+ // the following holds: the second
+ // vertex of the even lines in
+ // standard orientation is the
+ // vertex in the middle of the
+ // quad, whereas for odd lines the
+ // first vertex is the same middle
+ // vertex.
+ for (unsigned int i=0; i<24; ++i)
+ if (lines[i]->vertex_index((i+1)%2)==vertex_indices[i/4])
+ line_orientation_xyz[i]=true;
+ else
+ {
+ // it must be the other way
+ // round then
+ Assert(lines[i]->vertex_index(i%2)==vertex_indices[i/4],
+ ExcInternalError());
+ line_orientation_xyz[i]=false;
+ }
+ // for the last 6 lines the line
+ // orientation is always true,
+ // since they were just constructed
+ // that way
+ for (unsigned int i=24; i<30; ++i)
+ line_orientation_xyz[i]=true;
+ line_orientation=&line_orientation_xyz[0];
+
+ // set up the 12 quads,
+ // numbered as follows
+ // (left quad numbering,
+ // right line numbering
+ // extracted from above)
+ //
+ // * *
+ // /| 21|
+ // * | * 15
+ // y/|3* 20| *
+ // * |/| * |/|
+ // |2* |x 11 * 14
+ // |/|1* |/| *
+ // * |/ * |17
+ // |0* 10 *
+ // |/ |16
+ // * *
+ //
+ // x
+ // *---*---* *22-*-23*
+ // | 5 | 7 | 1 29 5
+ // *---*---* *26-*-27*
+ // | 4 | 6 | 0 28 4
+ // *---*---*y *18-*-19*
+ //
+ // y
+ // *----*----* *-12-*-13-*
+ // / 10 / 11 / 3 25 7
+ // *----*----* *-26-*-27-*
+ // / 8 / 9 / 2 24 6
+ // *----*----*x *--8-*--9-*
+
+ new_quads[0]->set (internal::Triangulation
+ ::TriaObject<2>(line_indices[10],
+ line_indices[28],
+ line_indices[16],
+ line_indices[24]));
+ new_quads[1]->set (internal::Triangulation
+ ::TriaObject<2>(line_indices[28],
+ line_indices[14],
+ line_indices[17],
+ line_indices[25]));
+ new_quads[2]->set (internal::Triangulation
+ ::TriaObject<2>(line_indices[11],
+ line_indices[29],
+ line_indices[24],
+ line_indices[20]));
+ new_quads[3]->set (internal::Triangulation
+ ::TriaObject<2>(line_indices[29],
+ line_indices[15],
+ line_indices[25],
+ line_indices[21]));
+ new_quads[4]->set (internal::Triangulation
+ ::TriaObject<2>(line_indices[18],
+ line_indices[26],
+ line_indices[0],
+ line_indices[28]));
+ new_quads[5]->set (internal::Triangulation
+ ::TriaObject<2>(line_indices[26],
+ line_indices[22],
+ line_indices[1],
+ line_indices[29]));
+ new_quads[6]->set (internal::Triangulation
+ ::TriaObject<2>(line_indices[19],
+ line_indices[27],
+ line_indices[28],
+ line_indices[4]));
+ new_quads[7]->set (internal::Triangulation
+ ::TriaObject<2>(line_indices[27],
+ line_indices[23],
+ line_indices[29],
+ line_indices[5]));
+ new_quads[8]->set (internal::Triangulation
+ ::TriaObject<2>(line_indices[2],
+ line_indices[24],
+ line_indices[8],
+ line_indices[26]));
+ new_quads[9]->set (internal::Triangulation
+ ::TriaObject<2>(line_indices[24],
+ line_indices[6],
+ line_indices[9],
+ line_indices[27]));
+ new_quads[10]->set (internal::Triangulation
+ ::TriaObject<2>(line_indices[3],
+ line_indices[25],
+ line_indices[26],
+ line_indices[12]));
+ new_quads[11]->set (internal::Triangulation
+ ::TriaObject<2>(line_indices[25],
+ line_indices[7],
+ line_indices[27],
+ line_indices[13]));
+
+ // now reset the line_orientation
+ // flags of outer lines as they
+ // cannot be set in a loop (at
+ // least not easily)
+ new_quads[0]->set_line_orientation(0,line_orientation[10]);
+ new_quads[0]->set_line_orientation(2,line_orientation[16]);
+
+ new_quads[1]->set_line_orientation(1,line_orientation[14]);
+ new_quads[1]->set_line_orientation(2,line_orientation[17]);
+
+ new_quads[2]->set_line_orientation(0,line_orientation[11]);
+ new_quads[2]->set_line_orientation(3,line_orientation[20]);
+
+ new_quads[3]->set_line_orientation(1,line_orientation[15]);
+ new_quads[3]->set_line_orientation(3,line_orientation[21]);
+
+ new_quads[4]->set_line_orientation(0,line_orientation[18]);
+ new_quads[4]->set_line_orientation(2,line_orientation[0]);
+
+ new_quads[5]->set_line_orientation(1,line_orientation[22]);
+ new_quads[5]->set_line_orientation(2,line_orientation[1]);
+
+ new_quads[6]->set_line_orientation(0,line_orientation[19]);
+ new_quads[6]->set_line_orientation(3,line_orientation[4]);
+
+ new_quads[7]->set_line_orientation(1,line_orientation[23]);
+ new_quads[7]->set_line_orientation(3,line_orientation[5]);
+
+ new_quads[8]->set_line_orientation(0,line_orientation[2]);
+ new_quads[8]->set_line_orientation(2,line_orientation[8]);
+
+ new_quads[9]->set_line_orientation(1,line_orientation[6]);
+ new_quads[9]->set_line_orientation(2,line_orientation[9]);
+
+ new_quads[10]->set_line_orientation(0,line_orientation[3]);
+ new_quads[10]->set_line_orientation(3,line_orientation[12]);
+
+ new_quads[11]->set_line_orientation(1,line_orientation[7]);
+ new_quads[11]->set_line_orientation(3,line_orientation[13]);
+
+ /////////////////////////////////
+ // create the eight new hexes
+ //
+ // again first collect
+ // some data. here, we
+ // need the indices of a
+ // whole lotta
+ // quads.
+
+ // the quads are
+ // numbered as follows:
+ //
+ // planes in the interior
+ // of the old hex:
+ // *
+ // /|
+ // * |
+ // /|3* *---*---* *----*----*
+ // * |/| | 5 | 7 | / 10 / 11 /
+ // |2* | *---*---* *----*----*
+ // |/|1* | 4 | 6 | / 8 / 9 /
+ // * |/ *---*---*y *----*----*x
+ // |0*
+ // |/
+ // *
+ //
+ // children of the faces
+ // of the old hex
+ // *-------* *-------*
+ // /|25 27| /34 35/|
+ // 15| | / /19
+ // / | | /32 33/ |
+ // * |24 26| *-------*18 |
+ // 1413*-------* |21 23| 17*
+ // | /30 31/ | | /
+ // 12/ / | |16
+ // |/28 29/ |20 22|/
+ // *-------* *-------*
+ //
+ // note that we have to
+ // take care of the
+ // orientation of
+ // faces.
+ const unsigned int quad_indices_xyz[36]
+ = {
+ new_quads[0]->index(), //0
+ new_quads[1]->index(),
+ new_quads[2]->index(),
+ new_quads[3]->index(),
+ new_quads[4]->index(),
+ new_quads[5]->index(),
+ new_quads[6]->index(),
+ new_quads[7]->index(),
+ new_quads[8]->index(),
+ new_quads[9]->index(),
+ new_quads[10]->index(),
+ new_quads[11]->index(), //11
+
+ hex->face(0)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[0],f_fl[0],f_ro[0])), //12
+ hex->face(0)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(1,f_or[0],f_fl[0],f_ro[0])),
+ hex->face(0)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(2,f_or[0],f_fl[0],f_ro[0])),
+ hex->face(0)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[0],f_fl[0],f_ro[0])),
+
+ hex->face(1)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[1],f_fl[1],f_ro[1])), //16
+ hex->face(1)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(1,f_or[1],f_fl[1],f_ro[1])),
+ hex->face(1)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(2,f_or[1],f_fl[1],f_ro[1])),
+ hex->face(1)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[1],f_fl[1],f_ro[1])),
+
+ hex->face(2)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[2],f_fl[2],f_ro[2])), //20
+ hex->face(2)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(1,f_or[2],f_fl[2],f_ro[2])),
+ hex->face(2)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(2,f_or[2],f_fl[2],f_ro[2])),
+ hex->face(2)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[2],f_fl[2],f_ro[2])),
+
+ hex->face(3)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[3],f_fl[3],f_ro[3])), //24
+ hex->face(3)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(1,f_or[3],f_fl[3],f_ro[3])),
+ hex->face(3)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(2,f_or[3],f_fl[3],f_ro[3])),
+ hex->face(3)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[3],f_fl[3],f_ro[3])),
+
+ hex->face(4)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[4],f_fl[4],f_ro[4])), //28
+ hex->face(4)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(1,f_or[4],f_fl[4],f_ro[4])),
+ hex->face(4)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(2,f_or[4],f_fl[4],f_ro[4])),
+ hex->face(4)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[4],f_fl[4],f_ro[4])),
+
+ hex->face(5)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(0,f_or[5],f_fl[5],f_ro[5])), //32
+ hex->face(5)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(1,f_or[5],f_fl[5],f_ro[5])),
+ hex->face(5)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(2,f_or[5],f_fl[5],f_ro[5])),
+ hex->face(5)->isotropic_child_index(GeometryInfo<dim>::standard_to_real_face_vertex(3,f_or[5],f_fl[5],f_ro[5]))
+ };
+ quad_indices=&quad_indices_xyz[0];
+
+ // bottom children
+ new_hexes[0]->set (internal::Triangulation
+ ::TriaObject<3>(quad_indices[12],
+ quad_indices[0],
+ quad_indices[20],
+ quad_indices[4],
+ quad_indices[28],
+ quad_indices[8]));
+ new_hexes[1]->set (internal::Triangulation
+ ::TriaObject<3>(quad_indices[0],
+ quad_indices[16],
+ quad_indices[22],
+ quad_indices[6],
+ quad_indices[29],
+ quad_indices[9]));
+ new_hexes[2]->set (internal::Triangulation
+ ::TriaObject<3>(quad_indices[13],
+ quad_indices[1],
+ quad_indices[4],
+ quad_indices[24],
+ quad_indices[30],
+ quad_indices[10]));
+ new_hexes[3]->set (internal::Triangulation
+ ::TriaObject<3>(quad_indices[1],
+ quad_indices[17],
+ quad_indices[6],
+ quad_indices[26],
+ quad_indices[31],
+ quad_indices[11]));
+
+ // top children
+ new_hexes[4]->set (internal::Triangulation
+ ::TriaObject<3>(quad_indices[14],
+ quad_indices[2],
+ quad_indices[21],
+ quad_indices[5],
+ quad_indices[8],
+ quad_indices[32]));
+ new_hexes[5]->set (internal::Triangulation
+ ::TriaObject<3>(quad_indices[2],
+ quad_indices[18],
+ quad_indices[23],
+ quad_indices[7],
+ quad_indices[9],
+ quad_indices[33]));
+ new_hexes[6]->set (internal::Triangulation
+ ::TriaObject<3>(quad_indices[15],
+ quad_indices[3],
+ quad_indices[5],
+ quad_indices[25],
+ quad_indices[10],
+ quad_indices[34]));
+ new_hexes[7]->set (internal::Triangulation
+ ::TriaObject<3>(quad_indices[3],
+ quad_indices[19],
+ quad_indices[7],
+ quad_indices[27],
+ quad_indices[11],
+ quad_indices[35]));
+ break;
+ }
+ default:
+ // all refinement cases
+ // have been treated,
+ // there only remains
+ // RefinementCase<dim>::no_refinement
+ // as untreated
+ // enumeration
+ // value. However, in
+ // that case we should
+ // have aborted much
+ // earlier. thus we
+ // should never get here
+ Assert(false, ExcInternalError());
+ break;
+ }//switch (ref_case)
+
+ // and set face orientation
+ // flags. note that new faces in
+ // the interior of the mother cell
+ // always have a correctly oriented
+ // face, but the ones on the outer
+ // faces will inherit this flag
+ //
+ // the flag have been set to true
+ // for all faces initially, now go
+ // the other way round and reset
+ // faces that are at the boundary
+ // of the mother cube
+ //
+ // the same is true for the
+ // face_flip and face_rotation
+ // flags. however, the latter two
+ // are set to false by default as
+ // this is the standard value
+
+ // loop over all faces and all
+ // (relevant) subfaces of that in
+ // order to set the correct values
+ // for face_orientation, face_flip
+ // and face_rotation, which are
+ // inherited from the corresponding
+ // face of the mother cube
+ for (unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell; ++f)
+ for (unsigned int s=0;
+ s<std::max(GeometryInfo<dim-1>::n_children(GeometryInfo<dim>::face_refinement_case(ref_case,f)),
+ 1U);
+ ++s)
+ {
+ const unsigned int current_child
+ =GeometryInfo<dim>::child_cell_on_face(ref_case,
+ f,
+ s,
+ f_or[f],
+ f_fl[f],
+ f_ro[f],
+ GeometryInfo<dim>::face_refinement_case(ref_case,
+ f,
+ f_or[f],
+ f_fl[f],
+ f_ro[f]));
+ new_hexes[current_child]->set_face_orientation (f, f_or[f]);
+ new_hexes[current_child]->set_face_flip (f, f_fl[f]);
+ new_hexes[current_child]->set_face_rotation (f, f_ro[f]);
+ }
+
+ // now see if
+ // we have
+ // created
+ // cells that
+ // are
+ // distorted
+ // and if so
+ // add them to
+ // our list
+ if ((check_for_distorted_cells == true)
+ &&
+ has_distorted_children (hex,
+ internal::int2type<dim>(),
+ internal::int2type<spacedim>()))
+ cells_with_distorted_children.distorted_cells.push_back (hex);
+
+ // note that the
+ // refinement flag was
+ // already cleared at the
+ // beginning of this loop
+ }
+ }
+
+ // clear user data on quads. we used some of
+ // this data to indicate anisotropic
+ // refinemnt cases on faces. all data should
+ // be cleared by now, but the information
+ // whether we used indices or pointers is
+ // still present. reset it now to enable the
+ // user to use whichever he likes later on.
+ triangulation.faces->quads.clear_user_data();
+
+ // return the list with distorted children
+ return cells_with_distorted_children;
+ }
+
+
+ /**
+ * At the boundary of the domain, the new
+ * point on the face may be far inside the
+ * current cell, if the boundary has a
+ * strong curvature. If we allow anisotropic
+ * refinement here, the resulting cell may
+ * be strongly distorted. To prevent this,
+ * this function flags such cells for
+ * isotropic refinement. It is called
+ * automatically from
+ * prepare_coarsening_and_refinement().
+ *
+ * This function does nothing in
+ * 1d (therefore the
+ * specialization).
+ */
+ template <int spacedim>
+ static
+ void
+ prevent_distorted_boundary_cells (const Triangulation<1,spacedim> &);
+
+
+ template <int dim, int spacedim>
+ static
+ void
+ prevent_distorted_boundary_cells (Triangulation<dim,spacedim> &triangulation)
+ {
+ // If the codimension is
+ // one, we cannot perform
+ // this check yet.
+ if(spacedim>dim) return;
+
+ for (typename Triangulation<dim,spacedim>::cell_iterator
+ cell=triangulation.begin(); cell!=triangulation.end(); ++cell)
+ if (cell->at_boundary() &&
+ cell->refine_flag_set() &&
+ cell->refine_flag_set()!=RefinementCase<dim>::isotropic_refinement)
+ {
+ // The cell is at the boundary
+ // and it is flagged for
+ // anisotropic
+ // refinement. Therefore, we have
+ // a closer look
+ const RefinementCase<dim> ref_case=cell->refine_flag_set();
+ for (unsigned int face_no=0;
+ face_no<GeometryInfo<dim>::faces_per_cell;
+ ++face_no)
+ if (cell->face(face_no)->at_boundary())
+ {
+ // this is the critical
+ // face at the boundary.
+ if (GeometryInfo<dim>::face_refinement_case(ref_case,face_no)
+ !=RefinementCase<dim-1>::isotropic_refinement)
+ {
+ // up to now, we do not
+ // want to refine this
+ // cell along the face
+ // under consideration
+ // here.
+ const typename Triangulation<dim,spacedim>::face_iterator
+ face = cell->face(face_no);
+ // the new point on the
+ // boundary would be
+ // this one.
+ const Point<spacedim> new_bound
+ = triangulation.get_boundary(face->boundary_indicator())
+ .get_new_point_on_face (face);
+ // to check it,
+ // transform to the
+ // unit cell with
+ // Q1Mapping
+ const Point<dim> new_unit
+ = StaticMappingQ1<dim,spacedim>::mapping.
+ transform_real_to_unit_cell(cell,
+ new_bound);
+
+ // Now, we have to
+ // calculate the
+ // distance from the
+ // face in the unit
+ // cell.
+
+ // take the correct
+ // coordinate direction (0
+ // for faces 0 and 1, 1 for
+ // faces 2 and 3, 2 for faces
+ // 4 and 5) and substract the
+ // correct boundary value of
+ // the face (0 for faces 0,
+ // 2, and 4; 1 for faces 1, 3
+ // and 5)
+ const double dist = std::fabs(new_unit[face_no/2] - face_no%2);
+ // compare this with
+ // the empirical value
+ // allowed. if it is
+ // too big, flag the
+ // face for isotropic
+ // refinement
+ const double allowed=0.25;
+
+ if (dist>allowed)
+ cell->flag_for_face_refinement(face_no);
+ }//if flagged for anistropic refinement
+ }//if (cell->face(face)->at_boundary())
+ }//for all cells
+ }
+
+
+ /**
+ * Some dimension dependent stuff for
+ * mesh smoothing.
+ *
+ * At present, this function does nothing
+ * in 1d and 2D, but makes sure no two
+ * cells with a level difference greater
+ * than one share one line in 3D. This
+ * is a requirement needed for the
+ * interpolation of hanging nodes, since
+ * otherwise to steps of interpolation
+ * would be necessary. This would make
+ * the processes implemented in the
+ * @p ConstraintMatrix class much more
+ * complex, since these two steps of
+ * interpolation do not commute.
+ */
+ template <int dim, int spacedim>
+ static
+ void
+ prepare_refinement_dim_dependent (const Triangulation<dim,spacedim> &)
+ {
+ Assert (dim < 3,
+ ExcMessage ("Wrong function called -- there should "
+ "be a specialization."));
+ }
+
+
+ template <int spacedim>
+ static
+ void
+ prepare_refinement_dim_dependent (Triangulation<3,spacedim> &triangulation)
+ {
+ const unsigned int dim = 3;
+
+ // first clear flags on lines,
+ // since we need them to determine
+ // which lines will be refined
+ triangulation.clear_user_flags_line();
+
+ // also clear flags on hexes, since we need
+ // them to mark those cells which are to be
+ // coarsened
+ triangulation.clear_user_flags_hex();
+
+ // variable to store whether the
+ // mesh was changed in the present
+ // loop and in the whole process
+ bool mesh_changed = false;
+
+ do
+ {
+ mesh_changed = false;
+
+ // for this following, we need to know
+ // which cells are going to be
+ // coarsened, if we had to make a
+ // decision. the following function
+ // sets these flags:
+ triangulation.fix_coarsen_flags ();
+
+
+ // flag those lines that are refined and
+ // will not be coarsened and those that
+ // will be refined
+ for (typename Triangulation<dim,spacedim>::cell_iterator
+ cell=triangulation.begin(); cell!=triangulation.end(); ++cell)
+ if (cell->refine_flag_set())
+ {
+ for (unsigned int line=0; line<GeometryInfo<dim>::lines_per_cell; ++line)
+ if (GeometryInfo<dim>::line_refinement_case(cell->refine_flag_set(), line)
+ ==RefinementCase<1>::cut_x)
+ // flag a line, that will be
+ // refined
+ cell->line(line)->set_user_flag();
+ }
+ else if(cell->has_children() && !cell->child(0)->coarsen_flag_set())
+ {
+ for (unsigned int line=0; line<GeometryInfo<dim>::lines_per_cell; ++line)
+ if (GeometryInfo<dim>::line_refinement_case(cell->refinement_case(), line)
+ ==RefinementCase<1>::cut_x)
+ // flag a line, that is refined
+ // and will stay so
+ cell->line(line)->set_user_flag();
+ }
+ else if(cell->has_children() && cell->child(0)->coarsen_flag_set())
+ cell->set_user_flag();
+
+
+ // now check whether there are
+ // cells with lines that are
+ // more than once refined or
+ // that will be more than once
+ // refined. The first thing
+ // should never be the case, in
+ // the second case we flag the
+ // cell for refinement
+ for (typename Triangulation<dim,spacedim>::active_cell_iterator
+ cell=triangulation.last_active(); cell!=triangulation.end(); --cell)
+ for (unsigned int line=0; line<GeometryInfo<dim>::lines_per_cell; ++line)
+ {
+ if (cell->line(line)->has_children())
+ {
+ // if this line is
+ // refined, its
+ // children should
+ // not have further
+ // children
+ //
+ // however, if any of
+ // the children is
+ // flagged for
+ // further
+ // refinement, we
+ // need to refine
+ // this cell also (at
+ // least, if the cell
+ // is not already
+ // flagged)
+ bool offending_line_found = false;
+
+ for (unsigned int c=0; c<2; ++c)
+ {
+ Assert (cell->line(line)->child(c)->has_children() == false,
+ ExcInternalError());
+
+ if (cell->line(line)->child(c)->user_flag_set () &&
+ (GeometryInfo<dim>::line_refinement_case(cell->refine_flag_set(),
+ line)
+ ==RefinementCase<1>::no_refinement))
+ {
+ // tag this
+ // cell for
+ // refinement
+ cell->clear_coarsen_flag ();
+ // if anisotropic
+ // coarsening is
+ // allowed: extend the
+ // refine_flag in the
+ // needed direction,
+ // else set refine_flag
+ // (isotropic)
+ if (triangulation.smooth_grid &
+ Triangulation<dim,spacedim>::allow_anisotropic_smoothing)
+ cell->flag_for_line_refinement(line);
+ else
+ cell->set_refine_flag();
+
+ for (unsigned int l=0; l<GeometryInfo<dim>::lines_per_cell; ++l)
+ if (GeometryInfo<dim>::line_refinement_case(cell->refine_flag_set(), line)
+ ==RefinementCase<1>::cut_x)
+ // flag a line,
+ // that will be
+ // refined
+ cell->line(l)->set_user_flag();
+ // note that
+ // we have
+ // changed
+ // the grid
+ offending_line_found = true;
+
+ // it may save us several
+ // loop iterations if we
+ // flag all lines of
+ // this cell now (and not
+ // at the outset of the
+ // next iteration) for
+ // refinement
+ for (unsigned int line=0;
+ line<GeometryInfo<dim>::lines_per_cell; ++line)
+ if (!cell->line(line)->has_children() &&
+ (GeometryInfo<dim>::line_refinement_case(cell->refine_flag_set(),
+ line)
+ !=RefinementCase<1>::no_refinement))
+ cell->line(line)->set_user_flag();
+
+ break;
+ }
+ }
+
+ if (offending_line_found)
+ {
+ mesh_changed = true;
+ break;
+ }
+ }
+ }
+
+
+ // there is another thing here:
+ // if any of the lines will be
+ // refined, then we may not
+ // coarsen the present cell
+ // similarly, if any of the lines
+ // *is* already refined, we may
+ // not coarsen the current
+ // cell. however, there's a
+ // catch: if the line is refined,
+ // but the cell behind it is
+ // going to be coarsened, then
+ // the situation changes. if we
+ // forget this second condition,
+ // the refine_and_coarsen_3d test
+ // will start to fail. note that
+ // to know which cells are going
+ // to be coarsened, the call for
+ // fix_coarsen_flags above is
+ // necessary
+ for (typename Triangulation<dim,spacedim>::cell_iterator
+ cell=triangulation.last(); cell!=triangulation.end(); --cell)
+ {
+ if (cell->user_flag_set())
+ for (unsigned int line=0; line<GeometryInfo<dim>::lines_per_cell; ++line)
+ if (cell->line(line)->has_children() &&
+ (cell->line(line)->child(0)->user_flag_set() ||
+ cell->line(line)->child(1)->user_flag_set()))
+ {
+ for (unsigned int c=0; c<cell->n_children(); ++c)
+ cell->child(c)->clear_coarsen_flag ();
+ cell->clear_user_flag();
+ for (unsigned int l=0; l<GeometryInfo<dim>::lines_per_cell; ++l)
+ if (GeometryInfo<dim>::line_refinement_case(cell->refinement_case(), l)
+ ==RefinementCase<1>::cut_x)
+ // flag a line, that is refined
+ // and will stay so
+ cell->line(l)->set_user_flag();
+ mesh_changed = true;
+ break;
+ }
+ }
+ }
+ while (mesh_changed == true);
+ }
+
+
+
+ /**
+ * Helper function for
+ * @p fix_coarsen_flags. Return wether
+ * coarsening of this cell is allowed.
+ * Coarsening can be forbidden if the
+ * neighboring cells are or will be
+ * refined twice along the common face.
+ */
+ template <int dim, int spacedim>
+ static
+ bool
+ coarsening_allowed (const typename Triangulation<dim,spacedim>::cell_iterator& cell)
+ {
+ // in 1d, coarsening is
+ // always allowed since we
+ // don't enforce the 2:1
+ // constraint there
+ if (dim == 1)
+ return true;
+
+ const RefinementCase<dim> ref_case = cell->refinement_case();
+ for (unsigned int n=0; n<GeometryInfo<dim>::faces_per_cell; ++n)
+ {
+ // if the cell is not refined
+ // along that face, coarsening
+ // will not change anything, so
+ // do nothing. the same applies,
+ // if the face is at the boandary
+ const RefinementCase<dim-1> face_ref_case =
+ GeometryInfo<dim>::face_refinement_case(cell->refinement_case(), n);
+
+ const unsigned int n_subfaces
+ = GeometryInfo<dim-1>::n_children(face_ref_case);
+
+ if (n_subfaces == 0 || cell->at_boundary(n))
+ continue;
+ for (unsigned int c=0; c<n_subfaces; ++c)
+ {
+ const typename Triangulation<dim,spacedim>::cell_iterator
+ child = cell->child(GeometryInfo<dim>::
+ child_cell_on_face(ref_case,
+ n,c));
+
+ const typename Triangulation<dim,spacedim>::cell_iterator
+ child_neighbor = child->neighbor(n);
+ if (!child->neighbor_is_coarser(n))
+ // in 2d, if the child's neighbor
+ // is coarser, then it has no
+ // children. however, in 3d it
+ // might be otherwise. consider
+ // for example, that our face
+ // might be refined with cut_x,
+ // but the neighbor is refined
+ // with cut_xy at that face. then
+ // the neighbor pointers of the
+ // children of our cell will point
+ // to the common neighbor cell,
+ // not to its children. what we
+ // really want to know in the
+ // following is, wether the
+ // neighbor cell is refined twice
+ // with reference to our cell.
+ // that only has to be asked, if
+ // the child's neighbor is not a
+ // coarser one.
+ if ((child_neighbor->has_children() &&
+ !child_neighbor->user_flag_set())||
+ // neighbor has children, which
+ // are further refined along
+ // the face, otherwise
+ // something went wrong in the
+ // contruction of neighbor
+ // pointers. then only allow
+ // coarsening if this neighbor
+ // will be coarsened as well
+ // (user_pointer is set). the
+ // same applies, if the
+ // neighbors children are not
+ // refined but will be after
+ // refinement
+ child_neighbor->refine_flag_set())
+ return false;
+ }
+ }
+ return true;
+ }
};
}
}
template <int dim, int spacedim>
Triangulation<dim, spacedim>::
Triangulation (const MeshSmoothing smooth_grid,
- const bool check_for_distorted_cells)
- :
- smooth_grid(smooth_grid),
- faces(NULL),
- anisotropic_refinement(false),
- check_for_distorted_cells(check_for_distorted_cells),
- vertex_to_boundary_id_map_1d (0)
+ const bool check_for_distorted_cells)
+ :
+ smooth_grid(smooth_grid),
+ faces(NULL),
+ anisotropic_refinement(false),
+ check_for_distorted_cells(check_for_distorted_cells),
+ vertex_to_boundary_id_map_1d (0)
{
if (dim == 1)
vertex_to_boundary_id_map_1d
template <int dim, int spacedim>
Triangulation<dim, spacedim>::
Triangulation (const Triangulation<dim, spacedim> & other)
- // do not set any subscriptors;
- // anyway, calling this constructor
- // is an error!
- :
- Subscriptor(),
- check_for_distorted_cells(other.check_for_distorted_cells),
- vertex_to_boundary_id_map_1d (0)
+ // do not set any subscriptors;
+ // anyway, calling this constructor
+ // is an error!
+ :
+ Subscriptor(),
+ check_for_distorted_cells(other.check_for_distorted_cells),
+ vertex_to_boundary_id_map_1d (0)
{
Assert (false, ExcInternalError());
}
levels.clear ();
delete faces;
- // the vertex_to_boundary_id_map_1d field
- // should be unused except in 1d
+ // the vertex_to_boundary_id_map_1d field
+ // should be unused except in 1d
Assert ((dim == 1)
- ||
- (vertex_to_boundary_id_map_1d == 0),
- ExcInternalError());
+ ||
+ (vertex_to_boundary_id_map_1d == 0),
+ ExcInternalError());
delete vertex_to_boundary_id_map_1d;
}
template <int dim, int spacedim>
void
Triangulation<dim, spacedim>::set_boundary (const types::boundary_id_t number,
- const Boundary<dim, spacedim>& boundary_object)
+ const Boundary<dim, spacedim>& boundary_object)
{
Assert(number < types::internal_face_boundary_id, ExcIndexRange(number,0,types::internal_face_boundary_id));
//if we have not found an entry
//connected with number, we return
//straight_boundary
- return straight_boundary;
+ return straight_boundary;
}
}
std::vector<types::boundary_id_t>
Triangulation<dim, spacedim>::get_boundary_indicators () const
{
- // in 1d, we store a map of all used
- // boundary indicators. use it for our
- // purposes
+ // in 1d, we store a map of all used
+ // boundary indicators. use it for our
+ // purposes
if (dim == 1)
{
std::vector<types::boundary_id_t> boundary_indicators;
for (std::map<unsigned int, types::boundary_id_t>::const_iterator
- p = vertex_to_boundary_id_map_1d->begin();
- p != vertex_to_boundary_id_map_1d->end();
- ++p)
- boundary_indicators.push_back (p->second);
+ p = vertex_to_boundary_id_map_1d->begin();
+ p != vertex_to_boundary_id_map_1d->end();
+ ++p)
+ boundary_indicators.push_back (p->second);
return boundary_indicators;
}
std::vector<bool> bi_exists(types::internal_face_boundary_id, false);
active_cell_iterator cell=begin_active();
for (; cell!=end(); ++cell)
- for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
- if (cell->at_boundary(face))
- bi_exists[cell->face(face)->boundary_indicator()]=true;
+ for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
+ if (cell->at_boundary(face))
+ bi_exists[cell->face(face)->boundary_indicator()]=true;
const unsigned int n_bi=
- std::count(bi_exists.begin(), bi_exists.end(), true);
+ std::count(bi_exists.begin(), bi_exists.end(), true);
std::vector<types::boundary_id_t> boundary_indicators(n_bi);
unsigned int bi_counter=0;
for (unsigned int i=0; i<bi_exists.size(); ++i)
- if (bi_exists[i]==true)
- boundary_indicators[bi_counter++]=i;
+ if (bi_exists[i]==true)
+ boundary_indicators[bi_counter++]=i;
return boundary_indicators;
}
Assert (dim == 1 || old_tria.faces != NULL, ExcInternalError());
- // copy normal elements
+ // copy normal elements
vertices = old_tria.vertices;
vertices_used = old_tria.vertices_used;
anisotropic_refinement = old_tria.anisotropic_refinement;
levels.reserve (old_tria.levels.size());
for (unsigned int level=0; level<old_tria.levels.size(); ++level)
levels.push_back (new
- internal::Triangulation::
- TriaLevel<dim>(*old_tria.levels[level]));
+ internal::Triangulation::
+ TriaLevel<dim>(*old_tria.levels[level]));
number_cache = old_tria.number_cache;
{
delete vertex_to_boundary_id_map_1d;
vertex_to_boundary_id_map_1d
- = (new std::map<unsigned int, types::boundary_id_t>
- (*old_tria.vertex_to_boundary_id_map_1d));
+ = (new std::map<unsigned int, types::boundary_id_t>
+ (*old_tria.vertex_to_boundary_id_map_1d));
}
- // inform RefinementListeners of old_tria of
- // the copy operation
+ // inform RefinementListeners of old_tria of
+ // the copy operation
old_tria.signals.copy (*this);
- // also inform all listeners that the
- // triangulation has been created
+ // also inform all listeners that the
+ // triangulation has been created
signals.create();
- // note that we need not copy the
- // subscriptor!
+ // note that we need not copy the
+ // subscriptor!
}
void
Triangulation<dim,spacedim>::
create_triangulation_compatibility (const std::vector<Point<spacedim> > &v,
- const std::vector<CellData<dim> > &cells,
- const SubCellData &subcelldata)
+ const std::vector<CellData<dim> > &cells,
+ const SubCellData &subcelldata)
{
std::vector<CellData<dim> > reordered_cells (cells);
SubCellData reordered_subcelldata (subcelldata);
- // in-place reordering of data
+ // in-place reordering of data
reorder_compatibility (reordered_cells, reordered_subcelldata);
- // now create triangulation from
- // reordered data
+ // now create triangulation from
+ // reordered data
create_triangulation(v, reordered_cells, reordered_subcelldata);
}
void
Triangulation<dim,spacedim>::
create_triangulation (const std::vector<Point<spacedim> > &v,
- const std::vector<CellData<dim> > &cells,
- const SubCellData &subcelldata)
+ const std::vector<CellData<dim> > &cells,
+ const SubCellData &subcelldata)
{
Assert (vertices.size() == 0, ExcTriangulationNotEmpty());
Assert (levels.size() == 0, ExcTriangulationNotEmpty());
Assert (faces == NULL, ExcTriangulationNotEmpty());
- // check that no forbidden arrays
- // are used
+ // check that no forbidden arrays
+ // are used
Assert (subcelldata.check_consistency(dim), ExcInternalError());
- // try to create a triangulation;
- // if this fails, we still want to
- // throw an exception but if we
- // just do so we'll get into
- // trouble because sometimes other
- // objects are already attached to
- // it:
+ // try to create a triangulation;
+ // if this fails, we still want to
+ // throw an exception but if we
+ // just do so we'll get into
+ // trouble because sometimes other
+ // objects are already attached to
+ // it:
try
{
internal::Triangulation::Implementation::create_triangulation (v, cells, subcelldata, *this);
compute_number_cache (*this, levels.size(), number_cache);
- // now verify that there are indeed
- // no distorted cells. as per the
- // documentation of this class, we
- // first collect all distorted
- // cells and then throw an
- // exception if there are any
+ // now verify that there are indeed
+ // no distorted cells. as per the
+ // documentation of this class, we
+ // first collect all distorted
+ // cells and then throw an
+ // exception if there are any
if (check_for_distorted_cells == true)
{
DistortedCellList distorted_cells = collect_distorted_coarse_cells (*this);
- // throw the array (and fill the
- // various location fields) if
- // there are distorted
- // cells. otherwise, just fall off
- // the end of the function
+ // throw the array (and fill the
+ // various location fields) if
+ // there are distorted
+ // cells. otherwise, just fall off
+ // the end of the function
AssertThrow (distorted_cells.distorted_cells.size() == 0,
- distorted_cells);
+ distorted_cells);
}
if (dim < spacedim)
{
Table<2,bool> correct(GeometryInfo< dim >::faces_per_cell,
- GeometryInfo< dim >::faces_per_cell);
+ GeometryInfo< dim >::faces_per_cell);
switch (dim)
- {
- case 1:
- {
- bool values [][2] = {{false,true},
- {true,false} };
- for (unsigned int i=0; i< GeometryInfo< dim >::faces_per_cell; ++i)
- for (unsigned int j=0; j< GeometryInfo< dim >::faces_per_cell; ++j)
- correct(i,j) = ( values[i][j]);
- break;
- }
- case 2:
- {
- bool values [][4]= {{false,true ,true , false},
- {true ,false,false, true },
- {true ,false,false, true },
- {false,true ,true , false} };
- for (unsigned int i=0; i< GeometryInfo< dim >::faces_per_cell; ++i)
- for (unsigned int j=0; j< GeometryInfo< dim >::faces_per_cell; ++j)
- correct(i,j) = ( values[i][j]);
- break;
- }
- default:
- Assert (false, ExcNotImplemented());
- }
+ {
+ case 1:
+ {
+ bool values [][2] = {{false,true},
+ {true,false} };
+ for (unsigned int i=0; i< GeometryInfo< dim >::faces_per_cell; ++i)
+ for (unsigned int j=0; j< GeometryInfo< dim >::faces_per_cell; ++j)
+ correct(i,j) = ( values[i][j]);
+ break;
+ }
+ case 2:
+ {
+ bool values [][4]= {{false,true ,true , false},
+ {true ,false,false, true },
+ {true ,false,false, true },
+ {false,true ,true , false} };
+ for (unsigned int i=0; i< GeometryInfo< dim >::faces_per_cell; ++i)
+ for (unsigned int j=0; j< GeometryInfo< dim >::faces_per_cell; ++j)
+ correct(i,j) = ( values[i][j]);
+ break;
+ }
+ default:
+ Assert (false, ExcNotImplemented());
+ }
std::list<active_cell_iterator> this_round, next_round;
begin_active()->set_user_flag ();
while (this_round.size() > 0)
- {
- for ( typename std::list<active_cell_iterator>::iterator cell = this_round.begin();
- cell != this_round.end(); ++cell)
- {
- for (unsigned int i = 0; i < GeometryInfo< dim >::faces_per_cell; ++i)
- {
- if ( !((*cell)->face(i)->at_boundary()) )
- {
- neighbor = (*cell)->neighbor(i);
-
- unsigned int cf = (*cell)->face_index(i);
- unsigned int j = 0;
- while(neighbor->face_index(j) != cf)
- {++j;}
-
- if ( (correct(i,j) && !(*cell)->direction_flag())
- ||
- (!correct(i,j) && (*cell)->direction_flag()) )
- {
- if (neighbor->user_flag_set() == false)
- {
- neighbor->set_direction_flag (false);
- neighbor->set_user_flag ();
- next_round.push_back (neighbor);
- }
- else
- Assert (neighbor->direction_flag() == false,
- ExcNonOrientableTriangulation());
-
- }
- }
- }
- }
-
- // Before we quit let's check
- // that if the triangulation
- // is disconnected that we
- // still get all cells
- if (next_round.size() == 0)
- for (active_cell_iterator cell = begin_active();
- cell != end(); ++cell)
- if (cell->user_flag_set() == false)
- {
- next_round.push_back (cell);
- cell->set_direction_flag (true);
- cell->set_user_flag ();
- break;
- }
-
- this_round = next_round;
- next_round.clear();
- }
+ {
+ for ( typename std::list<active_cell_iterator>::iterator cell = this_round.begin();
+ cell != this_round.end(); ++cell)
+ {
+ for (unsigned int i = 0; i < GeometryInfo< dim >::faces_per_cell; ++i)
+ {
+ if ( !((*cell)->face(i)->at_boundary()) )
+ {
+ neighbor = (*cell)->neighbor(i);
+
+ unsigned int cf = (*cell)->face_index(i);
+ unsigned int j = 0;
+ while(neighbor->face_index(j) != cf)
+ {++j;}
+
+ if ( (correct(i,j) && !(*cell)->direction_flag())
+ ||
+ (!correct(i,j) && (*cell)->direction_flag()) )
+ {
+ if (neighbor->user_flag_set() == false)
+ {
+ neighbor->set_direction_flag (false);
+ neighbor->set_user_flag ();
+ next_round.push_back (neighbor);
+ }
+ else
+ Assert (neighbor->direction_flag() == false,
+ ExcNonOrientableTriangulation());
+
+ }
+ }
+ }
+ }
+
+ // Before we quit let's check
+ // that if the triangulation
+ // is disconnected that we
+ // still get all cells
+ if (next_round.size() == 0)
+ for (active_cell_iterator cell = begin_active();
+ cell != end(); ++cell)
+ if (cell->user_flag_set() == false)
+ {
+ next_round.push_back (cell);
+ cell->set_direction_flag (true);
+ cell->set_user_flag ();
+ break;
+ }
+
+ this_round = next_round;
+ next_round.clear();
+ }
}
- // inform all listeners that the
- // triangulation has been created
+ // inform all listeners that the
+ // triangulation has been created
signals.create();
}
template <int dim, int spacedim>
void Triangulation<dim, spacedim>::distort_random (const double factor,
- const bool keep_boundary)
+ const bool keep_boundary)
{
internal::Triangulation::Implementation::distort_random (factor, keep_boundary, *this);
}
void Triangulation<dim, spacedim>::set_all_refine_flags ()
{
active_cell_iterator cell = begin_active(),
- endc = end();
+ endc = end();
for (; cell != endc; ++cell)
{
v.resize (dim*n_active_cells(), false);
std::vector<bool>::iterator i = v.begin();
active_cell_iterator cell = begin_active(),
- endc = end();
+ endc = end();
for (; cell!=endc; ++cell)
for (unsigned int j=0; j<dim; ++j,++i)
if (cell->refine_flag_set() & (1<<j) )
- *i = true;
+ *i = true;
Assert (i == v.end(), ExcInternalError());
}
std::vector<bool> v;
save_refine_flags (v);
write_bool_vector (mn_tria_refine_flags_begin, v, mn_tria_refine_flags_end,
- out);
+ out);
}
{
std::vector<bool> v;
read_bool_vector (mn_tria_refine_flags_begin, v, mn_tria_refine_flags_end,
- in);
+ in);
load_refine_flags (v);
}
AssertThrow (v.size() == dim*n_active_cells(), ExcGridReadError());
active_cell_iterator cell = begin_active(),
- endc = end();
+ endc = end();
std::vector<bool>::const_iterator i = v.begin();
for (; cell!=endc; ++cell)
{
unsigned int ref_case=0;
for(unsigned int j=0; j<dim; ++j, ++i)
- if (*i == true)
- ref_case+=1<<j;
+ if (*i == true)
+ ref_case+=1<<j;
Assert(ref_case<RefinementCase<dim>::isotropic_refinement+1,
- ExcGridReadError());
+ ExcGridReadError());
if (ref_case>0)
- cell->set_refine_flag(RefinementCase<dim>(ref_case));
+ cell->set_refine_flag(RefinementCase<dim>(ref_case));
else
- cell->clear_refine_flag();
+ cell->clear_refine_flag();
}
Assert (i == v.end(), ExcInternalError());
v.resize (n_active_cells(), false);
std::vector<bool>::iterator i = v.begin();
active_cell_iterator cell = begin_active(),
- endc = end();
+ endc = end();
for (; cell!=endc; ++cell, ++i)
*i = cell->coarsen_flag_set();
std::vector<bool> v;
save_coarsen_flags (v);
write_bool_vector (mn_tria_coarsen_flags_begin, v, mn_tria_coarsen_flags_end,
- out);
+ out);
}
{
std::vector<bool> v;
read_bool_vector (mn_tria_coarsen_flags_begin, v, mn_tria_coarsen_flags_end,
- in);
+ in);
load_coarsen_flags (v);
}
Assert (v.size() == n_active_cells(), ExcGridReadError());
active_cell_iterator cell = begin_active(),
- endc = end();
+ endc = end();
std::vector<bool>::const_iterator i = v.begin();
for (; cell!=endc; ++cell, ++i)
if (*i == true)
namespace
{
- // clear user data of cells
+ // clear user data of cells
template <int dim>
void clear_user_data (std::vector<internal::Triangulation::TriaLevel<dim>*> &levels)
{
}
- // clear user data of faces
+ // clear user data of faces
void clear_user_data (internal::Triangulation::TriaFaces<1> *)
{
- // nothing to do in 1d
+ // nothing to do in 1d
}
template <int dim, int spacedim>
void Triangulation<dim,spacedim>::clear_user_data ()
{
- // let functions in anonymous namespace do their work
+ // let functions in anonymous namespace do their work
dealii::clear_user_data (levels);
dealii::clear_user_data (faces);
}
namespace
{
void clear_user_flags_line (std::vector<internal::Triangulation::TriaLevel<1>*> &levels,
- internal::Triangulation::TriaFaces<1> *)
+ internal::Triangulation::TriaFaces<1> *)
{
for (unsigned int level=0; level<levels.size(); ++level)
levels[level]->cells.clear_user_flags();
template <int dim>
void clear_user_flags_line (std::vector<internal::Triangulation::TriaLevel<dim>*> &,
- internal::Triangulation::TriaFaces<dim> *faces)
+ internal::Triangulation::TriaFaces<dim> *faces)
{
faces->lines.clear_user_flags();
}
namespace
{
void clear_user_flags_quad (std::vector<internal::Triangulation::TriaLevel<1>*> &,
- internal::Triangulation::TriaFaces<1> *)
+ internal::Triangulation::TriaFaces<1> *)
{
- // nothing to do in 1d
+ // nothing to do in 1d
}
void clear_user_flags_quad (std::vector<internal::Triangulation::TriaLevel<2>*> &levels,
- internal::Triangulation::TriaFaces<2> *)
+ internal::Triangulation::TriaFaces<2> *)
{
for (unsigned int level=0; level<levels.size(); ++level)
levels[level]->cells.clear_user_flags();
template <int dim>
void clear_user_flags_quad (std::vector<internal::Triangulation::TriaLevel<dim>*> &,
- internal::Triangulation::TriaFaces<dim> *faces)
+ internal::Triangulation::TriaFaces<dim> *faces)
{
faces->quads.clear_user_flags();
}
namespace
{
void clear_user_flags_hex (std::vector<internal::Triangulation::TriaLevel<1>*> &,
- internal::Triangulation::TriaFaces<1> *)
+ internal::Triangulation::TriaFaces<1> *)
{
- // nothing to do in 1d
+ // nothing to do in 1d
}
void clear_user_flags_hex (std::vector<internal::Triangulation::TriaLevel<2>*> &,
- internal::Triangulation::TriaFaces<2> *)
+ internal::Triangulation::TriaFaces<2> *)
{
- // nothing to do in 2d
+ // nothing to do in 2d
}
void clear_user_flags_hex (std::vector<internal::Triangulation::TriaLevel<3>*> &levels,
- internal::Triangulation::TriaFaces<3> *)
+ internal::Triangulation::TriaFaces<3> *)
{
for (unsigned int level=0; level<levels.size(); ++level)
levels[level]->cells.clear_user_flags();
template <int dim, int spacedim>
void Triangulation<dim, spacedim>::save_user_flags (std::vector<bool> &v) const
{
- // clear vector and append
- // all the stuff later on
+ // clear vector and append
+ // all the stuff later on
v.clear ();
std::vector<bool> tmp;
Assert (v.size() == n_lines()+n_quads()+n_hexs(), ExcInternalError());
std::vector<bool> tmp;
- // first extract the flags
- // belonging to lines
+ // first extract the flags
+ // belonging to lines
tmp.insert (tmp.end(),
- v.begin(), v.begin()+n_lines());
- // and set the lines
+ v.begin(), v.begin()+n_lines());
+ // and set the lines
load_user_flags_line (tmp);
if (dim >= 2)
{
tmp.clear ();
tmp.insert (tmp.end(),
- v.begin()+n_lines(), v.begin()+n_lines()+n_quads());
+ v.begin()+n_lines(), v.begin()+n_lines()+n_quads());
load_user_flags_quad (tmp);
}
{
tmp.clear();
tmp.insert (tmp.end(),
- v.begin()+n_lines()+n_quads(), v.begin()+n_lines()+n_quads()+n_hexs());
+ v.begin()+n_lines()+n_quads(), v.begin()+n_lines()+n_quads()+n_hexs());
load_user_flags_hex (tmp);
}
v.resize (n_lines(), false);
std::vector<bool>::iterator i = v.begin();
line_iterator line = begin_line(),
- endl = end_line();
+ endl = end_line();
for (; line!=endl; ++line, ++i)
*i = line->user_flag_set();
std::vector<bool> v;
save_user_flags_line (v);
write_bool_vector (mn_tria_line_user_flags_begin, v, mn_tria_line_user_flags_end,
- out);
+ out);
}
{
std::vector<bool> v;
read_bool_vector (mn_tria_line_user_flags_begin, v, mn_tria_line_user_flags_end,
- in);
+ in);
load_user_flags_line (v);
}
Assert (v.size() == n_lines(), ExcGridReadError());
line_iterator line = begin_line(),
- endl = end_line();
+ endl = end_line();
std::vector<bool>::const_iterator i = v.begin();
for (; line!=endl; ++line, ++i)
if (*i == true)
{
std::vector<bool>::iterator i = v.begin();
quad_iterator quad = begin_quad(),
- endq = end_quad();
+ endq = end_quad();
for (; quad!=endq; ++quad, ++i)
- *i = get_user_flag (quad);
+ *i = get_user_flag (quad);
Assert (i == v.end(), ExcInternalError());
}
std::vector<bool> v;
save_user_flags_quad (v);
write_bool_vector (mn_tria_quad_user_flags_begin, v, mn_tria_quad_user_flags_end,
- out);
+ out);
}
{
std::vector<bool> v;
read_bool_vector (mn_tria_quad_user_flags_begin, v, mn_tria_quad_user_flags_end,
- in);
+ in);
load_user_flags_quad (v);
}
if (dim >= 2)
{
quad_iterator quad = begin_quad(),
- endq = end_quad();
+ endq = end_quad();
std::vector<bool>::const_iterator i = v.begin();
for (; quad!=endq; ++quad, ++i)
- if (*i == true)
- set_user_flag(quad);
- else
- clear_user_flag(quad);
+ if (*i == true)
+ set_user_flag(quad);
+ else
+ clear_user_flag(quad);
Assert (i == v.end(), ExcInternalError());
}
{
std::vector<bool>::iterator i = v.begin();
hex_iterator hex = begin_hex(),
- endh = end_hex();
+ endh = end_hex();
for (; hex!=endh; ++hex, ++i)
- *i = get_user_flag (hex);
+ *i = get_user_flag (hex);
Assert (i == v.end(), ExcInternalError());
}
std::vector<bool> v;
save_user_flags_hex (v);
write_bool_vector (mn_tria_hex_user_flags_begin, v, mn_tria_hex_user_flags_end,
- out);
+ out);
}
{
std::vector<bool> v;
read_bool_vector (mn_tria_hex_user_flags_begin, v, mn_tria_hex_user_flags_end,
- in);
+ in);
load_user_flags_hex (v);
}
if (dim >= 3)
{
hex_iterator hex = begin_hex(),
- endh = end_hex();
+ endh = end_hex();
std::vector<bool>::const_iterator i = v.begin();
for (; hex!=endh; ++hex, ++i)
- if (*i == true)
- set_user_flag(hex);
- else
- clear_user_flag(hex);
+ if (*i == true)
+ set_user_flag(hex);
+ else
+ clear_user_flag(hex);
Assert (i == v.end(), ExcInternalError());
}
template <int dim, int spacedim>
void Triangulation<dim, spacedim>::save_user_indices (std::vector<unsigned int> &v) const
{
- // clear vector and append all the
- // stuff later on
+ // clear vector and append all the
+ // stuff later on
v.clear ();
std::vector<unsigned int> tmp;
Assert (v.size() == n_lines()+n_quads()+n_hexs(), ExcInternalError());
std::vector<unsigned int> tmp;
- // first extract the indices
- // belonging to lines
+ // first extract the indices
+ // belonging to lines
tmp.insert (tmp.end(),
- v.begin(), v.begin()+n_lines());
- // and set the lines
+ v.begin(), v.begin()+n_lines());
+ // and set the lines
load_user_indices_line (tmp);
if (dim >= 2)
{
tmp.clear ();
tmp.insert (tmp.end(),
- v.begin()+n_lines(), v.begin()+n_lines()+n_quads());
+ v.begin()+n_lines(), v.begin()+n_lines()+n_quads());
load_user_indices_quad (tmp);
}
{
tmp.clear ();
tmp.insert (tmp.end(),
- v.begin()+n_lines()+n_quads(), v.begin()+n_lines()+n_quads()+n_hexs());
+ v.begin()+n_lines()+n_quads(), v.begin()+n_lines()+n_quads()+n_hexs());
load_user_indices_hex (tmp);
}
template <typename Iterator>
void set_user_index (const Iterator &i,
- const unsigned int x)
+ const unsigned int x)
{
i->set_user_index(x);
}
template <int structdim, int dim, int spacedim>
void set_user_index (const TriaIterator<InvalidAccessor<structdim,dim,spacedim> > &,
- const unsigned int)
+ const unsigned int)
{
Assert (false, ExcInternalError());
}
v.resize (n_lines(), 0);
std::vector<unsigned int>::iterator i = v.begin();
line_iterator line = begin_line(),
- endl = end_line();
+ endl = end_line();
for (; line!=endl; ++line, ++i)
*i = line->user_index();
}
Assert (v.size() == n_lines(), ExcGridReadError());
line_iterator line = begin_line(),
- endl = end_line();
+ endl = end_line();
std::vector<unsigned int>::const_iterator i = v.begin();
for (; line!=endl; ++line, ++i)
line->set_user_index(*i);
{
std::vector<unsigned int>::iterator i = v.begin();
quad_iterator quad = begin_quad(),
- endq = end_quad();
+ endq = end_quad();
for (; quad!=endq; ++quad, ++i)
- *i = get_user_index(quad);
+ *i = get_user_index(quad);
}
}
if (dim >= 2)
{
quad_iterator quad = begin_quad(),
- endq = end_quad();
+ endq = end_quad();
std::vector<unsigned int>::const_iterator i = v.begin();
for (; quad!=endq; ++quad, ++i)
- set_user_index(quad, *i);
+ set_user_index(quad, *i);
}
}
{
std::vector<unsigned int>::iterator i = v.begin();
hex_iterator hex = begin_hex(),
- endh = end_hex();
+ endh = end_hex();
for (; hex!=endh; ++hex, ++i)
- *i = get_user_index(hex);
+ *i = get_user_index(hex);
}
}
if (dim >= 3)
{
hex_iterator hex = begin_hex(),
- endh = end_hex();
+ endh = end_hex();
std::vector<unsigned int>::const_iterator i = v.begin();
for (; hex!=endh; ++hex, ++i)
- set_user_index(hex, *i);
+ set_user_index(hex, *i);
}
}
template <typename Iterator>
void set_user_pointer (const Iterator &i,
- void * x)
+ void * x)
{
i->set_user_pointer(x);
}
template <int structdim, int dim, int spacedim>
void set_user_pointer (const TriaIterator<InvalidAccessor<structdim,dim,spacedim> > &,
- void *)
+ void *)
{
Assert (false, ExcInternalError());
}
template <int dim, int spacedim>
void Triangulation<dim, spacedim>::save_user_pointers (std::vector<void *> &v) const
{
- // clear vector and append all the
- // stuff later on
+ // clear vector and append all the
+ // stuff later on
v.clear ();
std::vector<void *> tmp;
Assert (v.size() == n_lines()+n_quads()+n_hexs(), ExcInternalError());
std::vector<void *> tmp;
- // first extract the pointers
- // belonging to lines
+ // first extract the pointers
+ // belonging to lines
tmp.insert (tmp.end(),
- v.begin(), v.begin()+n_lines());
- // and set the lines
+ v.begin(), v.begin()+n_lines());
+ // and set the lines
load_user_pointers_line (tmp);
if (dim >= 2)
{
tmp.clear ();
tmp.insert (tmp.end(),
- v.begin()+n_lines(), v.begin()+n_lines()+n_quads());
+ v.begin()+n_lines(), v.begin()+n_lines()+n_quads());
load_user_pointers_quad (tmp);
}
{
tmp.clear ();
tmp.insert (tmp.end(),
- v.begin()+n_lines()+n_quads(), v.begin()+n_lines()+n_quads()+n_hexs());
+ v.begin()+n_lines()+n_quads(), v.begin()+n_lines()+n_quads()+n_hexs());
load_user_pointers_hex (tmp);
}
v.resize (n_lines(), 0);
std::vector<void *>::iterator i = v.begin();
line_iterator line = begin_line(),
- endl = end_line();
+ endl = end_line();
for (; line!=endl; ++line, ++i)
*i = line->user_pointer();
}
Assert (v.size() == n_lines(), ExcGridReadError());
line_iterator line = begin_line(),
- endl = end_line();
+ endl = end_line();
std::vector<void *>::const_iterator i = v.begin();
for (; line!=endl; ++line, ++i)
line->set_user_pointer(*i);
{
std::vector<void *>::iterator i = v.begin();
quad_iterator quad = begin_quad(),
- endq = end_quad();
+ endq = end_quad();
for (; quad!=endq; ++quad, ++i)
- *i = get_user_pointer(quad);
+ *i = get_user_pointer(quad);
}
}
if (dim >= 2)
{
quad_iterator quad = begin_quad(),
- endq = end_quad();
+ endq = end_quad();
std::vector<void *>::const_iterator i = v.begin();
for (; quad!=endq; ++quad, ++i)
- set_user_pointer(quad, *i);
+ set_user_pointer(quad, *i);
}
}
{
std::vector<void *>::iterator i = v.begin();
hex_iterator hex = begin_hex(),
- endh = end_hex();
+ endh = end_hex();
for (; hex!=endh; ++hex, ++i)
- *i = get_user_pointer(hex);
+ *i = get_user_pointer(hex);
}
}
if (dim >= 3)
{
hex_iterator hex = begin_hex(),
- endh = end_hex();
+ endh = end_hex();
std::vector<void *>::const_iterator i = v.begin();
for (; hex!=endh; ++hex, ++i)
- set_user_pointer(hex, *i);
+ set_user_pointer(hex, *i);
}
}
switch (dim)
{
case 1:
- return begin_raw_line (level);
+ return begin_raw_line (level);
case 2:
- return begin_raw_quad (level);
+ return begin_raw_quad (level);
case 3:
- return begin_raw_hex (level);
+ return begin_raw_hex (level);
default:
- Assert (false, ExcNotImplemented());
- return raw_cell_iterator();
+ Assert (false, ExcNotImplemented());
+ return raw_cell_iterator();
}
}
switch (dim)
{
case 1:
- return begin_line (level);
+ return begin_line (level);
case 2:
- return begin_quad (level);
+ return begin_quad (level);
case 3:
- return begin_hex (level);
+ return begin_hex (level);
default:
- Assert (false, ExcImpossibleInDim(dim));
- return cell_iterator();
+ Assert (false, ExcImpossibleInDim(dim));
+ return cell_iterator();
}
}
switch (dim)
{
case 1:
- return begin_active_line (level);
+ return begin_active_line (level);
case 2:
- return begin_active_quad (level);
+ return begin_active_quad (level);
case 3:
- return begin_active_hex (level);
+ return begin_active_hex (level);
default:
- Assert (false, ExcNotImplemented());
- return active_cell_iterator();
+ Assert (false, ExcNotImplemented());
+ return active_cell_iterator();
}
}
switch (dim)
{
case 1:
- return last_raw_line ();
+ return last_raw_line ();
case 2:
- return last_raw_quad ();
+ return last_raw_quad ();
case 3:
- return last_raw_hex ();
+ return last_raw_hex ();
default:
- Assert (false, ExcNotImplemented());
- return raw_cell_iterator();
+ Assert (false, ExcNotImplemented());
+ return raw_cell_iterator();
}
}
switch (dim)
{
case 1:
- return last_raw_line (level);
+ return last_raw_line (level);
case 2:
- return last_raw_quad (level);
+ return last_raw_quad (level);
case 3:
- return last_raw_hex (level);
+ return last_raw_hex (level);
default:
- Assert (false, ExcNotImplemented());
- return raw_cell_iterator();
+ Assert (false, ExcNotImplemented());
+ return raw_cell_iterator();
}
}
switch (dim)
{
case 1:
- return last_line ();
+ return last_line ();
case 2:
- return last_quad ();
+ return last_quad ();
case 3:
- return last_hex ();
+ return last_hex ();
default:
- Assert (false, ExcNotImplemented());
- return cell_iterator();
+ Assert (false, ExcNotImplemented());
+ return cell_iterator();
}
}
switch (dim)
{
case 1:
- return last_line (level);
+ return last_line (level);
case 2:
- return last_quad (level);
+ return last_quad (level);
case 3:
- return last_hex (level);
+ return last_hex (level);
default:
- Assert (false, ExcNotImplemented());
- return cell_iterator();
+ Assert (false, ExcNotImplemented());
+ return cell_iterator();
}
}
switch (dim)
{
case 1:
- return last_active_line ();
+ return last_active_line ();
case 2:
- return last_active_quad ();
+ return last_active_quad ();
case 3:
- return last_active_hex ();
+ return last_active_hex ();
default:
- Assert (false, ExcNotImplemented());
- return active_cell_iterator();
+ Assert (false, ExcNotImplemented());
+ return active_cell_iterator();
}
}
switch (dim)
{
case 1:
- return last_active_line (level);
+ return last_active_line (level);
case 2:
- return last_active_quad (level);
+ return last_active_quad (level);
case 3:
- return last_active_hex (level);
+ return last_active_hex (level);
default:
- Assert (false, ExcNotImplemented());
- return active_cell_iterator();
+ Assert (false, ExcNotImplemented());
+ return active_cell_iterator();
}
}
switch (dim)
{
case 1:
- return end_line();
+ return end_line();
case 2:
- return end_quad();
+ return end_quad();
case 3:
- return end_hex();
+ return end_hex();
default:
- Assert (false, ExcImpossibleInDim(dim));
- return raw_cell_iterator();
+ Assert (false, ExcImpossibleInDim(dim));
+ return raw_cell_iterator();
}
}
Triangulation<dim, spacedim>::end_raw (const unsigned int level) const
{
return (level == levels.size()-1 ?
- end() :
- begin_raw (level+1));
+ end() :
+ begin_raw (level+1));
}
Triangulation<dim, spacedim>::end (const unsigned int level) const
{
return (level == levels.size()-1 ?
- cell_iterator(end()) :
- begin (level+1));
+ cell_iterator(end()) :
+ begin (level+1));
}
Triangulation<dim, spacedim>::end_active (const unsigned int level) const
{
return (level == levels.size()-1 ?
- active_cell_iterator(end()) :
- begin_active (level+1));
+ active_cell_iterator(end()) :
+ begin_active (level+1));
}
switch (dim)
{
case 1:
- Assert (false, ExcImpossibleInDim(1));
- return raw_face_iterator();
+ Assert (false, ExcImpossibleInDim(1));
+ return raw_face_iterator();
case 2:
- return begin_raw_line ();
+ return begin_raw_line ();
case 3:
- return begin_raw_quad ();
+ return begin_raw_quad ();
default:
- Assert (false, ExcNotImplemented());
- return raw_face_iterator ();
+ Assert (false, ExcNotImplemented());
+ return raw_face_iterator ();
}
}
switch (dim)
{
case 1:
- Assert (false, ExcImpossibleInDim(1));
- return raw_face_iterator();
+ Assert (false, ExcImpossibleInDim(1));
+ return raw_face_iterator();
case 2:
- return begin_line ();
+ return begin_line ();
case 3:
- return begin_quad ();
+ return begin_quad ();
default:
- Assert (false, ExcNotImplemented());
- return face_iterator ();
+ Assert (false, ExcNotImplemented());
+ return face_iterator ();
}
}
switch (dim)
{
case 1:
- Assert (false, ExcImpossibleInDim(1));
- return raw_face_iterator();
+ Assert (false, ExcImpossibleInDim(1));
+ return raw_face_iterator();
case 2:
- return begin_active_line ();
+ return begin_active_line ();
case 3:
- return begin_active_quad ();
+ return begin_active_quad ();
default:
- Assert (false, ExcNotImplemented());
- return active_face_iterator ();
+ Assert (false, ExcNotImplemented());
+ return active_face_iterator ();
}
}
switch (dim)
{
case 1:
- Assert (false, ExcImpossibleInDim(1));
- return raw_face_iterator();
+ Assert (false, ExcImpossibleInDim(1));
+ return raw_face_iterator();
case 2:
- return end_line ();
+ return end_line ();
case 3:
- return end_quad ();
+ return end_quad ();
default:
- Assert (false, ExcNotImplemented());
- return raw_face_iterator ();
+ Assert (false, ExcNotImplemented());
+ return raw_face_iterator ();
}
}
switch (dim)
{
case 1:
- Assert (false, ExcImpossibleInDim(1));
- return raw_face_iterator();
+ Assert (false, ExcImpossibleInDim(1));
+ return raw_face_iterator();
case 2:
- return last_raw_line ();
+ return last_raw_line ();
case 3:
- return last_raw_quad ();
+ return last_raw_quad ();
default:
- Assert (false, ExcNotImplemented());
- return raw_face_iterator ();
+ Assert (false, ExcNotImplemented());
+ return raw_face_iterator ();
}
}
switch (dim)
{
case 1:
- Assert (false, ExcImpossibleInDim(1));
- return raw_face_iterator();
+ Assert (false, ExcImpossibleInDim(1));
+ return raw_face_iterator();
case 2:
- return last_line ();
+ return last_line ();
case 3:
- return last_quad ();
+ return last_quad ();
default:
- Assert (false, ExcNotImplemented());
- return raw_face_iterator ();
+ Assert (false, ExcNotImplemented());
+ return raw_face_iterator ();
}
}
switch (dim)
{
case 1:
- Assert (false, ExcImpossibleInDim(1));
- return raw_face_iterator();
+ Assert (false, ExcImpossibleInDim(1));
+ return raw_face_iterator();
case 2:
- return last_active_line ();
+ return last_active_line ();
case 3:
- return last_active_quad ();
+ return last_active_quad ();
default:
- Assert (false, ExcNotImplemented());
- return raw_face_iterator ();
+ Assert (false, ExcNotImplemented());
+ return raw_face_iterator ();
}
}
switch (dim)
{
case 1:
- Assert (level<levels.size(), ExcInvalidLevel(level));
+ Assert (level<levels.size(), ExcInvalidLevel(level));
- if (levels[level]->cells.cells.size() == 0)
- return end_line ();
+ if (levels[level]->cells.cells.size() == 0)
+ return end_line ();
- return raw_line_iterator (const_cast<Triangulation<dim,spacedim>*>(this),
- level,
- 0);
+ return raw_line_iterator (const_cast<Triangulation<dim,spacedim>*>(this),
+ level,
+ 0);
default:
- Assert (level == 0, ExcFacesHaveNoLevel());
- return raw_line_iterator (const_cast<Triangulation<dim, spacedim>*>(this),
- 0,
- 0);
+ Assert (level == 0, ExcFacesHaveNoLevel());
+ return raw_line_iterator (const_cast<Triangulation<dim, spacedim>*>(this),
+ 0,
+ 0);
}
}
typename Triangulation<dim, spacedim>::line_iterator
Triangulation<dim, spacedim>::begin_line (const unsigned int level) const
{
- // level is checked in begin_raw
+ // level is checked in begin_raw
raw_line_iterator ri = begin_raw_line (level);
if (ri.state() != IteratorState::valid)
return ri;
typename Triangulation<dim, spacedim>::active_line_iterator
Triangulation<dim, spacedim>::begin_active_line (const unsigned int level) const
{
- // level is checked in begin_raw
+ // level is checked in begin_raw
line_iterator i = begin_line (level);
if (i.state() != IteratorState::valid)
return i;
Triangulation<dim, spacedim>::end_line () const
{
return raw_line_iterator (const_cast<Triangulation<dim, spacedim>*>(this),
- -1,
- -1);
+ -1,
+ -1);
}
switch (dim)
{
case 1:
- Assert (level<levels.size(), ExcInvalidLevel(level));
- Assert (levels[level]->cells.cells.size() != 0,
- ExcEmptyLevel (level));
+ Assert (level<levels.size(), ExcInvalidLevel(level));
+ Assert (levels[level]->cells.cells.size() != 0,
+ ExcEmptyLevel (level));
- return raw_line_iterator (const_cast<Triangulation<dim,spacedim>*>(this),
- level,
- levels[level]->cells.cells.size()-1);
+ return raw_line_iterator (const_cast<Triangulation<dim,spacedim>*>(this),
+ level,
+ levels[level]->cells.cells.size()-1);
default:
- Assert (level == 0, ExcFacesHaveNoLevel());
- return raw_line_iterator (const_cast<Triangulation<dim, spacedim>*>(this),
- 0,
- n_raw_lines()-1);
+ Assert (level == 0, ExcFacesHaveNoLevel());
+ return raw_line_iterator (const_cast<Triangulation<dim, spacedim>*>(this),
+ 0,
+ n_raw_lines()-1);
}
}
typename Triangulation<dim, spacedim>::line_iterator
Triangulation<dim, spacedim>::last_line (const unsigned int level) const
{
- // level is checked in last_raw
+ // level is checked in last_raw
raw_line_iterator ri = last_raw_line(level);
if (ri->used()==true)
return ri;
typename Triangulation<dim, spacedim>::active_line_iterator
Triangulation<dim, spacedim>::last_active_line (const unsigned int level) const
{
- // level is checked in last_raw
+ // level is checked in last_raw
line_iterator i = last_line(level);
if (i->has_children()==false)
return i;
Assert (dim == 1 || level == 0, ExcFacesHaveNoLevel());
if (dim == 1)
return (level == levels.size()-1 ?
- end_line() :
- begin_raw_line (level+1));
+ end_line() :
+ begin_raw_line (level+1));
else
return end_line();
}
Assert (dim == 1 || level == 0, ExcFacesHaveNoLevel());
if (dim == 1)
return (level == levels.size()-1 ?
- line_iterator(end_line()) :
- begin_line (level+1));
+ line_iterator(end_line()) :
+ begin_line (level+1));
else
return line_iterator(end_line());
}
Assert (dim == 1 || level == 0, ExcFacesHaveNoLevel());
if (dim == 1)
return (level == levels.size()-1 ?
- active_line_iterator(end_line()) :
- begin_active_line (level+1));
+ active_line_iterator(end_line()) :
+ begin_active_line (level+1));
else
return active_line_iterator(end_line());
}
switch (dim)
{
case 1:
- Assert (false, ExcImpossibleInDim(1));
- return raw_hex_iterator();
+ Assert (false, ExcImpossibleInDim(1));
+ return raw_hex_iterator();
case 2:
{
- Assert (level<levels.size(), ExcInvalidLevel(level));
+ Assert (level<levels.size(), ExcInvalidLevel(level));
- if (levels[level]->cells.cells.size() == 0)
- return end_quad();
+ if (levels[level]->cells.cells.size() == 0)
+ return end_quad();
- return raw_quad_iterator (const_cast<Triangulation<dim,spacedim>*>(this),
- level,
- 0);
+ return raw_quad_iterator (const_cast<Triangulation<dim,spacedim>*>(this),
+ level,
+ 0);
}
case 3:
{
- Assert (level == 0, ExcFacesHaveNoLevel());
+ Assert (level == 0, ExcFacesHaveNoLevel());
- return raw_quad_iterator (const_cast<Triangulation<dim,spacedim>*>(this),
- 0,
- 0);
+ return raw_quad_iterator (const_cast<Triangulation<dim,spacedim>*>(this),
+ 0,
+ 0);
}
default:
- Assert (false, ExcNotImplemented());
- return raw_hex_iterator();
+ Assert (false, ExcNotImplemented());
+ return raw_hex_iterator();
}
}
typename Triangulation<dim,spacedim>::quad_iterator
Triangulation<dim,spacedim>::begin_quad (const unsigned int level) const
{
- // level is checked in begin_raw
+ // level is checked in begin_raw
raw_quad_iterator ri = begin_raw_quad (level);
if (ri.state() != IteratorState::valid)
return ri;
typename Triangulation<dim,spacedim>::active_quad_iterator
Triangulation<dim,spacedim>::begin_active_quad (const unsigned int level) const
{
- // level is checked in begin_raw
+ // level is checked in begin_raw
quad_iterator i = begin_quad (level);
if (i.state() != IteratorState::valid)
return i;
Assert (dim == 2 || level == 0, ExcFacesHaveNoLevel());
if (dim == 2)
return (level == levels.size()-1 ?
- end_quad() :
- begin_raw_quad (level+1));
+ end_quad() :
+ begin_raw_quad (level+1));
else
return end_quad();
}
Assert (dim == 2 || level == 0, ExcFacesHaveNoLevel());
if (dim == 2)
return (level == levels.size()-1 ?
- quad_iterator(end_quad()) :
- begin_quad (level+1));
+ quad_iterator(end_quad()) :
+ begin_quad (level+1));
else
return quad_iterator(end_quad());
}
Assert(dim == 2 || level == 0, ExcFacesHaveNoLevel());
if (dim == 2)
return (level == levels.size()-1 ?
- active_quad_iterator(end_quad()) :
- begin_active_quad (level+1));
+ active_quad_iterator(end_quad()) :
+ begin_active_quad (level+1));
else
return active_quad_iterator(end_quad());
}
Triangulation<dim,spacedim>::end_quad () const
{
return raw_quad_iterator (const_cast<Triangulation<dim, spacedim>*>(this),
- -1,
- -1);
+ -1,
+ -1);
}
switch (dim)
{
case 1:
- Assert (false, ExcImpossibleInDim(1));
- return raw_quad_iterator();
+ Assert (false, ExcImpossibleInDim(1));
+ return raw_quad_iterator();
case 2:
- Assert (level<levels.size(),
- ExcInvalidLevel(level));
- Assert (levels[level]->cells.cells.size() != 0,
- ExcEmptyLevel (level));
- return raw_quad_iterator (const_cast<Triangulation<dim,spacedim>*>(this),
- level,
- levels[level]->cells.cells.size()-1);
+ Assert (level<levels.size(),
+ ExcInvalidLevel(level));
+ Assert (levels[level]->cells.cells.size() != 0,
+ ExcEmptyLevel (level));
+ return raw_quad_iterator (const_cast<Triangulation<dim,spacedim>*>(this),
+ level,
+ levels[level]->cells.cells.size()-1);
case 3:
- Assert (level == 0, ExcFacesHaveNoLevel());
- return raw_quad_iterator (const_cast<Triangulation<dim,spacedim>*>(this),
- 0,
- n_raw_quads()-1);
+ Assert (level == 0, ExcFacesHaveNoLevel());
+ return raw_quad_iterator (const_cast<Triangulation<dim,spacedim>*>(this),
+ 0,
+ n_raw_quads()-1);
default:
- Assert (false, ExcNotImplemented());
- return raw_quad_iterator();
+ Assert (false, ExcNotImplemented());
+ return raw_quad_iterator();
}
}
typename Triangulation<dim,spacedim>::quad_iterator
Triangulation<dim,spacedim>::last_quad (const unsigned int level) const
{
- // level is checked in last_raw
+ // level is checked in last_raw
raw_quad_iterator ri = last_raw_quad(level);
if (ri->used()==true)
return ri;
typename Triangulation<dim,spacedim>::active_quad_iterator
Triangulation<dim,spacedim>::last_active_quad (const unsigned int level) const
{
- // level is checked in last_raw
+ // level is checked in last_raw
quad_iterator i = last_quad(level);
if (i->has_children()==false)
return i;
{
case 1:
case 2:
- Assert (false, ExcImpossibleInDim(1));
- return raw_hex_iterator();
+ Assert (false, ExcImpossibleInDim(1));
+ return raw_hex_iterator();
case 3:
{
- Assert (level<levels.size(), ExcInvalidLevel(level));
+ Assert (level<levels.size(), ExcInvalidLevel(level));
- if (levels[level]->cells.cells.size() == 0)
- return end_hex();
+ if (levels[level]->cells.cells.size() == 0)
+ return end_hex();
- return raw_hex_iterator (const_cast<Triangulation<dim,spacedim>*>(this),
- level,
- 0);
+ return raw_hex_iterator (const_cast<Triangulation<dim,spacedim>*>(this),
+ level,
+ 0);
}
default:
- Assert (false, ExcNotImplemented());
- return raw_hex_iterator();
+ Assert (false, ExcNotImplemented());
+ return raw_hex_iterator();
}
}
typename Triangulation<dim,spacedim>::hex_iterator
Triangulation<dim,spacedim>::begin_hex (const unsigned int level) const
{
- // level is checked in begin_raw
+ // level is checked in begin_raw
raw_hex_iterator ri = begin_raw_hex (level);
if (ri.state() != IteratorState::valid)
return ri;
typename Triangulation<dim, spacedim>::active_hex_iterator
Triangulation<dim, spacedim>::begin_active_hex (const unsigned int level) const
{
- // level is checked in begin_raw
+ // level is checked in begin_raw
hex_iterator i = begin_hex (level);
if (i.state() != IteratorState::valid)
return i;
Triangulation<dim, spacedim>::end_raw_hex (const unsigned int level) const
{
return (level == levels.size()-1 ?
- end_hex() :
- begin_raw_hex (level+1));
+ end_hex() :
+ begin_raw_hex (level+1));
}
Triangulation<dim, spacedim>::end_hex (const unsigned int level) const
{
return (level == levels.size()-1 ?
- hex_iterator(end_hex()) :
- begin_hex (level+1));
+ hex_iterator(end_hex()) :
+ begin_hex (level+1));
}
Triangulation<dim, spacedim>::end_active_hex (const unsigned int level) const
{
return (level == levels.size()-1 ?
- active_hex_iterator(end_hex()) :
- begin_active_hex (level+1));
+ active_hex_iterator(end_hex()) :
+ begin_active_hex (level+1));
}
Triangulation<dim, spacedim>::end_hex () const
{
return raw_hex_iterator (const_cast<Triangulation<dim,spacedim>*>(this),
- -1,
- -1);
+ -1,
+ -1);
}
{
case 1:
case 2:
- Assert (false, ExcImpossibleInDim(dim));
- return raw_hex_iterator();
+ Assert (false, ExcImpossibleInDim(dim));
+ return raw_hex_iterator();
case 3:
- Assert (level<levels.size(),
- ExcInvalidLevel(level));
- Assert (levels[level]->cells.cells.size() != 0,
- ExcEmptyLevel (level));
-
- return raw_hex_iterator (const_cast<Triangulation<dim,spacedim>*>(this),
- level,
- levels[level]->cells.cells.size()-1);
+ Assert (level<levels.size(),
+ ExcInvalidLevel(level));
+ Assert (levels[level]->cells.cells.size() != 0,
+ ExcEmptyLevel (level));
+
+ return raw_hex_iterator (const_cast<Triangulation<dim,spacedim>*>(this),
+ level,
+ levels[level]->cells.cells.size()-1);
default:
- Assert (false, ExcNotImplemented());
- return raw_hex_iterator();
+ Assert (false, ExcNotImplemented());
+ return raw_hex_iterator();
}
}
typename Triangulation<dim, spacedim>::hex_iterator
Triangulation<dim, spacedim>::last_hex (const unsigned int level) const
{
- // level is checked in last_raw
+ // level is checked in last_raw
raw_hex_iterator ri = last_raw_hex(level);
if (ri->used()==true)
return ri;
typename Triangulation<dim, spacedim>::active_hex_iterator
Triangulation<dim, spacedim>::last_active_hex (const unsigned int level) const
{
- // level is checked in last_raw
+ // level is checked in last_raw
hex_iterator i = last_hex(level);
if (i->has_children()==false)
return i;
switch (dim)
{
case 1:
- return 0;
+ return 0;
case 2:
- return n_lines();
+ return n_lines();
case 3:
- return n_quads();
+ return n_quads();
default:
- Assert (false, ExcNotImplemented());
+ Assert (false, ExcNotImplemented());
}
return 0;
}
switch (dim)
{
case 2:
- return n_raw_lines();
+ return n_raw_lines();
case 3:
- return n_raw_quads();
+ return n_raw_quads();
default:
- Assert (false, ExcNotImplemented());
+ Assert (false, ExcNotImplemented());
}
return 0;
}
switch (dim)
{
case 1:
- return 0;
+ return 0;
case 2:
- return n_active_lines();
+ return n_active_lines();
case 3:
- return n_active_quads();
+ return n_active_quads();
default:
- Assert (false, ExcNotImplemented());
+ Assert (false, ExcNotImplemented());
}
return 0;
}
switch (dim)
{
case 1:
- return n_raw_lines(level);
+ return n_raw_lines(level);
case 2:
- return n_raw_quads(level);
+ return n_raw_quads(level);
case 3:
- return n_raw_hexs(level);
+ return n_raw_hexs(level);
default:
- Assert (false, ExcNotImplemented());
+ Assert (false, ExcNotImplemented());
}
return 0;
}
switch (dim)
{
case 1:
- return n_lines(level);
+ return n_lines(level);
case 2:
- return n_quads(level);
+ return n_quads(level);
case 3:
- return n_hexs(level);
+ return n_hexs(level);
default:
- Assert (false, ExcNotImplemented());
+ Assert (false, ExcNotImplemented());
}
return 0;
}
switch (dim)
{
case 1:
- return n_active_lines(level);
+ return n_active_lines(level);
case 2:
- return n_active_quads(level);
+ return n_active_quads(level);
case 3:
- return n_active_hexs(level);
+ return n_active_hexs(level);
default:
- Assert (false, ExcNotImplemented());
+ Assert (false, ExcNotImplemented());
}
return 0;
}
unsigned int Triangulation<dim, spacedim>::n_lines (const unsigned int level) const
{
Assert (level < number_cache.n_lines_level.size(),
- ExcIndexRange (level, 0, number_cache.n_lines_level.size()));
+ ExcIndexRange (level, 0, number_cache.n_lines_level.size()));
Assert (dim == 1, ExcFacesHaveNoLevel());
return number_cache.n_lines_level[level];
}
unsigned int Triangulation<dim, spacedim>::n_active_lines (const unsigned int level) const
{
Assert (level < number_cache.n_lines_level.size(),
- ExcIndexRange (level, 0, number_cache.n_lines_level.size()));
+ ExcIndexRange (level, 0, number_cache.n_lines_level.size()));
Assert (dim == 1, ExcFacesHaveNoLevel());
return number_cache.n_active_lines_level[level];
{
Assert (dim == 2, ExcFacesHaveNoLevel());
Assert (level < number_cache.n_quads_level.size(),
- ExcIndexRange (level, 0, number_cache.n_quads_level.size()));
+ ExcIndexRange (level, 0, number_cache.n_quads_level.size()));
return number_cache.n_quads_level[level];
}
unsigned int Triangulation<dim, spacedim>::n_active_quads (const unsigned int level) const
{
Assert (level < number_cache.n_quads_level.size(),
- ExcIndexRange (level, 0, number_cache.n_quads_level.size()));
+ ExcIndexRange (level, 0, number_cache.n_quads_level.size()));
Assert (dim == 2, ExcFacesHaveNoLevel());
return number_cache.n_active_quads_level[level];
unsigned int Triangulation<3,3>::n_hexs (const unsigned int level) const
{
Assert (level < number_cache.n_hexes_level.size(),
- ExcIndexRange (level, 0, number_cache.n_hexes_level.size()));
+ ExcIndexRange (level, 0, number_cache.n_hexes_level.size()));
return number_cache.n_hexes_level[level];
}
unsigned int Triangulation<3,3>::n_active_hexs (const unsigned int level) const
{
Assert (level < number_cache.n_hexes_level.size(),
- ExcIndexRange (level, 0, number_cache.n_hexes_level.size()));
+ ExcIndexRange (level, 0, number_cache.n_hexes_level.size()));
return number_cache.n_active_hexes_level[level];
}
Triangulation<dim, spacedim>::n_used_vertices () const
{
return std::count_if (vertices_used.begin(), vertices_used.end(),
- std::bind2nd (std::equal_to<bool>(), true));
+ std::bind2nd (std::equal_to<bool>(), true));
}
unsigned int Triangulation<dim, spacedim>::max_adjacent_cells () const
{
cell_iterator cell = begin(0),
- endc = (n_levels() > 1 ? begin(1) : cell_iterator(end()));
- // store the largest index of the
- // vertices used on level 0
+ endc = (n_levels() > 1 ? begin(1) : cell_iterator(end()));
+ // store the largest index of the
+ // vertices used on level 0
unsigned int max_vertex_index = 0;
for (; cell!=endc; ++cell)
for (unsigned vertex=0; vertex<GeometryInfo<dim>::vertices_per_cell; ++vertex)
if (cell->vertex_index(vertex) > max_vertex_index)
- max_vertex_index = cell->vertex_index(vertex);
+ max_vertex_index = cell->vertex_index(vertex);
- // store the number of times a cell
- // touches a vertex. An unsigned
- // int should suffice, even for
- // larger dimensions
+ // store the number of times a cell
+ // touches a vertex. An unsigned
+ // int should suffice, even for
+ // larger dimensions
std::vector<unsigned short int> usage_count (max_vertex_index+1, 0);
- // touch a vertex's usage count
- // everytime we find an adjacent
- // element
+ // touch a vertex's usage count
+ // everytime we find an adjacent
+ // element
for (cell=begin(); cell!=endc; ++cell)
for (unsigned vertex=0; vertex<GeometryInfo<dim>::vertices_per_cell; ++vertex)
++usage_count[cell->vertex_index(vertex)];
return std::max (GeometryInfo<dim>::vertices_per_cell,
- static_cast<unsigned int>(*std::max_element (usage_count.begin(),
- usage_count.end())));
+ static_cast<unsigned int>(*std::max_element (usage_count.begin(),
+ usage_count.end())));
}
{
prepare_coarsening_and_refinement ();
- // verify a case with which we have had
- // some difficulty in the past (see the
- // deal.II/coarsening_* tests)
+ // verify a case with which we have had
+ // some difficulty in the past (see the
+ // deal.II/coarsening_* tests)
if (smooth_grid & limit_level_difference_at_vertices)
Assert (satisfies_level1_at_vertex_rule (*this) == true,
- ExcInternalError());
+ ExcInternalError());
- // Inform RefinementListeners
+ // Inform RefinementListeners
// about beginning of refinement.
signals.pre_refinement();
const DistortedCellList
cells_with_distorted_children = execute_refinement();
- // verify a case with which we have had
- // some difficulty in the past (see the
- // deal.II/coarsening_* tests)
+ // verify a case with which we have had
+ // some difficulty in the past (see the
+ // deal.II/coarsening_* tests)
if (smooth_grid & limit_level_difference_at_vertices)
Assert (satisfies_level1_at_vertex_rule (*this) == true,
- ExcInternalError());
+ ExcInternalError());
- // finally build up neighbor connectivity
- // information
+ // finally build up neighbor connectivity
+ // information
update_neighbors(*this);
- // Inform RefinementListeners
+ // Inform RefinementListeners
// about end of refinement.
signals.post_refinement();
AssertThrow (cells_with_distorted_children.distorted_cells.size() == 0,
- cells_with_distorted_children);
+ cells_with_distorted_children);
}
void
Triangulation<dim, spacedim>::clear_despite_subscriptions()
{
- // This is the former function
- // clear without the assertion in
- // the beginning.
+ // This is the former function
+ // clear without the assertion in
+ // the beginning.
for (unsigned int i=0; i<levels.size(); ++i)
delete levels[i];
levels.clear ();
- // re-compute number of lines
+ // re-compute number of lines
compute_number_cache (*this, levels.size(), number_cache);
#ifdef DEBUG
for (unsigned int level=0; level<levels.size(); ++level)
levels[level]->cells.monitor_memory (dim);
- // check whether really all
- // refinement flags are reset (also
- // of previously non-active cells
- // which we may not have
- // touched. If the refinement flag
- // of a non-active cell is set,
- // something went wrong since the
- // cell-accessors should have
- // caught this)
+ // check whether really all
+ // refinement flags are reset (also
+ // of previously non-active cells
+ // which we may not have
+ // touched. If the refinement flag
+ // of a non-active cell is set,
+ // something went wrong since the
+ // cell-accessors should have
+ // caught this)
cell_iterator cell = begin(),
- endc = end();
+ endc = end();
while (cell != endc)
Assert (!(cell++)->refine_flag_set(), ExcInternalError ());
#endif
template <int dim, int spacedim>
void Triangulation<dim, spacedim>::execute_coarsening ()
{
- // create a vector counting for each line how
- // many cells contain this line. in 3D, this
- // is used later on to decide which lines can
- // be deleted after coarsening a cell. in
- // other dimensions it will be ignored
+ // create a vector counting for each line how
+ // many cells contain this line. in 3D, this
+ // is used later on to decide which lines can
+ // be deleted after coarsening a cell. in
+ // other dimensions it will be ignored
std::vector<unsigned int> line_cell_count = count_cells_bounded_by_line (*this);
std::vector<unsigned int> quad_cell_count = count_cells_bounded_by_quad (*this);
- // loop over all cells. Flag all
- // cells of which all children are
- // flagged for
- // coarsening and delete the childrens'
- // flags. In effect, only those
- // cells are flagged of which originally
- // all children were flagged and for which
- // all children are on the same refinement
- // level. For flagging, the user flags are
- // used, to avoid confusion and because
- // non-active cells can't be flagged for
- // coarsening. Note that because of the
- // effects of @p{fix_coarsen_flags}, of a
- // cell either all or no children must
- // be flagged for coarsening, so it is
- // ok to only check the first child
+ // loop over all cells. Flag all
+ // cells of which all children are
+ // flagged for
+ // coarsening and delete the childrens'
+ // flags. In effect, only those
+ // cells are flagged of which originally
+ // all children were flagged and for which
+ // all children are on the same refinement
+ // level. For flagging, the user flags are
+ // used, to avoid confusion and because
+ // non-active cells can't be flagged for
+ // coarsening. Note that because of the
+ // effects of @p{fix_coarsen_flags}, of a
+ // cell either all or no children must
+ // be flagged for coarsening, so it is
+ // ok to only check the first child
clear_user_flags ();
cell_iterator cell = begin(),
- endc = end();
+ endc = end();
for (; cell!=endc; ++cell)
if (!cell->active())
if (cell->child(0)->coarsen_flag_set())
- {
- cell->set_user_flag();
- for (unsigned int child=0; child<cell->n_children(); ++child)
- {
- Assert (cell->child(child)->coarsen_flag_set(),
- ExcInternalError());
- cell->child(child)->clear_coarsen_flag();
- }
- }
-
-
- // now do the actual coarsening
- // step. Since the loop goes over
- // used cells we only need not
- // worry about deleting some cells
- // since the ++operator will then
- // just hop over them if we should
- // hit one. Do the loop in the
- // reverse way since we may only
- // delete some cells if their
- // neighbors have already been
- // deleted (if the latter are on a
- // higher level for example)
- //
- // if there is only one level,
- // there can not be anything to do
+ {
+ cell->set_user_flag();
+ for (unsigned int child=0; child<cell->n_children(); ++child)
+ {
+ Assert (cell->child(child)->coarsen_flag_set(),
+ ExcInternalError());
+ cell->child(child)->clear_coarsen_flag();
+ }
+ }
+
+
+ // now do the actual coarsening
+ // step. Since the loop goes over
+ // used cells we only need not
+ // worry about deleting some cells
+ // since the ++operator will then
+ // just hop over them if we should
+ // hit one. Do the loop in the
+ // reverse way since we may only
+ // delete some cells if their
+ // neighbors have already been
+ // deleted (if the latter are on a
+ // higher level for example)
+ //
+ // if there is only one level,
+ // there can not be anything to do
if (levels.size() >= 2)
for (cell = last(levels.size()-2); cell!=endc; --cell)
if (cell->user_flag_set())
- // use a separate function,
- // since this is dimension
- // specific
- internal::Triangulation::Implementation::delete_children (*this, cell,
- line_cell_count, quad_cell_count);
-
- // re-compute number of lines and
- // quads
+ // use a separate function,
+ // since this is dimension
+ // specific
+ internal::Triangulation::Implementation::delete_children (*this, cell,
+ line_cell_count, quad_cell_count);
+
+ // re-compute number of lines and
+ // quads
compute_number_cache (*this, levels.size(), number_cache);
- // in principle no user flags
- // should be
- // set any more at this point
+ // in principle no user flags
+ // should be
+ // set any more at this point
#if DEBUG
for (cell=begin(); cell!=endc; ++cell)
Assert (cell->user_flag_set() == false, ExcInternalError());
template <int dim, int spacedim>
void Triangulation<dim, spacedim>::fix_coarsen_flags ()
{
- // copy a piece of code from
- // prepare_coarsening_and_refinement that
- // ensures that the level difference at
- // vertices is limited if so desired. we
- // need this code here since at least in 1d
- // we don't call the dimension-independent
- // version of
- // prepare_coarsening_and_refinement
- // function. in 2d and 3d, having this hunk
- // here makes our lives a bit easier as
- // well as it takes care of these cases
- // earlier than it would otherwise happen.
- //
- // the main difference to the code
- // in p_c_and_r is that here we
- // absolutely have to make sure
- // that we get things right,
- // i.e. that in particular we set
- // flags right if
- // limit_level_difference_at_vertices
- // is set. to do so we iterate
- // until the flags don't change any
- // more
+ // copy a piece of code from
+ // prepare_coarsening_and_refinement that
+ // ensures that the level difference at
+ // vertices is limited if so desired. we
+ // need this code here since at least in 1d
+ // we don't call the dimension-independent
+ // version of
+ // prepare_coarsening_and_refinement
+ // function. in 2d and 3d, having this hunk
+ // here makes our lives a bit easier as
+ // well as it takes care of these cases
+ // earlier than it would otherwise happen.
+ //
+ // the main difference to the code
+ // in p_c_and_r is that here we
+ // absolutely have to make sure
+ // that we get things right,
+ // i.e. that in particular we set
+ // flags right if
+ // limit_level_difference_at_vertices
+ // is set. to do so we iterate
+ // until the flags don't change any
+ // more
std::vector<bool> previous_coarsen_flags (n_active_cells());
save_coarsen_flags (previous_coarsen_flags);
do
{
if (smooth_grid & limit_level_difference_at_vertices)
- {
- Assert(!anisotropic_refinement,
- ExcMessage("In case of anisotropic refinement the "
- "limit_level_difference_at_vertices flag for "
- "mesh smoothing must not be set!"));
-
- // store highest level one
- // of the cells adjacent to
- // a vertex belongs to
- std::fill (vertex_level.begin(), vertex_level.end(), 0);
- active_cell_iterator cell = begin_active(),
- endc = end();
- for (; cell!=endc; ++cell)
- {
- if (cell->refine_flag_set())
- for (unsigned int vertex=0; vertex<GeometryInfo<dim>::vertices_per_cell;
- ++vertex)
- vertex_level[cell->vertex_index(vertex)]
- = std::max (vertex_level[cell->vertex_index(vertex)],
- cell->level()+1);
- else if (!cell->coarsen_flag_set())
- for (unsigned int vertex=0; vertex<GeometryInfo<dim>::vertices_per_cell;
- ++vertex)
- vertex_level[cell->vertex_index(vertex)]
- = std::max (vertex_level[cell->vertex_index(vertex)],
- cell->level());
- else
- {
- // if coarsen flag is
- // set then tentatively
- // assume that the cell
- // will be
- // coarsened. this
- // isn't always true
- // (the coarsen flag
- // could be removed
- // again) and so we may
- // make an error
- // here. we try to
- // correct this by
- // iterating over the
- // entire process until
- // we are converged
- Assert (cell->coarsen_flag_set(), ExcInternalError());
- for (unsigned int vertex=0; vertex<GeometryInfo<dim>::vertices_per_cell;
- ++vertex)
- vertex_level[cell->vertex_index(vertex)]
- = std::max (vertex_level[cell->vertex_index(vertex)],
- cell->level()-1);
- }
- }
-
-
- // loop over all cells in reverse
- // order. do so because we can then
- // update the vertex levels on the
- // adjacent vertices and maybe
- // already flag additional cells in
- // this loop
- //
- // note that not only may we have
- // to add additional refinement
- // flags, but we will also have to
- // remove coarsening flags on cells
- // adjacent to vertices that will
- // see refinement
- for (cell=last_active(); cell != endc; --cell)
- if (cell->refine_flag_set() == false)
- {
- for (unsigned int vertex=0;
- vertex<GeometryInfo<dim>::vertices_per_cell; ++vertex)
- if (vertex_level[cell->vertex_index(vertex)] >=
- cell->level()+1)
- {
- // remove coarsen flag...
- cell->clear_coarsen_flag();
-
- // ...and if necessary also
- // refine the current cell,
- // at the same time
- // updating the level
- // information about
- // vertices
- if (vertex_level[cell->vertex_index(vertex)] >
- cell->level()+1)
- {
- cell->set_refine_flag();
-
- for (unsigned int v=0; v<GeometryInfo<dim>::vertices_per_cell;
- ++v)
- vertex_level[cell->vertex_index(v)]
- = std::max (vertex_level[cell->vertex_index(v)],
- cell->level()+1);
- }
-
- // continue and see whether
- // we may, for example, go
- // into the inner 'if'
- // above based on a
- // different vertex
- }
- }
- }
-
- // loop over all cells. Flag all
- // cells of which all children are
- // flagged for coarsening and
- // delete the childrens'
- // flags. Also delete all flags of
- // cells for which not all children
- // of a cell are flagged. In
- // effect, only those cells are
- // flagged of which originally all
- // children were flagged and for
- // which all children are on the
- // same refinement level. For
- // flagging, the user flags are
- // used, to avoid confusion and
- // because non-active cells can't
- // be flagged for coarsening
- //
- // In effect, all coarsen flags are
- // turned into user flags of the
- // mother cell if coarsening is
- // possible or deleted
- // otherwise.
+ {
+ Assert(!anisotropic_refinement,
+ ExcMessage("In case of anisotropic refinement the "
+ "limit_level_difference_at_vertices flag for "
+ "mesh smoothing must not be set!"));
+
+ // store highest level one
+ // of the cells adjacent to
+ // a vertex belongs to
+ std::fill (vertex_level.begin(), vertex_level.end(), 0);
+ active_cell_iterator cell = begin_active(),
+ endc = end();
+ for (; cell!=endc; ++cell)
+ {
+ if (cell->refine_flag_set())
+ for (unsigned int vertex=0; vertex<GeometryInfo<dim>::vertices_per_cell;
+ ++vertex)
+ vertex_level[cell->vertex_index(vertex)]
+ = std::max (vertex_level[cell->vertex_index(vertex)],
+ cell->level()+1);
+ else if (!cell->coarsen_flag_set())
+ for (unsigned int vertex=0; vertex<GeometryInfo<dim>::vertices_per_cell;
+ ++vertex)
+ vertex_level[cell->vertex_index(vertex)]
+ = std::max (vertex_level[cell->vertex_index(vertex)],
+ cell->level());
+ else
+ {
+ // if coarsen flag is
+ // set then tentatively
+ // assume that the cell
+ // will be
+ // coarsened. this
+ // isn't always true
+ // (the coarsen flag
+ // could be removed
+ // again) and so we may
+ // make an error
+ // here. we try to
+ // correct this by
+ // iterating over the
+ // entire process until
+ // we are converged
+ Assert (cell->coarsen_flag_set(), ExcInternalError());
+ for (unsigned int vertex=0; vertex<GeometryInfo<dim>::vertices_per_cell;
+ ++vertex)
+ vertex_level[cell->vertex_index(vertex)]
+ = std::max (vertex_level[cell->vertex_index(vertex)],
+ cell->level()-1);
+ }
+ }
+
+
+ // loop over all cells in reverse
+ // order. do so because we can then
+ // update the vertex levels on the
+ // adjacent vertices and maybe
+ // already flag additional cells in
+ // this loop
+ //
+ // note that not only may we have
+ // to add additional refinement
+ // flags, but we will also have to
+ // remove coarsening flags on cells
+ // adjacent to vertices that will
+ // see refinement
+ for (cell=last_active(); cell != endc; --cell)
+ if (cell->refine_flag_set() == false)
+ {
+ for (unsigned int vertex=0;
+ vertex<GeometryInfo<dim>::vertices_per_cell; ++vertex)
+ if (vertex_level[cell->vertex_index(vertex)] >=
+ cell->level()+1)
+ {
+ // remove coarsen flag...
+ cell->clear_coarsen_flag();
+
+ // ...and if necessary also
+ // refine the current cell,
+ // at the same time
+ // updating the level
+ // information about
+ // vertices
+ if (vertex_level[cell->vertex_index(vertex)] >
+ cell->level()+1)
+ {
+ cell->set_refine_flag();
+
+ for (unsigned int v=0; v<GeometryInfo<dim>::vertices_per_cell;
+ ++v)
+ vertex_level[cell->vertex_index(v)]
+ = std::max (vertex_level[cell->vertex_index(v)],
+ cell->level()+1);
+ }
+
+ // continue and see whether
+ // we may, for example, go
+ // into the inner 'if'
+ // above based on a
+ // different vertex
+ }
+ }
+ }
+
+ // loop over all cells. Flag all
+ // cells of which all children are
+ // flagged for coarsening and
+ // delete the childrens'
+ // flags. Also delete all flags of
+ // cells for which not all children
+ // of a cell are flagged. In
+ // effect, only those cells are
+ // flagged of which originally all
+ // children were flagged and for
+ // which all children are on the
+ // same refinement level. For
+ // flagging, the user flags are
+ // used, to avoid confusion and
+ // because non-active cells can't
+ // be flagged for coarsening
+ //
+ // In effect, all coarsen flags are
+ // turned into user flags of the
+ // mother cell if coarsening is
+ // possible or deleted
+ // otherwise.
clear_user_flags ();
- // Coarsen flags of
- // cells with no mother cell,
- // i.e. on the coarsest level are
- // deleted explicitly.
+ // Coarsen flags of
+ // cells with no mother cell,
+ // i.e. on the coarsest level are
+ // deleted explicitly.
active_cell_iterator acell = begin_active(0),
- end_ac = end_active(0);
+ end_ac = end_active(0);
for (; acell!=end_ac; ++acell)
- acell->clear_coarsen_flag();
+ acell->clear_coarsen_flag();
cell_iterator cell = begin(),
- endc = end();
+ endc = end();
for (; cell!=endc; ++cell)
- {
- // nothing to do if we are
- // already on the finest level
- if (cell->active())
- continue;
-
- const unsigned int n_children=cell->n_children();
- unsigned int flagged_children=0;
- for (unsigned int child=0; child<n_children; ++child)
- if (cell->child(child)->active() &&
- cell->child(child)->coarsen_flag_set())
- {
- ++flagged_children;
- // clear flag since we
- // don't need it anymore
- cell->child(child)->clear_coarsen_flag();
- }
-
- // flag this cell for
- // coarsening if all children
- // were flagged
- if (flagged_children == n_children)
- cell->set_user_flag();
- }
-
- // in principle no coarsen flags
- // should be set any more at this
- // point
+ {
+ // nothing to do if we are
+ // already on the finest level
+ if (cell->active())
+ continue;
+
+ const unsigned int n_children=cell->n_children();
+ unsigned int flagged_children=0;
+ for (unsigned int child=0; child<n_children; ++child)
+ if (cell->child(child)->active() &&
+ cell->child(child)->coarsen_flag_set())
+ {
+ ++flagged_children;
+ // clear flag since we
+ // don't need it anymore
+ cell->child(child)->clear_coarsen_flag();
+ }
+
+ // flag this cell for
+ // coarsening if all children
+ // were flagged
+ if (flagged_children == n_children)
+ cell->set_user_flag();
+ }
+
+ // in principle no coarsen flags
+ // should be set any more at this
+ // point
#if DEBUG
for (cell=begin(); cell!=endc; ++cell)
- Assert (cell->coarsen_flag_set() == false, ExcInternalError());
+ Assert (cell->coarsen_flag_set() == false, ExcInternalError());
#endif
- // now loop over all cells which have the
- // user flag set. their children were
- // flagged for coarsening. set the coarsen
- // flag again if we are sure that none of
- // the neighbors of these children are
- // refined, or will be refined, since then
- // we would get a two-level jump in
- // refinement. on the other hand, if one of
- // the children's neighbors has their user
- // flag set, then we know that its children
- // will go away by coarsening, and we will
- // be ok.
- //
- // note on the other hand that we do allow
- // level-2 jumps in refinement between
- // neighbors in 1d, so this whole procedure
- // is only necessary if we are not in 1d
- //
- // since we remove some coarsening/user
- // flags in the process, we have to work
- // from the finest level to the coarsest
- // one, since we occasionally inspect user
- // flags of cells on finer levels and need
- // to be sure that these flags are final
+ // now loop over all cells which have the
+ // user flag set. their children were
+ // flagged for coarsening. set the coarsen
+ // flag again if we are sure that none of
+ // the neighbors of these children are
+ // refined, or will be refined, since then
+ // we would get a two-level jump in
+ // refinement. on the other hand, if one of
+ // the children's neighbors has their user
+ // flag set, then we know that its children
+ // will go away by coarsening, and we will
+ // be ok.
+ //
+ // note on the other hand that we do allow
+ // level-2 jumps in refinement between
+ // neighbors in 1d, so this whole procedure
+ // is only necessary if we are not in 1d
+ //
+ // since we remove some coarsening/user
+ // flags in the process, we have to work
+ // from the finest level to the coarsest
+ // one, since we occasionally inspect user
+ // flags of cells on finer levels and need
+ // to be sure that these flags are final
for (cell=last(); cell!=endc; --cell)
- if (cell->user_flag_set())
- // if allowed: flag the
- // children for coarsening
- if (internal::Triangulation::Implementation::template coarsening_allowed<dim,spacedim>(cell))
- for (unsigned int c=0; c<cell->n_children(); ++c)
- {
- Assert (cell->child(c)->refine_flag_set()==false,
- ExcInternalError());
-
- cell->child(c)->set_coarsen_flag();
- }
-
- // clear all user flags again, now that we
- // don't need them any more
+ if (cell->user_flag_set())
+ // if allowed: flag the
+ // children for coarsening
+ if (internal::Triangulation::Implementation::template coarsening_allowed<dim,spacedim>(cell))
+ for (unsigned int c=0; c<cell->n_children(); ++c)
+ {
+ Assert (cell->child(c)->refine_flag_set()==false,
+ ExcInternalError());
+
+ cell->child(c)->set_coarsen_flag();
+ }
+
+ // clear all user flags again, now that we
+ // don't need them any more
clear_user_flags ();
- // now see if anything has
- // changed in the last
- // iteration of this function
+ // now see if anything has
+ // changed in the last
+ // iteration of this function
std::vector<bool> current_coarsen_flags (n_active_cells());
save_coarsen_flags (current_coarsen_flags);
template <>
bool Triangulation<1,1>::prepare_coarsening_and_refinement ()
{
- // save the flags to determine
- // whether something was changed in
- // the course of this function
+ // save the flags to determine
+ // whether something was changed in
+ // the course of this function
std::vector<bool> flags_before;
save_coarsen_flags (flags_before);
- // do nothing in 1d, except setting
- // the coarsening flags correctly
+ // do nothing in 1d, except setting
+ // the coarsening flags correctly
fix_coarsen_flags ();
std::vector<bool> flags_after;
template <>
bool Triangulation<1,2>::prepare_coarsening_and_refinement ()
{
- // save the flags to determine
- // whether something was changed in
- // the course of this function
+ // save the flags to determine
+ // whether something was changed in
+ // the course of this function
std::vector<bool> flags_before;
save_coarsen_flags (flags_before);
- // do nothing in 1d, except setting
- // the coarsening flags correctly
+ // do nothing in 1d, except setting
+ // the coarsening flags correctly
fix_coarsen_flags ();
std::vector<bool> flags_after;
template <>
bool Triangulation<1,3>::prepare_coarsening_and_refinement ()
{
- // save the flags to determine
- // whether something was changed in
- // the course of this function
+ // save the flags to determine
+ // whether something was changed in
+ // the course of this function
std::vector<bool> flags_before;
save_coarsen_flags (flags_before);
- // do nothing in 1d, except setting
- // the coarsening flags correctly
+ // do nothing in 1d, except setting
+ // the coarsening flags correctly
fix_coarsen_flags ();
std::vector<bool> flags_after;
namespace
{
- // check if the given @param cell marked
- // for coarsening would produce an
- // unrefined island. To break up long
- // chains of these cells we recursively
- // check our neighbors in case we change
- // this cell. This reduces the number of
- // outer iterations dramatically.
+ // check if the given @param cell marked
+ // for coarsening would produce an
+ // unrefined island. To break up long
+ // chains of these cells we recursively
+ // check our neighbors in case we change
+ // this cell. This reduces the number of
+ // outer iterations dramatically.
template <int dim, int spacedim>
void
possibly_do_not_produce_unrefined_islands(
Assert (cell->has_children(), ExcInternalError());
unsigned int n_neighbors=0;
- // count all neighbors
- // that will be refined
- // along the face of our
- // cell after the next
- // step
+ // count all neighbors
+ // that will be refined
+ // along the face of our
+ // cell after the next
+ // step
unsigned int count=0;
for (unsigned int n=0; n<GeometryInfo<dim>::faces_per_cell; ++n)
{
- const typename Triangulation<dim,spacedim>::cell_iterator neighbor = cell->neighbor(n);
- if (neighbor.state() == IteratorState::valid)
- {
- ++n_neighbors;
- if (face_will_be_refined_by_neighbor(cell,n))
- ++count;
- }
+ const typename Triangulation<dim,spacedim>::cell_iterator neighbor = cell->neighbor(n);
+ if (neighbor.state() == IteratorState::valid)
+ {
+ ++n_neighbors;
+ if (face_will_be_refined_by_neighbor(cell,n))
+ ++count;
+ }
}
- // clear coarsen flags if
- // either all existing
- // neighbors will be
- // refined or all but one
- // will be and the cell
- // is in the interior of
- // the domain
+ // clear coarsen flags if
+ // either all existing
+ // neighbors will be
+ // refined or all but one
+ // will be and the cell
+ // is in the interior of
+ // the domain
if (count==n_neighbors ||
- (count>=n_neighbors-1 &&
- n_neighbors == GeometryInfo<dim>::faces_per_cell) )
+ (count>=n_neighbors-1 &&
+ n_neighbors == GeometryInfo<dim>::faces_per_cell) )
{
- for (unsigned int c=0; c<cell->n_children(); ++c)
- cell->child(c)->clear_coarsen_flag();
-
- for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
- if (!cell->at_boundary(face)
- &&
- ( !cell->neighbor(face)->active() )
- && (cell_will_be_coarsened(cell->neighbor(face))) )
- possibly_do_not_produce_unrefined_islands<dim,spacedim>( cell->neighbor(face) );
+ for (unsigned int c=0; c<cell->n_children(); ++c)
+ cell->child(c)->clear_coarsen_flag();
+
+ for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
+ if (!cell->at_boundary(face)
+ &&
+ ( !cell->neighbor(face)->active() )
+ && (cell_will_be_coarsened(cell->neighbor(face))) )
+ possibly_do_not_produce_unrefined_islands<dim,spacedim>( cell->neighbor(face) );
}
}
- // see if the current cell needs to
- // be refined to avoid unrefined
- // islands.
- //
- // there are sometimes chains of
- // cells that induce refinement of
- // each other. to avoid running the
- // loop in
- // prepare_coarsening_and_refinement
- // over and over again for each one
- // of them, at least for the
- // isotropic refinement case we
- // seek to flag neighboring
- // elements as well as
- // necessary. this takes care of
- // (slightly pathological) cases
- // like deal.II/mesh_smoothing_03
+ // see if the current cell needs to
+ // be refined to avoid unrefined
+ // islands.
+ //
+ // there are sometimes chains of
+ // cells that induce refinement of
+ // each other. to avoid running the
+ // loop in
+ // prepare_coarsening_and_refinement
+ // over and over again for each one
+ // of them, at least for the
+ // isotropic refinement case we
+ // seek to flag neighboring
+ // elements as well as
+ // necessary. this takes care of
+ // (slightly pathological) cases
+ // like deal.II/mesh_smoothing_03
template <int dim, int spacedim>
void
possibly_refine_unrefined_island
Assert (cell->refine_flag_set() == false, ExcInternalError());
- // now we provide two
- // algorithms. the first one is
- // the standard one, coming from
- // the time, where only isotropic
- // refinement was possible. it
- // simply counts the neighbors
- // that are or will be refined
- // and compares to the number of
- // other ones. the second one
- // does this check independently
- // for each direction: if all
- // neighbors in one direction
- // (normally two, at the boundary
- // only one) are refined, the
- // current cell is flagged to be
- // refined in an according
- // direction.
+ // now we provide two
+ // algorithms. the first one is
+ // the standard one, coming from
+ // the time, where only isotropic
+ // refinement was possible. it
+ // simply counts the neighbors
+ // that are or will be refined
+ // and compares to the number of
+ // other ones. the second one
+ // does this check independently
+ // for each direction: if all
+ // neighbors in one direction
+ // (normally two, at the boundary
+ // only one) are refined, the
+ // current cell is flagged to be
+ // refined in an according
+ // direction.
if (allow_anisotropic_smoothing == false)
{
- // use first algorithm
- unsigned int refined_neighbors = 0,
- unrefined_neighbors = 0;
- for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
- if (!cell->at_boundary(face))
- {
- if (face_will_be_refined_by_neighbor(cell,face))
- ++refined_neighbors;
- else
- ++unrefined_neighbors;
- }
-
- if (unrefined_neighbors < refined_neighbors)
- {
- cell->clear_coarsen_flag();
- cell->set_refine_flag ();
-
- // ok, so now we have
- // flagged this cell. if
- // we know that there
- // were any unrefined
- // neighbors at all, see
- // if any of those will
- // have to be refined as
- // well
- if (unrefined_neighbors > 0)
- for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
- if (!cell->at_boundary(face)
- &&
- (face_will_be_refined_by_neighbor(cell,face) == false)
- &&
- (cell->neighbor(face)->has_children() == false)
- &&
- (cell->neighbor(face)->refine_flag_set() == false))
- possibly_refine_unrefined_island<dim,spacedim>
- (cell->neighbor(face),
- allow_anisotropic_smoothing);
- }
+ // use first algorithm
+ unsigned int refined_neighbors = 0,
+ unrefined_neighbors = 0;
+ for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
+ if (!cell->at_boundary(face))
+ {
+ if (face_will_be_refined_by_neighbor(cell,face))
+ ++refined_neighbors;
+ else
+ ++unrefined_neighbors;
+ }
+
+ if (unrefined_neighbors < refined_neighbors)
+ {
+ cell->clear_coarsen_flag();
+ cell->set_refine_flag ();
+
+ // ok, so now we have
+ // flagged this cell. if
+ // we know that there
+ // were any unrefined
+ // neighbors at all, see
+ // if any of those will
+ // have to be refined as
+ // well
+ if (unrefined_neighbors > 0)
+ for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
+ if (!cell->at_boundary(face)
+ &&
+ (face_will_be_refined_by_neighbor(cell,face) == false)
+ &&
+ (cell->neighbor(face)->has_children() == false)
+ &&
+ (cell->neighbor(face)->refine_flag_set() == false))
+ possibly_refine_unrefined_island<dim,spacedim>
+ (cell->neighbor(face),
+ allow_anisotropic_smoothing);
+ }
}
else
{
- // variable to store the cell
- // refine case needed to
- // fulfill all smoothing
- // requirements
- RefinementCase<dim> smoothing_cell_refinement_case
- = RefinementCase<dim>::no_refinement;
-
- // use second algorithm, do
- // the check individually for
- // each direction
- for (unsigned int face_pair=0;
- face_pair<GeometryInfo<dim>::faces_per_cell/2; ++face_pair)
- {
- // variable to store the
- // cell refine case
- // needed to refine at
- // the current face pair
- // in the same way as the
- // neighbors do...
- RefinementCase<dim> directional_cell_refinement_case
- = RefinementCase<dim>::isotropic_refinement;
-
- for (unsigned int face_index=0; face_index<2; ++face_index)
- {
- unsigned int face=2*face_pair+face_index;
- // variable to store
- // the refine case
- // (to come) of the
- // face under
- // consideration
- RefinementCase<dim-1> expected_face_ref_case
- = RefinementCase<dim-1>::no_refinement;
-
- if (cell->neighbor(face).state() == IteratorState::valid)
- face_will_be_refined_by_neighbor<dim,spacedim>(cell,face,expected_face_ref_case);
- // now extract which
- // refine case would
- // be necessary to
- // achive the same
- // face
- // refinement. set
- // the intersection
- // with other
- // requirements for
- // the same
- // direction.
-
- // note: using the
- // intersection is
- // not an obvious
- // decision, we could
- // also argue that it
- // is more natural to
- // use the
- // union. however,
- // intersection is
- // the less
- // aggressive tactic
- // and favours a
- // smaller number of
- // refined cells over
- // an intensive
- // smoothing. this
- // way we try not to
- // loose too much of
- // the effort we put
- // in anisotropic
- // refinement
- // indicators due to
- // overly aggressive
- // smoothing...
- directional_cell_refinement_case
- = (directional_cell_refinement_case &
- GeometryInfo<dim>::min_cell_refinement_case_for_face_refinement(
- expected_face_ref_case,
- face,
- cell->face_orientation(face),
- cell->face_flip(face),
- cell->face_rotation(face)));
- }//for both face indices
- // if both requirements
- // sum up to something
- // useful, add this to
- // the refine case for
- // smoothing. note: if
- // directional_cell_refinement_case
- // is isotropic still,
- // then something went
- // wrong...
- Assert(directional_cell_refinement_case <
- RefinementCase<dim>::isotropic_refinement,
- ExcInternalError());
- smoothing_cell_refinement_case = smoothing_cell_refinement_case |
- directional_cell_refinement_case;
- }//for all face_pairs
- // no we collected
- // contributions from all
- // directions. combine the
- // new flags with the
- // existing refine case, but
- // only if smoothing is
- // required
- if (smoothing_cell_refinement_case)
- {
- cell->clear_coarsen_flag();
- cell->set_refine_flag(cell->refine_flag_set() |
- smoothing_cell_refinement_case);
- }
+ // variable to store the cell
+ // refine case needed to
+ // fulfill all smoothing
+ // requirements
+ RefinementCase<dim> smoothing_cell_refinement_case
+ = RefinementCase<dim>::no_refinement;
+
+ // use second algorithm, do
+ // the check individually for
+ // each direction
+ for (unsigned int face_pair=0;
+ face_pair<GeometryInfo<dim>::faces_per_cell/2; ++face_pair)
+ {
+ // variable to store the
+ // cell refine case
+ // needed to refine at
+ // the current face pair
+ // in the same way as the
+ // neighbors do...
+ RefinementCase<dim> directional_cell_refinement_case
+ = RefinementCase<dim>::isotropic_refinement;
+
+ for (unsigned int face_index=0; face_index<2; ++face_index)
+ {
+ unsigned int face=2*face_pair+face_index;
+ // variable to store
+ // the refine case
+ // (to come) of the
+ // face under
+ // consideration
+ RefinementCase<dim-1> expected_face_ref_case
+ = RefinementCase<dim-1>::no_refinement;
+
+ if (cell->neighbor(face).state() == IteratorState::valid)
+ face_will_be_refined_by_neighbor<dim,spacedim>(cell,face,expected_face_ref_case);
+ // now extract which
+ // refine case would
+ // be necessary to
+ // achive the same
+ // face
+ // refinement. set
+ // the intersection
+ // with other
+ // requirements for
+ // the same
+ // direction.
+
+ // note: using the
+ // intersection is
+ // not an obvious
+ // decision, we could
+ // also argue that it
+ // is more natural to
+ // use the
+ // union. however,
+ // intersection is
+ // the less
+ // aggressive tactic
+ // and favours a
+ // smaller number of
+ // refined cells over
+ // an intensive
+ // smoothing. this
+ // way we try not to
+ // loose too much of
+ // the effort we put
+ // in anisotropic
+ // refinement
+ // indicators due to
+ // overly aggressive
+ // smoothing...
+ directional_cell_refinement_case
+ = (directional_cell_refinement_case &
+ GeometryInfo<dim>::min_cell_refinement_case_for_face_refinement(
+ expected_face_ref_case,
+ face,
+ cell->face_orientation(face),
+ cell->face_flip(face),
+ cell->face_rotation(face)));
+ }//for both face indices
+ // if both requirements
+ // sum up to something
+ // useful, add this to
+ // the refine case for
+ // smoothing. note: if
+ // directional_cell_refinement_case
+ // is isotropic still,
+ // then something went
+ // wrong...
+ Assert(directional_cell_refinement_case <
+ RefinementCase<dim>::isotropic_refinement,
+ ExcInternalError());
+ smoothing_cell_refinement_case = smoothing_cell_refinement_case |
+ directional_cell_refinement_case;
+ }//for all face_pairs
+ // no we collected
+ // contributions from all
+ // directions. combine the
+ // new flags with the
+ // existing refine case, but
+ // only if smoothing is
+ // required
+ if (smoothing_cell_refinement_case)
+ {
+ cell->clear_coarsen_flag();
+ cell->set_refine_flag(cell->refine_flag_set() |
+ smoothing_cell_refinement_case);
+ }
}
}
}
template <int dim, int spacedim>
bool Triangulation<dim,spacedim>::prepare_coarsening_and_refinement ()
{
- // save the flags to determine
- // whether something was changed in
- // the course of this function
+ // save the flags to determine
+ // whether something was changed in
+ // the course of this function
std::vector<bool> flags_before[2];
save_coarsen_flags (flags_before[0]);
save_refine_flags (flags_before[1]);
- // save the flags at the outset of
- // each loop. we do so in order to
- // find out whether something was
- // changed in the present loop, in
- // which case we would have to
- // re-run the loop. the other
- // possibility to find this out
- // would be to set a flag
- // @p{something_changed} to true
- // each time we change something.
- // however, sometimes one change in
- // one of the parts of the loop is
- // undone by another one, so we
- // might end up in an endless
- // loop. we could be tempted to
- // break this loop at an arbitrary
- // number of runs, but that would
- // not be a clean solution, since
- // we would either have to
- // 1/ break the loop too early, in which
- // case the promise that a second
- // call to this function immediately
- // after the first one does not
- // change anything, would be broken,
- // or
- // 2/ we do as many loops as there are
- // levels. we know that information
- // is transported over one level
- // in each run of the loop, so this
- // is enough. Unfortunately, each
- // loop is rather expensive, so
- // we chose the way presented here
+ // save the flags at the outset of
+ // each loop. we do so in order to
+ // find out whether something was
+ // changed in the present loop, in
+ // which case we would have to
+ // re-run the loop. the other
+ // possibility to find this out
+ // would be to set a flag
+ // @p{something_changed} to true
+ // each time we change something.
+ // however, sometimes one change in
+ // one of the parts of the loop is
+ // undone by another one, so we
+ // might end up in an endless
+ // loop. we could be tempted to
+ // break this loop at an arbitrary
+ // number of runs, but that would
+ // not be a clean solution, since
+ // we would either have to
+ // 1/ break the loop too early, in which
+ // case the promise that a second
+ // call to this function immediately
+ // after the first one does not
+ // change anything, would be broken,
+ // or
+ // 2/ we do as many loops as there are
+ // levels. we know that information
+ // is transported over one level
+ // in each run of the loop, so this
+ // is enough. Unfortunately, each
+ // loop is rather expensive, so
+ // we chose the way presented here
std::vector<bool> flags_before_loop[2] = {flags_before[0],
flags_before[1]};
- // now for what is done in each
- // loop: we have to fulfill several
- // tasks at the same time, namely
- // several mesh smoothing
- // algorithms and mesh
- // regularisation, by which we mean
- // that the next mesh fulfills
- // several requirements such as no
- // double refinement at each face
- // or line, etc.
- //
- // since doing these things at once
- // seems almost impossible (in the
- // first year of this library, they
- // were done in two functions, one
- // for refinement and one for
- // coarsening, and most things
- // within these were done at once,
- // so the code was rather
- // impossible to join into this,
- // only, function), we do them one
- // after each other. the order in
- // which we do them is such that
- // the important tasks, namely
- // regularisation, are done last
- // and the least important things
- // are done the first. the
- // following order is chosen:
- //
- // 0/ Only if coarsest_level_1 or
- // patch_level_1 is set:
- // clear all coarsen flags on level 1
- // to avoid level 0 cells being
- // created by coarsening.
- // As coarsen flags will never be added,
- // this can be done once and for all
- // before the actual loop starts.
- // 1/ do not coarsen a cell if
- // 'most of the neighbors' will be
- // refined after the step. This is
- // to prevent occurence of
- // unrefined islands.
- // 2/ eliminate refined islands in the
- // interior and at the boundary. since
- // they don't do much harm besides
- // increasing the number of degrees
- // of freedom, doing this has a
- // rather low priority.
- // 3/ limit the level difference of
- // neighboring cells at each vertex.
- // 4/ eliminate unrefined islands. this
- // has higher priority since this
- // diminishes the approximation
- // properties not only of the unrefined
- // island, but also of the surrounding
- // patch.
- // 5/ ensure patch level 1. Then the
- // triangulation consists of patches,
- // i.e. of cells that are
- // refined once. It follows that if at
- // least one of the children of a cell
- // is or will be refined than all children
- // need to be refined. This step
- // only sets refinement flags and does
- // not set coarsening flags.
- // If the patch_level_1 flag is set, then
- // eliminate_unrefined_islands,
- // eliminate_refined_inner_islands and
- // eliminate_refined_boundary_islands will
- // be fulfilled automatically and do not
- // need to be enforced separately.
- // 6/ take care of the requirement that no
- // double refinement is done at each face
- // 7/ take care that no double refinement
- // is done at each line in 3d or higher
- // dimensions.
- // 8/ make sure that all children of each
- // cell are either flagged for coarsening
- // or none of the children is
- //
- // For some of these steps, it is
- // known that they
- // interact. Namely, it is not
- // possible to guarantee that after
- // step 6 another step 5 would have
- // no effect; the same holds for
- // the opposite order and also when
- // taking into account step
- // 7. however, it is important to
- // guarantee that step five or six
- // do not undo something that step
- // 5 did, and step 7 not something
- // of step 6, otherwise the
- // requirements will not be
- // satisfied even if the loop
- // terminates. this is accomplished
- // by the fact that steps 5 and 6
- // only *add* refinement flags and
- // delete coarsening flags
- // (therefore, step 6 can't undo
- // something that step 4 already
- // did), and step 7 only deletes
- // coarsening flags, never adds
- // some. step 7 needs also take
- // care that it won't tag cells for
- // refinement for which some
- // neighbors are more refined or
- // will be refined.
-
- //////////////////////////////////////
- // STEP 0:
- // Only if coarsest_level_1 or
- // patch_level_1 is set:
- // clear all coarsen flags on level 1
- // to avoid level 0 cells being
- // created by coarsening.
+ // now for what is done in each
+ // loop: we have to fulfill several
+ // tasks at the same time, namely
+ // several mesh smoothing
+ // algorithms and mesh
+ // regularisation, by which we mean
+ // that the next mesh fulfills
+ // several requirements such as no
+ // double refinement at each face
+ // or line, etc.
+ //
+ // since doing these things at once
+ // seems almost impossible (in the
+ // first year of this library, they
+ // were done in two functions, one
+ // for refinement and one for
+ // coarsening, and most things
+ // within these were done at once,
+ // so the code was rather
+ // impossible to join into this,
+ // only, function), we do them one
+ // after each other. the order in
+ // which we do them is such that
+ // the important tasks, namely
+ // regularisation, are done last
+ // and the least important things
+ // are done the first. the
+ // following order is chosen:
+ //
+ // 0/ Only if coarsest_level_1 or
+ // patch_level_1 is set:
+ // clear all coarsen flags on level 1
+ // to avoid level 0 cells being
+ // created by coarsening.
+ // As coarsen flags will never be added,
+ // this can be done once and for all
+ // before the actual loop starts.
+ // 1/ do not coarsen a cell if
+ // 'most of the neighbors' will be
+ // refined after the step. This is
+ // to prevent occurence of
+ // unrefined islands.
+ // 2/ eliminate refined islands in the
+ // interior and at the boundary. since
+ // they don't do much harm besides
+ // increasing the number of degrees
+ // of freedom, doing this has a
+ // rather low priority.
+ // 3/ limit the level difference of
+ // neighboring cells at each vertex.
+ // 4/ eliminate unrefined islands. this
+ // has higher priority since this
+ // diminishes the approximation
+ // properties not only of the unrefined
+ // island, but also of the surrounding
+ // patch.
+ // 5/ ensure patch level 1. Then the
+ // triangulation consists of patches,
+ // i.e. of cells that are
+ // refined once. It follows that if at
+ // least one of the children of a cell
+ // is or will be refined than all children
+ // need to be refined. This step
+ // only sets refinement flags and does
+ // not set coarsening flags.
+ // If the patch_level_1 flag is set, then
+ // eliminate_unrefined_islands,
+ // eliminate_refined_inner_islands and
+ // eliminate_refined_boundary_islands will
+ // be fulfilled automatically and do not
+ // need to be enforced separately.
+ // 6/ take care of the requirement that no
+ // double refinement is done at each face
+ // 7/ take care that no double refinement
+ // is done at each line in 3d or higher
+ // dimensions.
+ // 8/ make sure that all children of each
+ // cell are either flagged for coarsening
+ // or none of the children is
+ //
+ // For some of these steps, it is
+ // known that they
+ // interact. Namely, it is not
+ // possible to guarantee that after
+ // step 6 another step 5 would have
+ // no effect; the same holds for
+ // the opposite order and also when
+ // taking into account step
+ // 7. however, it is important to
+ // guarantee that step five or six
+ // do not undo something that step
+ // 5 did, and step 7 not something
+ // of step 6, otherwise the
+ // requirements will not be
+ // satisfied even if the loop
+ // terminates. this is accomplished
+ // by the fact that steps 5 and 6
+ // only *add* refinement flags and
+ // delete coarsening flags
+ // (therefore, step 6 can't undo
+ // something that step 4 already
+ // did), and step 7 only deletes
+ // coarsening flags, never adds
+ // some. step 7 needs also take
+ // care that it won't tag cells for
+ // refinement for which some
+ // neighbors are more refined or
+ // will be refined.
+
+ //////////////////////////////////////
+ // STEP 0:
+ // Only if coarsest_level_1 or
+ // patch_level_1 is set:
+ // clear all coarsen flags on level 1
+ // to avoid level 0 cells being
+ // created by coarsening.
if (((smooth_grid & coarsest_level_1) ||
(smooth_grid & patch_level_1)) && n_levels()>=2)
{
active_cell_iterator
- cell=begin_active(1),
- endc=end_active(1);
+ cell=begin_active(1),
+ endc=end_active(1);
for (; cell!=endc; ++cell)
- cell->clear_coarsen_flag();
+ cell->clear_coarsen_flag();
}
bool mesh_changed_in_this_loop = false;
do
{
- //////////////////////////////////////
- // STEP 1:
- // do not coarsen a cell if 'most of
- // the neighbors' will be refined after
- // the step. This is to prevent the
- // occurence of unrefined islands.
- // If patch_level_1 is set, this will
- // be automatically fulfilled.
+ //////////////////////////////////////
+ // STEP 1:
+ // do not coarsen a cell if 'most of
+ // the neighbors' will be refined after
+ // the step. This is to prevent the
+ // occurence of unrefined islands.
+ // If patch_level_1 is set, this will
+ // be automatically fulfilled.
if (smooth_grid & do_not_produce_unrefined_islands &&
- !(smooth_grid & patch_level_1))
- {
- cell_iterator cell;
- const cell_iterator endc = end();
-
- for (cell=begin(); cell!=endc; ++cell)
- {
- // only do something if this
- // cell will be coarsened
- if (!cell->active() && cell_will_be_coarsened(cell))
- possibly_do_not_produce_unrefined_islands<dim,spacedim>(cell);
- }
- }
-
-
- //////////////////////////////////////
- // STEP 2:
- // eliminate refined islands in the
- // interior and at the boundary. since
- // they don't do much harm besides
- // increasing the number of degrees of
- // freedom, doing this has a rather low
- // priority.
- // If patch_level_1 is set, this will
- // be automatically fulfilled.
- //
- // there is one corner case
- // to consider: if this is a
- // distributed
- // triangulation, there may
- // be refined islands on the
- // boundary of which we own
- // only part (e.g. a single
- // cell in the corner of a
- // domain). the rest of the
- // island is ghost cells and
- // it *looks* like the area
- // around it (artificial
- // cells) are coarser but
- // this is only because they
- // may actually be equally
- // fine on other
- // processors. it's hard to
- // detect this case but we
- // can do the following:
- // only set coarsen flags to
- // remove this refined
- // island if all cells we
- // want to set flags on are
- // locally owned
+ !(smooth_grid & patch_level_1))
+ {
+ cell_iterator cell;
+ const cell_iterator endc = end();
+
+ for (cell=begin(); cell!=endc; ++cell)
+ {
+ // only do something if this
+ // cell will be coarsened
+ if (!cell->active() && cell_will_be_coarsened(cell))
+ possibly_do_not_produce_unrefined_islands<dim,spacedim>(cell);
+ }
+ }
+
+
+ //////////////////////////////////////
+ // STEP 2:
+ // eliminate refined islands in the
+ // interior and at the boundary. since
+ // they don't do much harm besides
+ // increasing the number of degrees of
+ // freedom, doing this has a rather low
+ // priority.
+ // If patch_level_1 is set, this will
+ // be automatically fulfilled.
+ //
+ // there is one corner case
+ // to consider: if this is a
+ // distributed
+ // triangulation, there may
+ // be refined islands on the
+ // boundary of which we own
+ // only part (e.g. a single
+ // cell in the corner of a
+ // domain). the rest of the
+ // island is ghost cells and
+ // it *looks* like the area
+ // around it (artificial
+ // cells) are coarser but
+ // this is only because they
+ // may actually be equally
+ // fine on other
+ // processors. it's hard to
+ // detect this case but we
+ // can do the following:
+ // only set coarsen flags to
+ // remove this refined
+ // island if all cells we
+ // want to set flags on are
+ // locally owned
if (smooth_grid & (eliminate_refined_inner_islands |
- eliminate_refined_boundary_islands) &&
- !(smooth_grid & patch_level_1))
- {
- cell_iterator cell;
- const cell_iterator endc = end();
-
- for (cell=begin(); cell!=endc; ++cell)
- if (!cell->active() ||
- (cell->active() &&
- cell->refine_flag_set() &&
- cell->is_locally_owned()))
- {
- // check whether all
- // children are
- // active, i.e. not
- // refined
- // themselves. This
- // is a precondition
- // that the children
- // may be coarsened
- // away. If the cell
- // is only flagged
- // for refinement,
- // then all future
- // children will be
- // active
- bool all_children_active = true;
- if (!cell->active())
- for (unsigned int c=0; c<cell->n_children(); ++c)
- if (!cell->child(c)->active() ||
- cell->child(c)->is_ghost() ||
- cell->child(c)->is_artificial())
- {
- all_children_active = false;
- break;
- }
-
- if (all_children_active)
- {
- // count number
- // of refined and
- // unrefined
- // neighbors of
- // cell.
- // neighbors on
- // lower levels
- // are counted as
- // unrefined
- // since they can
- // only get to
- // the same level
- // as this cell
- // by the next
- // refinement
- // cycle
- unsigned int unrefined_neighbors = 0,
- total_neighbors = 0;
-
- for (unsigned int n=0; n<GeometryInfo<dim>::faces_per_cell; ++n)
- {
- const cell_iterator neighbor = cell->neighbor(n);
- if (neighbor.state() == IteratorState::valid)
- {
- ++total_neighbors;
-
- if (!face_will_be_refined_by_neighbor(cell,n))
- ++unrefined_neighbors;
- }
-
- }
-
- // if all
- // neighbors
- // unrefined:
- // mark this cell
- // for coarsening
- // or don't
- // refine if
- // marked for
- // that
- //
- // also do the
- // distinction
- // between the
- // two versions
- // of the
- // eliminate_refined_*_islands
- // flag
- //
- // the last check
- // is whether
- // there are any
- // neighbors at
- // all. if not
- // so, then we
- // are (e.g.) on
- // the coarsest
- // grid with one
- // cell, for
- // which, of
- // course, we do
- // not remove the
- // refine flag.
- if ((unrefined_neighbors == total_neighbors)
- &&
- (((unrefined_neighbors==GeometryInfo<dim>::faces_per_cell) &&
- (smooth_grid & eliminate_refined_inner_islands)) ||
- ((unrefined_neighbors<GeometryInfo<dim>::faces_per_cell) &&
- (smooth_grid & eliminate_refined_boundary_islands)) )
- &&
- (total_neighbors != 0))
- {
- if (!cell->active())
- for (unsigned int c=0; c<cell->n_children(); ++c)
- {
- cell->child(c)->clear_refine_flag ();
- cell->child(c)->set_coarsen_flag ();
- }
- else
- cell->clear_refine_flag();
- }
- }
- }
- }
-
- //////////////////////////////////////
- // STEP 3:
- // limit the level difference of
- // neighboring cells at each vertex.
- //
- // in case of anisotropic refinement
- // this does not make sense. as soon
- // as one cell is anisotropically
- // refined, an Assertion is
- // thrown. therefore we can ignore
- // this problem later on
+ eliminate_refined_boundary_islands) &&
+ !(smooth_grid & patch_level_1))
+ {
+ cell_iterator cell;
+ const cell_iterator endc = end();
+
+ for (cell=begin(); cell!=endc; ++cell)
+ if (!cell->active() ||
+ (cell->active() &&
+ cell->refine_flag_set() &&
+ cell->is_locally_owned()))
+ {
+ // check whether all
+ // children are
+ // active, i.e. not
+ // refined
+ // themselves. This
+ // is a precondition
+ // that the children
+ // may be coarsened
+ // away. If the cell
+ // is only flagged
+ // for refinement,
+ // then all future
+ // children will be
+ // active
+ bool all_children_active = true;
+ if (!cell->active())
+ for (unsigned int c=0; c<cell->n_children(); ++c)
+ if (!cell->child(c)->active() ||
+ cell->child(c)->is_ghost() ||
+ cell->child(c)->is_artificial())
+ {
+ all_children_active = false;
+ break;
+ }
+
+ if (all_children_active)
+ {
+ // count number
+ // of refined and
+ // unrefined
+ // neighbors of
+ // cell.
+ // neighbors on
+ // lower levels
+ // are counted as
+ // unrefined
+ // since they can
+ // only get to
+ // the same level
+ // as this cell
+ // by the next
+ // refinement
+ // cycle
+ unsigned int unrefined_neighbors = 0,
+ total_neighbors = 0;
+
+ for (unsigned int n=0; n<GeometryInfo<dim>::faces_per_cell; ++n)
+ {
+ const cell_iterator neighbor = cell->neighbor(n);
+ if (neighbor.state() == IteratorState::valid)
+ {
+ ++total_neighbors;
+
+ if (!face_will_be_refined_by_neighbor(cell,n))
+ ++unrefined_neighbors;
+ }
+
+ }
+
+ // if all
+ // neighbors
+ // unrefined:
+ // mark this cell
+ // for coarsening
+ // or don't
+ // refine if
+ // marked for
+ // that
+ //
+ // also do the
+ // distinction
+ // between the
+ // two versions
+ // of the
+ // eliminate_refined_*_islands
+ // flag
+ //
+ // the last check
+ // is whether
+ // there are any
+ // neighbors at
+ // all. if not
+ // so, then we
+ // are (e.g.) on
+ // the coarsest
+ // grid with one
+ // cell, for
+ // which, of
+ // course, we do
+ // not remove the
+ // refine flag.
+ if ((unrefined_neighbors == total_neighbors)
+ &&
+ (((unrefined_neighbors==GeometryInfo<dim>::faces_per_cell) &&
+ (smooth_grid & eliminate_refined_inner_islands)) ||
+ ((unrefined_neighbors<GeometryInfo<dim>::faces_per_cell) &&
+ (smooth_grid & eliminate_refined_boundary_islands)) )
+ &&
+ (total_neighbors != 0))
+ {
+ if (!cell->active())
+ for (unsigned int c=0; c<cell->n_children(); ++c)
+ {
+ cell->child(c)->clear_refine_flag ();
+ cell->child(c)->set_coarsen_flag ();
+ }
+ else
+ cell->clear_refine_flag();
+ }
+ }
+ }
+ }
+
+ //////////////////////////////////////
+ // STEP 3:
+ // limit the level difference of
+ // neighboring cells at each vertex.
+ //
+ // in case of anisotropic refinement
+ // this does not make sense. as soon
+ // as one cell is anisotropically
+ // refined, an Assertion is
+ // thrown. therefore we can ignore
+ // this problem later on
if (smooth_grid & limit_level_difference_at_vertices)
- {
- Assert(!anisotropic_refinement,
- ExcMessage("In case of anisotropic refinement the "
- "limit_level_difference_at_vertices flag for "
- "mesh smoothing must not be set!"));
-
- // store highest level one
- // of the cells adjacent to
- // a vertex belongs to
- std::vector<int> vertex_level (vertices.size(), 0);
- active_cell_iterator cell = begin_active(),
- endc = end();
- for (; cell!=endc; ++cell)
- {
- if (cell->refine_flag_set())
- for (unsigned int vertex=0; vertex<GeometryInfo<dim>::vertices_per_cell;
- ++vertex)
- vertex_level[cell->vertex_index(vertex)]
- = std::max (vertex_level[cell->vertex_index(vertex)],
- cell->level()+1);
- else if (!cell->coarsen_flag_set())
- for (unsigned int vertex=0; vertex<GeometryInfo<dim>::vertices_per_cell;
- ++vertex)
- vertex_level[cell->vertex_index(vertex)]
- = std::max (vertex_level[cell->vertex_index(vertex)],
- cell->level());
- else
- {
- // if coarsen flag is set then
- // tentatively assume that the
- // cell will be coarsened. this
- // isn't always true (the
- // coarsen flag could be
- // removed again) and so we may
- // make an error here
- Assert (cell->coarsen_flag_set(), ExcInternalError());
- for (unsigned int vertex=0; vertex<GeometryInfo<dim>::vertices_per_cell;
- ++vertex)
- vertex_level[cell->vertex_index(vertex)]
- = std::max (vertex_level[cell->vertex_index(vertex)],
- cell->level()-1);
- }
- }
-
-
- // loop over all cells in reverse
- // order. do so because we can then
- // update the vertex levels on the
- // adjacent vertices and maybe
- // already flag additional cells in
- // this loop
- //
- // note that not only may we have
- // to add additional refinement
- // flags, but we will also have to
- // remove coarsening flags on cells
- // adjacent to vertices that will
- // see refinement
- for (cell=last_active(); cell != endc; --cell)
- if (cell->refine_flag_set() == false)
- {
- for (unsigned int vertex=0;
- vertex<GeometryInfo<dim>::vertices_per_cell; ++vertex)
- if (vertex_level[cell->vertex_index(vertex)] >=
- cell->level()+1)
- {
- // remove coarsen flag...
- cell->clear_coarsen_flag();
-
- // ...and if necessary also
- // refine the current cell,
- // at the same time
- // updating the level
- // information about
- // vertices
- if (vertex_level[cell->vertex_index(vertex)] >
- cell->level()+1)
- {
- cell->set_refine_flag();
-
- for (unsigned int v=0; v<GeometryInfo<dim>::vertices_per_cell;
- ++v)
- vertex_level[cell->vertex_index(v)]
- = std::max (vertex_level[cell->vertex_index(v)],
- cell->level()+1);
- }
-
- // continue and see whether
- // we may, for example, go
- // into the inner 'if'
- // above based on a
- // different vertex
- }
- }
- }
-
- /////////////////////////////////////
- // STEP 4:
- // eliminate unrefined
- // islands. this has higher
- // priority since this
- // diminishes the
- // approximation properties
- // not only of the unrefined
- // island, but also of the
- // surrounding patch.
- //
- // do the loop from finest
- // to coarsest cells since
- // we may trigger a cascade
- // by marking cells for
- // refinement which may
- // trigger more cells
- // further down below
+ {
+ Assert(!anisotropic_refinement,
+ ExcMessage("In case of anisotropic refinement the "
+ "limit_level_difference_at_vertices flag for "
+ "mesh smoothing must not be set!"));
+
+ // store highest level one
+ // of the cells adjacent to
+ // a vertex belongs to
+ std::vector<int> vertex_level (vertices.size(), 0);
+ active_cell_iterator cell = begin_active(),
+ endc = end();
+ for (; cell!=endc; ++cell)
+ {
+ if (cell->refine_flag_set())
+ for (unsigned int vertex=0; vertex<GeometryInfo<dim>::vertices_per_cell;
+ ++vertex)
+ vertex_level[cell->vertex_index(vertex)]
+ = std::max (vertex_level[cell->vertex_index(vertex)],
+ cell->level()+1);
+ else if (!cell->coarsen_flag_set())
+ for (unsigned int vertex=0; vertex<GeometryInfo<dim>::vertices_per_cell;
+ ++vertex)
+ vertex_level[cell->vertex_index(vertex)]
+ = std::max (vertex_level[cell->vertex_index(vertex)],
+ cell->level());
+ else
+ {
+ // if coarsen flag is set then
+ // tentatively assume that the
+ // cell will be coarsened. this
+ // isn't always true (the
+ // coarsen flag could be
+ // removed again) and so we may
+ // make an error here
+ Assert (cell->coarsen_flag_set(), ExcInternalError());
+ for (unsigned int vertex=0; vertex<GeometryInfo<dim>::vertices_per_cell;
+ ++vertex)
+ vertex_level[cell->vertex_index(vertex)]
+ = std::max (vertex_level[cell->vertex_index(vertex)],
+ cell->level()-1);
+ }
+ }
+
+
+ // loop over all cells in reverse
+ // order. do so because we can then
+ // update the vertex levels on the
+ // adjacent vertices and maybe
+ // already flag additional cells in
+ // this loop
+ //
+ // note that not only may we have
+ // to add additional refinement
+ // flags, but we will also have to
+ // remove coarsening flags on cells
+ // adjacent to vertices that will
+ // see refinement
+ for (cell=last_active(); cell != endc; --cell)
+ if (cell->refine_flag_set() == false)
+ {
+ for (unsigned int vertex=0;
+ vertex<GeometryInfo<dim>::vertices_per_cell; ++vertex)
+ if (vertex_level[cell->vertex_index(vertex)] >=
+ cell->level()+1)
+ {
+ // remove coarsen flag...
+ cell->clear_coarsen_flag();
+
+ // ...and if necessary also
+ // refine the current cell,
+ // at the same time
+ // updating the level
+ // information about
+ // vertices
+ if (vertex_level[cell->vertex_index(vertex)] >
+ cell->level()+1)
+ {
+ cell->set_refine_flag();
+
+ for (unsigned int v=0; v<GeometryInfo<dim>::vertices_per_cell;
+ ++v)
+ vertex_level[cell->vertex_index(v)]
+ = std::max (vertex_level[cell->vertex_index(v)],
+ cell->level()+1);
+ }
+
+ // continue and see whether
+ // we may, for example, go
+ // into the inner 'if'
+ // above based on a
+ // different vertex
+ }
+ }
+ }
+
+ /////////////////////////////////////
+ // STEP 4:
+ // eliminate unrefined
+ // islands. this has higher
+ // priority since this
+ // diminishes the
+ // approximation properties
+ // not only of the unrefined
+ // island, but also of the
+ // surrounding patch.
+ //
+ // do the loop from finest
+ // to coarsest cells since
+ // we may trigger a cascade
+ // by marking cells for
+ // refinement which may
+ // trigger more cells
+ // further down below
if (smooth_grid & eliminate_unrefined_islands)
- {
- active_cell_iterator cell=last_active(),
- endc=end();
-
- for (; cell != endc; --cell)
- // only do something if
- // cell is not already
- // flagged for
- // (isotropic) refinement
- if (cell->refine_flag_set() != RefinementCase<dim>::isotropic_refinement)
- possibly_refine_unrefined_island<dim,spacedim>
- (cell,
- (smooth_grid & allow_anisotropic_smoothing) != 0);
- }
-
- /////////////////////////////////
- // STEP 5:
- // ensure patch level 1.
- //
- // Introduce some terminology:
- // - a cell that is refined
- // once is a patch of
- // level 1 simply called patch.
- // - a cell that is globally
- // refined twice is called
- // a patch of level 2.
- // - patch level n says that
- // the triangulation consists
- // of patches of level n.
- // This makes sense only
- // if the grid is already at
- // least n times globally
- // refined.
- //
- // E.g. from patch level 1
- // follows: if at least one
- // of the children of a cell
- // is or will be refined
- // than enforce all
- // children to be
- // refined.
-
- // This step 4 only
- // sets refinement flags and
- // does not set coarsening
- // flags.
+ {
+ active_cell_iterator cell=last_active(),
+ endc=end();
+
+ for (; cell != endc; --cell)
+ // only do something if
+ // cell is not already
+ // flagged for
+ // (isotropic) refinement
+ if (cell->refine_flag_set() != RefinementCase<dim>::isotropic_refinement)
+ possibly_refine_unrefined_island<dim,spacedim>
+ (cell,
+ (smooth_grid & allow_anisotropic_smoothing) != 0);
+ }
+
+ /////////////////////////////////
+ // STEP 5:
+ // ensure patch level 1.
+ //
+ // Introduce some terminology:
+ // - a cell that is refined
+ // once is a patch of
+ // level 1 simply called patch.
+ // - a cell that is globally
+ // refined twice is called
+ // a patch of level 2.
+ // - patch level n says that
+ // the triangulation consists
+ // of patches of level n.
+ // This makes sense only
+ // if the grid is already at
+ // least n times globally
+ // refined.
+ //
+ // E.g. from patch level 1
+ // follows: if at least one
+ // of the children of a cell
+ // is or will be refined
+ // than enforce all
+ // children to be
+ // refined.
+
+ // This step 4 only
+ // sets refinement flags and
+ // does not set coarsening
+ // flags.
if (smooth_grid & patch_level_1)
- {
- // An important assumption
- // (A) is that before
- // calling this function
- // the grid was already of
- // patch level 1.
-
- // loop over all cells
- // whose children are all
- // active. (By assumption
- // (A) either all or none
- // of the children are
- // active). If the refine
- // flag of at least one of
- // the children is set then
- // set_refine_flag and
- // clear_coarsen_flag of
- // all children.
- for (cell_iterator cell = begin(); cell != end(); ++cell)
- if (!cell->active())
- {
- // ensure the
- // invariant. we can
- // then check whether
- // all of its
- // children are
- // further refined or
- // not by simply
- // looking at the
- // first child
- Assert (cell_is_patch_level_1(cell),
- ExcInternalError());
- if (cell->child(0)->has_children() == true)
- continue;
-
- // cell is found to
- // be a patch.
- // combine the refine
- // cases of all
- // children
- RefinementCase<dim> combined_ref_case = RefinementCase<dim>::no_refinement;
- for (unsigned int i=0; i<cell->n_children(); ++i)
- combined_ref_case = combined_ref_case |
- cell->child(i)->refine_flag_set();
- if (combined_ref_case != RefinementCase<dim>::no_refinement)
- for (unsigned int i=0; i<cell->n_children(); ++i)
- {
- cell_iterator child = cell->child(i);
-
- child->clear_coarsen_flag();
- child->set_refine_flag(combined_ref_case);
- }
- }
-
- // The code above dealt
- // with the case where we
- // may get a
- // non-patch_level_1 mesh
- // from refinement. Now
- // also deal with the case
- // where we could get such
- // a mesh by coarsening.
- // Coarsen the children
- // (and remove the
- // grandchildren) only if
- // all cell->grandchild(i)
- // ->coarsen_flag_set()
- // are set.
- //
- // for a case where this is
- // a bit tricky, take a
- // look at the
- // mesh_smoothing_0[12]
- // testcases
- for (cell_iterator cell = begin(); cell != end(); ++cell)
- {
- // check if this cell
- // has active
- // grandchildren. note
- // that we know that it
- // is patch_level_1,
- // i.e. if one of its
- // children is active
- // then so are all, and
- // it isn't going to
- // have any
- // grandchildren at
- // all:
- if (cell->active()
- ||
- cell->child(0)->active())
- continue;
-
- // cell is not active,
- // and so are none of
- // its children. check
- // the
- // grandchildren. note
- // that the children
- // are also
- // patch_level_1, and
- // so we only ever need
- // to check their first
- // child
- const unsigned int n_children=cell->n_children();
- bool has_active_grandchildren = false;
-
- for (unsigned int i=0; i<n_children; ++i)
- if (cell->child(i)->child(0)->active())
- {
- has_active_grandchildren = true;
- break;
- }
-
- if (has_active_grandchildren == false)
- continue;
-
-
- // ok, there are active
- // grandchildren. see
- // if either all or
- // none of them are
- // flagged for
- // coarsening
- unsigned int n_grandchildren=0;
- // count all coarsen
- // flags of the
- // grandchildren.
- unsigned int n_coarsen_flags=0;
- // cell is not a
- // patch (of level 1)
- // as it has a
- // grandchild. Is
- // cell a patch of
- // level 2??
- // Therefore: find
- // out whether all
- // cell->child(i) are
- // patches
- for (unsigned int c=0; c<n_children; ++c)
- {
- // get at the
- // child. by
- // assumption
- // (A), and the
- // check by which
- // we got here,
- // the child is
- // not active
- cell_iterator child=cell->child(c);
-
- const unsigned int nn_children=child->n_children();
- n_grandchildren += nn_children;
-
- // if child is
- // found to be a
- // patch of
- // active cells
- // itself, then
- // add up how
- // many of its
- // children are
- // supposed to be
- // coarsened
- if (child->child(0)->active())
- for (unsigned int cc=0; cc<nn_children; ++cc)
- if (child->child(cc)->coarsen_flag_set())
- ++n_coarsen_flags;
- }
-
- // if not all
- // grandchildren are
- // supposed to be
- // coarsened
- // (e.g. because some
- // simply don't have
- // the flag set, or
- // because they are not
- // active and therefore
- // cannot carry the
- // flag), then remove
- // the coarsen flag
- // from all of the
- // active
- // grandchildren. note
- // that there may be
- // coarsen flags on the
- // grandgrandchildren
- // -- we don't clear
- // them here, but we'll
- // get to them in later
- // iterations if
- // necessary
- //
- // there is nothing
- // we have to do if
- // no coarsen flags
- // have been set at
- // all
- if ((n_coarsen_flags != n_grandchildren)
- &&
- (n_coarsen_flags > 0))
- for (unsigned int c=0; c<n_children; ++c)
- {
- const cell_iterator child = cell->child(c);
- if (child->child(0)->active())
- for (unsigned int cc=0; cc<child->n_children(); ++cc)
- child->child(cc)->clear_coarsen_flag();
- }
- }
- }
-
- //////////////////////////////////
- //
- // at the boundary we could end up with
- // cells with negative volume or at
- // least with a part, that is negative,
- // if the cell is refined
- // anisotropically. we have to check,
- // whether that can happen
+ {
+ // An important assumption
+ // (A) is that before
+ // calling this function
+ // the grid was already of
+ // patch level 1.
+
+ // loop over all cells
+ // whose children are all
+ // active. (By assumption
+ // (A) either all or none
+ // of the children are
+ // active). If the refine
+ // flag of at least one of
+ // the children is set then
+ // set_refine_flag and
+ // clear_coarsen_flag of
+ // all children.
+ for (cell_iterator cell = begin(); cell != end(); ++cell)
+ if (!cell->active())
+ {
+ // ensure the
+ // invariant. we can
+ // then check whether
+ // all of its
+ // children are
+ // further refined or
+ // not by simply
+ // looking at the
+ // first child
+ Assert (cell_is_patch_level_1(cell),
+ ExcInternalError());
+ if (cell->child(0)->has_children() == true)
+ continue;
+
+ // cell is found to
+ // be a patch.
+ // combine the refine
+ // cases of all
+ // children
+ RefinementCase<dim> combined_ref_case = RefinementCase<dim>::no_refinement;
+ for (unsigned int i=0; i<cell->n_children(); ++i)
+ combined_ref_case = combined_ref_case |
+ cell->child(i)->refine_flag_set();
+ if (combined_ref_case != RefinementCase<dim>::no_refinement)
+ for (unsigned int i=0; i<cell->n_children(); ++i)
+ {
+ cell_iterator child = cell->child(i);
+
+ child->clear_coarsen_flag();
+ child->set_refine_flag(combined_ref_case);
+ }
+ }
+
+ // The code above dealt
+ // with the case where we
+ // may get a
+ // non-patch_level_1 mesh
+ // from refinement. Now
+ // also deal with the case
+ // where we could get such
+ // a mesh by coarsening.
+ // Coarsen the children
+ // (and remove the
+ // grandchildren) only if
+ // all cell->grandchild(i)
+ // ->coarsen_flag_set()
+ // are set.
+ //
+ // for a case where this is
+ // a bit tricky, take a
+ // look at the
+ // mesh_smoothing_0[12]
+ // testcases
+ for (cell_iterator cell = begin(); cell != end(); ++cell)
+ {
+ // check if this cell
+ // has active
+ // grandchildren. note
+ // that we know that it
+ // is patch_level_1,
+ // i.e. if one of its
+ // children is active
+ // then so are all, and
+ // it isn't going to
+ // have any
+ // grandchildren at
+ // all:
+ if (cell->active()
+ ||
+ cell->child(0)->active())
+ continue;
+
+ // cell is not active,
+ // and so are none of
+ // its children. check
+ // the
+ // grandchildren. note
+ // that the children
+ // are also
+ // patch_level_1, and
+ // so we only ever need
+ // to check their first
+ // child
+ const unsigned int n_children=cell->n_children();
+ bool has_active_grandchildren = false;
+
+ for (unsigned int i=0; i<n_children; ++i)
+ if (cell->child(i)->child(0)->active())
+ {
+ has_active_grandchildren = true;
+ break;
+ }
+
+ if (has_active_grandchildren == false)
+ continue;
+
+
+ // ok, there are active
+ // grandchildren. see
+ // if either all or
+ // none of them are
+ // flagged for
+ // coarsening
+ unsigned int n_grandchildren=0;
+ // count all coarsen
+ // flags of the
+ // grandchildren.
+ unsigned int n_coarsen_flags=0;
+ // cell is not a
+ // patch (of level 1)
+ // as it has a
+ // grandchild. Is
+ // cell a patch of
+ // level 2??
+ // Therefore: find
+ // out whether all
+ // cell->child(i) are
+ // patches
+ for (unsigned int c=0; c<n_children; ++c)
+ {
+ // get at the
+ // child. by
+ // assumption
+ // (A), and the
+ // check by which
+ // we got here,
+ // the child is
+ // not active
+ cell_iterator child=cell->child(c);
+
+ const unsigned int nn_children=child->n_children();
+ n_grandchildren += nn_children;
+
+ // if child is
+ // found to be a
+ // patch of
+ // active cells
+ // itself, then
+ // add up how
+ // many of its
+ // children are
+ // supposed to be
+ // coarsened
+ if (child->child(0)->active())
+ for (unsigned int cc=0; cc<nn_children; ++cc)
+ if (child->child(cc)->coarsen_flag_set())
+ ++n_coarsen_flags;
+ }
+
+ // if not all
+ // grandchildren are
+ // supposed to be
+ // coarsened
+ // (e.g. because some
+ // simply don't have
+ // the flag set, or
+ // because they are not
+ // active and therefore
+ // cannot carry the
+ // flag), then remove
+ // the coarsen flag
+ // from all of the
+ // active
+ // grandchildren. note
+ // that there may be
+ // coarsen flags on the
+ // grandgrandchildren
+ // -- we don't clear
+ // them here, but we'll
+ // get to them in later
+ // iterations if
+ // necessary
+ //
+ // there is nothing
+ // we have to do if
+ // no coarsen flags
+ // have been set at
+ // all
+ if ((n_coarsen_flags != n_grandchildren)
+ &&
+ (n_coarsen_flags > 0))
+ for (unsigned int c=0; c<n_children; ++c)
+ {
+ const cell_iterator child = cell->child(c);
+ if (child->child(0)->active())
+ for (unsigned int cc=0; cc<child->n_children(); ++cc)
+ child->child(cc)->clear_coarsen_flag();
+ }
+ }
+ }
+
+ //////////////////////////////////
+ //
+ // at the boundary we could end up with
+ // cells with negative volume or at
+ // least with a part, that is negative,
+ // if the cell is refined
+ // anisotropically. we have to check,
+ // whether that can happen
internal::Triangulation::Implementation::prevent_distorted_boundary_cells(*this);
- /////////////////////////////////
- // STEP 6:
- // take care of the requirement that no
- // double refinement is done at each face
- //
- // in case of anisotropic refinement
- // it is only likely, but not sure,
- // that the cells, which are more
- // refined along a certain face common
- // to two cells are on a higher
- // level. therefore we cannot be sure,
- // that the requirement of no double
- // refinement is fulfilled after a
- // single pass of the following
- // actions. We could just wait for the
- // next global loop. when this
- // function terminates, the
- // requirement will be
- // fullfilled. However, it might be
- // faster to insert an inner loop
- // here.
+ /////////////////////////////////
+ // STEP 6:
+ // take care of the requirement that no
+ // double refinement is done at each face
+ //
+ // in case of anisotropic refinement
+ // it is only likely, but not sure,
+ // that the cells, which are more
+ // refined along a certain face common
+ // to two cells are on a higher
+ // level. therefore we cannot be sure,
+ // that the requirement of no double
+ // refinement is fulfilled after a
+ // single pass of the following
+ // actions. We could just wait for the
+ // next global loop. when this
+ // function terminates, the
+ // requirement will be
+ // fullfilled. However, it might be
+ // faster to insert an inner loop
+ // here.
bool changed = true;
while (changed)
- {
- changed=false;
- active_cell_iterator cell=last_active(),
- endc=end();
-
- for (; cell != endc; --cell)
- if (cell->refine_flag_set())
- {
- // loop over neighbors of cell
- for (unsigned int i=0; i<GeometryInfo<dim>::faces_per_cell; ++i)
- {
- // only do something if the
- // face is not at the boundary
- // and if the face will be
- // refined with the RefineCase
- // currently flagged for
- if (cell->neighbor(i).state() == IteratorState::valid &&
- (GeometryInfo<dim>::face_refinement_case(cell->refine_flag_set(),
- i)
- != RefinementCase<dim-1>::no_refinement))
- {
- // 1) if the neighbor has
- // children: nothing to
- // worry about.
- // 2) if the neighbor is
- // active and a coarser
- // one, ensure, that its
- // refine_flag is set
- // 3) if the neighbor is
- // active and as
- // refined along the face
- // as our current cell,
- // make sure, that no
- // coarsen_flag is set. if
- // we remove the coarsen
- // flag of our neighbor,
- // fix_coarsen_flags() makes
- // sure, that the mother
- // cell will not be
- // coarsened
- if (cell->neighbor(i)->active())
- {
- if (cell->neighbor_is_coarser(i))
- {
- if (cell->neighbor(i)->coarsen_flag_set())
- cell->neighbor(i)->clear_coarsen_flag();
- // we'll set the
- // refine flag
- // for this
- // neighbor
- // below. we
- // note, that we
- // have changed
- // something by
- // setting the
- // changed flag
- // to true. We do
- // not need to do
- // so, if we just
- // removed the
- // coarsen flag,
- // as the changed
- // flag only
- // indicates the
- // need to re-run
- // the inner
- // loop. however,
- // we only loop
- // over cells
- // flagged for
- // refinement
- // here, so
- // nothing to
- // worry about if
- // we remove
- // coarsen flags
-
- if (dim==2)
- {
- if (smooth_grid & allow_anisotropic_smoothing)
- changed=cell->neighbor(i)->flag_for_face_refinement(cell->neighbor_of_coarser_neighbor(i).first,
- RefinementCase<dim-1>::cut_x);
- else
- {
- if (!cell->neighbor(i)->refine_flag_set())
- changed=true;
- cell->neighbor(i)->set_refine_flag();
- }
- }
- else //i.e. if (dim==3)
- {
+ {
+ changed=false;
+ active_cell_iterator cell=last_active(),
+ endc=end();
+
+ for (; cell != endc; --cell)
+ if (cell->refine_flag_set())
+ {
+ // loop over neighbors of cell
+ for (unsigned int i=0; i<GeometryInfo<dim>::faces_per_cell; ++i)
+ {
+ // only do something if the
+ // face is not at the boundary
+ // and if the face will be
+ // refined with the RefineCase
+ // currently flagged for
+ if (cell->neighbor(i).state() == IteratorState::valid &&
+ (GeometryInfo<dim>::face_refinement_case(cell->refine_flag_set(),
+ i)
+ != RefinementCase<dim-1>::no_refinement))
+ {
+ // 1) if the neighbor has
+ // children: nothing to
+ // worry about.
+ // 2) if the neighbor is
+ // active and a coarser
+ // one, ensure, that its
+ // refine_flag is set
+ // 3) if the neighbor is
+ // active and as
+ // refined along the face
+ // as our current cell,
+ // make sure, that no
+ // coarsen_flag is set. if
+ // we remove the coarsen
+ // flag of our neighbor,
+ // fix_coarsen_flags() makes
+ // sure, that the mother
+ // cell will not be
+ // coarsened
+ if (cell->neighbor(i)->active())
+ {
+ if (cell->neighbor_is_coarser(i))
+ {
+ if (cell->neighbor(i)->coarsen_flag_set())
+ cell->neighbor(i)->clear_coarsen_flag();
+ // we'll set the
+ // refine flag
+ // for this
+ // neighbor
+ // below. we
+ // note, that we
+ // have changed
+ // something by
+ // setting the
+ // changed flag
+ // to true. We do
+ // not need to do
+ // so, if we just
+ // removed the
+ // coarsen flag,
+ // as the changed
+ // flag only
+ // indicates the
+ // need to re-run
+ // the inner
+ // loop. however,
+ // we only loop
+ // over cells
+ // flagged for
+ // refinement
+ // here, so
+ // nothing to
+ // worry about if
+ // we remove
+ // coarsen flags
+
+ if (dim==2)
+ {
+ if (smooth_grid & allow_anisotropic_smoothing)
+ changed=cell->neighbor(i)->flag_for_face_refinement(cell->neighbor_of_coarser_neighbor(i).first,
+ RefinementCase<dim-1>::cut_x);
+ else
+ {
+ if (!cell->neighbor(i)->refine_flag_set())
+ changed=true;
+ cell->neighbor(i)->set_refine_flag();
+ }
+ }
+ else //i.e. if (dim==3)
+ {
// ugly situations might arise here, consider the following situation, which
// shows neighboring cells at the common face, where the upper right element is
// coarser at the given face. Now the upper child element of the lower left
// / /
// / /
- std::pair<unsigned int, unsigned int> nb_indices
- =cell->neighbor_of_coarser_neighbor(i);
- unsigned int refined_along_x=0,
- refined_along_y=0,
- to_be_refined_along_x=0,
- to_be_refined_along_y=0;
+ std::pair<unsigned int, unsigned int> nb_indices
+ =cell->neighbor_of_coarser_neighbor(i);
+ unsigned int refined_along_x=0,
+ refined_along_y=0,
+ to_be_refined_along_x=0,
+ to_be_refined_along_y=0;
- const int this_face_index=cell->face_index(i);
+ const int this_face_index=cell->face_index(i);
// step 1: detect, along which axis the face is currently refined
- if ((this_face_index
- == cell->neighbor(i)->face(nb_indices.first)->child_index(0)) ||
- (this_face_index
- == cell->neighbor(i)->face(nb_indices.first)->child_index(1)))
- {
- // this
- // might
- // be an
- // anisotropic
- // child. get
- // the
- // face
- // refine
- // case
- // of the
- // neighbors
- // face
- // and
- // count
- // refinements
- // in x
- // and y
- // direction.
- RefinementCase<dim-1> frc=cell->neighbor(i)->face(nb_indices.first)->refinement_case();
- if (frc & RefinementCase<dim>::cut_x)
- ++refined_along_x;
- if (frc & RefinementCase<dim>::cut_y)
- ++refined_along_y;
- }
- else
- // this has
- // to be an
- // isotropic
- // child
- {
- ++refined_along_x;
- ++refined_along_y;
- }
+ if ((this_face_index
+ == cell->neighbor(i)->face(nb_indices.first)->child_index(0)) ||
+ (this_face_index
+ == cell->neighbor(i)->face(nb_indices.first)->child_index(1)))
+ {
+ // this
+ // might
+ // be an
+ // anisotropic
+ // child. get
+ // the
+ // face
+ // refine
+ // case
+ // of the
+ // neighbors
+ // face
+ // and
+ // count
+ // refinements
+ // in x
+ // and y
+ // direction.
+ RefinementCase<dim-1> frc=cell->neighbor(i)->face(nb_indices.first)->refinement_case();
+ if (frc & RefinementCase<dim>::cut_x)
+ ++refined_along_x;
+ if (frc & RefinementCase<dim>::cut_y)
+ ++refined_along_y;
+ }
+ else
+ // this has
+ // to be an
+ // isotropic
+ // child
+ {
+ ++refined_along_x;
+ ++refined_along_y;
+ }
// step 2: detect, along which axis the face has to be refined given the current
// refine flag
- RefinementCase<dim-1> flagged_frc=
- GeometryInfo<dim>::face_refinement_case(cell->refine_flag_set(),
- i,
- cell->face_orientation(i),
- cell->face_flip(i),
- cell->face_rotation(i));
- if (flagged_frc & RefinementCase<dim>::cut_x)
- ++to_be_refined_along_x;
- if (flagged_frc & RefinementCase<dim>::cut_y)
- ++to_be_refined_along_y;
+ RefinementCase<dim-1> flagged_frc=
+ GeometryInfo<dim>::face_refinement_case(cell->refine_flag_set(),
+ i,
+ cell->face_orientation(i),
+ cell->face_flip(i),
+ cell->face_rotation(i));
+ if (flagged_frc & RefinementCase<dim>::cut_x)
+ ++to_be_refined_along_x;
+ if (flagged_frc & RefinementCase<dim>::cut_y)
+ ++to_be_refined_along_y;
// step 3: set the refine flag of the (coarser and active) neighbor.
- if ((smooth_grid & allow_anisotropic_smoothing) ||
- cell->neighbor(i)->refine_flag_set())
- {
- if (refined_along_x + to_be_refined_along_x > 1)
- changed |= cell->neighbor(i)->flag_for_face_refinement(nb_indices.first,
- RefinementCase<dim-1>::cut_axis(0));
- if (refined_along_y + to_be_refined_along_y > 1)
- changed |= cell->neighbor(i)->flag_for_face_refinement(nb_indices.first,
- RefinementCase<dim-1>::cut_axis(1));
- }
- else
- {
- if (cell->neighbor(i)->refine_flag_set()!=RefinementCase<dim>::isotropic_refinement)
- changed=true;
- cell->neighbor(i)->set_refine_flag();
- }
+ if ((smooth_grid & allow_anisotropic_smoothing) ||
+ cell->neighbor(i)->refine_flag_set())
+ {
+ if (refined_along_x + to_be_refined_along_x > 1)
+ changed |= cell->neighbor(i)->flag_for_face_refinement(nb_indices.first,
+ RefinementCase<dim-1>::cut_axis(0));
+ if (refined_along_y + to_be_refined_along_y > 1)
+ changed |= cell->neighbor(i)->flag_for_face_refinement(nb_indices.first,
+ RefinementCase<dim-1>::cut_axis(1));
+ }
+ else
+ {
+ if (cell->neighbor(i)->refine_flag_set()!=RefinementCase<dim>::isotropic_refinement)
+ changed=true;
+ cell->neighbor(i)->set_refine_flag();
+ }
// step 4: if necessary (see above) add to the refine flag of the current cell
- cell_iterator nb=cell->neighbor(i);
- RefinementCase<dim-1> nb_frc
- = GeometryInfo<dim>::face_refinement_case(nb->refine_flag_set(),
- nb_indices.first,
- nb->face_orientation(nb_indices.first),
- nb->face_flip(nb_indices.first),
- nb->face_rotation(nb_indices.first));
- if ((nb_frc & RefinementCase<dim>::cut_x) &&
- !(refined_along_x || to_be_refined_along_x))
- changed |= cell->flag_for_face_refinement(i,RefinementCase<dim-1>::cut_axis(0));
- if ((nb_frc & RefinementCase<dim>::cut_y) &&
- !(refined_along_y || to_be_refined_along_y))
- changed |= cell->flag_for_face_refinement(i,RefinementCase<dim-1>::cut_axis(1));
- }
- }// if neighbor is coarser
- else // -> now the neighbor is not coarser
- {
- cell->neighbor(i)->clear_coarsen_flag();
- const unsigned int nb_nb=cell->neighbor_of_neighbor(i);
- const cell_iterator neighbor=cell->neighbor(i);
- RefinementCase<dim-1> face_ref_case=
- GeometryInfo<dim>::face_refinement_case(neighbor->refine_flag_set(),
- nb_nb,
- neighbor->face_orientation(nb_nb),
- neighbor->face_flip(nb_nb),
- neighbor->face_rotation(nb_nb));
- RefinementCase<dim-1> needed_face_ref_case
- =GeometryInfo<dim>::face_refinement_case(cell->refine_flag_set(),
- i,
- cell->face_orientation(i),
- cell->face_flip(i),
- cell->face_rotation(i));
- // if the
- // neighbor wants
- // to refine the
- // face with
- // cut_x and we
- // want cut_y or
- // vice versa, we
- // have to refine
- // isotropically
- // at the given
- // face
- if ((face_ref_case==RefinementCase<dim>::cut_x && needed_face_ref_case==RefinementCase<dim>::cut_y) ||
- (face_ref_case==RefinementCase<dim>::cut_y && needed_face_ref_case==RefinementCase<dim>::cut_x))
- {
- changed=cell->flag_for_face_refinement(i, face_ref_case);
- neighbor->flag_for_face_refinement(nb_nb, needed_face_ref_case);
- }
- }
- }
- else //-> the neighbor is not active
- {
- RefinementCase<dim-1> face_ref_case = cell->face(i)->refinement_case(),
- needed_face_ref_case = GeometryInfo<dim>::face_refinement_case(cell->refine_flag_set(),
- i,
- cell->face_orientation(i),
- cell->face_flip(i),
- cell->face_rotation(i));
- // if the face is
- // refined with cut_x
- // and we want cut_y
- // or vice versa, we
- // have to refine
- // isotropically at
- // the given face
- if ((face_ref_case==RefinementCase<dim>::cut_x && needed_face_ref_case==RefinementCase<dim>::cut_y) ||
- (face_ref_case==RefinementCase<dim>::cut_y && needed_face_ref_case==RefinementCase<dim>::cut_x))
- changed=cell->flag_for_face_refinement(i, face_ref_case);
- }
- }
- }
- }
- }
-
- //////////////////////////////////////
- // STEP 7:
- // take care that no double refinement
- // is done at each line in 3d or higher
- // dimensions.
+ cell_iterator nb=cell->neighbor(i);
+ RefinementCase<dim-1> nb_frc
+ = GeometryInfo<dim>::face_refinement_case(nb->refine_flag_set(),
+ nb_indices.first,
+ nb->face_orientation(nb_indices.first),
+ nb->face_flip(nb_indices.first),
+ nb->face_rotation(nb_indices.first));
+ if ((nb_frc & RefinementCase<dim>::cut_x) &&
+ !(refined_along_x || to_be_refined_along_x))
+ changed |= cell->flag_for_face_refinement(i,RefinementCase<dim-1>::cut_axis(0));
+ if ((nb_frc & RefinementCase<dim>::cut_y) &&
+ !(refined_along_y || to_be_refined_along_y))
+ changed |= cell->flag_for_face_refinement(i,RefinementCase<dim-1>::cut_axis(1));
+ }
+ }// if neighbor is coarser
+ else // -> now the neighbor is not coarser
+ {
+ cell->neighbor(i)->clear_coarsen_flag();
+ const unsigned int nb_nb=cell->neighbor_of_neighbor(i);
+ const cell_iterator neighbor=cell->neighbor(i);
+ RefinementCase<dim-1> face_ref_case=
+ GeometryInfo<dim>::face_refinement_case(neighbor->refine_flag_set(),
+ nb_nb,
+ neighbor->face_orientation(nb_nb),
+ neighbor->face_flip(nb_nb),
+ neighbor->face_rotation(nb_nb));
+ RefinementCase<dim-1> needed_face_ref_case
+ =GeometryInfo<dim>::face_refinement_case(cell->refine_flag_set(),
+ i,
+ cell->face_orientation(i),
+ cell->face_flip(i),
+ cell->face_rotation(i));
+ // if the
+ // neighbor wants
+ // to refine the
+ // face with
+ // cut_x and we
+ // want cut_y or
+ // vice versa, we
+ // have to refine
+ // isotropically
+ // at the given
+ // face
+ if ((face_ref_case==RefinementCase<dim>::cut_x && needed_face_ref_case==RefinementCase<dim>::cut_y) ||
+ (face_ref_case==RefinementCase<dim>::cut_y && needed_face_ref_case==RefinementCase<dim>::cut_x))
+ {
+ changed=cell->flag_for_face_refinement(i, face_ref_case);
+ neighbor->flag_for_face_refinement(nb_nb, needed_face_ref_case);
+ }
+ }
+ }
+ else //-> the neighbor is not active
+ {
+ RefinementCase<dim-1> face_ref_case = cell->face(i)->refinement_case(),
+ needed_face_ref_case = GeometryInfo<dim>::face_refinement_case(cell->refine_flag_set(),
+ i,
+ cell->face_orientation(i),
+ cell->face_flip(i),
+ cell->face_rotation(i));
+ // if the face is
+ // refined with cut_x
+ // and we want cut_y
+ // or vice versa, we
+ // have to refine
+ // isotropically at
+ // the given face
+ if ((face_ref_case==RefinementCase<dim>::cut_x && needed_face_ref_case==RefinementCase<dim>::cut_y) ||
+ (face_ref_case==RefinementCase<dim>::cut_y && needed_face_ref_case==RefinementCase<dim>::cut_x))
+ changed=cell->flag_for_face_refinement(i, face_ref_case);
+ }
+ }
+ }
+ }
+ }
+
+ //////////////////////////////////////
+ // STEP 7:
+ // take care that no double refinement
+ // is done at each line in 3d or higher
+ // dimensions.
internal::Triangulation::Implementation::prepare_refinement_dim_dependent (*this);
- //////////////////////////////////////
- // STEP 8:
- // make sure that all children of each
- // cell are either flagged for coarsening
- // or none of the children is
+ //////////////////////////////////////
+ // STEP 8:
+ // make sure that all children of each
+ // cell are either flagged for coarsening
+ // or none of the children is
fix_coarsen_flags ();
- // get the refinement and coarsening
- // flags
+ // get the refinement and coarsening
+ // flags
std::vector<bool> flags_after_loop[2];
save_coarsen_flags (flags_after_loop[0]);
save_refine_flags (flags_after_loop[1]);
- // find out whether something was
- // changed in this loop
+ // find out whether something was
+ // changed in this loop
mesh_changed_in_this_loop
- = ((flags_before_loop[0] != flags_after_loop[0]) ||
- (flags_before_loop[1] != flags_after_loop[1]));
+ = ((flags_before_loop[0] != flags_after_loop[0]) ||
+ (flags_before_loop[1] != flags_after_loop[1]));
- // set the flags for the next loop
- // already
+ // set the flags for the next loop
+ // already
flags_before_loop[0].swap(flags_after_loop[0]);
flags_before_loop[1].swap(flags_after_loop[1]);
}
while (mesh_changed_in_this_loop);
- // find out whether something was really
- // changed in this function. Note that
- // @p{flags_before_loop} represents the
- // state after the last loop, i.e.
- // the present state
+ // find out whether something was really
+ // changed in this function. Note that
+ // @p{flags_before_loop} represents the
+ // state after the last loop, i.e.
+ // the present state
return ((flags_before[0] != flags_before_loop[0]) ||
- (flags_before[1] != flags_before_loop[1]));
+ (flags_before[1] != flags_before_loop[1]));
}
template <int dim, int spacedim>
void Triangulation<dim, spacedim>::write_bool_vector (const unsigned int magic_number1,
- const std::vector<bool> &v,
- const unsigned int magic_number2,
- std::ostream &out)
+ const std::vector<bool> &v,
+ const unsigned int magic_number2,
+ std::ostream &out)
{
const unsigned int N = v.size();
unsigned char *flags = new unsigned char[N/8+1];
AssertThrow (out, ExcIO());
- // format:
- // 0. magic number
- // 1. number of flags
- // 2. the flags
- // 3. magic number
+ // format:
+ // 0. magic number
+ // 1. number of flags
+ // 2. the flags
+ // 3. magic number
out << magic_number1 << ' ' << N << std::endl;
for (unsigned int i=0; i<N/8+1; ++i)
out << static_cast<unsigned int>(flags[i]) << ' ';
template <int dim, int spacedim>
void Triangulation<dim, spacedim>::read_bool_vector (const unsigned int magic_number1,
- std::vector<bool> &v,
- const unsigned int magic_number2,
- std::istream &in)
+ std::vector<bool> &v,
+ const unsigned int magic_number2,
+ std::istream &in)
{
AssertThrow (in, ExcIO());
template<int dim, int spacedim>
Triangulation<dim, spacedim>::DistortedCellList::~DistortedCellList () throw ()
{
- // don't do anything here. the compiler
- // will automatically convert any
- // exceptions created by the destructors of
- // the member variables into abort() in
- // order to satisfy the throw()
- // specification
+ // don't do anything here. the compiler
+ // will automatically convert any
+ // exceptions created by the destructors of
+ // the member variables into abort() in
+ // order to satisfy the throw()
+ // specification
}
template<int dim, int spacedim>
void Triangulation<dim, spacedim>::
RefinementListener::copy_notification (const Triangulation<dim, spacedim> &,
- const Triangulation<dim, spacedim> &)
+ const Triangulation<dim, spacedim> &)
{}
connections.push_back
(signals.create.connect (std_cxx1x::bind (&RefinementListener::create_notification,
- std_cxx1x::ref(listener),
- std_cxx1x::cref(*this))));
+ std_cxx1x::ref(listener),
+ std_cxx1x::cref(*this))));
connections.push_back
(signals.copy.connect (std_cxx1x::bind (&RefinementListener::copy_notification,
- std_cxx1x::ref(listener),
- std_cxx1x::cref(*this),
- std_cxx1x::_1)));
+ std_cxx1x::ref(listener),
+ std_cxx1x::cref(*this),
+ std_cxx1x::_1)));
connections.push_back
(signals.pre_refinement.connect (std_cxx1x::bind (&RefinementListener::pre_refinement_notification,
- std_cxx1x::ref(listener),
- std_cxx1x::cref(*this))));
+ std_cxx1x::ref(listener),
+ std_cxx1x::cref(*this))));
connections.push_back
(signals.post_refinement.connect (std_cxx1x::bind (&RefinementListener::post_refinement_notification,
std_cxx1x::ref(listener),
- std_cxx1x::cref(*this))));
+ std_cxx1x::cref(*this))));
// now push the set of connections into the map
refinement_listener_map.insert (std::make_pair(&listener, connections));
Triangulation<dim, spacedim>::remove_refinement_listener (RefinementListener &listener) const
{
Assert (refinement_listener_map.find (&listener) != refinement_listener_map.end(),
- ExcMessage("You try to remove a refinement listener that does "
- "not appear to have been added previously."));
+ ExcMessage("You try to remove a refinement listener that does "
+ "not appear to have been added previously."));
// get the element of the map, and terminate these
// connections. then erase the element from the list
// $Id$
// Version: $Name$
//
-// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 by the deal.II authors
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
// anonymous namespace for helper functions
namespace
{
- // given the number of face's child
- // (subface_no), return the number of the
- // subface concerning the FaceRefineCase of
- // the face
+ // given the number of face's child
+ // (subface_no), return the number of the
+ // subface concerning the FaceRefineCase of
+ // the face
inline
unsigned int translate_subface_no(const TriaIterator<TriaAccessor<2, 3, 3> > &face,
- const unsigned int subface_no)
+ const unsigned int subface_no)
{
Assert(face->has_children(), ExcInternalError());
Assert(subface_no<face->n_children(), ExcInternalError());
if(face->child(subface_no)->has_children())
- // although the subface is refine, it
- // still matches the face of the cell
- // invoking the
- // neighbor_of_coarser_neighbor
- // function. this means that we are
- // looking from one cell (anisotropic
- // child) to a coarser neighbor which is
- // refined stronger than we are
- // (isotropically). So we won't be able
- // to use the neighbor_child_on_subface
- // function anyway, as the neighbor is
- // not active. In this case, simply
- // return the subface_no.
+ // although the subface is refine, it
+ // still matches the face of the cell
+ // invoking the
+ // neighbor_of_coarser_neighbor
+ // function. this means that we are
+ // looking from one cell (anisotropic
+ // child) to a coarser neighbor which is
+ // refined stronger than we are
+ // (isotropically). So we won't be able
+ // to use the neighbor_child_on_subface
+ // function anyway, as the neighbor is
+ // not active. In this case, simply
+ // return the subface_no.
return subface_no;
const bool first_child_has_children=face->child(0)->has_children();
- // if the first child has children
- // (FaceRefineCase case_x1y or case_y1x),
- // then the current subface_no needs to be
- // 1 and the result of this function is 2,
- // else simply return the given number,
- // which is 0 or 1 in an anisotropic case
- // (case_x, case_y, casex2y or casey2x) or
- // 0...3 in an isotropic case (case_xy)
+ // if the first child has children
+ // (FaceRefineCase case_x1y or case_y1x),
+ // then the current subface_no needs to be
+ // 1 and the result of this function is 2,
+ // else simply return the given number,
+ // which is 0 or 1 in an anisotropic case
+ // (case_x, case_y, casex2y or casey2x) or
+ // 0...3 in an isotropic case (case_xy)
return subface_no + first_child_has_children;
}
- // given the number of face's child
- // (subface_no) and grandchild
- // (subsubface_no), return the number of the
- // subface concerning the FaceRefineCase of
- // the face
+ // given the number of face's child
+ // (subface_no) and grandchild
+ // (subsubface_no), return the number of the
+ // subface concerning the FaceRefineCase of
+ // the face
inline
unsigned int translate_subface_no(const TriaIterator<TriaAccessor<2, 3, 3> > &face,
- const unsigned int subface_no,
- const unsigned int subsubface_no)
+ const unsigned int subface_no,
+ const unsigned int subsubface_no)
{
Assert(face->has_children(), ExcInternalError());
- // the subface must be refined, otherwise
- // we would have ended up in the second
- // function of this name...
+ // the subface must be refined, otherwise
+ // we would have ended up in the second
+ // function of this name...
Assert(face->child(subface_no)->has_children(), ExcInternalError());
Assert(subsubface_no<face->child(subface_no)->n_children(), ExcInternalError());
- // This can only be an anisotropic refinement case
+ // This can only be an anisotropic refinement case
Assert(face->refinement_case() < RefinementCase<2>::isotropic_refinement,
- ExcInternalError());
+ ExcInternalError());
const bool first_child_has_children=face->child(0)->has_children();
static const unsigned int e = deal_II_numbers::invalid_unsigned_int;
- // array containing the translation of the
- // numbers,
- //
- // first index: subface_no
- // second index: subsubface_no
- // third index: does the first subface have children? -> no and yes
+ // array containing the translation of the
+ // numbers,
+ //
+ // first index: subface_no
+ // second index: subsubface_no
+ // third index: does the first subface have children? -> no and yes
static const unsigned int translated_subface_no[2][2][2]
=
{{{e,0}, // first subface, first subsubface, first_child_has_children==no and yes
- {e,1}}, // first subface, second subsubface, first_child_has_children==no and yes
+ {e,1}}, // first subface, second subsubface, first_child_has_children==no and yes
{{1,2}, // second subface, first subsubface, first_child_has_children==no and yes
- {2,3}}}; // second subface, second subsubface, first_child_has_children==no and yes
+ {2,3}}}; // second subface, second subsubface, first_child_has_children==no and yes
Assert(translated_subface_no[subface_no][subsubface_no][first_child_has_children]!=e,
- ExcInternalError());
+ ExcInternalError());
return translated_subface_no[subface_no][subsubface_no][first_child_has_children];
}
Point<2>
barycenter (const TriaAccessor<2, 2, 2> &accessor)
{
- // the evaluation of the formulae
- // is a bit tricky when done dimension
- // independently, so we write this function
- // for 2D and 3D separately
+ // the evaluation of the formulae
+ // is a bit tricky when done dimension
+ // independently, so we write this function
+ // for 2D and 3D separately
/*
Get the computation of the barycenter by this little Maple script. We
use the bilinear mapping of the unit quad to the real quad. However,
*/
const double x[4] = { accessor.vertex(0)(0),
- accessor.vertex(1)(0),
- accessor.vertex(2)(0),
- accessor.vertex(3)(0) };
+ accessor.vertex(1)(0),
+ accessor.vertex(2)(0),
+ accessor.vertex(3)(0) };
const double y[4] = { accessor.vertex(0)(1),
- accessor.vertex(1)(1),
- accessor.vertex(2)(1),
- accessor.vertex(3)(1) };
+ accessor.vertex(1)(1),
+ accessor.vertex(2)(1),
+ accessor.vertex(3)(1) };
const double t1 = x[0]*x[1];
const double t3 = x[0]*x[0];
const double t5 = x[1]*x[1];
*/
const double x[8] = { accessor.vertex(0)(0),
- accessor.vertex(1)(0),
- accessor.vertex(5)(0),
- accessor.vertex(4)(0),
- accessor.vertex(2)(0),
- accessor.vertex(3)(0),
- accessor.vertex(7)(0),
- accessor.vertex(6)(0) };
+ accessor.vertex(1)(0),
+ accessor.vertex(5)(0),
+ accessor.vertex(4)(0),
+ accessor.vertex(2)(0),
+ accessor.vertex(3)(0),
+ accessor.vertex(7)(0),
+ accessor.vertex(6)(0) };
const double y[8] = { accessor.vertex(0)(1),
- accessor.vertex(1)(1),
- accessor.vertex(5)(1),
- accessor.vertex(4)(1),
- accessor.vertex(2)(1),
- accessor.vertex(3)(1),
- accessor.vertex(7)(1),
- accessor.vertex(6)(1) };
+ accessor.vertex(1)(1),
+ accessor.vertex(5)(1),
+ accessor.vertex(4)(1),
+ accessor.vertex(2)(1),
+ accessor.vertex(3)(1),
+ accessor.vertex(7)(1),
+ accessor.vertex(6)(1) };
const double z[8] = { accessor.vertex(0)(2),
- accessor.vertex(1)(2),
- accessor.vertex(5)(2),
- accessor.vertex(4)(2),
- accessor.vertex(2)(2),
- accessor.vertex(3)(2),
- accessor.vertex(7)(2),
- accessor.vertex(6)(2) };
+ accessor.vertex(1)(2),
+ accessor.vertex(5)(2),
+ accessor.vertex(4)(2),
+ accessor.vertex(2)(2),
+ accessor.vertex(3)(2),
+ accessor.vertex(7)(2),
+ accessor.vertex(6)(2) };
double s1, s2, s3, s4, s5, s6, s7, s8;
s1 = 1.0/6.0;
s8 = -x[2]*x[2]*y[0]*z[3]-2.0*z[6]*x[7]*x[7]*y[4]-z[5]*x[7]*x[7]*y[4]-z
- [6]*x[7]*x[7]*y[5]+2.0*y[6]*x[7]*x[7]*z[4]-z[5]*x[6]*x[6]*y[4]+x[6]*x[6]*y[4]*z
- [7]-z[1]*x[0]*x[0]*y[2]-x[6]*x[6]*y[7]*z[4]+2.0*x[6]*x[6]*y[5]*z[7]-2.0*x[6]*x
- [6]*y[7]*z[5]+y[5]*x[6]*x[6]*z[4]+2.0*x[5]*x[5]*y[4]*z[6]+x[0]*x[0]*y[7]*z[4]
- -2.0*x[5]*x[5]*y[6]*z[4];
+ [6]*x[7]*x[7]*y[5]+2.0*y[6]*x[7]*x[7]*z[4]-z[5]*x[6]*x[6]*y[4]+x[6]*x[6]*y[4]*z
+ [7]-z[1]*x[0]*x[0]*y[2]-x[6]*x[6]*y[7]*z[4]+2.0*x[6]*x[6]*y[5]*z[7]-2.0*x[6]*x
+ [6]*y[7]*z[5]+y[5]*x[6]*x[6]*z[4]+2.0*x[5]*x[5]*y[4]*z[6]+x[0]*x[0]*y[7]*z[4]
+ -2.0*x[5]*x[5]*y[6]*z[4];
s7 = s8-y[6]*x[5]*x[5]*z[7]+z[6]*x[5]*x[5]*y[7]-y[1]*x[0]*x[0]*z[5]+x[7]*
- z[5]*x[4]*y[7]-x[7]*y[6]*x[5]*z[7]-2.0*x[7]*x[6]*y[7]*z[4]+2.0*x[7]*x[6]*y[4]*z
- [7]-x[7]*x[5]*y[7]*z[4]-2.0*x[7]*y[6]*x[4]*z[7]-x[7]*y[5]*x[4]*z[7]+x[2]*x[2]*y
- [3]*z[0]-x[7]*x[6]*y[7]*z[5]+x[7]*x[6]*y[5]*z[7]+2.0*x[1]*x[1]*y[0]*z[5]+x[7]*z
- [6]*x[5]*y[7];
+ z[5]*x[4]*y[7]-x[7]*y[6]*x[5]*z[7]-2.0*x[7]*x[6]*y[7]*z[4]+2.0*x[7]*x[6]*y[4]*z
+ [7]-x[7]*x[5]*y[7]*z[4]-2.0*x[7]*y[6]*x[4]*z[7]-x[7]*y[5]*x[4]*z[7]+x[2]*x[2]*y
+ [3]*z[0]-x[7]*x[6]*y[7]*z[5]+x[7]*x[6]*y[5]*z[7]+2.0*x[1]*x[1]*y[0]*z[5]+x[7]*z
+ [6]*x[5]*y[7];
s8 = -2.0*x[1]*x[1]*y[5]*z[0]+z[1]*x[0]*x[0]*y[5]+2.0*x[2]*x[2]*y[3]*z[1]
- -z[5]*x[4]*x[4]*y[1]+y[5]*x[4]*x[4]*z[1]-2.0*x[5]*x[5]*y[4]*z[1]+2.0*x[5]*x[5]*
- y[1]*z[4]-2.0*x[2]*x[2]*y[1]*z[3]-y[1]*x[2]*x[2]*z[0]+x[7]*y[2]*x[3]*z[7]+x[7]*
- z[2]*x[6]*y[3]+2.0*x[7]*z[6]*x[4]*y[7]+z[5]*x[1]*x[1]*y[4]+z[1]*x[2]*x[2]*y[0]
- -2.0*y[0]*x[3]*x[3]*z[7];
+ -z[5]*x[4]*x[4]*y[1]+y[5]*x[4]*x[4]*z[1]-2.0*x[5]*x[5]*y[4]*z[1]+2.0*x[5]*x[5]*
+ y[1]*z[4]-2.0*x[2]*x[2]*y[1]*z[3]-y[1]*x[2]*x[2]*z[0]+x[7]*y[2]*x[3]*z[7]+x[7]*
+ z[2]*x[6]*y[3]+2.0*x[7]*z[6]*x[4]*y[7]+z[5]*x[1]*x[1]*y[4]+z[1]*x[2]*x[2]*y[0]
+ -2.0*y[0]*x[3]*x[3]*z[7];
s6 = s8+2.0*z[0]*x[3]*x[3]*y[7]-x[7]*x[2]*y[3]*z[7]-x[7]*z[2]*x[3]*y[7]+x
- [7]*x[2]*y[7]*z[3]-x[7]*y[2]*x[6]*z[3]+x[4]*x[5]*y[1]*z[4]-x[4]*x[5]*y[4]*z[1]+
- x[4]*z[5]*x[1]*y[4]-x[4]*y[5]*x[1]*z[4]-2.0*x[5]*z[5]*x[4]*y[1]-2.0*x[5]*y[5]*x
- [1]*z[4]+2.0*x[5]*z[5]*x[1]*y[4]+2.0*x[5]*y[5]*x[4]*z[1]-x[6]*z[5]*x[7]*y[4]-z
- [2]*x[3]*x[3]*y[6]+s7;
+ [7]*x[2]*y[7]*z[3]-x[7]*y[2]*x[6]*z[3]+x[4]*x[5]*y[1]*z[4]-x[4]*x[5]*y[4]*z[1]+
+ x[4]*z[5]*x[1]*y[4]-x[4]*y[5]*x[1]*z[4]-2.0*x[5]*z[5]*x[4]*y[1]-2.0*x[5]*y[5]*x
+ [1]*z[4]+2.0*x[5]*z[5]*x[1]*y[4]+2.0*x[5]*y[5]*x[4]*z[1]-x[6]*z[5]*x[7]*y[4]-z
+ [2]*x[3]*x[3]*y[6]+s7;
s8 = -2.0*x[6]*z[6]*x[7]*y[5]-x[6]*y[6]*x[4]*z[7]+y[2]*x[3]*x[3]*z[6]+x
- [6]*y[6]*x[7]*z[4]+2.0*y[2]*x[3]*x[3]*z[7]+x[0]*x[1]*y[0]*z[5]+x[0]*y[1]*x[5]*z
- [0]-x[0]*z[1]*x[5]*y[0]-2.0*z[2]*x[3]*x[3]*y[7]+2.0*x[6]*z[6]*x[5]*y[7]-x[0]*x
- [1]*y[5]*z[0]-x[6]*y[5]*x[4]*z[6]-2.0*x[3]*z[0]*x[7]*y[3]-x[6]*z[6]*x[7]*y[4]
- -2.0*x[1]*z[1]*x[5]*y[0];
+ [6]*y[6]*x[7]*z[4]+2.0*y[2]*x[3]*x[3]*z[7]+x[0]*x[1]*y[0]*z[5]+x[0]*y[1]*x[5]*z
+ [0]-x[0]*z[1]*x[5]*y[0]-2.0*z[2]*x[3]*x[3]*y[7]+2.0*x[6]*z[6]*x[5]*y[7]-x[0]*x
+ [1]*y[5]*z[0]-x[6]*y[5]*x[4]*z[6]-2.0*x[3]*z[0]*x[7]*y[3]-x[6]*z[6]*x[7]*y[4]
+ -2.0*x[1]*z[1]*x[5]*y[0];
s7 = s8+2.0*x[1]*y[1]*x[5]*z[0]+2.0*x[1]*z[1]*x[0]*y[5]+2.0*x[3]*y[0]*x
- [7]*z[3]+2.0*x[3]*x[0]*y[3]*z[7]-2.0*x[3]*x[0]*y[7]*z[3]-2.0*x[1]*y[1]*x[0]*z
- [5]-2.0*x[6]*y[6]*x[5]*z[7]+s6-y[5]*x[1]*x[1]*z[4]+x[6]*z[6]*x[4]*y[7]-2.0*x[2]
- *y[2]*x[3]*z[1]+x[6]*z[5]*x[4]*y[6]+x[6]*x[5]*y[4]*z[6]-y[6]*x[7]*x[7]*z[2]-x
- [6]*x[5]*y[6]*z[4];
+ [7]*z[3]+2.0*x[3]*x[0]*y[3]*z[7]-2.0*x[3]*x[0]*y[7]*z[3]-2.0*x[1]*y[1]*x[0]*z
+ [5]-2.0*x[6]*y[6]*x[5]*z[7]+s6-y[5]*x[1]*x[1]*z[4]+x[6]*z[6]*x[4]*y[7]-2.0*x[2]
+ *y[2]*x[3]*z[1]+x[6]*z[5]*x[4]*y[6]+x[6]*x[5]*y[4]*z[6]-y[6]*x[7]*x[7]*z[2]-x
+ [6]*x[5]*y[6]*z[4];
s8 = x[3]*x[3]*y[7]*z[4]-2.0*y[6]*x[7]*x[7]*z[3]+z[6]*x[7]*x[7]*y[2]+2.0*
- z[6]*x[7]*x[7]*y[3]+2.0*y[1]*x[0]*x[0]*z[3]+2.0*x[0]*x[1]*y[3]*z[0]-2.0*x[0]*y
- [0]*x[3]*z[4]-2.0*x[0]*z[1]*x[4]*y[0]-2.0*x[0]*y[1]*x[3]*z[0]+2.0*x[0]*y[0]*x
- [4]*z[3]-2.0*x[0]*z[0]*x[4]*y[3]+2.0*x[0]*x[1]*y[0]*z[4]+2.0*x[0]*z[1]*x[3]*y
- [0]-2.0*x[0]*x[1]*y[0]*z[3]-2.0*x[0]*x[1]*y[4]*z[0]+2.0*x[0]*y[1]*x[4]*z[0];
+ z[6]*x[7]*x[7]*y[3]+2.0*y[1]*x[0]*x[0]*z[3]+2.0*x[0]*x[1]*y[3]*z[0]-2.0*x[0]*y
+ [0]*x[3]*z[4]-2.0*x[0]*z[1]*x[4]*y[0]-2.0*x[0]*y[1]*x[3]*z[0]+2.0*x[0]*y[0]*x
+ [4]*z[3]-2.0*x[0]*z[0]*x[4]*y[3]+2.0*x[0]*x[1]*y[0]*z[4]+2.0*x[0]*z[1]*x[3]*y
+ [0]-2.0*x[0]*x[1]*y[0]*z[3]-2.0*x[0]*x[1]*y[4]*z[0]+2.0*x[0]*y[1]*x[4]*z[0];
s5 = s8+2.0*x[0]*z[0]*x[3]*y[4]+x[1]*y[1]*x[0]*z[3]-x[1]*z[1]*x[4]*y[0]-x
- [1]*y[1]*x[0]*z[4]+x[1]*z[1]*x[0]*y[4]-x[1]*y[1]*x[3]*z[0]-x[1]*z[1]*x[0]*y[3]-
- x[0]*z[5]*x[4]*y[1]+x[0]*y[5]*x[4]*z[1]-2.0*x[4]*x[0]*y[4]*z[7]-2.0*x[4]*y[5]*x
- [0]*z[4]+2.0*x[4]*z[5]*x[0]*y[4]-2.0*x[4]*x[5]*y[4]*z[0]-2.0*x[4]*y[0]*x[7]*z
- [4]-x[5]*y[5]*x[0]*z[4]+s7;
+ [1]*y[1]*x[0]*z[4]+x[1]*z[1]*x[0]*y[4]-x[1]*y[1]*x[3]*z[0]-x[1]*z[1]*x[0]*y[3]-
+ x[0]*z[5]*x[4]*y[1]+x[0]*y[5]*x[4]*z[1]-2.0*x[4]*x[0]*y[4]*z[7]-2.0*x[4]*y[5]*x
+ [0]*z[4]+2.0*x[4]*z[5]*x[0]*y[4]-2.0*x[4]*x[5]*y[4]*z[0]-2.0*x[4]*y[0]*x[7]*z
+ [4]-x[5]*y[5]*x[0]*z[4]+s7;
s8 = x[5]*z[5]*x[0]*y[4]-x[5]*z[5]*x[4]*y[0]+x[1]*z[5]*x[0]*y[4]+x[5]*y
- [5]*x[4]*z[0]-x[0]*y[0]*x[7]*z[4]-x[0]*z[5]*x[4]*y[0]-x[1]*y[5]*x[0]*z[4]+x[0]*
- z[0]*x[7]*y[4]+x[0]*y[5]*x[4]*z[0]-x[0]*z[0]*x[4]*y[7]+x[0]*x[5]*y[0]*z[4]+x[0]
- *y[0]*x[4]*z[7]-x[0]*x[5]*y[4]*z[0]-x[3]*x[3]*y[4]*z[7]+2.0*x[2]*z[2]*x[3]*y[1]
- ;
+ [5]*x[4]*z[0]-x[0]*y[0]*x[7]*z[4]-x[0]*z[5]*x[4]*y[0]-x[1]*y[5]*x[0]*z[4]+x[0]*
+ z[0]*x[7]*y[4]+x[0]*y[5]*x[4]*z[0]-x[0]*z[0]*x[4]*y[7]+x[0]*x[5]*y[0]*z[4]+x[0]
+ *y[0]*x[4]*z[7]-x[0]*x[5]*y[4]*z[0]-x[3]*x[3]*y[4]*z[7]+2.0*x[2]*z[2]*x[3]*y[1]
+ ;
s7 = s8-x[5]*x[5]*y[4]*z[0]+2.0*y[5]*x[4]*x[4]*z[0]-2.0*z[0]*x[4]*x[4]*y
- [7]+2.0*y[0]*x[4]*x[4]*z[7]-2.0*z[5]*x[4]*x[4]*y[0]+x[5]*x[5]*y[4]*z[7]-x[5]*x
- [5]*y[7]*z[4]-2.0*y[5]*x[4]*x[4]*z[7]+2.0*z[5]*x[4]*x[4]*y[7]-x[0]*x[0]*y[7]*z
- [3]+y[2]*x[0]*x[0]*z[3]+x[0]*x[0]*y[3]*z[7]-x[5]*x[1]*y[4]*z[0]+x[5]*y[1]*x[4]*
- z[0]-x[4]*y[0]*x[3]*z[4];
+ [7]+2.0*y[0]*x[4]*x[4]*z[7]-2.0*z[5]*x[4]*x[4]*y[0]+x[5]*x[5]*y[4]*z[7]-x[5]*x
+ [5]*y[7]*z[4]-2.0*y[5]*x[4]*x[4]*z[7]+2.0*z[5]*x[4]*x[4]*y[7]-x[0]*x[0]*y[7]*z
+ [3]+y[2]*x[0]*x[0]*z[3]+x[0]*x[0]*y[3]*z[7]-x[5]*x[1]*y[4]*z[0]+x[5]*y[1]*x[4]*
+ z[0]-x[4]*y[0]*x[3]*z[4];
s8 = -x[4]*y[1]*x[0]*z[4]+x[4]*z[1]*x[0]*y[4]+x[4]*x[0]*y[3]*z[4]-x[4]*x
- [0]*y[4]*z[3]+x[4]*x[1]*y[0]*z[4]-x[4]*x[1]*y[4]*z[0]+x[4]*z[0]*x[3]*y[4]+x[5]*
- x[1]*y[0]*z[4]+x[1]*z[1]*x[3]*y[0]+x[1]*y[1]*x[4]*z[0]-x[5]*z[1]*x[4]*y[0]-2.0*
- y[1]*x[0]*x[0]*z[4]+2.0*z[1]*x[0]*x[0]*y[4]+2.0*x[0]*x[0]*y[3]*z[4]-2.0*z[1]*x
- [0]*x[0]*y[3];
+ [0]*y[4]*z[3]+x[4]*x[1]*y[0]*z[4]-x[4]*x[1]*y[4]*z[0]+x[4]*z[0]*x[3]*y[4]+x[5]*
+ x[1]*y[0]*z[4]+x[1]*z[1]*x[3]*y[0]+x[1]*y[1]*x[4]*z[0]-x[5]*z[1]*x[4]*y[0]-2.0*
+ y[1]*x[0]*x[0]*z[4]+2.0*z[1]*x[0]*x[0]*y[4]+2.0*x[0]*x[0]*y[3]*z[4]-2.0*z[1]*x
+ [0]*x[0]*y[3];
s6 = s8-2.0*x[0]*x[0]*y[4]*z[3]+x[1]*x[1]*y[3]*z[0]+x[1]*x[1]*y[0]*z[4]-x
- [1]*x[1]*y[0]*z[3]-x[1]*x[1]*y[4]*z[0]-z[1]*x[4]*x[4]*y[0]+y[0]*x[4]*x[4]*z[3]-
- z[0]*x[4]*x[4]*y[3]+y[1]*x[4]*x[4]*z[0]-x[0]*x[0]*y[4]*z[7]-y[5]*x[0]*x[0]*z[4]
- +z[5]*x[0]*x[0]*y[4]+x[5]*x[5]*y[0]*z[4]-x[0]*y[0]*x[3]*z[7]+x[0]*z[0]*x[3]*y
- [7]+s7;
+ [1]*x[1]*y[0]*z[3]-x[1]*x[1]*y[4]*z[0]-z[1]*x[4]*x[4]*y[0]+y[0]*x[4]*x[4]*z[3]-
+ z[0]*x[4]*x[4]*y[3]+y[1]*x[4]*x[4]*z[0]-x[0]*x[0]*y[4]*z[7]-y[5]*x[0]*x[0]*z[4]
+ +z[5]*x[0]*x[0]*y[4]+x[5]*x[5]*y[0]*z[4]-x[0]*y[0]*x[3]*z[7]+x[0]*z[0]*x[3]*y
+ [7]+s7;
s8 = s6+x[0]*x[2]*y[3]*z[0]-x[0]*x[2]*y[0]*z[3]+x[0]*y[0]*x[7]*z[3]-x[0]*
- y[2]*x[3]*z[0]+x[0]*z[2]*x[3]*y[0]-x[0]*z[0]*x[7]*y[3]+x[1]*x[2]*y[3]*z[0]-z[2]
- *x[0]*x[0]*y[3]+x[3]*z[2]*x[6]*y[3]-x[3]*x[2]*y[3]*z[6]+x[3]*x[2]*y[6]*z[3]-x
- [3]*y[2]*x[6]*z[3]-2.0*x[3]*y[2]*x[7]*z[3]+2.0*x[3]*z[2]*x[7]*y[3];
+ y[2]*x[3]*z[0]+x[0]*z[2]*x[3]*y[0]-x[0]*z[0]*x[7]*y[3]+x[1]*x[2]*y[3]*z[0]-z[2]
+ *x[0]*x[0]*y[3]+x[3]*z[2]*x[6]*y[3]-x[3]*x[2]*y[3]*z[6]+x[3]*x[2]*y[6]*z[3]-x
+ [3]*y[2]*x[6]*z[3]-2.0*x[3]*y[2]*x[7]*z[3]+2.0*x[3]*z[2]*x[7]*y[3];
s7 = s8+2.0*x[4]*y[5]*x[7]*z[4]+2.0*x[4]*x[5]*y[4]*z[7]-2.0*x[4]*z[5]*x
- [7]*y[4]-2.0*x[4]*x[5]*y[7]*z[4]+x[5]*y[5]*x[7]*z[4]-x[5]*z[5]*x[7]*y[4]-x[5]*y
- [5]*x[4]*z[7]+x[5]*z[5]*x[4]*y[7]+2.0*x[3]*x[2]*y[7]*z[3]-2.0*x[2]*z[2]*x[1]*y
- [3]+2.0*x[4]*z[0]*x[7]*y[4]+2.0*x[4]*x[0]*y[7]*z[4]+2.0*x[4]*x[5]*y[0]*z[4]-x
- [7]*x[6]*y[2]*z[7]-2.0*x[3]*x[2]*y[3]*z[7]-x[0]*x[4]*y[7]*z[3];
+ [7]*y[4]-2.0*x[4]*x[5]*y[7]*z[4]+x[5]*y[5]*x[7]*z[4]-x[5]*z[5]*x[7]*y[4]-x[5]*y
+ [5]*x[4]*z[7]+x[5]*z[5]*x[4]*y[7]+2.0*x[3]*x[2]*y[7]*z[3]-2.0*x[2]*z[2]*x[1]*y
+ [3]+2.0*x[4]*z[0]*x[7]*y[4]+2.0*x[4]*x[0]*y[7]*z[4]+2.0*x[4]*x[5]*y[0]*z[4]-x
+ [7]*x[6]*y[2]*z[7]-2.0*x[3]*x[2]*y[3]*z[7]-x[0]*x[4]*y[7]*z[3];
s8 = x[0]*x[3]*y[7]*z[4]-x[0]*x[3]*y[4]*z[7]+x[0]*x[4]*y[3]*z[7]-2.0*x[7]
- *z[6]*x[3]*y[7]+x[3]*x[7]*y[4]*z[3]-x[3]*x[4]*y[7]*z[3]-x[3]*x[7]*y[3]*z[4]+x
- [3]*x[4]*y[3]*z[7]+2.0*x[2]*y[2]*x[1]*z[3]+y[6]*x[3]*x[3]*z[7]-z[6]*x[3]*x[3]*y
- [7]-x[1]*z[5]*x[4]*y[1]-x[1]*x[5]*y[4]*z[1]-x[1]*z[2]*x[0]*y[3]-x[1]*x[2]*y[0]*
- z[3]+x[1]*y[2]*x[0]*z[3];
+ *z[6]*x[3]*y[7]+x[3]*x[7]*y[4]*z[3]-x[3]*x[4]*y[7]*z[3]-x[3]*x[7]*y[3]*z[4]+x
+ [3]*x[4]*y[3]*z[7]+2.0*x[2]*y[2]*x[1]*z[3]+y[6]*x[3]*x[3]*z[7]-z[6]*x[3]*x[3]*y
+ [7]-x[1]*z[5]*x[4]*y[1]-x[1]*x[5]*y[4]*z[1]-x[1]*z[2]*x[0]*y[3]-x[1]*x[2]*y[0]*
+ z[3]+x[1]*y[2]*x[0]*z[3];
s4 = s8+x[1]*x[5]*y[1]*z[4]+x[1]*y[5]*x[4]*z[1]+x[4]*y[0]*x[7]*z[3]-x[4]*
- z[0]*x[7]*y[3]-x[4]*x[4]*y[7]*z[3]+x[4]*x[4]*y[3]*z[7]+x[3]*z[6]*x[7]*y[3]-x[3]
- *x[6]*y[3]*z[7]+x[3]*x[6]*y[7]*z[3]-x[3]*z[6]*x[2]*y[7]-x[3]*y[6]*x[7]*z[3]+x
- [3]*z[6]*x[7]*y[2]+x[3]*y[6]*x[2]*z[7]+2.0*x[5]*z[5]*x[4]*y[6]+s5+s7;
+ z[0]*x[7]*y[3]-x[4]*x[4]*y[7]*z[3]+x[4]*x[4]*y[3]*z[7]+x[3]*z[6]*x[7]*y[3]-x[3]
+ *x[6]*y[3]*z[7]+x[3]*x[6]*y[7]*z[3]-x[3]*z[6]*x[2]*y[7]-x[3]*y[6]*x[7]*z[3]+x
+ [3]*z[6]*x[7]*y[2]+x[3]*y[6]*x[2]*z[7]+2.0*x[5]*z[5]*x[4]*y[6]+s5+s7;
s8 = s4-2.0*x[5]*z[5]*x[6]*y[4]-x[5]*z[6]*x[7]*y[5]+x[5]*x[6]*y[5]*z[7]-x
- [5]*x[6]*y[7]*z[5]-2.0*x[5]*y[5]*x[4]*z[6]+2.0*x[5]*y[5]*x[6]*z[4]-x[3]*y[6]*x
- [7]*z[2]+x[4]*x[7]*y[4]*z[3]+x[4]*x[3]*y[7]*z[4]-x[4]*x[7]*y[3]*z[4]-x[4]*x[3]*
- y[4]*z[7]-z[1]*x[5]*x[5]*y[0]+y[1]*x[5]*x[5]*z[0]+x[4]*y[6]*x[7]*z[4];
+ [5]*x[6]*y[7]*z[5]-2.0*x[5]*y[5]*x[4]*z[6]+2.0*x[5]*y[5]*x[6]*z[4]-x[3]*y[6]*x
+ [7]*z[2]+x[4]*x[7]*y[4]*z[3]+x[4]*x[3]*y[7]*z[4]-x[4]*x[7]*y[3]*z[4]-x[4]*x[3]*
+ y[4]*z[7]-z[1]*x[5]*x[5]*y[0]+y[1]*x[5]*x[5]*z[0]+x[4]*y[6]*x[7]*z[4];
s7 = s8-x[4]*x[6]*y[7]*z[4]+x[4]*x[6]*y[4]*z[7]-x[4]*z[6]*x[7]*y[4]-x[5]*
- y[6]*x[4]*z[7]-x[5]*x[6]*y[7]*z[4]+x[5]*x[6]*y[4]*z[7]+x[5]*z[6]*x[4]*y[7]-y[6]
- *x[4]*x[4]*z[7]+z[6]*x[4]*x[4]*y[7]+x[7]*x[5]*y[4]*z[7]-y[2]*x[7]*x[7]*z[3]+z
- [2]*x[7]*x[7]*y[3]-y[0]*x[3]*x[3]*z[4]-y[1]*x[3]*x[3]*z[0]+z[1]*x[3]*x[3]*y[0];
+ y[6]*x[4]*z[7]-x[5]*x[6]*y[7]*z[4]+x[5]*x[6]*y[4]*z[7]+x[5]*z[6]*x[4]*y[7]-y[6]
+ *x[4]*x[4]*z[7]+z[6]*x[4]*x[4]*y[7]+x[7]*x[5]*y[4]*z[7]-y[2]*x[7]*x[7]*z[3]+z
+ [2]*x[7]*x[7]*y[3]-y[0]*x[3]*x[3]*z[4]-y[1]*x[3]*x[3]*z[0]+z[1]*x[3]*x[3]*y[0];
s8 = z[0]*x[3]*x[3]*y[4]-x[2]*y[1]*x[3]*z[0]+x[2]*z[1]*x[3]*y[0]+x[3]*y
- [1]*x[0]*z[3]+x[3]*x[1]*y[3]*z[0]+x[3]*x[0]*y[3]*z[4]-x[3]*z[1]*x[0]*y[3]-x[3]*
- x[0]*y[4]*z[3]+x[3]*y[0]*x[4]*z[3]-x[3]*z[0]*x[4]*y[3]-x[3]*x[1]*y[0]*z[3]+x[3]
- *z[0]*x[7]*y[4]-x[3]*y[0]*x[7]*z[4]+z[0]*x[7]*x[7]*y[4]-y[0]*x[7]*x[7]*z[4];
+ [1]*x[0]*z[3]+x[3]*x[1]*y[3]*z[0]+x[3]*x[0]*y[3]*z[4]-x[3]*z[1]*x[0]*y[3]-x[3]*
+ x[0]*y[4]*z[3]+x[3]*y[0]*x[4]*z[3]-x[3]*z[0]*x[4]*y[3]-x[3]*x[1]*y[0]*z[3]+x[3]
+ *z[0]*x[7]*y[4]-x[3]*y[0]*x[7]*z[4]+z[0]*x[7]*x[7]*y[4]-y[0]*x[7]*x[7]*z[4];
s6 = s8+y[1]*x[0]*x[0]*z[2]-2.0*y[2]*x[3]*x[3]*z[0]+2.0*z[2]*x[3]*x[3]*y
- [0]-2.0*x[1]*x[1]*y[0]*z[2]+2.0*x[1]*x[1]*y[2]*z[0]-y[2]*x[3]*x[3]*z[1]+z[2]*x
- [3]*x[3]*y[1]-y[5]*x[4]*x[4]*z[6]+z[5]*x[4]*x[4]*y[6]+x[7]*x[0]*y[7]*z[4]-x[7]*
- z[0]*x[4]*y[7]-x[7]*x[0]*y[4]*z[7]+x[7]*y[0]*x[4]*z[7]-x[0]*x[1]*y[0]*z[2]+x[0]
- *z[1]*x[2]*y[0]+s7;
+ [0]-2.0*x[1]*x[1]*y[0]*z[2]+2.0*x[1]*x[1]*y[2]*z[0]-y[2]*x[3]*x[3]*z[1]+z[2]*x
+ [3]*x[3]*y[1]-y[5]*x[4]*x[4]*z[6]+z[5]*x[4]*x[4]*y[6]+x[7]*x[0]*y[7]*z[4]-x[7]*
+ z[0]*x[4]*y[7]-x[7]*x[0]*y[4]*z[7]+x[7]*y[0]*x[4]*z[7]-x[0]*x[1]*y[0]*z[2]+x[0]
+ *z[1]*x[2]*y[0]+s7;
s8 = s6+x[0]*x[1]*y[2]*z[0]-x[0]*y[1]*x[2]*z[0]-x[3]*z[1]*x[0]*y[2]+2.0*x
- [3]*x[2]*y[3]*z[0]+y[0]*x[7]*x[7]*z[3]-z[0]*x[7]*x[7]*y[3]-2.0*x[3]*z[2]*x[0]*y
- [3]-2.0*x[3]*x[2]*y[0]*z[3]+2.0*x[3]*y[2]*x[0]*z[3]+x[3]*x[2]*y[3]*z[1]-x[3]*x
- [2]*y[1]*z[3]-x[5]*y[1]*x[0]*z[5]+x[3]*y[1]*x[0]*z[2]+x[4]*y[6]*x[7]*z[5];
+ [3]*x[2]*y[3]*z[0]+y[0]*x[7]*x[7]*z[3]-z[0]*x[7]*x[7]*y[3]-2.0*x[3]*z[2]*x[0]*y
+ [3]-2.0*x[3]*x[2]*y[0]*z[3]+2.0*x[3]*y[2]*x[0]*z[3]+x[3]*x[2]*y[3]*z[1]-x[3]*x
+ [2]*y[1]*z[3]-x[5]*y[1]*x[0]*z[5]+x[3]*y[1]*x[0]*z[2]+x[4]*y[6]*x[7]*z[5];
s7 = s8-x[5]*x[1]*y[5]*z[0]+2.0*x[1]*z[1]*x[2]*y[0]-2.0*x[1]*z[1]*x[0]*y
- [2]+x[1]*x[2]*y[3]*z[1]-x[1]*x[2]*y[1]*z[3]+2.0*x[1]*y[1]*x[0]*z[2]-2.0*x[1]*y
- [1]*x[2]*z[0]-z[2]*x[1]*x[1]*y[3]+y[2]*x[1]*x[1]*z[3]+y[5]*x[7]*x[7]*z[4]+y[6]*
- x[7]*x[7]*z[5]+x[7]*x[6]*y[7]*z[2]+x[7]*y[6]*x[2]*z[7]-x[7]*z[6]*x[2]*y[7]-2.0*
- x[7]*x[6]*y[3]*z[7];
+ [2]+x[1]*x[2]*y[3]*z[1]-x[1]*x[2]*y[1]*z[3]+2.0*x[1]*y[1]*x[0]*z[2]-2.0*x[1]*y
+ [1]*x[2]*z[0]-z[2]*x[1]*x[1]*y[3]+y[2]*x[1]*x[1]*z[3]+y[5]*x[7]*x[7]*z[4]+y[6]*
+ x[7]*x[7]*z[5]+x[7]*x[6]*y[7]*z[2]+x[7]*y[6]*x[2]*z[7]-x[7]*z[6]*x[2]*y[7]-2.0*
+ x[7]*x[6]*y[3]*z[7];
s8 = s7+2.0*x[7]*x[6]*y[7]*z[3]+2.0*x[7]*y[6]*x[3]*z[7]-x[3]*z[2]*x[1]*y
- [3]+x[3]*y[2]*x[1]*z[3]+x[5]*x[1]*y[0]*z[5]+x[4]*y[5]*x[6]*z[4]+x[5]*z[1]*x[0]*
- y[5]-x[4]*z[6]*x[7]*y[5]-x[4]*x[5]*y[6]*z[4]+x[4]*x[5]*y[4]*z[6]-x[4]*z[5]*x[6]
- *y[4]-x[1]*y[2]*x[3]*z[1]+x[1]*z[2]*x[3]*y[1]-x[2]*x[1]*y[0]*z[2]-x[2]*z[1]*x
- [0]*y[2];
+ [3]+x[3]*y[2]*x[1]*z[3]+x[5]*x[1]*y[0]*z[5]+x[4]*y[5]*x[6]*z[4]+x[5]*z[1]*x[0]*
+ y[5]-x[4]*z[6]*x[7]*y[5]-x[4]*x[5]*y[6]*z[4]+x[4]*x[5]*y[4]*z[6]-x[4]*z[5]*x[6]
+ *y[4]-x[1]*y[2]*x[3]*z[1]+x[1]*z[2]*x[3]*y[1]-x[2]*x[1]*y[0]*z[2]-x[2]*z[1]*x
+ [0]*y[2];
s5 = s8+x[2]*x[1]*y[2]*z[0]-x[2]*z[2]*x[0]*y[3]+x[2]*y[2]*x[0]*z[3]-x[2]*
- y[2]*x[3]*z[0]+x[2]*z[2]*x[3]*y[0]+x[2]*y[1]*x[0]*z[2]+x[5]*y[6]*x[7]*z[5]+x[6]
- *y[5]*x[7]*z[4]+2.0*x[6]*y[6]*x[7]*z[5]-x[7]*y[0]*x[3]*z[7]+x[7]*z[0]*x[3]*y[7]
- -x[7]*x[0]*y[7]*z[3]+x[7]*x[0]*y[3]*z[7]+2.0*x[7]*x[7]*y[4]*z[3]-2.0*x[7]*x[7]*
- y[3]*z[4]-2.0*x[1]*x[1]*y[2]*z[5];
+ y[2]*x[3]*z[0]+x[2]*z[2]*x[3]*y[0]+x[2]*y[1]*x[0]*z[2]+x[5]*y[6]*x[7]*z[5]+x[6]
+ *y[5]*x[7]*z[4]+2.0*x[6]*y[6]*x[7]*z[5]-x[7]*y[0]*x[3]*z[7]+x[7]*z[0]*x[3]*y[7]
+ -x[7]*x[0]*y[7]*z[3]+x[7]*x[0]*y[3]*z[7]+2.0*x[7]*x[7]*y[4]*z[3]-2.0*x[7]*x[7]*
+ y[3]*z[4]-2.0*x[1]*x[1]*y[2]*z[5];
s8 = s5-2.0*x[7]*x[4]*y[7]*z[3]+2.0*x[7]*x[3]*y[7]*z[4]-2.0*x[7]*x[3]*y
- [4]*z[7]+2.0*x[7]*x[4]*y[3]*z[7]+2.0*x[1]*x[1]*y[5]*z[2]-x[1]*x[1]*y[2]*z[6]+x
- [1]*x[1]*y[6]*z[2]+z[1]*x[5]*x[5]*y[2]-y[1]*x[5]*x[5]*z[2]-x[1]*x[1]*y[6]*z[5]+
- x[1]*x[1]*y[5]*z[6]+x[5]*x[5]*y[6]*z[2]-x[5]*x[5]*y[2]*z[6]-2.0*y[1]*x[5]*x[5]*
- z[6];
+ [4]*z[7]+2.0*x[7]*x[4]*y[3]*z[7]+2.0*x[1]*x[1]*y[5]*z[2]-x[1]*x[1]*y[2]*z[6]+x
+ [1]*x[1]*y[6]*z[2]+z[1]*x[5]*x[5]*y[2]-y[1]*x[5]*x[5]*z[2]-x[1]*x[1]*y[6]*z[5]+
+ x[1]*x[1]*y[5]*z[6]+x[5]*x[5]*y[6]*z[2]-x[5]*x[5]*y[2]*z[6]-2.0*y[1]*x[5]*x[5]*
+ z[6];
s7 = s8+2.0*z[1]*x[5]*x[5]*y[6]+2.0*x[1]*z[1]*x[5]*y[2]+2.0*x[1]*y[1]*x
- [2]*z[5]-2.0*x[1]*z[1]*x[2]*y[5]-2.0*x[1]*y[1]*x[5]*z[2]-x[1]*y[1]*x[6]*z[2]-x
- [1]*z[1]*x[2]*y[6]+x[1]*z[1]*x[6]*y[2]+x[1]*y[1]*x[2]*z[6]-x[5]*x[1]*y[2]*z[5]+
- x[5]*y[1]*x[2]*z[5]-x[5]*z[1]*x[2]*y[5]+x[5]*x[1]*y[5]*z[2]-x[5]*y[1]*x[6]*z[2]
- -x[5]*x[1]*y[2]*z[6];
+ [2]*z[5]-2.0*x[1]*z[1]*x[2]*y[5]-2.0*x[1]*y[1]*x[5]*z[2]-x[1]*y[1]*x[6]*z[2]-x
+ [1]*z[1]*x[2]*y[6]+x[1]*z[1]*x[6]*y[2]+x[1]*y[1]*x[2]*z[6]-x[5]*x[1]*y[2]*z[5]+
+ x[5]*y[1]*x[2]*z[5]-x[5]*z[1]*x[2]*y[5]+x[5]*x[1]*y[5]*z[2]-x[5]*y[1]*x[6]*z[2]
+ -x[5]*x[1]*y[2]*z[6];
s8 = s7+x[5]*x[1]*y[6]*z[2]+x[5]*z[1]*x[6]*y[2]+x[1]*x[2]*y[5]*z[6]-x[1]*
- x[2]*y[6]*z[5]-x[1]*z[1]*x[6]*y[5]-x[1]*y[1]*x[5]*z[6]+x[1]*z[1]*x[5]*y[6]+x[1]
- *y[1]*x[6]*z[5]-x[5]*x[6]*y[5]*z[2]+x[5]*x[2]*y[5]*z[6]-x[5]*x[2]*y[6]*z[5]+x
- [5]*x[6]*y[2]*z[5]-2.0*x[5]*z[1]*x[6]*y[5]-2.0*x[5]*x[1]*y[6]*z[5]+2.0*x[5]*x
- [1]*y[5]*z[6];
+ x[2]*y[6]*z[5]-x[1]*z[1]*x[6]*y[5]-x[1]*y[1]*x[5]*z[6]+x[1]*z[1]*x[5]*y[6]+x[1]
+ *y[1]*x[6]*z[5]-x[5]*x[6]*y[5]*z[2]+x[5]*x[2]*y[5]*z[6]-x[5]*x[2]*y[6]*z[5]+x
+ [5]*x[6]*y[2]*z[5]-2.0*x[5]*z[1]*x[6]*y[5]-2.0*x[5]*x[1]*y[6]*z[5]+2.0*x[5]*x
+ [1]*y[5]*z[6];
s6 = s8+2.0*x[5]*y[1]*x[6]*z[5]+2.0*x[2]*x[1]*y[6]*z[2]+2.0*x[2]*z[1]*x
- [6]*y[2]-2.0*x[2]*x[1]*y[2]*z[6]+x[2]*x[5]*y[6]*z[2]+x[2]*x[6]*y[2]*z[5]-x[2]*x
- [5]*y[2]*z[6]+y[1]*x[2]*x[2]*z[5]-z[1]*x[2]*x[2]*y[5]-2.0*x[2]*y[1]*x[6]*z[2]-x
- [2]*x[6]*y[5]*z[2]-2.0*z[1]*x[2]*x[2]*y[6]+x[2]*x[2]*y[5]*z[6]-x[2]*x[2]*y[6]*z
- [5]+2.0*y[1]*x[2]*x[2]*z[6]+x[2]*z[1]*x[5]*y[2];
+ [6]*y[2]-2.0*x[2]*x[1]*y[2]*z[6]+x[2]*x[5]*y[6]*z[2]+x[2]*x[6]*y[2]*z[5]-x[2]*x
+ [5]*y[2]*z[6]+y[1]*x[2]*x[2]*z[5]-z[1]*x[2]*x[2]*y[5]-2.0*x[2]*y[1]*x[6]*z[2]-x
+ [2]*x[6]*y[5]*z[2]-2.0*z[1]*x[2]*x[2]*y[6]+x[2]*x[2]*y[5]*z[6]-x[2]*x[2]*y[6]*z
+ [5]+2.0*y[1]*x[2]*x[2]*z[6]+x[2]*z[1]*x[5]*y[2];
s8 = s6-x[2]*x[1]*y[2]*z[5]+x[2]*x[1]*y[5]*z[2]-x[2]*y[1]*x[5]*z[2]+x[6]*
- y[1]*x[2]*z[5]-x[6]*z[1]*x[2]*y[5]-z[1]*x[6]*x[6]*y[5]+y[1]*x[6]*x[6]*z[5]-y[1]
- *x[6]*x[6]*z[2]-2.0*x[6]*x[6]*y[5]*z[2]+2.0*x[6]*x[6]*y[2]*z[5]+z[1]*x[6]*x[6]*
- y[2]-x[6]*x[1]*y[6]*z[5]-x[6]*y[1]*x[5]*z[6]+x[6]*x[1]*y[5]*z[6];
+ y[1]*x[2]*z[5]-x[6]*z[1]*x[2]*y[5]-z[1]*x[6]*x[6]*y[5]+y[1]*x[6]*x[6]*z[5]-y[1]
+ *x[6]*x[6]*z[2]-2.0*x[6]*x[6]*y[5]*z[2]+2.0*x[6]*x[6]*y[2]*z[5]+z[1]*x[6]*x[6]*
+ y[2]-x[6]*x[1]*y[6]*z[5]-x[6]*y[1]*x[5]*z[6]+x[6]*x[1]*y[5]*z[6];
s7 = s8+x[6]*z[1]*x[5]*y[6]-x[6]*z[1]*x[2]*y[6]-x[6]*x[1]*y[2]*z[6]+2.0*x
- [6]*x[5]*y[6]*z[2]+2.0*x[6]*x[2]*y[5]*z[6]-2.0*x[6]*x[2]*y[6]*z[5]-2.0*x[6]*x
- [5]*y[2]*z[6]+x[6]*x[1]*y[6]*z[2]+x[6]*y[1]*x[2]*z[6]-x[2]*x[2]*y[3]*z[7]+x[2]*
- x[2]*y[7]*z[3]-x[2]*z[2]*x[3]*y[7]-x[2]*y[2]*x[7]*z[3]+x[2]*z[2]*x[7]*y[3]+x[2]
- *y[2]*x[3]*z[7]-x[6]*x[6]*y[3]*z[7];
+ [6]*x[5]*y[6]*z[2]+2.0*x[6]*x[2]*y[5]*z[6]-2.0*x[6]*x[2]*y[6]*z[5]-2.0*x[6]*x
+ [5]*y[2]*z[6]+x[6]*x[1]*y[6]*z[2]+x[6]*y[1]*x[2]*z[6]-x[2]*x[2]*y[3]*z[7]+x[2]*
+ x[2]*y[7]*z[3]-x[2]*z[2]*x[3]*y[7]-x[2]*y[2]*x[7]*z[3]+x[2]*z[2]*x[7]*y[3]+x[2]
+ *y[2]*x[3]*z[7]-x[6]*x[6]*y[3]*z[7];
s8 = s7+x[6]*x[6]*y[7]*z[3]-x[6]*x[2]*y[3]*z[7]+x[6]*x[2]*y[7]*z[3]-x[6]*
- y[6]*x[7]*z[3]+x[6]*y[6]*x[3]*z[7]-x[6]*z[6]*x[3]*y[7]+x[6]*z[6]*x[7]*y[3]+y[6]
- *x[2]*x[2]*z[7]-z[6]*x[2]*x[2]*y[7]+2.0*x[2]*x[2]*y[6]*z[3]-x[2]*y[6]*x[7]*z[2]
- -2.0*x[2]*y[2]*x[6]*z[3]-2.0*x[2]*x[2]*y[3]*z[6]+2.0*x[2]*y[2]*x[3]*z[6]-x[2]*x
- [6]*y[2]*z[7];
+ y[6]*x[7]*z[3]+x[6]*y[6]*x[3]*z[7]-x[6]*z[6]*x[3]*y[7]+x[6]*z[6]*x[7]*y[3]+y[6]
+ *x[2]*x[2]*z[7]-z[6]*x[2]*x[2]*y[7]+2.0*x[2]*x[2]*y[6]*z[3]-x[2]*y[6]*x[7]*z[2]
+ -2.0*x[2]*y[2]*x[6]*z[3]-2.0*x[2]*x[2]*y[3]*z[6]+2.0*x[2]*y[2]*x[3]*z[6]-x[2]*x
+ [6]*y[2]*z[7];
s3 = s8+x[2]*x[6]*y[7]*z[2]+x[2]*z[6]*x[7]*y[2]+2.0*x[2]*z[2]*x[6]*y[3]
- -2.0*x[2]*z[2]*x[3]*y[6]-y[2]*x[6]*x[6]*z[3]-2.0*x[6]*x[6]*y[2]*z[7]+2.0*x[6]*x
- [6]*y[7]*z[2]+z[2]*x[6]*x[6]*y[3]-2.0*x[6]*y[6]*x[7]*z[2]+x[6]*y[2]*x[3]*z[6]-x
- [6]*x[2]*y[3]*z[6]+2.0*x[6]*z[6]*x[7]*y[2]+2.0*x[6]*y[6]*x[2]*z[7]-2.0*x[6]*z
- [6]*x[2]*y[7]+x[6]*x[2]*y[6]*z[3]-x[6]*z[2]*x[3]*y[6];
+ -2.0*x[2]*z[2]*x[3]*y[6]-y[2]*x[6]*x[6]*z[3]-2.0*x[6]*x[6]*y[2]*z[7]+2.0*x[6]*x
+ [6]*y[7]*z[2]+z[2]*x[6]*x[6]*y[3]-2.0*x[6]*y[6]*x[7]*z[2]+x[6]*y[2]*x[3]*z[6]-x
+ [6]*x[2]*y[3]*z[6]+2.0*x[6]*z[6]*x[7]*y[2]+2.0*x[6]*y[6]*x[2]*z[7]-2.0*x[6]*z
+ [6]*x[2]*y[7]+x[6]*x[2]*y[6]*z[3]-x[6]*z[2]*x[3]*y[6];
s8 = y[1]*x[0]*z[3]+x[1]*y[3]*z[0]-y[0]*x[3]*z[7]-x[1]*y[5]*z[0]-y[0]*x
- [3]*z[4]-x[1]*y[0]*z[2]+z[1]*x[2]*y[0]-y[1]*x[0]*z[5]-z[1]*x[0]*y[2]-y[1]*x[0]*
- z[4]+z[1]*x[5]*y[2]+z[0]*x[7]*y[4]+z[0]*x[3]*y[7]+z[1]*x[0]*y[4]-x[1]*y[2]*z[5]
- +x[2]*y[3]*z[0]+y[1]*x[2]*z[5]-x[2]*y[3]*z[7];
+ [3]*z[4]-x[1]*y[0]*z[2]+z[1]*x[2]*y[0]-y[1]*x[0]*z[5]-z[1]*x[0]*y[2]-y[1]*x[0]*
+ z[4]+z[1]*x[5]*y[2]+z[0]*x[7]*y[4]+z[0]*x[3]*y[7]+z[1]*x[0]*y[4]-x[1]*y[2]*z[5]
+ +x[2]*y[3]*z[0]+y[1]*x[2]*z[5]-x[2]*y[3]*z[7];
s7 = s8-z[1]*x[2]*y[5]-y[1]*x[3]*z[0]-x[0]*y[7]*z[3]-z[1]*x[0]*y[3]+y[5]*
- x[4]*z[0]-x[0]*y[4]*z[3]+y[5]*x[7]*z[4]-z[0]*x[4]*y[3]+x[1]*y[0]*z[4]-z[2]*x[3]
- *y[7]-y[6]*x[7]*z[2]+x[1]*y[5]*z[2]+y[6]*x[7]*z[5]+x[0]*y[7]*z[4]+x[1]*y[2]*z
- [0]-z[1]*x[4]*y[0]-z[0]*x[4]*y[7]-z[2]*x[0]*y[3];
+ x[4]*z[0]-x[0]*y[4]*z[3]+y[5]*x[7]*z[4]-z[0]*x[4]*y[3]+x[1]*y[0]*z[4]-z[2]*x[3]
+ *y[7]-y[6]*x[7]*z[2]+x[1]*y[5]*z[2]+y[6]*x[7]*z[5]+x[0]*y[7]*z[4]+x[1]*y[2]*z
+ [0]-z[1]*x[4]*y[0]-z[0]*x[4]*y[7]-z[2]*x[0]*y[3];
s8 = x[5]*y[0]*z[4]+z[1]*x[0]*y[5]-x[2]*y[0]*z[3]-z[1]*x[5]*y[0]+y[1]*x
- [5]*z[0]-x[1]*y[0]*z[3]-x[1]*y[4]*z[0]-y[1]*x[5]*z[2]+x[2]*y[7]*z[3]+y[0]*x[4]*
- z[3]-x[0]*y[4]*z[7]+x[1]*y[0]*z[5]-y[1]*x[6]*z[2]-y[2]*x[6]*z[3]+y[0]*x[7]*z[3]
- -y[2]*x[7]*z[3]+z[2]*x[7]*y[3]+y[2]*x[0]*z[3];
+ [5]*z[0]-x[1]*y[0]*z[3]-x[1]*y[4]*z[0]-y[1]*x[5]*z[2]+x[2]*y[7]*z[3]+y[0]*x[4]*
+ z[3]-x[0]*y[4]*z[7]+x[1]*y[0]*z[5]-y[1]*x[6]*z[2]-y[2]*x[6]*z[3]+y[0]*x[7]*z[3]
+ -y[2]*x[7]*z[3]+z[2]*x[7]*y[3]+y[2]*x[0]*z[3];
s6 = s8+y[2]*x[3]*z[7]-y[2]*x[3]*z[0]-x[6]*y[5]*z[2]-y[5]*x[0]*z[4]+z[2]*
- x[3]*y[0]+x[2]*y[3]*z[1]+x[0]*y[3]*z[7]-x[2]*y[1]*z[3]+y[1]*x[4]*z[0]+y[1]*x[0]
- *z[2]-z[1]*x[2]*y[6]+y[2]*x[3]*z[6]-y[1]*x[2]*z[0]+z[1]*x[3]*y[0]-x[1]*y[2]*z
- [6]-x[2]*y[3]*z[6]+x[0]*y[3]*z[4]+z[0]*x[3]*y[4]+s7;
+ x[3]*y[0]+x[2]*y[3]*z[1]+x[0]*y[3]*z[7]-x[2]*y[1]*z[3]+y[1]*x[4]*z[0]+y[1]*x[0]
+ *z[2]-z[1]*x[2]*y[6]+y[2]*x[3]*z[6]-y[1]*x[2]*z[0]+z[1]*x[3]*y[0]-x[1]*y[2]*z
+ [6]-x[2]*y[3]*z[6]+x[0]*y[3]*z[4]+z[0]*x[3]*y[4]+s7;
s8 = x[5]*y[4]*z[7]+s6+y[5]*x[6]*z[4]-y[5]*x[4]*z[6]+z[6]*x[5]*y[7]-x[6]*
- y[2]*z[7]-x[6]*y[7]*z[5]+x[5]*y[6]*z[2]+x[6]*y[5]*z[7]+x[6]*y[7]*z[2]+y[6]*x[7]
- *z[4]-y[6]*x[4]*z[7]-y[6]*x[7]*z[3]+z[6]*x[7]*y[2]+x[2]*y[5]*z[6]-x[2]*y[6]*z
- [5]+y[6]*x[2]*z[7]+x[6]*y[2]*z[5];
+ y[2]*z[7]-x[6]*y[7]*z[5]+x[5]*y[6]*z[2]+x[6]*y[5]*z[7]+x[6]*y[7]*z[2]+y[6]*x[7]
+ *z[4]-y[6]*x[4]*z[7]-y[6]*x[7]*z[3]+z[6]*x[7]*y[2]+x[2]*y[5]*z[6]-x[2]*y[6]*z
+ [5]+y[6]*x[2]*z[7]+x[6]*y[2]*z[5];
s7 = s8-x[5]*y[2]*z[6]-z[6]*x[7]*y[5]-z[5]*x[7]*y[4]+z[5]*x[0]*y[4]-y[5]*
- x[4]*z[7]+y[0]*x[4]*z[7]-z[6]*x[2]*y[7]-x[5]*y[4]*z[0]-x[5]*y[7]*z[4]-y[0]*x[7]
- *z[4]+y[5]*x[4]*z[1]-x[6]*y[7]*z[4]+x[7]*y[4]*z[3]-x[4]*y[7]*z[3]+x[3]*y[7]*z
- [4]-x[7]*y[3]*z[4]-x[6]*y[3]*z[7]+x[6]*y[4]*z[7];
+ x[4]*z[7]+y[0]*x[4]*z[7]-z[6]*x[2]*y[7]-x[5]*y[4]*z[0]-x[5]*y[7]*z[4]-y[0]*x[7]
+ *z[4]+y[5]*x[4]*z[1]-x[6]*y[7]*z[4]+x[7]*y[4]*z[3]-x[4]*y[7]*z[3]+x[3]*y[7]*z
+ [4]-x[7]*y[3]*z[4]-x[6]*y[3]*z[7]+x[6]*y[4]*z[7];
s8 = -x[3]*y[4]*z[7]+x[4]*y[3]*z[7]-z[6]*x[7]*y[4]-z[1]*x[6]*y[5]+x[6]*y
- [7]*z[3]-x[1]*y[6]*z[5]-y[1]*x[5]*z[6]+z[5]*x[4]*y[7]-z[5]*x[4]*y[0]+x[1]*y[5]*
- z[6]-y[6]*x[5]*z[7]-y[2]*x[3]*z[1]+z[1]*x[5]*y[6]-y[5]*x[1]*z[4]+z[6]*x[4]*y[7]
- +x[5]*y[1]*z[4]-x[5]*y[6]*z[4]+y[6]*x[3]*z[7]-x[5]*y[4]*z[1];
+ [7]*z[3]-x[1]*y[6]*z[5]-y[1]*x[5]*z[6]+z[5]*x[4]*y[7]-z[5]*x[4]*y[0]+x[1]*y[5]*
+ z[6]-y[6]*x[5]*z[7]-y[2]*x[3]*z[1]+z[1]*x[5]*y[6]-y[5]*x[1]*z[4]+z[6]*x[4]*y[7]
+ +x[5]*y[1]*z[4]-x[5]*y[6]*z[4]+y[6]*x[3]*z[7]-x[5]*y[4]*z[1];
s5 = s8+x[5]*y[4]*z[6]+z[5]*x[1]*y[4]+y[1]*x[6]*z[5]-z[6]*x[3]*y[7]+z[6]*
- x[7]*y[3]-z[5]*x[6]*y[4]-z[5]*x[4]*y[1]+z[5]*x[4]*y[6]+x[1]*y[6]*z[2]+x[2]*y[6]
- *z[3]+z[2]*x[6]*y[3]+z[1]*x[6]*y[2]+z[2]*x[3]*y[1]-z[2]*x[1]*y[3]-z[2]*x[3]*y
- [6]+y[2]*x[1]*z[3]+y[1]*x[2]*z[6]-z[0]*x[7]*y[3]+s7;
+ x[7]*y[3]-z[5]*x[6]*y[4]-z[5]*x[4]*y[1]+z[5]*x[4]*y[6]+x[1]*y[6]*z[2]+x[2]*y[6]
+ *z[3]+z[2]*x[6]*y[3]+z[1]*x[6]*y[2]+z[2]*x[3]*y[1]-z[2]*x[1]*y[3]-z[2]*x[3]*y
+ [6]+y[2]*x[1]*z[3]+y[1]*x[2]*z[6]-z[0]*x[7]*y[3]+s7;
s4 = 1/s5;
s2 = s3*s4;
const double unknown0 = s1*s2;
s1 = 1.0/6.0;
s8 = 2.0*x[1]*y[0]*y[0]*z[4]+x[5]*y[0]*y[0]*z[4]-x[1]*y[4]*y[4]*z[0]+z[1]
- *x[0]*y[4]*y[4]+x[1]*y[0]*y[0]*z[5]-z[1]*x[5]*y[0]*y[0]-2.0*z[1]*x[4]*y[0]*y[0]
- +2.0*z[1]*x[3]*y[0]*y[0]+z[2]*x[3]*y[0]*y[0]+y[0]*y[0]*x[7]*z[3]+2.0*y[0]*y[0]*
- x[4]*z[3]-2.0*x[1]*y[0]*y[0]*z[3]-2.0*x[5]*y[4]*y[4]*z[0]+2.0*z[5]*x[0]*y[4]*y
- [4]+2.0*y[4]*y[5]*x[7]*z[4];
+ *x[0]*y[4]*y[4]+x[1]*y[0]*y[0]*z[5]-z[1]*x[5]*y[0]*y[0]-2.0*z[1]*x[4]*y[0]*y[0]
+ +2.0*z[1]*x[3]*y[0]*y[0]+z[2]*x[3]*y[0]*y[0]+y[0]*y[0]*x[7]*z[3]+2.0*y[0]*y[0]*
+ x[4]*z[3]-2.0*x[1]*y[0]*y[0]*z[3]-2.0*x[5]*y[4]*y[4]*z[0]+2.0*z[5]*x[0]*y[4]*y
+ [4]+2.0*y[4]*y[5]*x[7]*z[4];
s7 = s8-x[3]*y[4]*y[4]*z[7]+x[7]*y[4]*y[4]*z[3]+z[0]*x[3]*y[4]*y[4]-2.0*x
- [0]*y[4]*y[4]*z[7]-y[1]*x[1]*y[4]*z[0]-x[0]*y[4]*y[4]*z[3]+2.0*z[0]*x[7]*y[4]*y
- [4]+y[4]*z[6]*x[4]*y[7]-y[0]*y[0]*x[7]*z[4]+y[0]*y[0]*x[4]*z[7]+2.0*y[4]*z[5]*x
- [4]*y[7]-2.0*y[4]*x[5]*y[7]*z[4]-y[4]*x[6]*y[7]*z[4]-y[4]*y[6]*x[4]*z[7]-2.0*y
- [4]*y[5]*x[4]*z[7];
+ [0]*y[4]*y[4]*z[7]-y[1]*x[1]*y[4]*z[0]-x[0]*y[4]*y[4]*z[3]+2.0*z[0]*x[7]*y[4]*y
+ [4]+y[4]*z[6]*x[4]*y[7]-y[0]*y[0]*x[7]*z[4]+y[0]*y[0]*x[4]*z[7]+2.0*y[4]*z[5]*x
+ [4]*y[7]-2.0*y[4]*x[5]*y[7]*z[4]-y[4]*x[6]*y[7]*z[4]-y[4]*y[6]*x[4]*z[7]-2.0*y
+ [4]*y[5]*x[4]*z[7];
s8 = y[4]*y[6]*x[7]*z[4]-y[7]*y[2]*x[7]*z[3]+y[7]*z[2]*x[7]*y[3]+y[7]*y
- [2]*x[3]*z[7]+2.0*x[5]*y[4]*y[4]*z[7]-y[7]*x[2]*y[3]*z[7]-y[0]*z[0]*x[4]*y[7]+z
- [6]*x[7]*y[3]*y[3]-y[0]*x[0]*y[4]*z[7]+y[0]*x[0]*y[7]*z[4]-2.0*x[2]*y[3]*y[3]*z
- [7]-z[5]*x[4]*y[0]*y[0]+y[0]*z[0]*x[7]*y[4]-2.0*z[6]*x[3]*y[7]*y[7]+z[1]*x[2]*y
- [0]*y[0];
+ [2]*x[3]*z[7]+2.0*x[5]*y[4]*y[4]*z[7]-y[7]*x[2]*y[3]*z[7]-y[0]*z[0]*x[4]*y[7]+z
+ [6]*x[7]*y[3]*y[3]-y[0]*x[0]*y[4]*z[7]+y[0]*x[0]*y[7]*z[4]-2.0*x[2]*y[3]*y[3]*z
+ [7]-z[5]*x[4]*y[0]*y[0]+y[0]*z[0]*x[7]*y[4]-2.0*z[6]*x[3]*y[7]*y[7]+z[1]*x[2]*y
+ [0]*y[0];
s6 = s8+y[4]*y[0]*x[4]*z[3]-2.0*y[4]*z[0]*x[4]*y[7]+2.0*y[4]*x[0]*y[7]*z
- [4]-y[4]*z[0]*x[4]*y[3]-y[4]*x[0]*y[7]*z[3]+y[4]*z[0]*x[3]*y[7]-y[4]*y[0]*x[3]*
- z[4]+y[0]*x[4]*y[3]*z[7]-y[0]*x[7]*y[3]*z[4]-y[0]*x[3]*y[4]*z[7]+y[0]*x[7]*y[4]
- *z[3]+x[2]*y[7]*y[7]*z[3]-z[2]*x[3]*y[7]*y[7]-2.0*z[2]*x[0]*y[3]*y[3]+2.0*y[0]*
- z[1]*x[0]*y[4]+s7;
+ [4]-y[4]*z[0]*x[4]*y[3]-y[4]*x[0]*y[7]*z[3]+y[4]*z[0]*x[3]*y[7]-y[4]*y[0]*x[3]*
+ z[4]+y[0]*x[4]*y[3]*z[7]-y[0]*x[7]*y[3]*z[4]-y[0]*x[3]*y[4]*z[7]+y[0]*x[7]*y[4]
+ *z[3]+x[2]*y[7]*y[7]*z[3]-z[2]*x[3]*y[7]*y[7]-2.0*z[2]*x[0]*y[3]*y[3]+2.0*y[0]*
+ z[1]*x[0]*y[4]+s7;
s8 = -2.0*y[0]*y[1]*x[0]*z[4]-y[0]*y[1]*x[0]*z[5]-y[0]*y[0]*x[3]*z[7]-z
- [1]*x[0]*y[3]*y[3]-y[0]*x[1]*y[5]*z[0]-2.0*z[0]*x[7]*y[3]*y[3]+x[0]*y[3]*y[3]*z
- [4]+2.0*x[0]*y[3]*y[3]*z[7]-z[0]*x[4]*y[3]*y[3]+2.0*x[2]*y[3]*y[3]*z[0]+x[1]*y
- [3]*y[3]*z[0]+2.0*y[7]*z[6]*x[7]*y[3]+2.0*y[7]*y[6]*x[3]*z[7]-2.0*y[7]*y[6]*x
- [7]*z[3]-2.0*y[7]*x[6]*y[3]*z[7];
+ [1]*x[0]*y[3]*y[3]-y[0]*x[1]*y[5]*z[0]-2.0*z[0]*x[7]*y[3]*y[3]+x[0]*y[3]*y[3]*z
+ [4]+2.0*x[0]*y[3]*y[3]*z[7]-z[0]*x[4]*y[3]*y[3]+2.0*x[2]*y[3]*y[3]*z[0]+x[1]*y
+ [3]*y[3]*z[0]+2.0*y[7]*z[6]*x[7]*y[3]+2.0*y[7]*y[6]*x[3]*z[7]-2.0*y[7]*y[6]*x
+ [7]*z[3]-2.0*y[7]*x[6]*y[3]*z[7];
s7 = s8+y[4]*x[4]*y[3]*z[7]-y[4]*x[4]*y[7]*z[3]+y[4]*x[3]*y[7]*z[4]-y[4]*
- x[7]*y[3]*z[4]+2.0*y[4]*y[0]*x[4]*z[7]-2.0*y[4]*y[0]*x[7]*z[4]+2.0*x[6]*y[7]*y
- [7]*z[3]+y[4]*x[0]*y[3]*z[4]+y[0]*y[1]*x[5]*z[0]+y[0]*z[1]*x[0]*y[5]-x[2]*y[0]*
- y[0]*z[3]+x[4]*y[3]*y[3]*z[7]-x[7]*y[3]*y[3]*z[4]-x[5]*y[4]*y[4]*z[1]+y[3]*z[0]
- *x[3]*y[4];
+ x[7]*y[3]*z[4]+2.0*y[4]*y[0]*x[4]*z[7]-2.0*y[4]*y[0]*x[7]*z[4]+2.0*x[6]*y[7]*y
+ [7]*z[3]+y[4]*x[0]*y[3]*z[4]+y[0]*y[1]*x[5]*z[0]+y[0]*z[1]*x[0]*y[5]-x[2]*y[0]*
+ y[0]*z[3]+x[4]*y[3]*y[3]*z[7]-x[7]*y[3]*y[3]*z[4]-x[5]*y[4]*y[4]*z[1]+y[3]*z[0]
+ *x[3]*y[4];
s8 = y[3]*y[0]*x[4]*z[3]+2.0*y[3]*y[0]*x[7]*z[3]+2.0*y[3]*y[2]*x[0]*z[3]
- -2.0*y[3]*y[2]*x[3]*z[0]+2.0*y[3]*z[2]*x[3]*y[0]+y[3]*z[1]*x[3]*y[0]-2.0*y[3]*x
- [2]*y[0]*z[3]-y[3]*x[1]*y[0]*z[3]-y[3]*y[1]*x[3]*z[0]-2.0*y[3]*x[0]*y[7]*z[3]-y
- [3]*x[0]*y[4]*z[3]-2.0*y[3]*y[0]*x[3]*z[7]-y[3]*y[0]*x[3]*z[4]+2.0*y[3]*z[0]*x
- [3]*y[7]+y[3]*y[1]*x[0]*z[3]+z[5]*x[1]*y[4]*y[4];
+ -2.0*y[3]*y[2]*x[3]*z[0]+2.0*y[3]*z[2]*x[3]*y[0]+y[3]*z[1]*x[3]*y[0]-2.0*y[3]*x
+ [2]*y[0]*z[3]-y[3]*x[1]*y[0]*z[3]-y[3]*y[1]*x[3]*z[0]-2.0*y[3]*x[0]*y[7]*z[3]-y
+ [3]*x[0]*y[4]*z[3]-2.0*y[3]*y[0]*x[3]*z[7]-y[3]*y[0]*x[3]*z[4]+2.0*y[3]*z[0]*x
+ [3]*y[7]+y[3]*y[1]*x[0]*z[3]+z[5]*x[1]*y[4]*y[4];
s5 = s8-2.0*y[0]*y[0]*x[3]*z[4]-2.0*y[0]*x[1]*y[4]*z[0]+y[3]*x[7]*y[4]*z
- [3]-y[3]*x[4]*y[7]*z[3]+y[3]*x[3]*y[7]*z[4]-y[3]*x[3]*y[4]*z[7]+y[3]*x[0]*y[7]*
- z[4]-y[3]*z[0]*x[4]*y[7]-2.0*y[4]*y[5]*x[0]*z[4]+s6+y[7]*x[0]*y[3]*z[7]-y[7]*z
- [0]*x[7]*y[3]+y[7]*y[0]*x[7]*z[3]-y[7]*y[0]*x[3]*z[7]+2.0*y[0]*y[1]*x[4]*z[0]+
- s7;
+ [3]-y[3]*x[4]*y[7]*z[3]+y[3]*x[3]*y[7]*z[4]-y[3]*x[3]*y[4]*z[7]+y[3]*x[0]*y[7]*
+ z[4]-y[3]*z[0]*x[4]*y[7]-2.0*y[4]*y[5]*x[0]*z[4]+s6+y[7]*x[0]*y[3]*z[7]-y[7]*z
+ [0]*x[7]*y[3]+y[7]*y[0]*x[7]*z[3]-y[7]*y[0]*x[3]*z[7]+2.0*y[0]*y[1]*x[4]*z[0]+
+ s7;
s8 = -2.0*y[7]*x[7]*y[3]*z[4]-2.0*y[7]*x[3]*y[4]*z[7]+2.0*y[7]*x[4]*y[3]*
- z[7]+y[7]*y[0]*x[4]*z[7]-y[7]*y[0]*x[7]*z[4]+2.0*y[7]*x[7]*y[4]*z[3]-y[7]*x[0]*
- y[4]*z[7]+y[7]*z[0]*x[7]*y[4]+z[5]*x[4]*y[7]*y[7]+2.0*z[6]*x[4]*y[7]*y[7]-x[5]*
- y[7]*y[7]*z[4]-2.0*x[6]*y[7]*y[7]*z[4]+2.0*y[7]*x[6]*y[4]*z[7]-2.0*y[7]*z[6]*x
- [7]*y[4]+2.0*y[7]*y[6]*x[7]*z[4];
+ z[7]+y[7]*y[0]*x[4]*z[7]-y[7]*y[0]*x[7]*z[4]+2.0*y[7]*x[7]*y[4]*z[3]-y[7]*x[0]*
+ y[4]*z[7]+y[7]*z[0]*x[7]*y[4]+z[5]*x[4]*y[7]*y[7]+2.0*z[6]*x[4]*y[7]*y[7]-x[5]*
+ y[7]*y[7]*z[4]-2.0*x[6]*y[7]*y[7]*z[4]+2.0*y[7]*x[6]*y[4]*z[7]-2.0*y[7]*z[6]*x
+ [7]*y[4]+2.0*y[7]*y[6]*x[7]*z[4];
s7 = s8-2.0*y[7]*y[6]*x[4]*z[7]-y[7]*z[5]*x[7]*y[4]-y[7]*y[5]*x[4]*z[7]-x
- [0]*y[7]*y[7]*z[3]+z[0]*x[3]*y[7]*y[7]+y[7]*x[5]*y[4]*z[7]+y[7]*y[5]*x[7]*z[4]-
- y[4]*x[1]*y[5]*z[0]-x[1]*y[0]*y[0]*z[2]-y[4]*y[5]*x[1]*z[4]-2.0*y[4]*z[5]*x[4]*
- y[0]-y[4]*y[1]*x[0]*z[4]+y[4]*y[5]*x[4]*z[1]+y[0]*z[0]*x[3]*y[7]-y[0]*z[1]*x[0]
- *y[2];
+ [0]*y[7]*y[7]*z[3]+z[0]*x[3]*y[7]*y[7]+y[7]*x[5]*y[4]*z[7]+y[7]*y[5]*x[7]*z[4]-
+ y[4]*x[1]*y[5]*z[0]-x[1]*y[0]*y[0]*z[2]-y[4]*y[5]*x[1]*z[4]-2.0*y[4]*z[5]*x[4]*
+ y[0]-y[4]*y[1]*x[0]*z[4]+y[4]*y[5]*x[4]*z[1]+y[0]*z[0]*x[3]*y[7]-y[0]*z[1]*x[0]
+ *y[2];
s8 = 2.0*y[0]*x[1]*y[3]*z[0]+y[4]*y[1]*x[4]*z[0]+2.0*y[0]*y[1]*x[0]*z[3]+
- y[4]*x[1]*y[0]*z[5]-y[4]*z[1]*x[5]*y[0]+y[4]*z[1]*x[0]*y[5]-y[4]*z[1]*x[4]*y[0]
- +y[4]*x[1]*y[0]*z[4]-y[4]*z[5]*x[4]*y[1]+x[5]*y[4]*y[4]*z[6]-z[5]*x[6]*y[4]*y
- [4]+y[4]*x[5]*y[1]*z[4]-y[0]*z[2]*x[0]*y[3]+y[0]*y[5]*x[4]*z[0]+y[0]*x[1]*y[2]*
- z[0];
+ y[4]*x[1]*y[0]*z[5]-y[4]*z[1]*x[5]*y[0]+y[4]*z[1]*x[0]*y[5]-y[4]*z[1]*x[4]*y[0]
+ +y[4]*x[1]*y[0]*z[4]-y[4]*z[5]*x[4]*y[1]+x[5]*y[4]*y[4]*z[6]-z[5]*x[6]*y[4]*y
+ [4]+y[4]*x[5]*y[1]*z[4]-y[0]*z[2]*x[0]*y[3]+y[0]*y[5]*x[4]*z[0]+y[0]*x[1]*y[2]*
+ z[0];
s6 = s8-2.0*y[0]*z[0]*x[4]*y[3]-2.0*y[0]*x[0]*y[4]*z[3]-2.0*y[0]*z[1]*x
- [0]*y[3]-y[0]*x[0]*y[7]*z[3]-2.0*y[0]*y[1]*x[3]*z[0]+y[0]*x[2]*y[3]*z[0]-y[0]*y
- [1]*x[2]*z[0]+y[0]*y[1]*x[0]*z[2]-y[0]*x[2]*y[1]*z[3]+y[0]*x[0]*y[3]*z[7]+y[0]*
- x[2]*y[3]*z[1]-y[0]*y[2]*x[3]*z[0]+y[0]*y[2]*x[0]*z[3]-y[0]*y[5]*x[0]*z[4]-y[4]
- *y[5]*x[4]*z[6]+s7;
+ [0]*y[3]-y[0]*x[0]*y[7]*z[3]-2.0*y[0]*y[1]*x[3]*z[0]+y[0]*x[2]*y[3]*z[0]-y[0]*y
+ [1]*x[2]*z[0]+y[0]*y[1]*x[0]*z[2]-y[0]*x[2]*y[1]*z[3]+y[0]*x[0]*y[3]*z[7]+y[0]*
+ x[2]*y[3]*z[1]-y[0]*y[2]*x[3]*z[0]+y[0]*y[2]*x[0]*z[3]-y[0]*y[5]*x[0]*z[4]-y[4]
+ *y[5]*x[4]*z[6]+s7;
s8 = s6+y[4]*z[6]*x[5]*y[7]-y[4]*x[6]*y[7]*z[5]+y[4]*x[6]*y[5]*z[7]-y[4]*
- z[6]*x[7]*y[5]-y[4]*x[5]*y[6]*z[4]+y[4]*z[5]*x[4]*y[6]+y[4]*y[5]*x[6]*z[4]-2.0*
- y[1]*y[1]*x[0]*z[5]+2.0*y[1]*y[1]*x[5]*z[0]-2.0*y[2]*y[2]*x[6]*z[3]+x[5]*y[1]*y
- [1]*z[4]-z[5]*x[4]*y[1]*y[1]-x[6]*y[2]*y[2]*z[7]+z[6]*x[7]*y[2]*y[2];
+ z[6]*x[7]*y[5]-y[4]*x[5]*y[6]*z[4]+y[4]*z[5]*x[4]*y[6]+y[4]*y[5]*x[6]*z[4]-2.0*
+ y[1]*y[1]*x[0]*z[5]+2.0*y[1]*y[1]*x[5]*z[0]-2.0*y[2]*y[2]*x[6]*z[3]+x[5]*y[1]*y
+ [1]*z[4]-z[5]*x[4]*y[1]*y[1]-x[6]*y[2]*y[2]*z[7]+z[6]*x[7]*y[2]*y[2];
s7 = s8-x[1]*y[5]*y[5]*z[0]+z[1]*x[0]*y[5]*y[5]+y[1]*y[5]*x[4]*z[1]-y[1]*
- y[5]*x[1]*z[4]-2.0*y[2]*z[2]*x[3]*y[6]+2.0*y[1]*z[1]*x[0]*y[5]-2.0*y[1]*z[1]*x
- [5]*y[0]+2.0*y[1]*x[1]*y[0]*z[5]-y[2]*x[2]*y[3]*z[7]-y[2]*z[2]*x[3]*y[7]+y[2]*x
- [2]*y[7]*z[3]+y[2]*z[2]*x[7]*y[3]-2.0*y[2]*x[2]*y[3]*z[6]+2.0*y[2]*x[2]*y[6]*z
- [3]+2.0*y[2]*z[2]*x[6]*y[3]-y[3]*y[2]*x[6]*z[3];
+ y[5]*x[1]*z[4]-2.0*y[2]*z[2]*x[3]*y[6]+2.0*y[1]*z[1]*x[0]*y[5]-2.0*y[1]*z[1]*x
+ [5]*y[0]+2.0*y[1]*x[1]*y[0]*z[5]-y[2]*x[2]*y[3]*z[7]-y[2]*z[2]*x[3]*y[7]+y[2]*x
+ [2]*y[7]*z[3]+y[2]*z[2]*x[7]*y[3]-2.0*y[2]*x[2]*y[3]*z[6]+2.0*y[2]*x[2]*y[6]*z
+ [3]+2.0*y[2]*z[2]*x[6]*y[3]-y[3]*y[2]*x[6]*z[3];
s8 = y[3]*y[2]*x[3]*z[6]+y[3]*x[2]*y[6]*z[3]-y[3]*z[2]*x[3]*y[6]-y[2]*y
- [2]*x[7]*z[3]+2.0*y[2]*y[2]*x[3]*z[6]+y[2]*y[2]*x[3]*z[7]-2.0*y[1]*x[1]*y[5]*z
- [0]-x[2]*y[3]*y[3]*z[6]+z[2]*x[6]*y[3]*y[3]+2.0*y[6]*x[2]*y[5]*z[6]+2.0*y[6]*x
- [6]*y[2]*z[5]-2.0*y[6]*x[5]*y[2]*z[6]+2.0*y[3]*x[2]*y[7]*z[3]-2.0*y[3]*z[2]*x
- [3]*y[7]-y[0]*z[0]*x[7]*y[3]-y[0]*z[2]*x[1]*y[3];
+ [2]*x[7]*z[3]+2.0*y[2]*y[2]*x[3]*z[6]+y[2]*y[2]*x[3]*z[7]-2.0*y[1]*x[1]*y[5]*z
+ [0]-x[2]*y[3]*y[3]*z[6]+z[2]*x[6]*y[3]*y[3]+2.0*y[6]*x[2]*y[5]*z[6]+2.0*y[6]*x
+ [6]*y[2]*z[5]-2.0*y[6]*x[5]*y[2]*z[6]+2.0*y[3]*x[2]*y[7]*z[3]-2.0*y[3]*z[2]*x
+ [3]*y[7]-y[0]*z[0]*x[7]*y[3]-y[0]*z[2]*x[1]*y[3];
s4 = s8-y[2]*y[6]*x[7]*z[2]+y[0]*z[2]*x[3]*y[1]+y[1]*z[5]*x[1]*y[4]-y[1]*
- x[5]*y[4]*z[1]+2.0*y[0]*z[0]*x[3]*y[4]+2.0*y[0]*x[0]*y[3]*z[4]+2.0*z[2]*x[7]*y
- [3]*y[3]-2.0*z[5]*x[7]*y[4]*y[4]+x[6]*y[4]*y[4]*z[7]-z[6]*x[7]*y[4]*y[4]+y[1]*y
- [1]*x[0]*z[3]+y[3]*x[6]*y[7]*z[2]-y[3]*z[6]*x[2]*y[7]+2.0*y[3]*y[2]*x[3]*z[7]+
- s5+s7;
+ x[5]*y[4]*z[1]+2.0*y[0]*z[0]*x[3]*y[4]+2.0*y[0]*x[0]*y[3]*z[4]+2.0*z[2]*x[7]*y
+ [3]*y[3]-2.0*z[5]*x[7]*y[4]*y[4]+x[6]*y[4]*y[4]*z[7]-z[6]*x[7]*y[4]*y[4]+y[1]*y
+ [1]*x[0]*z[3]+y[3]*x[6]*y[7]*z[2]-y[3]*z[6]*x[2]*y[7]+2.0*y[3]*y[2]*x[3]*z[7]+
+ s5+s7;
s8 = s4+y[2]*x[6]*y[7]*z[2]-y[2]*y[6]*x[7]*z[3]+y[2]*y[6]*x[2]*z[7]-y[2]*
- z[6]*x[2]*y[7]-y[2]*x[6]*y[3]*z[7]+y[2]*y[6]*x[3]*z[7]+y[2]*z[6]*x[7]*y[3]-2.0*
- y[3]*y[2]*x[7]*z[3]-x[6]*y[3]*y[3]*z[7]+y[1]*y[1]*x[4]*z[0]-y[1]*y[1]*x[3]*z[0]
- +x[2]*y[6]*y[6]*z[3]-z[2]*x[3]*y[6]*y[6]-y[1]*y[1]*x[0]*z[4];
+ z[6]*x[2]*y[7]-y[2]*x[6]*y[3]*z[7]+y[2]*y[6]*x[3]*z[7]+y[2]*z[6]*x[7]*y[3]-2.0*
+ y[3]*y[2]*x[7]*z[3]-x[6]*y[3]*y[3]*z[7]+y[1]*y[1]*x[4]*z[0]-y[1]*y[1]*x[3]*z[0]
+ +x[2]*y[6]*y[6]*z[3]-z[2]*x[3]*y[6]*y[6]-y[1]*y[1]*x[0]*z[4];
s7 = s8+y[5]*x[1]*y[0]*z[5]+y[6]*x[2]*y[7]*z[3]-y[6]*y[2]*x[6]*z[3]+y[6]*
- y[2]*x[3]*z[6]-y[6]*x[2]*y[3]*z[6]+y[6]*z[2]*x[6]*y[3]-y[5]*y[1]*x[0]*z[5]-y[5]
- *z[1]*x[5]*y[0]+y[5]*y[1]*x[5]*z[0]-y[6]*z[2]*x[3]*y[7]-y[7]*y[6]*x[7]*z[2]+2.0
- *y[6]*y[6]*x[2]*z[7]+y[6]*y[6]*x[3]*z[7]+x[6]*y[7]*y[7]*z[2]-z[6]*x[2]*y[7]*y
- [7];
+ y[2]*x[3]*z[6]-y[6]*x[2]*y[3]*z[6]+y[6]*z[2]*x[6]*y[3]-y[5]*y[1]*x[0]*z[5]-y[5]
+ *z[1]*x[5]*y[0]+y[5]*y[1]*x[5]*z[0]-y[6]*z[2]*x[3]*y[7]-y[7]*y[6]*x[7]*z[2]+2.0
+ *y[6]*y[6]*x[2]*z[7]+y[6]*y[6]*x[3]*z[7]+x[6]*y[7]*y[7]*z[2]-z[6]*x[2]*y[7]*y
+ [7];
s8 = -x[2]*y[1]*y[1]*z[3]+2.0*y[1]*y[1]*x[0]*z[2]-2.0*y[1]*y[1]*x[2]*z[0]
- +z[2]*x[3]*y[1]*y[1]-z[1]*x[0]*y[2]*y[2]+x[1]*y[2]*y[2]*z[0]+y[2]*y[2]*x[0]*z
- [3]-y[2]*y[2]*x[3]*z[0]-2.0*y[2]*y[2]*x[3]*z[1]+y[1]*x[1]*y[3]*z[0]-2.0*y[6]*y
- [6]*x[7]*z[2]+2.0*y[5]*y[5]*x[4]*z[1]-2.0*y[5]*y[5]*x[1]*z[4]-y[6]*y[6]*x[7]*z
- [3]-2.0*y[1]*x[1]*y[0]*z[2];
+ +z[2]*x[3]*y[1]*y[1]-z[1]*x[0]*y[2]*y[2]+x[1]*y[2]*y[2]*z[0]+y[2]*y[2]*x[0]*z
+ [3]-y[2]*y[2]*x[3]*z[0]-2.0*y[2]*y[2]*x[3]*z[1]+y[1]*x[1]*y[3]*z[0]-2.0*y[6]*y
+ [6]*x[7]*z[2]+2.0*y[5]*y[5]*x[4]*z[1]-2.0*y[5]*y[5]*x[1]*z[4]-y[6]*y[6]*x[7]*z
+ [3]-2.0*y[1]*x[1]*y[0]*z[2];
s6 = s8+2.0*y[1]*z[1]*x[2]*y[0]-2.0*y[1]*z[1]*x[0]*y[2]+2.0*y[1]*x[1]*y
- [2]*z[0]+y[1]*x[2]*y[3]*z[1]-y[1]*y[2]*x[3]*z[1]-y[1]*z[2]*x[1]*y[3]+y[1]*y[2]*
- x[1]*z[3]-y[2]*x[1]*y[0]*z[2]+y[2]*z[1]*x[2]*y[0]+y[2]*x[2]*y[3]*z[0]-y[7]*x[6]
- *y[2]*z[7]+y[7]*z[6]*x[7]*y[2]+y[7]*y[6]*x[2]*z[7]-y[6]*x[6]*y[3]*z[7]+y[6]*x
- [6]*y[7]*z[3]+s7;
+ [2]*z[0]+y[1]*x[2]*y[3]*z[1]-y[1]*y[2]*x[3]*z[1]-y[1]*z[2]*x[1]*y[3]+y[1]*y[2]*
+ x[1]*z[3]-y[2]*x[1]*y[0]*z[2]+y[2]*z[1]*x[2]*y[0]+y[2]*x[2]*y[3]*z[0]-y[7]*x[6]
+ *y[2]*z[7]+y[7]*z[6]*x[7]*y[2]+y[7]*y[6]*x[2]*z[7]-y[6]*x[6]*y[3]*z[7]+y[6]*x
+ [6]*y[7]*z[3]+s7;
s8 = s6-y[6]*z[6]*x[3]*y[7]+y[6]*z[6]*x[7]*y[3]+2.0*y[2]*y[2]*x[1]*z[3]+x
- [2]*y[3]*y[3]*z[1]-z[2]*x[1]*y[3]*y[3]+y[1]*x[1]*y[0]*z[4]+y[1]*z[1]*x[3]*y[0]-
- y[1]*x[1]*y[0]*z[3]+2.0*y[5]*x[5]*y[1]*z[4]-2.0*y[5]*x[5]*y[4]*z[1]+2.0*y[5]*z
- [5]*x[1]*y[4]-2.0*y[5]*z[5]*x[4]*y[1]-2.0*y[6]*x[6]*y[2]*z[7]+2.0*y[6]*x[6]*y
- [7]*z[2];
+ [2]*y[3]*y[3]*z[1]-z[2]*x[1]*y[3]*y[3]+y[1]*x[1]*y[0]*z[4]+y[1]*z[1]*x[3]*y[0]-
+ y[1]*x[1]*y[0]*z[3]+2.0*y[5]*x[5]*y[1]*z[4]-2.0*y[5]*x[5]*y[4]*z[1]+2.0*y[5]*z
+ [5]*x[1]*y[4]-2.0*y[5]*z[5]*x[4]*y[1]-2.0*y[6]*x[6]*y[2]*z[7]+2.0*y[6]*x[6]*y
+ [7]*z[2];
s7 = s8+2.0*y[6]*z[6]*x[7]*y[2]-2.0*y[6]*z[6]*x[2]*y[7]-y[1]*z[1]*x[4]*y
- [0]+y[1]*z[1]*x[0]*y[4]-y[1]*z[1]*x[0]*y[3]+2.0*y[6]*y[6]*x[7]*z[5]+2.0*y[5]*y
- [5]*x[6]*z[4]-2.0*y[5]*y[5]*x[4]*z[6]+x[6]*y[5]*y[5]*z[7]-y[3]*x[2]*y[1]*z[3]-y
- [3]*y[2]*x[3]*z[1]+y[3]*z[2]*x[3]*y[1]+y[3]*y[2]*x[1]*z[3]-y[2]*x[2]*y[0]*z[3]+
- y[2]*z[2]*x[3]*y[0];
+ [0]+y[1]*z[1]*x[0]*y[4]-y[1]*z[1]*x[0]*y[3]+2.0*y[6]*y[6]*x[7]*z[5]+2.0*y[5]*y
+ [5]*x[6]*z[4]-2.0*y[5]*y[5]*x[4]*z[6]+x[6]*y[5]*y[5]*z[7]-y[3]*x[2]*y[1]*z[3]-y
+ [3]*y[2]*x[3]*z[1]+y[3]*z[2]*x[3]*y[1]+y[3]*y[2]*x[1]*z[3]-y[2]*x[2]*y[0]*z[3]+
+ y[2]*z[2]*x[3]*y[0];
s8 = s7+2.0*y[2]*x[2]*y[3]*z[1]-2.0*y[2]*x[2]*y[1]*z[3]+y[2]*y[1]*x[0]*z
- [2]-y[2]*y[1]*x[2]*z[0]+2.0*y[2]*z[2]*x[3]*y[1]-2.0*y[2]*z[2]*x[1]*y[3]-y[2]*z
- [2]*x[0]*y[3]+y[5]*z[6]*x[5]*y[7]-y[5]*x[6]*y[7]*z[5]-y[5]*y[6]*x[4]*z[7]-y[5]*
- y[6]*x[5]*z[7]-2.0*y[5]*x[5]*y[6]*z[4]+2.0*y[5]*x[5]*y[4]*z[6]-2.0*y[5]*z[5]*x
- [6]*y[4]+2.0*y[5]*z[5]*x[4]*y[6];
+ [2]-y[2]*y[1]*x[2]*z[0]+2.0*y[2]*z[2]*x[3]*y[1]-2.0*y[2]*z[2]*x[1]*y[3]-y[2]*z
+ [2]*x[0]*y[3]+y[5]*z[6]*x[5]*y[7]-y[5]*x[6]*y[7]*z[5]-y[5]*y[6]*x[4]*z[7]-y[5]*
+ y[6]*x[5]*z[7]-2.0*y[5]*x[5]*y[6]*z[4]+2.0*y[5]*x[5]*y[4]*z[6]-2.0*y[5]*z[5]*x
+ [6]*y[4]+2.0*y[5]*z[5]*x[4]*y[6];
s5 = s8-y[1]*y[5]*x[0]*z[4]-z[6]*x[7]*y[5]*y[5]+y[6]*y[6]*x[7]*z[4]-y[6]*
- y[6]*x[4]*z[7]-2.0*y[6]*y[6]*x[5]*z[7]-x[5]*y[6]*y[6]*z[4]+z[5]*x[4]*y[6]*y[6]+
- z[6]*x[5]*y[7]*y[7]-x[6]*y[7]*y[7]*z[5]+y[1]*y[5]*x[4]*z[0]+y[7]*y[6]*x[7]*z[5]
- +y[6]*y[5]*x[7]*z[4]+y[5]*y[6]*x[7]*z[5]+y[6]*y[5]*x[6]*z[4]-y[6]*y[5]*x[4]*z
- [6]+2.0*y[6]*z[6]*x[5]*y[7];
+ y[6]*x[4]*z[7]-2.0*y[6]*y[6]*x[5]*z[7]-x[5]*y[6]*y[6]*z[4]+z[5]*x[4]*y[6]*y[6]+
+ z[6]*x[5]*y[7]*y[7]-x[6]*y[7]*y[7]*z[5]+y[1]*y[5]*x[4]*z[0]+y[7]*y[6]*x[7]*z[5]
+ +y[6]*y[5]*x[7]*z[4]+y[5]*y[6]*x[7]*z[5]+y[6]*y[5]*x[6]*z[4]-y[6]*y[5]*x[4]*z
+ [6]+2.0*y[6]*z[6]*x[5]*y[7];
s8 = s5-2.0*y[6]*x[6]*y[7]*z[5]+2.0*y[6]*x[6]*y[5]*z[7]-2.0*y[6]*z[6]*x
- [7]*y[5]-y[6]*x[5]*y[7]*z[4]-y[6]*x[6]*y[7]*z[4]+y[6]*x[6]*y[4]*z[7]-y[6]*z[6]*
- x[7]*y[4]+y[6]*z[5]*x[4]*y[7]+y[6]*z[6]*x[4]*y[7]+y[6]*x[5]*y[4]*z[6]-y[6]*z[5]
- *x[6]*y[4]+y[7]*x[6]*y[5]*z[7]-y[7]*z[6]*x[7]*y[5]-2.0*y[6]*x[6]*y[5]*z[2];
+ [7]*y[5]-y[6]*x[5]*y[7]*z[4]-y[6]*x[6]*y[7]*z[4]+y[6]*x[6]*y[4]*z[7]-y[6]*z[6]*
+ x[7]*y[4]+y[6]*z[5]*x[4]*y[7]+y[6]*z[6]*x[4]*y[7]+y[6]*x[5]*y[4]*z[6]-y[6]*z[5]
+ *x[6]*y[4]+y[7]*x[6]*y[5]*z[7]-y[7]*z[6]*x[7]*y[5]-2.0*y[6]*x[6]*y[5]*z[2];
s7 = s8-y[7]*y[6]*x[5]*z[7]+2.0*y[4]*y[5]*x[4]*z[0]+2.0*x[3]*y[7]*y[7]*z
- [4]-2.0*x[4]*y[7]*y[7]*z[3]-z[0]*x[4]*y[7]*y[7]+x[0]*y[7]*y[7]*z[4]-y[0]*z[5]*x
- [4]*y[1]+y[0]*x[5]*y[1]*z[4]-y[0]*x[5]*y[4]*z[0]+y[0]*z[5]*x[0]*y[4]-y[5]*y[5]*
- x[0]*z[4]+y[5]*y[5]*x[4]*z[0]+2.0*y[1]*y[1]*x[2]*z[5]-2.0*y[1]*y[1]*x[5]*z[2]+z
- [1]*x[5]*y[2]*y[2];
+ [4]-2.0*x[4]*y[7]*y[7]*z[3]-z[0]*x[4]*y[7]*y[7]+x[0]*y[7]*y[7]*z[4]-y[0]*z[5]*x
+ [4]*y[1]+y[0]*x[5]*y[1]*z[4]-y[0]*x[5]*y[4]*z[0]+y[0]*z[5]*x[0]*y[4]-y[5]*y[5]*
+ x[0]*z[4]+y[5]*y[5]*x[4]*z[0]+2.0*y[1]*y[1]*x[2]*z[5]-2.0*y[1]*y[1]*x[5]*z[2]+z
+ [1]*x[5]*y[2]*y[2];
s8 = s7-x[1]*y[2]*y[2]*z[5]-y[5]*z[5]*x[4]*y[0]+y[5]*z[5]*x[0]*y[4]-y[5]*
- x[5]*y[4]*z[0]-y[2]*x[1]*y[6]*z[5]-y[2]*y[1]*x[5]*z[6]+y[2]*z[1]*x[5]*y[6]+y[2]
- *y[1]*x[6]*z[5]-y[1]*z[1]*x[6]*y[5]-y[1]*x[1]*y[6]*z[5]+y[1]*x[1]*y[5]*z[6]+y
- [1]*z[1]*x[5]*y[6]+y[5]*x[5]*y[0]*z[4]+y[2]*y[1]*x[2]*z[5]-y[2]*z[1]*x[2]*y[5];
+ x[5]*y[4]*z[0]-y[2]*x[1]*y[6]*z[5]-y[2]*y[1]*x[5]*z[6]+y[2]*z[1]*x[5]*y[6]+y[2]
+ *y[1]*x[6]*z[5]-y[1]*z[1]*x[6]*y[5]-y[1]*x[1]*y[6]*z[5]+y[1]*x[1]*y[5]*z[6]+y
+ [1]*z[1]*x[5]*y[6]+y[5]*x[5]*y[0]*z[4]+y[2]*y[1]*x[2]*z[5]-y[2]*z[1]*x[2]*y[5];
s6 = s8+y[2]*x[1]*y[5]*z[2]-y[2]*y[1]*x[5]*z[2]-y[1]*y[1]*x[5]*z[6]+y[1]*
- y[1]*x[6]*z[5]-z[1]*x[2]*y[5]*y[5]+x[1]*y[5]*y[5]*z[2]+2.0*y[1]*z[1]*x[5]*y[2]
- -2.0*y[1]*x[1]*y[2]*z[5]-2.0*y[1]*z[1]*x[2]*y[5]+2.0*y[1]*x[1]*y[5]*z[2]-y[1]*y
- [1]*x[6]*z[2]+y[1]*y[1]*x[2]*z[6]-2.0*y[5]*x[1]*y[6]*z[5]-2.0*y[5]*y[1]*x[5]*z
- [6]+2.0*y[5]*z[1]*x[5]*y[6]+2.0*y[5]*y[1]*x[6]*z[5];
+ y[1]*x[6]*z[5]-z[1]*x[2]*y[5]*y[5]+x[1]*y[5]*y[5]*z[2]+2.0*y[1]*z[1]*x[5]*y[2]
+ -2.0*y[1]*x[1]*y[2]*z[5]-2.0*y[1]*z[1]*x[2]*y[5]+2.0*y[1]*x[1]*y[5]*z[2]-y[1]*y
+ [1]*x[6]*z[2]+y[1]*y[1]*x[2]*z[6]-2.0*y[5]*x[1]*y[6]*z[5]-2.0*y[5]*y[1]*x[5]*z
+ [6]+2.0*y[5]*z[1]*x[5]*y[6]+2.0*y[5]*y[1]*x[6]*z[5];
s8 = s6-y[6]*z[1]*x[6]*y[5]-y[6]*y[1]*x[5]*z[6]+y[6]*x[1]*y[5]*z[6]+y[6]*
- y[1]*x[6]*z[5]-2.0*z[1]*x[6]*y[5]*y[5]+2.0*x[1]*y[5]*y[5]*z[6]-x[1]*y[6]*y[6]*z
- [5]+z[1]*x[5]*y[6]*y[6]+y[5]*z[1]*x[5]*y[2]-y[5]*x[1]*y[2]*z[5]+y[5]*y[1]*x[2]*
- z[5]-y[5]*y[1]*x[5]*z[2]-y[6]*z[1]*x[2]*y[5]+y[6]*x[1]*y[5]*z[2];
+ y[1]*x[6]*z[5]-2.0*z[1]*x[6]*y[5]*y[5]+2.0*x[1]*y[5]*y[5]*z[6]-x[1]*y[6]*y[6]*z
+ [5]+z[1]*x[5]*y[6]*y[6]+y[5]*z[1]*x[5]*y[2]-y[5]*x[1]*y[2]*z[5]+y[5]*y[1]*x[2]*
+ z[5]-y[5]*y[1]*x[5]*z[2]-y[6]*z[1]*x[2]*y[5]+y[6]*x[1]*y[5]*z[2];
s7 = s8-y[1]*z[1]*x[2]*y[6]-y[1]*x[1]*y[2]*z[6]+y[1]*x[1]*y[6]*z[2]+y[1]*
- z[1]*x[6]*y[2]+y[5]*x[5]*y[6]*z[2]-y[5]*x[2]*y[6]*z[5]+y[5]*x[6]*y[2]*z[5]-y[5]
- *x[5]*y[2]*z[6]-x[6]*y[5]*y[5]*z[2]+x[2]*y[5]*y[5]*z[6]-y[5]*y[5]*x[4]*z[7]+y
- [5]*y[5]*x[7]*z[4]-y[1]*x[6]*y[5]*z[2]+y[1]*x[2]*y[5]*z[6]-y[2]*x[6]*y[5]*z[2]
- -2.0*y[2]*y[1]*x[6]*z[2];
+ z[1]*x[6]*y[2]+y[5]*x[5]*y[6]*z[2]-y[5]*x[2]*y[6]*z[5]+y[5]*x[6]*y[2]*z[5]-y[5]
+ *x[5]*y[2]*z[6]-x[6]*y[5]*y[5]*z[2]+x[2]*y[5]*y[5]*z[6]-y[5]*y[5]*x[4]*z[7]+y
+ [5]*y[5]*x[7]*z[4]-y[1]*x[6]*y[5]*z[2]+y[1]*x[2]*y[5]*z[6]-y[2]*x[6]*y[5]*z[2]
+ -2.0*y[2]*y[1]*x[6]*z[2];
s8 = s7-2.0*y[2]*z[1]*x[2]*y[6]+2.0*y[2]*x[1]*y[6]*z[2]+2.0*y[2]*y[1]*x
- [2]*z[6]-2.0*x[1]*y[2]*y[2]*z[6]+2.0*z[1]*x[6]*y[2]*y[2]+x[6]*y[2]*y[2]*z[5]-x
- [5]*y[2]*y[2]*z[6]+2.0*x[5]*y[6]*y[6]*z[2]-2.0*x[2]*y[6]*y[6]*z[5]-z[1]*x[2]*y
- [6]*y[6]-y[6]*y[1]*x[6]*z[2]-y[6]*x[1]*y[2]*z[6]+y[6]*z[1]*x[6]*y[2]+y[6]*y[1]*
- x[2]*z[6]+x[1]*y[6]*y[6]*z[2];
+ [2]*z[6]-2.0*x[1]*y[2]*y[2]*z[6]+2.0*z[1]*x[6]*y[2]*y[2]+x[6]*y[2]*y[2]*z[5]-x
+ [5]*y[2]*y[2]*z[6]+2.0*x[5]*y[6]*y[6]*z[2]-2.0*x[2]*y[6]*y[6]*z[5]-z[1]*x[2]*y
+ [6]*y[6]-y[6]*y[1]*x[6]*z[2]-y[6]*x[1]*y[2]*z[6]+y[6]*z[1]*x[6]*y[2]+y[6]*y[1]*
+ x[2]*z[6]+x[1]*y[6]*y[6]*z[2];
s3 = s8+y[2]*x[5]*y[6]*z[2]+y[2]*x[2]*y[5]*z[6]-y[2]*x[2]*y[6]*z[5]+y[5]*
- z[5]*x[4]*y[7]+y[5]*x[5]*y[4]*z[7]-y[5]*z[5]*x[7]*y[4]-y[5]*x[5]*y[7]*z[4]+2.0*
- y[4]*x[5]*y[0]*z[4]-y[3]*z[6]*x[3]*y[7]+y[3]*y[6]*x[3]*z[7]+y[3]*x[6]*y[7]*z[3]
- -y[3]*y[6]*x[7]*z[3]-y[2]*y[1]*x[3]*z[0]-y[2]*z[1]*x[0]*y[3]+y[2]*y[1]*x[0]*z
- [3]+y[2]*x[1]*y[3]*z[0];
+ z[5]*x[4]*y[7]+y[5]*x[5]*y[4]*z[7]-y[5]*z[5]*x[7]*y[4]-y[5]*x[5]*y[7]*z[4]+2.0*
+ y[4]*x[5]*y[0]*z[4]-y[3]*z[6]*x[3]*y[7]+y[3]*y[6]*x[3]*z[7]+y[3]*x[6]*y[7]*z[3]
+ -y[3]*y[6]*x[7]*z[3]-y[2]*y[1]*x[3]*z[0]-y[2]*z[1]*x[0]*y[3]+y[2]*y[1]*x[0]*z
+ [3]+y[2]*x[1]*y[3]*z[0];
s8 = y[1]*x[0]*z[3]+x[1]*y[3]*z[0]-y[0]*x[3]*z[7]-x[1]*y[5]*z[0]-y[0]*x
- [3]*z[4]-x[1]*y[0]*z[2]+z[1]*x[2]*y[0]-y[1]*x[0]*z[5]-z[1]*x[0]*y[2]-y[1]*x[0]*
- z[4]+z[1]*x[5]*y[2]+z[0]*x[7]*y[4]+z[0]*x[3]*y[7]+z[1]*x[0]*y[4]-x[1]*y[2]*z[5]
- +x[2]*y[3]*z[0]+y[1]*x[2]*z[5]-x[2]*y[3]*z[7];
+ [3]*z[4]-x[1]*y[0]*z[2]+z[1]*x[2]*y[0]-y[1]*x[0]*z[5]-z[1]*x[0]*y[2]-y[1]*x[0]*
+ z[4]+z[1]*x[5]*y[2]+z[0]*x[7]*y[4]+z[0]*x[3]*y[7]+z[1]*x[0]*y[4]-x[1]*y[2]*z[5]
+ +x[2]*y[3]*z[0]+y[1]*x[2]*z[5]-x[2]*y[3]*z[7];
s7 = s8-z[1]*x[2]*y[5]-y[1]*x[3]*z[0]-x[0]*y[7]*z[3]-z[1]*x[0]*y[3]+y[5]*
- x[4]*z[0]-x[0]*y[4]*z[3]+y[5]*x[7]*z[4]-z[0]*x[4]*y[3]+x[1]*y[0]*z[4]-z[2]*x[3]
- *y[7]-y[6]*x[7]*z[2]+x[1]*y[5]*z[2]+y[6]*x[7]*z[5]+x[0]*y[7]*z[4]+x[1]*y[2]*z
- [0]-z[1]*x[4]*y[0]-z[0]*x[4]*y[7]-z[2]*x[0]*y[3];
+ x[4]*z[0]-x[0]*y[4]*z[3]+y[5]*x[7]*z[4]-z[0]*x[4]*y[3]+x[1]*y[0]*z[4]-z[2]*x[3]
+ *y[7]-y[6]*x[7]*z[2]+x[1]*y[5]*z[2]+y[6]*x[7]*z[5]+x[0]*y[7]*z[4]+x[1]*y[2]*z
+ [0]-z[1]*x[4]*y[0]-z[0]*x[4]*y[7]-z[2]*x[0]*y[3];
s8 = x[5]*y[0]*z[4]+z[1]*x[0]*y[5]-x[2]*y[0]*z[3]-z[1]*x[5]*y[0]+y[1]*x
- [5]*z[0]-x[1]*y[0]*z[3]-x[1]*y[4]*z[0]-y[1]*x[5]*z[2]+x[2]*y[7]*z[3]+y[0]*x[4]*
- z[3]-x[0]*y[4]*z[7]+x[1]*y[0]*z[5]-y[1]*x[6]*z[2]-y[2]*x[6]*z[3]+y[0]*x[7]*z[3]
- -y[2]*x[7]*z[3]+z[2]*x[7]*y[3]+y[2]*x[0]*z[3];
+ [5]*z[0]-x[1]*y[0]*z[3]-x[1]*y[4]*z[0]-y[1]*x[5]*z[2]+x[2]*y[7]*z[3]+y[0]*x[4]*
+ z[3]-x[0]*y[4]*z[7]+x[1]*y[0]*z[5]-y[1]*x[6]*z[2]-y[2]*x[6]*z[3]+y[0]*x[7]*z[3]
+ -y[2]*x[7]*z[3]+z[2]*x[7]*y[3]+y[2]*x[0]*z[3];
s6 = s8+y[2]*x[3]*z[7]-y[2]*x[3]*z[0]-x[6]*y[5]*z[2]-y[5]*x[0]*z[4]+z[2]*
- x[3]*y[0]+x[2]*y[3]*z[1]+x[0]*y[3]*z[7]-x[2]*y[1]*z[3]+y[1]*x[4]*z[0]+y[1]*x[0]
- *z[2]-z[1]*x[2]*y[6]+y[2]*x[3]*z[6]-y[1]*x[2]*z[0]+z[1]*x[3]*y[0]-x[1]*y[2]*z
- [6]-x[2]*y[3]*z[6]+x[0]*y[3]*z[4]+z[0]*x[3]*y[4]+s7;
+ x[3]*y[0]+x[2]*y[3]*z[1]+x[0]*y[3]*z[7]-x[2]*y[1]*z[3]+y[1]*x[4]*z[0]+y[1]*x[0]
+ *z[2]-z[1]*x[2]*y[6]+y[2]*x[3]*z[6]-y[1]*x[2]*z[0]+z[1]*x[3]*y[0]-x[1]*y[2]*z
+ [6]-x[2]*y[3]*z[6]+x[0]*y[3]*z[4]+z[0]*x[3]*y[4]+s7;
s8 = x[5]*y[4]*z[7]+s6+y[5]*x[6]*z[4]-y[5]*x[4]*z[6]+z[6]*x[5]*y[7]-x[6]*
- y[2]*z[7]-x[6]*y[7]*z[5]+x[5]*y[6]*z[2]+x[6]*y[5]*z[7]+x[6]*y[7]*z[2]+y[6]*x[7]
- *z[4]-y[6]*x[4]*z[7]-y[6]*x[7]*z[3]+z[6]*x[7]*y[2]+x[2]*y[5]*z[6]-x[2]*y[6]*z
- [5]+y[6]*x[2]*z[7]+x[6]*y[2]*z[5];
+ y[2]*z[7]-x[6]*y[7]*z[5]+x[5]*y[6]*z[2]+x[6]*y[5]*z[7]+x[6]*y[7]*z[2]+y[6]*x[7]
+ *z[4]-y[6]*x[4]*z[7]-y[6]*x[7]*z[3]+z[6]*x[7]*y[2]+x[2]*y[5]*z[6]-x[2]*y[6]*z
+ [5]+y[6]*x[2]*z[7]+x[6]*y[2]*z[5];
s7 = s8-x[5]*y[2]*z[6]-z[6]*x[7]*y[5]-z[5]*x[7]*y[4]+z[5]*x[0]*y[4]-y[5]*
- x[4]*z[7]+y[0]*x[4]*z[7]-z[6]*x[2]*y[7]-x[5]*y[4]*z[0]-x[5]*y[7]*z[4]-y[0]*x[7]
- *z[4]+y[5]*x[4]*z[1]-x[6]*y[7]*z[4]+x[7]*y[4]*z[3]-x[4]*y[7]*z[3]+x[3]*y[7]*z
- [4]-x[7]*y[3]*z[4]-x[6]*y[3]*z[7]+x[6]*y[4]*z[7];
+ x[4]*z[7]+y[0]*x[4]*z[7]-z[6]*x[2]*y[7]-x[5]*y[4]*z[0]-x[5]*y[7]*z[4]-y[0]*x[7]
+ *z[4]+y[5]*x[4]*z[1]-x[6]*y[7]*z[4]+x[7]*y[4]*z[3]-x[4]*y[7]*z[3]+x[3]*y[7]*z
+ [4]-x[7]*y[3]*z[4]-x[6]*y[3]*z[7]+x[6]*y[4]*z[7];
s8 = -x[3]*y[4]*z[7]+x[4]*y[3]*z[7]-z[6]*x[7]*y[4]-z[1]*x[6]*y[5]+x[6]*y
- [7]*z[3]-x[1]*y[6]*z[5]-y[1]*x[5]*z[6]+z[5]*x[4]*y[7]-z[5]*x[4]*y[0]+x[1]*y[5]*
- z[6]-y[6]*x[5]*z[7]-y[2]*x[3]*z[1]+z[1]*x[5]*y[6]-y[5]*x[1]*z[4]+z[6]*x[4]*y[7]
- +x[5]*y[1]*z[4]-x[5]*y[6]*z[4]+y[6]*x[3]*z[7]-x[5]*y[4]*z[1];
+ [7]*z[3]-x[1]*y[6]*z[5]-y[1]*x[5]*z[6]+z[5]*x[4]*y[7]-z[5]*x[4]*y[0]+x[1]*y[5]*
+ z[6]-y[6]*x[5]*z[7]-y[2]*x[3]*z[1]+z[1]*x[5]*y[6]-y[5]*x[1]*z[4]+z[6]*x[4]*y[7]
+ +x[5]*y[1]*z[4]-x[5]*y[6]*z[4]+y[6]*x[3]*z[7]-x[5]*y[4]*z[1];
s5 = s8+x[5]*y[4]*z[6]+z[5]*x[1]*y[4]+y[1]*x[6]*z[5]-z[6]*x[3]*y[7]+z[6]*
- x[7]*y[3]-z[5]*x[6]*y[4]-z[5]*x[4]*y[1]+z[5]*x[4]*y[6]+x[1]*y[6]*z[2]+x[2]*y[6]
- *z[3]+z[2]*x[6]*y[3]+z[1]*x[6]*y[2]+z[2]*x[3]*y[1]-z[2]*x[1]*y[3]-z[2]*x[3]*y
- [6]+y[2]*x[1]*z[3]+y[1]*x[2]*z[6]-z[0]*x[7]*y[3]+s7;
+ x[7]*y[3]-z[5]*x[6]*y[4]-z[5]*x[4]*y[1]+z[5]*x[4]*y[6]+x[1]*y[6]*z[2]+x[2]*y[6]
+ *z[3]+z[2]*x[6]*y[3]+z[1]*x[6]*y[2]+z[2]*x[3]*y[1]-z[2]*x[1]*y[3]-z[2]*x[3]*y
+ [6]+y[2]*x[1]*z[3]+y[1]*x[2]*z[6]-z[0]*x[7]*y[3]+s7;
s4 = 1/s5;
s2 = s3*s4;
const double unknown1 = s1*s2;
s1 = 1.0/6.0;
s8 = -z[2]*x[1]*y[2]*z[5]+z[2]*y[1]*x[2]*z[5]-z[2]*z[1]*x[2]*y[5]+z[2]*z
- [1]*x[5]*y[2]+2.0*y[5]*x[7]*z[4]*z[4]-y[1]*x[2]*z[0]*z[0]+x[0]*y[3]*z[7]*z[7]
- -2.0*z[5]*z[5]*x[4]*y[1]+2.0*z[5]*z[5]*x[1]*y[4]+z[5]*z[5]*x[0]*y[4]-2.0*z[2]*z
- [2]*x[1]*y[3]+2.0*z[2]*z[2]*x[3]*y[1]-x[0]*y[4]*z[7]*z[7]-y[0]*x[3]*z[7]*z[7]+x
- [1]*y[0]*z[5]*z[5];
+ [1]*x[5]*y[2]+2.0*y[5]*x[7]*z[4]*z[4]-y[1]*x[2]*z[0]*z[0]+x[0]*y[3]*z[7]*z[7]
+ -2.0*z[5]*z[5]*x[4]*y[1]+2.0*z[5]*z[5]*x[1]*y[4]+z[5]*z[5]*x[0]*y[4]-2.0*z[2]*z
+ [2]*x[1]*y[3]+2.0*z[2]*z[2]*x[3]*y[1]-x[0]*y[4]*z[7]*z[7]-y[0]*x[3]*z[7]*z[7]+x
+ [1]*y[0]*z[5]*z[5];
s7 = s8-y[1]*x[0]*z[5]*z[5]+z[1]*y[1]*x[2]*z[6]+y[1]*x[0]*z[2]*z[2]+z[2]*
- z[2]*x[3]*y[0]-z[2]*z[2]*x[0]*y[3]-x[1]*y[0]*z[2]*z[2]+2.0*z[5]*z[5]*x[4]*y[6]
- -2.0*z[5]*z[5]*x[6]*y[4]-z[5]*z[5]*x[7]*y[4]-x[6]*y[7]*z[5]*z[5]+2.0*z[2]*y[1]*
- x[2]*z[6]-2.0*z[2]*x[1]*y[2]*z[6]+2.0*z[2]*z[1]*x[6]*y[2]-y[6]*x[5]*z[7]*z[7]+
- 2.0*x[6]*y[4]*z[7]*z[7];
+ z[2]*x[3]*y[0]-z[2]*z[2]*x[0]*y[3]-x[1]*y[0]*z[2]*z[2]+2.0*z[5]*z[5]*x[4]*y[6]
+ -2.0*z[5]*z[5]*x[6]*y[4]-z[5]*z[5]*x[7]*y[4]-x[6]*y[7]*z[5]*z[5]+2.0*z[2]*y[1]*
+ x[2]*z[6]-2.0*z[2]*x[1]*y[2]*z[6]+2.0*z[2]*z[1]*x[6]*y[2]-y[6]*x[5]*z[7]*z[7]+
+ 2.0*x[6]*y[4]*z[7]*z[7];
s8 = -2.0*y[6]*x[4]*z[7]*z[7]+x[6]*y[5]*z[7]*z[7]-2.0*z[2]*z[1]*x[2]*y[6]
- +z[4]*y[6]*x[7]*z[5]+x[5]*y[4]*z[6]*z[6]+z[6]*z[6]*x[4]*y[7]-z[6]*z[6]*x[7]*y
- [4]-2.0*z[6]*z[6]*x[7]*y[5]+2.0*z[6]*z[6]*x[5]*y[7]-y[5]*x[4]*z[6]*z[6]+2.0*z
- [0]*z[0]*x[3]*y[4]-x[6]*y[5]*z[2]*z[2]+z[1]*z[1]*x[5]*y[6]-z[1]*z[1]*x[6]*y[5]-
- z[5]*z[5]*x[4]*y[0];
+ +z[4]*y[6]*x[7]*z[5]+x[5]*y[4]*z[6]*z[6]+z[6]*z[6]*x[4]*y[7]-z[6]*z[6]*x[7]*y
+ [4]-2.0*z[6]*z[6]*x[7]*y[5]+2.0*z[6]*z[6]*x[5]*y[7]-y[5]*x[4]*z[6]*z[6]+2.0*z
+ [0]*z[0]*x[3]*y[4]-x[6]*y[5]*z[2]*z[2]+z[1]*z[1]*x[5]*y[6]-z[1]*z[1]*x[6]*y[5]-
+ z[5]*z[5]*x[4]*y[0];
s6 = s8+2.0*x[1]*y[3]*z[0]*z[0]+2.0*x[1]*y[6]*z[2]*z[2]-2.0*y[1]*x[6]*z
- [2]*z[2]-y[1]*x[5]*z[2]*z[2]-z[1]*z[1]*x[2]*y[6]-2.0*z[1]*z[1]*x[2]*y[5]+2.0*z
- [1]*z[1]*x[5]*y[2]+z[1]*y[1]*x[6]*z[5]+y[1]*x[2]*z[5]*z[5]+z[2]*z[1]*x[2]*y[0]+
- z[1]*x[1]*y[5]*z[6]-z[1]*x[1]*y[6]*z[5]-z[1]*y[1]*x[5]*z[6]-z[1]*x[2]*y[6]*z[5]
- +z[1]*x[6]*y[2]*z[5]+s7;
+ [2]*z[2]-y[1]*x[5]*z[2]*z[2]-z[1]*z[1]*x[2]*y[6]-2.0*z[1]*z[1]*x[2]*y[5]+2.0*z
+ [1]*z[1]*x[5]*y[2]+z[1]*y[1]*x[6]*z[5]+y[1]*x[2]*z[5]*z[5]+z[2]*z[1]*x[2]*y[0]+
+ z[1]*x[1]*y[5]*z[6]-z[1]*x[1]*y[6]*z[5]-z[1]*y[1]*x[5]*z[6]-z[1]*x[2]*y[6]*z[5]
+ +z[1]*x[6]*y[2]*z[5]+s7;
s8 = -x[1]*y[2]*z[5]*z[5]+z[1]*x[5]*y[6]*z[2]-2.0*z[2]*z[2]*x[3]*y[6]+2.0
- *z[2]*z[2]*x[6]*y[3]+z[2]*z[2]*x[7]*y[3]-z[2]*z[2]*x[3]*y[7]-z[1]*x[6]*y[5]*z
- [2]+2.0*z[1]*x[1]*y[5]*z[2]-2.0*x[3]*y[4]*z[7]*z[7]+2.0*x[4]*y[3]*z[7]*z[7]+x
- [5]*y[6]*z[2]*z[2]+y[1]*x[2]*z[6]*z[6]+y[0]*x[4]*z[7]*z[7]+z[2]*x[2]*y[3]*z[0]-
- x[1]*y[2]*z[6]*z[6];
+ *z[2]*z[2]*x[6]*y[3]+z[2]*z[2]*x[7]*y[3]-z[2]*z[2]*x[3]*y[7]-z[1]*x[6]*y[5]*z
+ [2]+2.0*z[1]*x[1]*y[5]*z[2]-2.0*x[3]*y[4]*z[7]*z[7]+2.0*x[4]*y[3]*z[7]*z[7]+x
+ [5]*y[6]*z[2]*z[2]+y[1]*x[2]*z[6]*z[6]+y[0]*x[4]*z[7]*z[7]+z[2]*x[2]*y[3]*z[0]-
+ x[1]*y[2]*z[6]*z[6];
s7 = s8-z[7]*z[2]*x[3]*y[7]+x[2]*y[6]*z[3]*z[3]-y[2]*x[6]*z[3]*z[3]-z[6]*
- x[2]*y[3]*z[7]-z[2]*z[1]*x[0]*y[2]+z[6]*z[2]*x[6]*y[3]-z[6]*z[2]*x[3]*y[6]+z[6]
- *x[2]*y[6]*z[3]+z[2]*x[1]*y[2]*z[0]+z[6]*y[2]*x[3]*z[7]-z[4]*z[5]*x[6]*y[4]+z
- [4]*z[5]*x[4]*y[6]-z[4]*y[6]*x[5]*z[7]+z[4]*z[6]*x[4]*y[7]+z[4]*x[5]*y[4]*z[6];
+ x[2]*y[3]*z[7]-z[2]*z[1]*x[0]*y[2]+z[6]*z[2]*x[6]*y[3]-z[6]*z[2]*x[3]*y[6]+z[6]
+ *x[2]*y[6]*z[3]+z[2]*x[1]*y[2]*z[0]+z[6]*y[2]*x[3]*z[7]-z[4]*z[5]*x[6]*y[4]+z
+ [4]*z[5]*x[4]*y[6]-z[4]*y[6]*x[5]*z[7]+z[4]*z[6]*x[4]*y[7]+z[4]*x[5]*y[4]*z[6];
s8 = -z[6]*y[2]*x[6]*z[3]-z[4]*y[5]*x[4]*z[6]-z[2]*y[1]*x[5]*z[6]+z[2]*x
- [1]*y[5]*z[6]+z[4]*x[6]*y[4]*z[7]+2.0*z[4]*z[5]*x[4]*y[7]-z[4]*z[6]*x[7]*y[4]+x
- [6]*y[7]*z[3]*z[3]-2.0*z[4]*z[5]*x[7]*y[4]-2.0*z[4]*y[5]*x[4]*z[7]-z[4]*y[6]*x
- [4]*z[7]+z[4]*x[6]*y[5]*z[7]-z[4]*x[6]*y[7]*z[5]+2.0*z[4]*x[5]*y[4]*z[7]+z[2]*x
- [2]*y[5]*z[6]-z[2]*x[2]*y[6]*z[5];
+ [1]*y[5]*z[6]+z[4]*x[6]*y[4]*z[7]+2.0*z[4]*z[5]*x[4]*y[7]-z[4]*z[6]*x[7]*y[4]+x
+ [6]*y[7]*z[3]*z[3]-2.0*z[4]*z[5]*x[7]*y[4]-2.0*z[4]*y[5]*x[4]*z[7]-z[4]*y[6]*x
+ [4]*z[7]+z[4]*x[6]*y[5]*z[7]-z[4]*x[6]*y[7]*z[5]+2.0*z[4]*x[5]*y[4]*z[7]+z[2]*x
+ [2]*y[5]*z[6]-z[2]*x[2]*y[6]*z[5];
s5 = s8+z[2]*x[6]*y[2]*z[5]-z[2]*x[5]*y[2]*z[6]-z[2]*x[2]*y[3]*z[7]-x[2]*
- y[3]*z[7]*z[7]+2.0*z[2]*x[2]*y[3]*z[1]-z[2]*y[2]*x[3]*z[0]+z[2]*y[2]*x[0]*z[3]-
- z[2]*x[2]*y[0]*z[3]-z[7]*y[2]*x[7]*z[3]+z[7]*z[2]*x[7]*y[3]+z[7]*x[2]*y[7]*z[3]
- +z[6]*y[1]*x[2]*z[5]-z[6]*x[1]*y[2]*z[5]+z[5]*x[1]*y[5]*z[2]+s6+s7;
+ y[3]*z[7]*z[7]+2.0*z[2]*x[2]*y[3]*z[1]-z[2]*y[2]*x[3]*z[0]+z[2]*y[2]*x[0]*z[3]-
+ z[2]*x[2]*y[0]*z[3]-z[7]*y[2]*x[7]*z[3]+z[7]*z[2]*x[7]*y[3]+z[7]*x[2]*y[7]*z[3]
+ +z[6]*y[1]*x[2]*z[5]-z[6]*x[1]*y[2]*z[5]+z[5]*x[1]*y[5]*z[2]+s6+s7;
s8 = z[5]*z[1]*x[5]*y[2]-z[5]*z[1]*x[2]*y[5]-y[6]*x[7]*z[2]*z[2]+2.0*z[2]
- *x[2]*y[6]*z[3]-2.0*z[2]*x[2]*y[3]*z[6]+2.0*z[2]*y[2]*x[3]*z[6]+y[2]*x[3]*z[6]*
- z[6]+y[6]*x[7]*z[5]*z[5]+z[2]*y[2]*x[3]*z[7]-z[2]*y[2]*x[7]*z[3]-2.0*z[2]*y[2]*
- x[6]*z[3]+z[2]*x[2]*y[7]*z[3]+x[6]*y[2]*z[5]*z[5]-2.0*z[2]*x[2]*y[1]*z[3]-x[2]*
- y[6]*z[5]*z[5];
+ *x[2]*y[6]*z[3]-2.0*z[2]*x[2]*y[3]*z[6]+2.0*z[2]*y[2]*x[3]*z[6]+y[2]*x[3]*z[6]*
+ z[6]+y[6]*x[7]*z[5]*z[5]+z[2]*y[2]*x[3]*z[7]-z[2]*y[2]*x[7]*z[3]-2.0*z[2]*y[2]*
+ x[6]*z[3]+z[2]*x[2]*y[7]*z[3]+x[6]*y[2]*z[5]*z[5]-2.0*z[2]*x[2]*y[1]*z[3]-x[2]*
+ y[6]*z[5]*z[5];
s7 = s8-y[1]*x[5]*z[6]*z[6]+z[6]*x[1]*y[6]*z[2]-z[3]*z[2]*x[3]*y[6]+z[6]*
- z[1]*x[6]*y[2]-z[6]*z[1]*x[2]*y[6]-z[6]*y[1]*x[6]*z[2]-2.0*x[5]*y[2]*z[6]*z[6]+
- z[4]*z[1]*x[0]*y[4]-z[3]*x[2]*y[3]*z[6]-z[5]*y[1]*x[5]*z[2]+z[3]*y[2]*x[3]*z[6]
- +2.0*x[2]*y[5]*z[6]*z[6]-z[5]*x[1]*y[5]*z[0]+y[2]*x[3]*z[7]*z[7]-x[2]*y[3]*z[6]
- *z[6];
+ z[1]*x[6]*y[2]-z[6]*z[1]*x[2]*y[6]-z[6]*y[1]*x[6]*z[2]-2.0*x[5]*y[2]*z[6]*z[6]+
+ z[4]*z[1]*x[0]*y[4]-z[3]*x[2]*y[3]*z[6]-z[5]*y[1]*x[5]*z[2]+z[3]*y[2]*x[3]*z[6]
+ +2.0*x[2]*y[5]*z[6]*z[6]-z[5]*x[1]*y[5]*z[0]+y[2]*x[3]*z[7]*z[7]-x[2]*y[3]*z[6]
+ *z[6];
s8 = z[5]*y[5]*x[4]*z[0]+z[3]*z[2]*x[6]*y[3]+x[1]*y[5]*z[6]*z[6]+z[5]*y
- [5]*x[7]*z[4]-z[1]*x[1]*y[2]*z[6]+z[1]*x[1]*y[6]*z[2]+2.0*z[6]*y[6]*x[7]*z[5]-z
- [7]*y[6]*x[7]*z[2]-z[3]*y[6]*x[7]*z[2]+x[6]*y[7]*z[2]*z[2]-2.0*z[6]*y[6]*x[7]*z
- [2]-2.0*x[6]*y[3]*z[7]*z[7]-x[6]*y[2]*z[7]*z[7]-z[5]*x[6]*y[5]*z[2]+y[6]*x[2]*z
- [7]*z[7];
+ [5]*x[7]*z[4]-z[1]*x[1]*y[2]*z[6]+z[1]*x[1]*y[6]*z[2]+2.0*z[6]*y[6]*x[7]*z[5]-z
+ [7]*y[6]*x[7]*z[2]-z[3]*y[6]*x[7]*z[2]+x[6]*y[7]*z[2]*z[2]-2.0*z[6]*y[6]*x[7]*z
+ [2]-2.0*x[6]*y[3]*z[7]*z[7]-x[6]*y[2]*z[7]*z[7]-z[5]*x[6]*y[5]*z[2]+y[6]*x[2]*z
+ [7]*z[7];
s6 = s8+2.0*y[6]*x[3]*z[7]*z[7]+z[6]*z[6]*x[7]*y[3]-y[6]*x[7]*z[3]*z[3]+z
- [5]*x[5]*y[0]*z[4]+2.0*z[6]*z[6]*x[7]*y[2]-2.0*z[6]*z[6]*x[2]*y[7]-z[6]*z[6]*x
- [3]*y[7]+z[7]*y[6]*x[7]*z[5]+z[7]*y[5]*x[7]*z[4]-2.0*z[7]*x[7]*y[3]*z[4]+2.0*z
- [7]*x[3]*y[7]*z[4]-2.0*z[7]*x[4]*y[7]*z[3]+2.0*z[7]*x[7]*y[4]*z[3]-z[7]*y[0]*x
- [7]*z[4]-2.0*z[7]*z[6]*x[3]*y[7]+s7;
+ [5]*x[5]*y[0]*z[4]+2.0*z[6]*z[6]*x[7]*y[2]-2.0*z[6]*z[6]*x[2]*y[7]-z[6]*z[6]*x
+ [3]*y[7]+z[7]*y[6]*x[7]*z[5]+z[7]*y[5]*x[7]*z[4]-2.0*z[7]*x[7]*y[3]*z[4]+2.0*z
+ [7]*x[3]*y[7]*z[4]-2.0*z[7]*x[4]*y[7]*z[3]+2.0*z[7]*x[7]*y[4]*z[3]-z[7]*y[0]*x
+ [7]*z[4]-2.0*z[7]*z[6]*x[3]*y[7]+s7;
s8 = s6+2.0*z[7]*z[6]*x[7]*y[3]+2.0*z[7]*x[6]*y[7]*z[3]+z[7]*x[6]*y[7]*z
- [2]-2.0*z[7]*y[6]*x[7]*z[3]+z[7]*z[6]*x[7]*y[2]-z[7]*z[6]*x[2]*y[7]+z[5]*y[1]*x
- [5]*z[0]-z[5]*z[1]*x[5]*y[0]+2.0*y[1]*x[6]*z[5]*z[5]-2.0*x[1]*y[6]*z[5]*z[5]+z
- [5]*z[1]*x[0]*y[5]+z[6]*y[6]*x[3]*z[7]+2.0*z[6]*x[6]*y[7]*z[2]-z[6]*y[6]*x[7]*z
- [3];
+ [2]-2.0*z[7]*y[6]*x[7]*z[3]+z[7]*z[6]*x[7]*y[2]-z[7]*z[6]*x[2]*y[7]+z[5]*y[1]*x
+ [5]*z[0]-z[5]*z[1]*x[5]*y[0]+2.0*y[1]*x[6]*z[5]*z[5]-2.0*x[1]*y[6]*z[5]*z[5]+z
+ [5]*z[1]*x[0]*y[5]+z[6]*y[6]*x[3]*z[7]+2.0*z[6]*x[6]*y[7]*z[2]-z[6]*y[6]*x[7]*z
+ [3];
s7 = s8+2.0*z[6]*y[6]*x[2]*z[7]-z[6]*x[6]*y[3]*z[7]+z[6]*x[6]*y[7]*z[3]
- -2.0*z[6]*x[6]*y[2]*z[7]-2.0*z[1]*y[1]*x[5]*z[2]-z[1]*y[1]*x[6]*z[2]-z[7]*z[0]*
- x[7]*y[3]-2.0*z[6]*x[6]*y[5]*z[2]-z[2]*z[6]*x[3]*y[7]+z[2]*x[6]*y[7]*z[3]-z[2]*
- z[6]*x[2]*y[7]+y[5]*x[6]*z[4]*z[4]+z[2]*y[6]*x[2]*z[7]+y[6]*x[7]*z[4]*z[4]+z[2]
- *z[6]*x[7]*y[2]-2.0*x[5]*y[7]*z[4]*z[4];
+ -2.0*z[6]*x[6]*y[2]*z[7]-2.0*z[1]*y[1]*x[5]*z[2]-z[1]*y[1]*x[6]*z[2]-z[7]*z[0]*
+ x[7]*y[3]-2.0*z[6]*x[6]*y[5]*z[2]-z[2]*z[6]*x[3]*y[7]+z[2]*x[6]*y[7]*z[3]-z[2]*
+ z[6]*x[2]*y[7]+y[5]*x[6]*z[4]*z[4]+z[2]*y[6]*x[2]*z[7]+y[6]*x[7]*z[4]*z[4]+z[2]
+ *z[6]*x[7]*y[2]-2.0*x[5]*y[7]*z[4]*z[4];
s8 = -x[6]*y[7]*z[4]*z[4]-z[5]*y[5]*x[0]*z[4]-z[2]*x[6]*y[2]*z[7]-x[5]*y
- [6]*z[4]*z[4]-2.0*z[5]*y[1]*x[5]*z[6]+2.0*z[5]*z[1]*x[5]*y[6]+2.0*z[5]*x[1]*y
- [5]*z[6]-2.0*z[5]*z[1]*x[6]*y[5]-z[5]*x[5]*y[2]*z[6]+z[5]*x[5]*y[6]*z[2]+z[5]*x
- [2]*y[5]*z[6]+z[5]*z[5]*x[4]*y[7]-y[5]*x[4]*z[7]*z[7]+x[5]*y[4]*z[7]*z[7]+z[6]*
- z[1]*x[5]*y[6]+z[6]*y[1]*x[6]*z[5];
+ [6]*z[4]*z[4]-2.0*z[5]*y[1]*x[5]*z[6]+2.0*z[5]*z[1]*x[5]*y[6]+2.0*z[5]*x[1]*y
+ [5]*z[6]-2.0*z[5]*z[1]*x[6]*y[5]-z[5]*x[5]*y[2]*z[6]+z[5]*x[5]*y[6]*z[2]+z[5]*x
+ [2]*y[5]*z[6]+z[5]*z[5]*x[4]*y[7]-y[5]*x[4]*z[7]*z[7]+x[5]*y[4]*z[7]*z[7]+z[6]*
+ z[1]*x[5]*y[6]+z[6]*y[1]*x[6]*z[5];
s4 = s8-z[6]*z[1]*x[6]*y[5]-z[6]*x[1]*y[6]*z[5]+z[2]*z[6]*x[7]*y[3]+2.0*z
- [6]*x[6]*y[2]*z[5]+2.0*z[6]*x[5]*y[6]*z[2]-2.0*z[6]*x[2]*y[6]*z[5]+z[7]*z[0]*x
- [3]*y[7]+z[7]*z[0]*x[7]*y[4]+z[3]*z[6]*x[7]*y[3]-z[3]*z[6]*x[3]*y[7]-z[3]*x[6]*
- y[3]*z[7]+z[3]*y[6]*x[2]*z[7]-z[3]*x[6]*y[2]*z[7]+z[5]*x[5]*y[4]*z[7]+s5+s7;
+ [6]*x[6]*y[2]*z[5]+2.0*z[6]*x[5]*y[6]*z[2]-2.0*z[6]*x[2]*y[6]*z[5]+z[7]*z[0]*x
+ [3]*y[7]+z[7]*z[0]*x[7]*y[4]+z[3]*z[6]*x[7]*y[3]-z[3]*z[6]*x[3]*y[7]-z[3]*x[6]*
+ y[3]*z[7]+z[3]*y[6]*x[2]*z[7]-z[3]*x[6]*y[2]*z[7]+z[5]*x[5]*y[4]*z[7]+s5+s7;
s8 = s4+z[3]*y[6]*x[3]*z[7]-z[7]*x[0]*y[7]*z[3]+z[6]*x[5]*y[4]*z[7]+z[7]*
- y[0]*x[7]*z[3]+z[5]*z[6]*x[4]*y[7]-2.0*z[5]*x[5]*y[6]*z[4]+2.0*z[5]*x[5]*y[4]*z
- [6]-z[5]*x[5]*y[7]*z[4]-z[5]*y[6]*x[5]*z[7]-z[5]*z[6]*x[7]*y[4]-z[7]*z[0]*x[4]*
- y[7]-z[5]*z[6]*x[7]*y[5]-z[5]*y[5]*x[4]*z[7]+z[7]*x[0]*y[7]*z[4];
+ y[0]*x[7]*z[3]+z[5]*z[6]*x[4]*y[7]-2.0*z[5]*x[5]*y[6]*z[4]+2.0*z[5]*x[5]*y[4]*z
+ [6]-z[5]*x[5]*y[7]*z[4]-z[5]*y[6]*x[5]*z[7]-z[5]*z[6]*x[7]*y[4]-z[7]*z[0]*x[4]*
+ y[7]-z[5]*z[6]*x[7]*y[5]-z[5]*y[5]*x[4]*z[7]+z[7]*x[0]*y[7]*z[4];
s7 = s8-2.0*z[5]*y[5]*x[4]*z[6]+z[5]*z[6]*x[5]*y[7]+z[5]*x[6]*y[5]*z[7]+
- 2.0*z[5]*y[5]*x[6]*z[4]+z[6]*z[5]*x[4]*y[6]-z[6]*x[5]*y[6]*z[4]-z[6]*z[5]*x[6]*
- y[4]-z[6]*x[6]*y[7]*z[4]-2.0*z[6]*y[6]*x[5]*z[7]+z[6]*x[6]*y[4]*z[7]-z[6]*y[5]*
- x[4]*z[7]-z[6]*y[6]*x[4]*z[7]+z[6]*y[6]*x[7]*z[4]+z[6]*y[5]*x[6]*z[4]+2.0*z[6]*
- x[6]*y[5]*z[7];
+ 2.0*z[5]*y[5]*x[6]*z[4]+z[6]*z[5]*x[4]*y[6]-z[6]*x[5]*y[6]*z[4]-z[6]*z[5]*x[6]*
+ y[4]-z[6]*x[6]*y[7]*z[4]-2.0*z[6]*y[6]*x[5]*z[7]+z[6]*x[6]*y[4]*z[7]-z[6]*y[5]*
+ x[4]*z[7]-z[6]*y[6]*x[4]*z[7]+z[6]*y[6]*x[7]*z[4]+z[6]*y[5]*x[6]*z[4]+2.0*z[6]*
+ x[6]*y[5]*z[7];
s8 = -2.0*z[6]*x[6]*y[7]*z[5]-z[2]*y[1]*x[2]*z[0]+2.0*z[7]*z[6]*x[4]*y[7]
- -2.0*z[7]*x[6]*y[7]*z[4]-2.0*z[7]*z[6]*x[7]*y[4]+z[7]*z[5]*x[4]*y[7]-z[7]*z[5]*
- x[7]*y[4]-z[7]*x[5]*y[7]*z[4]+2.0*z[7]*y[6]*x[7]*z[4]-z[7]*z[6]*x[7]*y[5]+z[7]*
- z[6]*x[5]*y[7]-z[7]*x[6]*y[7]*z[5]+z[1]*z[1]*x[6]*y[2]+s7+x[1]*y[5]*z[2]*z[2];
+ -2.0*z[7]*x[6]*y[7]*z[4]-2.0*z[7]*z[6]*x[7]*y[4]+z[7]*z[5]*x[4]*y[7]-z[7]*z[5]*
+ x[7]*y[4]-z[7]*x[5]*y[7]*z[4]+2.0*z[7]*y[6]*x[7]*z[4]-z[7]*z[6]*x[7]*y[5]+z[7]*
+ z[6]*x[5]*y[7]-z[7]*x[6]*y[7]*z[5]+z[1]*z[1]*x[6]*y[2]+s7+x[1]*y[5]*z[2]*z[2];
s6 = s8+2.0*z[2]*y[2]*x[1]*z[3]-2.0*z[2]*y[2]*x[3]*z[1]-2.0*x[1]*y[4]*z
- [0]*z[0]+2.0*y[1]*x[4]*z[0]*z[0]+2.0*x[2]*y[7]*z[3]*z[3]-2.0*y[2]*x[7]*z[3]*z
- [3]-x[1]*y[5]*z[0]*z[0]+z[0]*z[0]*x[7]*y[4]+z[0]*z[0]*x[3]*y[7]+x[2]*y[3]*z[0]*
- z[0]-2.0*y[1]*x[3]*z[0]*z[0]+y[5]*x[4]*z[0]*z[0]-2.0*z[0]*z[0]*x[4]*y[3]+x[1]*y
- [2]*z[0]*z[0]-z[0]*z[0]*x[4]*y[7]+y[1]*x[5]*z[0]*z[0];
+ [0]*z[0]+2.0*y[1]*x[4]*z[0]*z[0]+2.0*x[2]*y[7]*z[3]*z[3]-2.0*y[2]*x[7]*z[3]*z
+ [3]-x[1]*y[5]*z[0]*z[0]+z[0]*z[0]*x[7]*y[4]+z[0]*z[0]*x[3]*y[7]+x[2]*y[3]*z[0]*
+ z[0]-2.0*y[1]*x[3]*z[0]*z[0]+y[5]*x[4]*z[0]*z[0]-2.0*z[0]*z[0]*x[4]*y[3]+x[1]*y
+ [2]*z[0]*z[0]-z[0]*z[0]*x[4]*y[7]+y[1]*x[5]*z[0]*z[0];
s8 = s6-y[2]*x[3]*z[0]*z[0]+y[1]*x[0]*z[3]*z[3]-2.0*x[0]*y[7]*z[3]*z[3]-x
- [0]*y[4]*z[3]*z[3]-2.0*x[2]*y[0]*z[3]*z[3]-x[1]*y[0]*z[3]*z[3]+y[0]*x[4]*z[3]*z
- [3]-2.0*z[0]*y[1]*x[0]*z[4]+2.0*z[0]*z[1]*x[0]*y[4]+2.0*z[0]*x[1]*y[0]*z[4]-2.0
- *z[0]*z[1]*x[4]*y[0]-2.0*z[3]*x[2]*y[3]*z[7]-2.0*z[3]*z[2]*x[3]*y[7]+2.0*z[3]*z
- [2]*x[7]*y[3];
+ [0]*y[4]*z[3]*z[3]-2.0*x[2]*y[0]*z[3]*z[3]-x[1]*y[0]*z[3]*z[3]+y[0]*x[4]*z[3]*z
+ [3]-2.0*z[0]*y[1]*x[0]*z[4]+2.0*z[0]*z[1]*x[0]*y[4]+2.0*z[0]*x[1]*y[0]*z[4]-2.0
+ *z[0]*z[1]*x[4]*y[0]-2.0*z[3]*x[2]*y[3]*z[7]-2.0*z[3]*z[2]*x[3]*y[7]+2.0*z[3]*z
+ [2]*x[7]*y[3];
s7 = s8+2.0*z[3]*y[2]*x[3]*z[7]+2.0*z[5]*y[5]*x[4]*z[1]+2.0*z[0]*y[1]*x
- [0]*z[3]-z[0]*y[0]*x[3]*z[7]-2.0*z[0]*y[0]*x[3]*z[4]-z[0]*x[1]*y[0]*z[2]+z[0]*z
- [1]*x[2]*y[0]-z[0]*y[1]*x[0]*z[5]-z[0]*z[1]*x[0]*y[2]-z[0]*x[0]*y[7]*z[3]-2.0*z
- [0]*z[1]*x[0]*y[3]-z[5]*x[5]*y[4]*z[0]-2.0*z[0]*x[0]*y[4]*z[3]+z[0]*x[0]*y[7]*z
- [4]-z[0]*z[2]*x[0]*y[3];
+ [0]*z[3]-z[0]*y[0]*x[3]*z[7]-2.0*z[0]*y[0]*x[3]*z[4]-z[0]*x[1]*y[0]*z[2]+z[0]*z
+ [1]*x[2]*y[0]-z[0]*y[1]*x[0]*z[5]-z[0]*z[1]*x[0]*y[2]-z[0]*x[0]*y[7]*z[3]-2.0*z
+ [0]*z[1]*x[0]*y[3]-z[5]*x[5]*y[4]*z[0]-2.0*z[0]*x[0]*y[4]*z[3]+z[0]*x[0]*y[7]*z
+ [4]-z[0]*z[2]*x[0]*y[3];
s8 = s7+z[0]*x[5]*y[0]*z[4]+z[0]*z[1]*x[0]*y[5]-z[0]*x[2]*y[0]*z[3]-z[0]*
- z[1]*x[5]*y[0]-2.0*z[0]*x[1]*y[0]*z[3]+2.0*z[0]*y[0]*x[4]*z[3]-z[0]*x[0]*y[4]*z
- [7]+z[0]*x[1]*y[0]*z[5]+z[0]*y[0]*x[7]*z[3]+z[0]*y[2]*x[0]*z[3]-z[0]*y[5]*x[0]*
- z[4]+z[0]*z[2]*x[3]*y[0]+z[0]*x[2]*y[3]*z[1]+z[0]*x[0]*y[3]*z[7]-z[0]*x[2]*y[1]
- *z[3];
+ z[1]*x[5]*y[0]-2.0*z[0]*x[1]*y[0]*z[3]+2.0*z[0]*y[0]*x[4]*z[3]-z[0]*x[0]*y[4]*z
+ [7]+z[0]*x[1]*y[0]*z[5]+z[0]*y[0]*x[7]*z[3]+z[0]*y[2]*x[0]*z[3]-z[0]*y[5]*x[0]*
+ z[4]+z[0]*z[2]*x[3]*y[0]+z[0]*x[2]*y[3]*z[1]+z[0]*x[0]*y[3]*z[7]-z[0]*x[2]*y[1]
+ *z[3];
s5 = s8+z[0]*y[1]*x[0]*z[2]+z[3]*x[1]*y[3]*z[0]-2.0*z[3]*y[0]*x[3]*z[7]-z
- [3]*y[0]*x[3]*z[4]-z[3]*x[1]*y[0]*z[2]+z[3]*z[0]*x[7]*y[4]+2.0*z[3]*z[0]*x[3]*y
- [7]+2.0*z[3]*x[2]*y[3]*z[0]-z[3]*y[1]*x[3]*z[0]-z[3]*z[1]*x[0]*y[3]-z[3]*z[0]*x
- [4]*y[3]+z[3]*x[1]*y[2]*z[0]-z[3]*z[0]*x[4]*y[7]-2.0*z[3]*z[2]*x[0]*y[3]-z[3]*x
- [0]*y[4]*z[7]-2.0*z[3]*y[2]*x[3]*z[0];
+ [3]*y[0]*x[3]*z[4]-z[3]*x[1]*y[0]*z[2]+z[3]*z[0]*x[7]*y[4]+2.0*z[3]*z[0]*x[3]*y
+ [7]+2.0*z[3]*x[2]*y[3]*z[0]-z[3]*y[1]*x[3]*z[0]-z[3]*z[1]*x[0]*y[3]-z[3]*z[0]*x
+ [4]*y[3]+z[3]*x[1]*y[2]*z[0]-z[3]*z[0]*x[4]*y[7]-2.0*z[3]*z[2]*x[0]*y[3]-z[3]*x
+ [0]*y[4]*z[7]-2.0*z[3]*y[2]*x[3]*z[0];
s8 = s5+2.0*z[3]*z[2]*x[3]*y[0]+z[3]*x[2]*y[3]*z[1]+2.0*z[3]*x[0]*y[3]*z
- [7]+z[3]*y[1]*x[0]*z[2]-z[4]*y[0]*x[3]*z[7]-z[4]*x[1]*y[5]*z[0]-z[4]*y[1]*x[0]*
- z[5]+2.0*z[4]*z[0]*x[7]*y[4]+z[4]*z[0]*x[3]*y[7]+2.0*z[4]*y[5]*x[4]*z[0]+2.0*y
- [0]*x[7]*z[3]*z[3]+2.0*y[2]*x[0]*z[3]*z[3]-x[2]*y[1]*z[3]*z[3]-y[0]*x[3]*z[4]*z
- [4];
+ [7]+z[3]*y[1]*x[0]*z[2]-z[4]*y[0]*x[3]*z[7]-z[4]*x[1]*y[5]*z[0]-z[4]*y[1]*x[0]*
+ z[5]+2.0*z[4]*z[0]*x[7]*y[4]+z[4]*z[0]*x[3]*y[7]+2.0*z[4]*y[5]*x[4]*z[0]+2.0*y
+ [0]*x[7]*z[3]*z[3]+2.0*y[2]*x[0]*z[3]*z[3]-x[2]*y[1]*z[3]*z[3]-y[0]*x[3]*z[4]*z
+ [4];
s7 = s8-y[1]*x[0]*z[4]*z[4]+x[1]*y[0]*z[4]*z[4]+2.0*x[0]*y[7]*z[4]*z[4]+
- 2.0*x[5]*y[0]*z[4]*z[4]-2.0*y[5]*x[0]*z[4]*z[4]+2.0*z[1]*z[1]*x[2]*y[0]-2.0*z
- [1]*z[1]*x[0]*y[2]+z[1]*z[1]*x[0]*y[4]-z[1]*z[1]*x[0]*y[3]-z[1]*z[1]*x[4]*y[0]+
- 2.0*z[1]*z[1]*x[0]*y[5]-2.0*z[1]*z[1]*x[5]*y[0]+x[2]*y[3]*z[1]*z[1]-x[5]*y[4]*z
- [0]*z[0]-z[0]*z[0]*x[7]*y[3];
+ 2.0*x[5]*y[0]*z[4]*z[4]-2.0*y[5]*x[0]*z[4]*z[4]+2.0*z[1]*z[1]*x[2]*y[0]-2.0*z
+ [1]*z[1]*x[0]*y[2]+z[1]*z[1]*x[0]*y[4]-z[1]*z[1]*x[0]*y[3]-z[1]*z[1]*x[4]*y[0]+
+ 2.0*z[1]*z[1]*x[0]*y[5]-2.0*z[1]*z[1]*x[5]*y[0]+x[2]*y[3]*z[1]*z[1]-x[5]*y[4]*z
+ [0]*z[0]-z[0]*z[0]*x[7]*y[3];
s8 = s7+x[7]*y[4]*z[3]*z[3]-x[4]*y[7]*z[3]*z[3]+y[2]*x[1]*z[3]*z[3]+x[0]*
- y[3]*z[4]*z[4]-2.0*y[0]*x[7]*z[4]*z[4]+x[3]*y[7]*z[4]*z[4]-x[7]*y[3]*z[4]*z[4]-
- y[5]*x[1]*z[4]*z[4]+x[5]*y[1]*z[4]*z[4]+z[1]*z[1]*x[3]*y[0]+y[5]*x[4]*z[1]*z[1]
- -y[2]*x[3]*z[1]*z[1]-x[5]*y[4]*z[1]*z[1]-z[4]*x[0]*y[4]*z[3]-z[4]*z[0]*x[4]*y
- [3];
+ y[3]*z[4]*z[4]-2.0*y[0]*x[7]*z[4]*z[4]+x[3]*y[7]*z[4]*z[4]-x[7]*y[3]*z[4]*z[4]-
+ y[5]*x[1]*z[4]*z[4]+x[5]*y[1]*z[4]*z[4]+z[1]*z[1]*x[3]*y[0]+y[5]*x[4]*z[1]*z[1]
+ -y[2]*x[3]*z[1]*z[1]-x[5]*y[4]*z[1]*z[1]-z[4]*x[0]*y[4]*z[3]-z[4]*z[0]*x[4]*y
+ [3];
s6 = s8-z[4]*z[1]*x[4]*y[0]-2.0*z[4]*z[0]*x[4]*y[7]+z[4]*y[1]*x[5]*z[0]
- -2.0*z[5]*x[5]*y[4]*z[1]-z[4]*x[1]*y[4]*z[0]+z[4]*y[0]*x[4]*z[3]-2.0*z[4]*x[0]*
- y[4]*z[7]+z[4]*x[1]*y[0]*z[5]-2.0*z[1]*x[1]*y[2]*z[5]+z[4]*x[0]*y[3]*z[7]+2.0*z
- [5]*x[5]*y[1]*z[4]+z[4]*y[1]*x[4]*z[0]+z[1]*y[1]*x[0]*z[3]+z[1]*x[1]*y[3]*z[0]
- -2.0*z[1]*x[1]*y[5]*z[0]-2.0*z[1]*x[1]*y[0]*z[2];
+ -2.0*z[5]*x[5]*y[4]*z[1]-z[4]*x[1]*y[4]*z[0]+z[4]*y[0]*x[4]*z[3]-2.0*z[4]*x[0]*
+ y[4]*z[7]+z[4]*x[1]*y[0]*z[5]-2.0*z[1]*x[1]*y[2]*z[5]+z[4]*x[0]*y[3]*z[7]+2.0*z
+ [5]*x[5]*y[1]*z[4]+z[4]*y[1]*x[4]*z[0]+z[1]*y[1]*x[0]*z[3]+z[1]*x[1]*y[3]*z[0]
+ -2.0*z[1]*x[1]*y[5]*z[0]-2.0*z[1]*x[1]*y[0]*z[2];
s8 = s6-2.0*z[1]*y[1]*x[0]*z[5]-z[1]*y[1]*x[0]*z[4]+2.0*z[1]*y[1]*x[2]*z
- [5]-z[1]*y[1]*x[3]*z[0]-2.0*z[5]*y[5]*x[1]*z[4]+z[1]*y[5]*x[4]*z[0]+z[1]*x[1]*y
- [0]*z[4]+2.0*z[1]*x[1]*y[2]*z[0]-z[1]*z[2]*x[0]*y[3]+2.0*z[1]*y[1]*x[5]*z[0]-z
- [1]*x[1]*y[0]*z[3]-z[1]*x[1]*y[4]*z[0]+2.0*z[1]*x[1]*y[0]*z[5]-z[1]*y[2]*x[3]*z
- [0];
+ [5]-z[1]*y[1]*x[3]*z[0]-2.0*z[5]*y[5]*x[1]*z[4]+z[1]*y[5]*x[4]*z[0]+z[1]*x[1]*y
+ [0]*z[4]+2.0*z[1]*x[1]*y[2]*z[0]-z[1]*z[2]*x[0]*y[3]+2.0*z[1]*y[1]*x[5]*z[0]-z
+ [1]*x[1]*y[0]*z[3]-z[1]*x[1]*y[4]*z[0]+2.0*z[1]*x[1]*y[0]*z[5]-z[1]*y[2]*x[3]*z
+ [0];
s7 = s8+z[1]*z[2]*x[3]*y[0]-z[1]*x[2]*y[1]*z[3]+z[1]*y[1]*x[4]*z[0]+2.0*z
- [1]*y[1]*x[0]*z[2]+2.0*z[0]*z[1]*x[3]*y[0]+2.0*z[0]*x[0]*y[3]*z[4]+z[0]*z[5]*x
- [0]*y[4]+z[0]*y[0]*x[4]*z[7]-z[0]*y[0]*x[7]*z[4]-z[0]*x[7]*y[3]*z[4]-z[0]*z[5]*
- x[4]*y[0]-z[0]*x[5]*y[4]*z[1]+z[3]*z[1]*x[3]*y[0]+z[3]*x[0]*y[3]*z[4]+z[3]*z[0]
- *x[3]*y[4]+z[3]*y[0]*x[4]*z[7];
+ [1]*y[1]*x[0]*z[2]+2.0*z[0]*z[1]*x[3]*y[0]+2.0*z[0]*x[0]*y[3]*z[4]+z[0]*z[5]*x
+ [0]*y[4]+z[0]*y[0]*x[4]*z[7]-z[0]*y[0]*x[7]*z[4]-z[0]*x[7]*y[3]*z[4]-z[0]*z[5]*
+ x[4]*y[0]-z[0]*x[5]*y[4]*z[1]+z[3]*z[1]*x[3]*y[0]+z[3]*x[0]*y[3]*z[4]+z[3]*z[0]
+ *x[3]*y[4]+z[3]*y[0]*x[4]*z[7];
s8 = s7+z[3]*x[3]*y[7]*z[4]-z[3]*x[7]*y[3]*z[4]-z[3]*x[3]*y[4]*z[7]+z[3]*
- x[4]*y[3]*z[7]-z[3]*y[2]*x[3]*z[1]+z[3]*z[2]*x[3]*y[1]-z[3]*z[2]*x[1]*y[3]-2.0*
- z[3]*z[0]*x[7]*y[3]+z[4]*z[0]*x[3]*y[4]+2.0*z[4]*z[5]*x[0]*y[4]+2.0*z[4]*y[0]*x
- [4]*z[7]-2.0*z[4]*x[5]*y[4]*z[0]+z[4]*y[5]*x[4]*z[1]+z[4]*x[7]*y[4]*z[3]-z[4]*x
- [4]*y[7]*z[3];
+ x[4]*y[3]*z[7]-z[3]*y[2]*x[3]*z[1]+z[3]*z[2]*x[3]*y[1]-z[3]*z[2]*x[1]*y[3]-2.0*
+ z[3]*z[0]*x[7]*y[3]+z[4]*z[0]*x[3]*y[4]+2.0*z[4]*z[5]*x[0]*y[4]+2.0*z[4]*y[0]*x
+ [4]*z[7]-2.0*z[4]*x[5]*y[4]*z[0]+z[4]*y[5]*x[4]*z[1]+z[4]*x[7]*y[4]*z[3]-z[4]*x
+ [4]*y[7]*z[3];
s3 = s8-z[4]*x[3]*y[4]*z[7]+z[4]*x[4]*y[3]*z[7]-2.0*z[4]*z[5]*x[4]*y[0]-z
- [4]*x[5]*y[4]*z[1]+z[4]*z[5]*x[1]*y[4]-z[4]*z[5]*x[4]*y[1]-2.0*z[1]*y[1]*x[2]*z
- [0]+z[1]*z[5]*x[0]*y[4]-z[1]*z[5]*x[4]*y[0]-z[1]*y[5]*x[1]*z[4]+z[1]*x[5]*y[1]*
- z[4]+z[1]*z[5]*x[1]*y[4]-z[1]*z[5]*x[4]*y[1]+z[1]*z[2]*x[3]*y[1]-z[1]*z[2]*x[1]
- *y[3]+z[1]*y[2]*x[1]*z[3];
+ [4]*x[5]*y[4]*z[1]+z[4]*z[5]*x[1]*y[4]-z[4]*z[5]*x[4]*y[1]-2.0*z[1]*y[1]*x[2]*z
+ [0]+z[1]*z[5]*x[0]*y[4]-z[1]*z[5]*x[4]*y[0]-z[1]*y[5]*x[1]*z[4]+z[1]*x[5]*y[1]*
+ z[4]+z[1]*z[5]*x[1]*y[4]-z[1]*z[5]*x[4]*y[1]+z[1]*z[2]*x[3]*y[1]-z[1]*z[2]*x[1]
+ *y[3]+z[1]*y[2]*x[1]*z[3];
s8 = y[1]*x[0]*z[3]+x[1]*y[3]*z[0]-y[0]*x[3]*z[7]-x[1]*y[5]*z[0]-y[0]*x
- [3]*z[4]-x[1]*y[0]*z[2]+z[1]*x[2]*y[0]-y[1]*x[0]*z[5]-z[1]*x[0]*y[2]-y[1]*x[0]*
- z[4]+z[1]*x[5]*y[2]+z[0]*x[7]*y[4]+z[0]*x[3]*y[7]+z[1]*x[0]*y[4]-x[1]*y[2]*z[5]
- +x[2]*y[3]*z[0]+y[1]*x[2]*z[5]-x[2]*y[3]*z[7];
+ [3]*z[4]-x[1]*y[0]*z[2]+z[1]*x[2]*y[0]-y[1]*x[0]*z[5]-z[1]*x[0]*y[2]-y[1]*x[0]*
+ z[4]+z[1]*x[5]*y[2]+z[0]*x[7]*y[4]+z[0]*x[3]*y[7]+z[1]*x[0]*y[4]-x[1]*y[2]*z[5]
+ +x[2]*y[3]*z[0]+y[1]*x[2]*z[5]-x[2]*y[3]*z[7];
s7 = s8-z[1]*x[2]*y[5]-y[1]*x[3]*z[0]-x[0]*y[7]*z[3]-z[1]*x[0]*y[3]+y[5]*
- x[4]*z[0]-x[0]*y[4]*z[3]+y[5]*x[7]*z[4]-z[0]*x[4]*y[3]+x[1]*y[0]*z[4]-z[2]*x[3]
- *y[7]-y[6]*x[7]*z[2]+x[1]*y[5]*z[2]+y[6]*x[7]*z[5]+x[0]*y[7]*z[4]+x[1]*y[2]*z
- [0]-z[1]*x[4]*y[0]-z[0]*x[4]*y[7]-z[2]*x[0]*y[3];
+ x[4]*z[0]-x[0]*y[4]*z[3]+y[5]*x[7]*z[4]-z[0]*x[4]*y[3]+x[1]*y[0]*z[4]-z[2]*x[3]
+ *y[7]-y[6]*x[7]*z[2]+x[1]*y[5]*z[2]+y[6]*x[7]*z[5]+x[0]*y[7]*z[4]+x[1]*y[2]*z
+ [0]-z[1]*x[4]*y[0]-z[0]*x[4]*y[7]-z[2]*x[0]*y[3];
s8 = x[5]*y[0]*z[4]+z[1]*x[0]*y[5]-x[2]*y[0]*z[3]-z[1]*x[5]*y[0]+y[1]*x
- [5]*z[0]-x[1]*y[0]*z[3]-x[1]*y[4]*z[0]-y[1]*x[5]*z[2]+x[2]*y[7]*z[3]+y[0]*x[4]*
- z[3]-x[0]*y[4]*z[7]+x[1]*y[0]*z[5]-y[1]*x[6]*z[2]-y[2]*x[6]*z[3]+y[0]*x[7]*z[3]
- -y[2]*x[7]*z[3]+z[2]*x[7]*y[3]+y[2]*x[0]*z[3];
+ [5]*z[0]-x[1]*y[0]*z[3]-x[1]*y[4]*z[0]-y[1]*x[5]*z[2]+x[2]*y[7]*z[3]+y[0]*x[4]*
+ z[3]-x[0]*y[4]*z[7]+x[1]*y[0]*z[5]-y[1]*x[6]*z[2]-y[2]*x[6]*z[3]+y[0]*x[7]*z[3]
+ -y[2]*x[7]*z[3]+z[2]*x[7]*y[3]+y[2]*x[0]*z[3];
s6 = s8+y[2]*x[3]*z[7]-y[2]*x[3]*z[0]-x[6]*y[5]*z[2]-y[5]*x[0]*z[4]+z[2]*
- x[3]*y[0]+x[2]*y[3]*z[1]+x[0]*y[3]*z[7]-x[2]*y[1]*z[3]+y[1]*x[4]*z[0]+y[1]*x[0]
- *z[2]-z[1]*x[2]*y[6]+y[2]*x[3]*z[6]-y[1]*x[2]*z[0]+z[1]*x[3]*y[0]-x[1]*y[2]*z
- [6]-x[2]*y[3]*z[6]+x[0]*y[3]*z[4]+z[0]*x[3]*y[4]+s7;
+ x[3]*y[0]+x[2]*y[3]*z[1]+x[0]*y[3]*z[7]-x[2]*y[1]*z[3]+y[1]*x[4]*z[0]+y[1]*x[0]
+ *z[2]-z[1]*x[2]*y[6]+y[2]*x[3]*z[6]-y[1]*x[2]*z[0]+z[1]*x[3]*y[0]-x[1]*y[2]*z
+ [6]-x[2]*y[3]*z[6]+x[0]*y[3]*z[4]+z[0]*x[3]*y[4]+s7;
s8 = x[5]*y[4]*z[7]+s6+y[5]*x[6]*z[4]-y[5]*x[4]*z[6]+z[6]*x[5]*y[7]-x[6]*
- y[2]*z[7]-x[6]*y[7]*z[5]+x[5]*y[6]*z[2]+x[6]*y[5]*z[7]+x[6]*y[7]*z[2]+y[6]*x[7]
- *z[4]-y[6]*x[4]*z[7]-y[6]*x[7]*z[3]+z[6]*x[7]*y[2]+x[2]*y[5]*z[6]-x[2]*y[6]*z
- [5]+y[6]*x[2]*z[7]+x[6]*y[2]*z[5];
+ y[2]*z[7]-x[6]*y[7]*z[5]+x[5]*y[6]*z[2]+x[6]*y[5]*z[7]+x[6]*y[7]*z[2]+y[6]*x[7]
+ *z[4]-y[6]*x[4]*z[7]-y[6]*x[7]*z[3]+z[6]*x[7]*y[2]+x[2]*y[5]*z[6]-x[2]*y[6]*z
+ [5]+y[6]*x[2]*z[7]+x[6]*y[2]*z[5];
s7 = s8-x[5]*y[2]*z[6]-z[6]*x[7]*y[5]-z[5]*x[7]*y[4]+z[5]*x[0]*y[4]-y[5]*
- x[4]*z[7]+y[0]*x[4]*z[7]-z[6]*x[2]*y[7]-x[5]*y[4]*z[0]-x[5]*y[7]*z[4]-y[0]*x[7]
- *z[4]+y[5]*x[4]*z[1]-x[6]*y[7]*z[4]+x[7]*y[4]*z[3]-x[4]*y[7]*z[3]+x[3]*y[7]*z
- [4]-x[7]*y[3]*z[4]-x[6]*y[3]*z[7]+x[6]*y[4]*z[7];
+ x[4]*z[7]+y[0]*x[4]*z[7]-z[6]*x[2]*y[7]-x[5]*y[4]*z[0]-x[5]*y[7]*z[4]-y[0]*x[7]
+ *z[4]+y[5]*x[4]*z[1]-x[6]*y[7]*z[4]+x[7]*y[4]*z[3]-x[4]*y[7]*z[3]+x[3]*y[7]*z
+ [4]-x[7]*y[3]*z[4]-x[6]*y[3]*z[7]+x[6]*y[4]*z[7];
s8 = -x[3]*y[4]*z[7]+x[4]*y[3]*z[7]-z[6]*x[7]*y[4]-z[1]*x[6]*y[5]+x[6]*y
- [7]*z[3]-x[1]*y[6]*z[5]-y[1]*x[5]*z[6]+z[5]*x[4]*y[7]-z[5]*x[4]*y[0]+x[1]*y[5]*
- z[6]-y[6]*x[5]*z[7]-y[2]*x[3]*z[1]+z[1]*x[5]*y[6]-y[5]*x[1]*z[4]+z[6]*x[4]*y[7]
- +x[5]*y[1]*z[4]-x[5]*y[6]*z[4]+y[6]*x[3]*z[7]-x[5]*y[4]*z[1];
+ [7]*z[3]-x[1]*y[6]*z[5]-y[1]*x[5]*z[6]+z[5]*x[4]*y[7]-z[5]*x[4]*y[0]+x[1]*y[5]*
+ z[6]-y[6]*x[5]*z[7]-y[2]*x[3]*z[1]+z[1]*x[5]*y[6]-y[5]*x[1]*z[4]+z[6]*x[4]*y[7]
+ +x[5]*y[1]*z[4]-x[5]*y[6]*z[4]+y[6]*x[3]*z[7]-x[5]*y[4]*z[1];
s5 = s8+x[5]*y[4]*z[6]+z[5]*x[1]*y[4]+y[1]*x[6]*z[5]-z[6]*x[3]*y[7]+z[6]*
- x[7]*y[3]-z[5]*x[6]*y[4]-z[5]*x[4]*y[1]+z[5]*x[4]*y[6]+x[1]*y[6]*z[2]+x[2]*y[6]
- *z[3]+z[2]*x[6]*y[3]+z[1]*x[6]*y[2]+z[2]*x[3]*y[1]-z[2]*x[1]*y[3]-z[2]*x[3]*y
- [6]+y[2]*x[1]*z[3]+y[1]*x[2]*z[6]-z[0]*x[7]*y[3]+s7;
+ x[7]*y[3]-z[5]*x[6]*y[4]-z[5]*x[4]*y[1]+z[5]*x[4]*y[6]+x[1]*y[6]*z[2]+x[2]*y[6]
+ *z[3]+z[2]*x[6]*y[3]+z[1]*x[6]*y[2]+z[2]*x[3]*y[1]-z[2]*x[1]*y[3]-z[2]*x[3]*y
+ [6]+y[2]*x[1]*z[3]+y[1]*x[2]*z[6]-z[0]*x[7]*y[3]+s7;
s4 = 1/s5;
s2 = s3*s4;
const double unknown2 = s1*s2;
Point<spacedim>
barycenter (const TriaAccessor<structdim, dim, spacedim> &)
{
- // this function catches all the cases not
- // explicitly handled above
+ // this function catches all the cases not
+ // explicitly handled above
Assert (false, ExcNotImplemented());
return Point<spacedim>();
}
double
measure (const TriaAccessor<1, dim, spacedim> &accessor)
{
- // remember that we use (dim-)linear
- // mappings
+ // remember that we use (dim-)linear
+ // mappings
return std::sqrt((accessor.vertex(1)-accessor.vertex(0)).square());
}
double
measure (const TriaAccessor<2,2,2> &accessor)
{
- // the evaluation of the formulae
- // is a bit tricky when done dimension
- // independently, so we write this function
- // for 2D and 3D separately
+ // the evaluation of the formulae
+ // is a bit tricky when done dimension
+ // independently, so we write this function
+ // for 2D and 3D separately
/*
Get the computation of the measure by this little Maple script. We
use the blinear mapping of the unit quad to the real quad. However,
*/
const double x[4] = { accessor.vertex(0)(0),
- accessor.vertex(1)(0),
- accessor.vertex(2)(0),
- accessor.vertex(3)(0) };
+ accessor.vertex(1)(0),
+ accessor.vertex(2)(0),
+ accessor.vertex(3)(0) };
const double y[4] = { accessor.vertex(0)(1),
- accessor.vertex(1)(1),
- accessor.vertex(2)(1),
- accessor.vertex(3)(1) };
+ accessor.vertex(1)(1),
+ accessor.vertex(2)(1),
+ accessor.vertex(3)(1) };
return (-x[1]*y[0]+x[1]*y[3]+y[0]*x[2]+x[0]*y[1]-x[0]*y[2]-y[1]*x[3]-x[2]*y[3]+x[3]*y[2])/2;
}
vertex_indices[i] = accessor.vertex_index(i);
return GridTools::cell_measure<3>(accessor.get_triangulation().get_vertices(),
- vertex_indices);
+ vertex_indices);
}
double
measure (const TriaAccessor<structdim, dim, spacedim> &)
{
- // catch-all for all cases not explicitly
- // listed above
+ // catch-all for all cases not explicitly
+ // listed above
Assert (false, ExcNotImplemented());
return -1e10;
}
TriaAccessor<structdim, dim, spacedim>::
barycenter () const
{
- // call the function in the anonymous
- // namespace above
+ // call the function in the anonymous
+ // namespace above
return dealii::barycenter (*this);
}
TriaAccessor<structdim, dim, spacedim>::
measure () const
{
- // call the function in the anonymous
- // namespace above
+ // call the function in the anonymous
+ // namespace above
return dealii::measure (*this);
}
double TriaAccessor<2,2,2>::extent_in_direction(const unsigned int axis) const
{
const unsigned int lines[2][2] = {{2,3}, /// Lines along x-axis, see GeometryInfo
- {0,1}};/// Lines along y-axis
+ {0,1}};/// Lines along y-axis
Assert (axis < 2, ExcIndexRange (axis, 0, 2));
return std::max(this->line(lines[axis][0])->diameter(),
- this->line(lines[axis][1])->diameter());
+ this->line(lines[axis][1])->diameter());
}
template <>
double TriaAccessor<2,2,3>::extent_in_direction(const unsigned int axis) const
{
const unsigned int lines[2][2] = {{2,3}, /// Lines along x-axis, see GeometryInfo
- {0,1}};/// Lines along y-axis
+ {0,1}};/// Lines along y-axis
Assert (axis < 2, ExcIndexRange (axis, 0, 2));
return std::max(this->line(lines[axis][0])->diameter(),
- this->line(lines[axis][1])->diameter());
+ this->line(lines[axis][1])->diameter());
}
template <>
double TriaAccessor<3,3,3>::extent_in_direction(const unsigned int axis) const
{
- const unsigned int lines[3][4] = {{2,3,6,7}, /// Lines along x-axis, see GeometryInfo
- {0,1,4,5}, /// Lines along y-axis
- {8,9,10,11}}; /// Lines along z-axis
+ const unsigned int lines[3][4] = {{2,3,6,7}, /// Lines along x-axis, see GeometryInfo
+ {0,1,4,5}, /// Lines along y-axis
+ {8,9,10,11}}; /// Lines along z-axis
Assert (axis < 3, ExcIndexRange (axis, 0, 3));
double lengths[4] = { this->line(lines[axis][0])->diameter(),
- this->line(lines[axis][1])->diameter(),
- this->line(lines[axis][2])->diameter(),
- this->line(lines[axis][3])->diameter() };
+ this->line(lines[axis][1])->diameter(),
+ this->line(lines[axis][2])->diameter(),
+ this->line(lines[axis][3])->diameter() };
return std::max(std::max(lengths[0], lengths[1]),
- std::max(lengths[2], lengths[3]));
+ std::max(lengths[2], lengths[3]));
}
template <>
bool CellAccessor<2>::point_inside (const Point<2> &p) const
{
- // we check whether the point is
- // inside the cell by making sure
- // that it on the inner side of
- // each line defined by the faces,
- // i.e. for each of the four faces
- // we take the line that connects
- // the two vertices and subdivide
- // the whole domain by that in two
- // and check whether the point is
- // on the `cell-side' (rather than
- // the `out-side') of this line. if
- // the point is on the `cell-side'
- // for all four faces, it must be
- // inside the cell.
-
- // we want the faces in counter
- // clockwise orientation
+ // we check whether the point is
+ // inside the cell by making sure
+ // that it on the inner side of
+ // each line defined by the faces,
+ // i.e. for each of the four faces
+ // we take the line that connects
+ // the two vertices and subdivide
+ // the whole domain by that in two
+ // and check whether the point is
+ // on the `cell-side' (rather than
+ // the `out-side') of this line. if
+ // the point is on the `cell-side'
+ // for all four faces, it must be
+ // inside the cell.
+
+ // we want the faces in counter
+ // clockwise orientation
static const int direction[4]={-1,1,1,-1};
for (unsigned int f=0; f<4; ++f)
{
- // vector from the first vertex
- // of the line to the point
+ // vector from the first vertex
+ // of the line to the point
const Point<2> to_p = p-this->vertex(
- GeometryInfo<2>::face_to_cell_vertices(f,0));
- // vector describing the line
+ GeometryInfo<2>::face_to_cell_vertices(f,0));
+ // vector describing the line
const Point<2> face = direction[f]*(
- this->vertex(GeometryInfo<2>::face_to_cell_vertices(f,1)) -
- this->vertex(GeometryInfo<2>::face_to_cell_vertices(f,0)));
-
- // if we rotate the face vector
- // by 90 degrees to the left
- // (i.e. it points to the
- // inside) and take the scalar
- // product with the vector from
- // the vertex to the point,
- // then the point is in the
- // `cell-side' if the scalar
- // product is positive. if this
- // is not the case, we can be
- // sure that the point is
- // outside
+ this->vertex(GeometryInfo<2>::face_to_cell_vertices(f,1)) -
+ this->vertex(GeometryInfo<2>::face_to_cell_vertices(f,0)));
+
+ // if we rotate the face vector
+ // by 90 degrees to the left
+ // (i.e. it points to the
+ // inside) and take the scalar
+ // product with the vector from
+ // the vertex to the point,
+ // then the point is in the
+ // `cell-side' if the scalar
+ // product is positive. if this
+ // is not the case, we can be
+ // sure that the point is
+ // outside
if ((-face(1)*to_p(0)+face(0)*to_p(1))<0)
- return false;
+ return false;
};
- // if we arrived here, then the
- // point is inside for all four
- // faces, and thus inside
+ // if we arrived here, then the
+ // point is inside for all four
+ // faces, and thus inside
return true;
}
template <>
bool CellAccessor<3>::point_inside (const Point<3> &p) const
{
- // original implementation by Joerg
- // Weimar
+ // original implementation by Joerg
+ // Weimar
// we first eliminate points based
// on the maximum and minumum of
for (unsigned int v=1; v<GeometryInfo<dim>::vertices_per_cell; ++v)
for (unsigned int d=0; d<dim; ++d)
{
- maxp[d] = std::max (maxp[d],this->vertex(v)[d]);
- minp[d] = std::min (minp[d],this->vertex(v)[d]);
+ maxp[d] = std::max (maxp[d],this->vertex(v)[d]);
+ minp[d] = std::min (minp[d],this->vertex(v)[d]);
}
- // rule out points outside the
- // bounding box of this cell
+ // rule out points outside the
+ // bounding box of this cell
for (unsigned int d=0; d<dim; d++)
if ((p[d] < minp[d]) || (p[d] > maxp[d]))
return false;
- // now we need to check more
- // carefully: transform to the
- // unit cube
- // and check there.
+ // now we need to check more
+ // carefully: transform to the
+ // unit cube
+ // and check there.
const TriaRawIterator< CellAccessor<dim,spacedim> > cell_iterator (*this);
return (GeometryInfo<dim>::is_inside_unit_cell (
- StaticMappingQ1<dim,spacedim>::mapping.transform_real_to_unit_cell(cell_iterator, p)));
+ StaticMappingQ1<dim,spacedim>::mapping.transform_real_to_unit_cell(cell_iterator, p)));
}
/*------------------------ Functions: CellAccessor<dim,spacedim> -----------------------*/
- // For codim>0 we proceed as follows:
- // 1) project point onto manifold and
- // 2) transform to the unit cell with a Q1 mapping
- // 3) then check if inside unit cell
+ // For codim>0 we proceed as follows:
+ // 1) project point onto manifold and
+ // 2) transform to the unit cell with a Q1 mapping
+ // 3) then check if inside unit cell
template<int dim, int spacedim>
template<int dim_,int spacedim_ >
bool CellAccessor<dim,spacedim>::
switch (dim)
{
case 1:
- return at_boundary(0) || at_boundary(1);
+ return at_boundary(0) || at_boundary(1);
case 2:
- return (at_boundary(0) || at_boundary(1) ||
- at_boundary(2) || at_boundary(3));
+ return (at_boundary(0) || at_boundary(1) ||
+ at_boundary(2) || at_boundary(3));
case 3:
- return (at_boundary(0) || at_boundary(1) ||
- at_boundary(2) || at_boundary(3) ||
- at_boundary(4) || at_boundary(5));
+ return (at_boundary(0) || at_boundary(1) ||
+ at_boundary(2) || at_boundary(3) ||
+ at_boundary(4) || at_boundary(5));
default:
- Assert (false, ExcNotImplemented());
- return false;
+ Assert (false, ExcNotImplemented());
+ return false;
}
}
= new_direction_flag;
else
Assert (new_direction_flag == true,
- ExcMessage ("If dim==spacedim, direction flags are always true and "
- "can not be set to anything else."));
+ ExcMessage ("If dim==spacedim, direction flags are always true and "
+ "can not be set to anything else."));
}
template <int dim, int spacedim>
void CellAccessor<dim, spacedim>::set_neighbor (const unsigned int i,
- const TriaIterator<CellAccessor<dim, spacedim> > &pointer) const
+ const TriaIterator<CellAccessor<dim, spacedim> > &pointer) const
{
AssertIndexRange (i, GeometryInfo<dim>::faces_per_cell);
if (pointer.state() == IteratorState::valid)
{
this->tria->levels[this->present_level]->
- neighbors[this->present_index*GeometryInfo<dim>::faces_per_cell+i].first
- = pointer->present_level;
+ neighbors[this->present_index*GeometryInfo<dim>::faces_per_cell+i].first
+ = pointer->present_level;
this->tria->levels[this->present_level]->
- neighbors[this->present_index*GeometryInfo<dim>::faces_per_cell+i].second
- = pointer->present_index;
+ neighbors[this->present_index*GeometryInfo<dim>::faces_per_cell+i].second
+ = pointer->present_index;
}
else
{
this->tria->levels[this->present_level]->
- neighbors[this->present_index*GeometryInfo<dim>::faces_per_cell+i].first
- = -1;
+ neighbors[this->present_index*GeometryInfo<dim>::faces_per_cell+i].first
+ = -1;
this->tria->levels[this->present_level]->
- neighbors[this->present_index*GeometryInfo<dim>::faces_per_cell+i].second
- = -1;
+ neighbors[this->present_index*GeometryInfo<dim>::faces_per_cell+i].second
+ = -1;
};
}
{
AssertIndexRange (neighbor, GeometryInfo<dim>::faces_per_cell);
- // if we have a 1d mesh in 1d, we
- // can assume that the left
- // neighbor of the right neigbor is
- // the current cell. but that is an
- // invariant that isn't true if the
- // mesh is embedded in a higher
- // dimensional space, so we have to
- // fall back onto the generic code
- // below
+ // if we have a 1d mesh in 1d, we
+ // can assume that the left
+ // neighbor of the right neigbor is
+ // the current cell. but that is an
+ // invariant that isn't true if the
+ // mesh is embedded in a higher
+ // dimensional space, so we have to
+ // fall back onto the generic code
+ // below
if ((dim==1) && (spacedim==dim))
return GeometryInfo<dim>::opposite_face[neighbor];
const TriaIterator<CellAccessor<dim, spacedim> > neighbor_cell = this->neighbor(neighbor);
- // usually, on regular patches of
- // the grid, this cell is just on
- // the opposite side of the
- // neighbor that the neighbor is of
- // this cell. for example in 2d, if
- // we want to know the
- // neighbor_of_neighbor if
- // neighbor==1 (the right
- // neighbor), then we will get 3
- // (the left neighbor) in most
- // cases. look up this relationship
- // in the table provided by
- // GeometryInfo and try it
+ // usually, on regular patches of
+ // the grid, this cell is just on
+ // the opposite side of the
+ // neighbor that the neighbor is of
+ // this cell. for example in 2d, if
+ // we want to know the
+ // neighbor_of_neighbor if
+ // neighbor==1 (the right
+ // neighbor), then we will get 3
+ // (the left neighbor) in most
+ // cases. look up this relationship
+ // in the table provided by
+ // GeometryInfo and try it
const unsigned int this_face_index=face_index(neighbor);
const unsigned int neighbor_guess
if (neighbor_cell->face_index (neighbor_guess) == this_face_index)
return neighbor_guess;
else
- // if the guess was false, then
- // we need to loop over all
- // neighbors and find the number
- // the hard way
+ // if the guess was false, then
+ // we need to loop over all
+ // neighbors and find the number
+ // the hard way
{
for (unsigned int face_no=0; face_no<GeometryInfo<dim>::faces_per_cell; ++face_no)
- if (neighbor_cell->face_index (face_no) == this_face_index)
- return face_no;
-
- // running over all neighbors
- // faces we did not find the
- // present face. Thereby the
- // neighbor must be coarser
- // than the present
- // cell. Return an invalid
- // unsigned int in this case.
+ if (neighbor_cell->face_index (face_no) == this_face_index)
+ return face_no;
+
+ // running over all neighbors
+ // faces we did not find the
+ // present face. Thereby the
+ // neighbor must be coarser
+ // than the present
+ // cell. Return an invalid
+ // unsigned int in this case.
return numbers::invalid_unsigned_int;
}
}
{
const unsigned int n2=neighbor_of_neighbor_internal(neighbor);
Assert (n2!=numbers::invalid_unsigned_int,
- TriaAccessorExceptions::ExcNeighborIsCoarser());
+ TriaAccessorExceptions::ExcNeighborIsCoarser());
return n2;
}
CellAccessor<dim, spacedim>::neighbor_of_coarser_neighbor (const unsigned int neighbor) const
{
AssertIndexRange (neighbor, GeometryInfo<dim>::faces_per_cell);
- // make sure that the neighbor is
- // on a coarser level
+ // make sure that the neighbor is
+ // on a coarser level
Assert (neighbor_is_coarser(neighbor),
- TriaAccessorExceptions::ExcNeighborIsNotCoarser());
+ TriaAccessorExceptions::ExcNeighborIsNotCoarser());
switch (dim)
{
case 2:
{
- const int this_face_index=face_index(neighbor);
- const TriaIterator<CellAccessor<2,spacedim> > neighbor_cell = this->neighbor(neighbor);
-
- // usually, on regular patches of
- // the grid, this cell is just on
- // the opposite side of the
- // neighbor that the neighbor is of
- // this cell. for example in 2d, if
- // we want to know the
- // neighbor_of_neighbor if
- // neighbor==1 (the right
- // neighbor), then we will get 0
- // (the left neighbor) in most
- // cases. look up this relationship
- // in the table provided by
- // GeometryInfo and try it
- const unsigned int face_no_guess
- = GeometryInfo<2>::opposite_face[neighbor];
-
- const TriaIterator<TriaAccessor<1, 2, spacedim> > face_guess
- =neighbor_cell->face(face_no_guess);
-
- if (face_guess->has_children())
- for (unsigned int subface_no=0; subface_no<face_guess->n_children(); ++subface_no)
- if (face_guess->child_index(subface_no)==this_face_index)
- return std::make_pair (face_no_guess, subface_no);
-
- // if the guess was false, then
- // we need to loop over all faces
- // and subfaces and find the
- // number the hard way
- for (unsigned int face_no=0; face_no<GeometryInfo<2>::faces_per_cell; ++face_no)
- {
- if (face_no!=face_no_guess)
- {
- const TriaIterator<TriaAccessor<1, 2, spacedim> > face
- =neighbor_cell->face(face_no);
- if (face->has_children())
- for (unsigned int subface_no=0; subface_no<face->n_children(); ++subface_no)
- if (face->child_index(subface_no)==this_face_index)
- return std::make_pair (face_no, subface_no);
- }
- }
-
- // we should never get here,
- // since then we did not find
- // our way back...
- Assert (false, ExcInternalError());
- return std::make_pair (deal_II_numbers::invalid_unsigned_int,
- deal_II_numbers::invalid_unsigned_int);
+ const int this_face_index=face_index(neighbor);
+ const TriaIterator<CellAccessor<2,spacedim> > neighbor_cell = this->neighbor(neighbor);
+
+ // usually, on regular patches of
+ // the grid, this cell is just on
+ // the opposite side of the
+ // neighbor that the neighbor is of
+ // this cell. for example in 2d, if
+ // we want to know the
+ // neighbor_of_neighbor if
+ // neighbor==1 (the right
+ // neighbor), then we will get 0
+ // (the left neighbor) in most
+ // cases. look up this relationship
+ // in the table provided by
+ // GeometryInfo and try it
+ const unsigned int face_no_guess
+ = GeometryInfo<2>::opposite_face[neighbor];
+
+ const TriaIterator<TriaAccessor<1, 2, spacedim> > face_guess
+ =neighbor_cell->face(face_no_guess);
+
+ if (face_guess->has_children())
+ for (unsigned int subface_no=0; subface_no<face_guess->n_children(); ++subface_no)
+ if (face_guess->child_index(subface_no)==this_face_index)
+ return std::make_pair (face_no_guess, subface_no);
+
+ // if the guess was false, then
+ // we need to loop over all faces
+ // and subfaces and find the
+ // number the hard way
+ for (unsigned int face_no=0; face_no<GeometryInfo<2>::faces_per_cell; ++face_no)
+ {
+ if (face_no!=face_no_guess)
+ {
+ const TriaIterator<TriaAccessor<1, 2, spacedim> > face
+ =neighbor_cell->face(face_no);
+ if (face->has_children())
+ for (unsigned int subface_no=0; subface_no<face->n_children(); ++subface_no)
+ if (face->child_index(subface_no)==this_face_index)
+ return std::make_pair (face_no, subface_no);
+ }
+ }
+
+ // we should never get here,
+ // since then we did not find
+ // our way back...
+ Assert (false, ExcInternalError());
+ return std::make_pair (deal_II_numbers::invalid_unsigned_int,
+ deal_II_numbers::invalid_unsigned_int);
}
case 3:
{
- const int this_face_index=face_index(neighbor);
- const TriaIterator<CellAccessor<3, spacedim> >
- neighbor_cell = this->neighbor(neighbor);
-
- // usually, on regular patches of
- // the grid, this cell is just on
- // the opposite side of the
- // neighbor that the neighbor is of
- // this cell. for example in 2d, if
- // we want to know the
- // neighbor_of_neighbor if
- // neighbor==1 (the right
- // neighbor), then we will get 0
- // (the left neighbor) in most
- // cases. look up this relationship
- // in the table provided by
- // GeometryInfo and try it
- const unsigned int face_no_guess
- = GeometryInfo<3>::opposite_face[neighbor];
-
- const TriaIterator<TriaAccessor<3-1, 3, spacedim> > face_guess
- =neighbor_cell->face(face_no_guess);
-
- if (face_guess->has_children())
- for (unsigned int subface_no=0; subface_no<face_guess->n_children(); ++subface_no)
- if (face_guess->child_index(subface_no)==this_face_index)
- // call a helper function, that
- // translates the current subface
- // number to a subface number for
- // the current FaceRefineCase
- return std::make_pair (face_no_guess, translate_subface_no(face_guess, subface_no));
- else if (face_guess->child(subface_no)->has_children())
- for (unsigned int subsub_no=0; subsub_no<face_guess->child(subface_no)->n_children(); ++subsub_no)
- if (face_guess->child(subface_no)->child_index(subsub_no)==this_face_index)
- // call a helper function, that
- // translates the current subface
- // number and subsubface number to
- // a subface number for the current
- // FaceRefineCase
- return std::make_pair (face_no_guess, translate_subface_no(face_guess, subface_no, subsub_no));
-
-
-
- // if the guess was false, then
- // we need to loop over all faces
- // and subfaces and find the
- // number the hard way
- for (unsigned int face_no=0; face_no<GeometryInfo<3>::faces_per_cell; ++face_no)
- {
- if (face_no!=face_no_guess)
- {
- const TriaIterator<TriaAccessor<3-1, 3, spacedim> > face
- =neighbor_cell->face(face_no);
- if (face->has_children())
- for (unsigned int subface_no=0; subface_no<face->n_children(); ++subface_no)
- if (face->child_index(subface_no)==this_face_index)
- // call a helper function, that
- // translates the current subface
- // number to a subface number for
- // the current FaceRefineCase
- return std::make_pair (face_no, translate_subface_no(face, subface_no));
- else if (face->child(subface_no)->has_children())
- for (unsigned int subsub_no=0; subsub_no<face->child(subface_no)->n_children(); ++subsub_no)
- if (face->child(subface_no)->child_index(subsub_no)==this_face_index)
- // call a helper function, that
- // translates the current subface
- // number and subsubface number to
- // a subface number for the current
- // FaceRefineCase
- return std::make_pair (face_no, translate_subface_no(face, subface_no, subsub_no));
- }
- }
-
- // we should never get here,
- // since then we did not find
- // our way back...
- Assert (false, ExcInternalError());
- return std::make_pair (numbers::invalid_unsigned_int,
- numbers::invalid_unsigned_int);
+ const int this_face_index=face_index(neighbor);
+ const TriaIterator<CellAccessor<3, spacedim> >
+ neighbor_cell = this->neighbor(neighbor);
+
+ // usually, on regular patches of
+ // the grid, this cell is just on
+ // the opposite side of the
+ // neighbor that the neighbor is of
+ // this cell. for example in 2d, if
+ // we want to know the
+ // neighbor_of_neighbor if
+ // neighbor==1 (the right
+ // neighbor), then we will get 0
+ // (the left neighbor) in most
+ // cases. look up this relationship
+ // in the table provided by
+ // GeometryInfo and try it
+ const unsigned int face_no_guess
+ = GeometryInfo<3>::opposite_face[neighbor];
+
+ const TriaIterator<TriaAccessor<3-1, 3, spacedim> > face_guess
+ =neighbor_cell->face(face_no_guess);
+
+ if (face_guess->has_children())
+ for (unsigned int subface_no=0; subface_no<face_guess->n_children(); ++subface_no)
+ if (face_guess->child_index(subface_no)==this_face_index)
+ // call a helper function, that
+ // translates the current subface
+ // number to a subface number for
+ // the current FaceRefineCase
+ return std::make_pair (face_no_guess, translate_subface_no(face_guess, subface_no));
+ else if (face_guess->child(subface_no)->has_children())
+ for (unsigned int subsub_no=0; subsub_no<face_guess->child(subface_no)->n_children(); ++subsub_no)
+ if (face_guess->child(subface_no)->child_index(subsub_no)==this_face_index)
+ // call a helper function, that
+ // translates the current subface
+ // number and subsubface number to
+ // a subface number for the current
+ // FaceRefineCase
+ return std::make_pair (face_no_guess, translate_subface_no(face_guess, subface_no, subsub_no));
+
+
+
+ // if the guess was false, then
+ // we need to loop over all faces
+ // and subfaces and find the
+ // number the hard way
+ for (unsigned int face_no=0; face_no<GeometryInfo<3>::faces_per_cell; ++face_no)
+ {
+ if (face_no!=face_no_guess)
+ {
+ const TriaIterator<TriaAccessor<3-1, 3, spacedim> > face
+ =neighbor_cell->face(face_no);
+ if (face->has_children())
+ for (unsigned int subface_no=0; subface_no<face->n_children(); ++subface_no)
+ if (face->child_index(subface_no)==this_face_index)
+ // call a helper function, that
+ // translates the current subface
+ // number to a subface number for
+ // the current FaceRefineCase
+ return std::make_pair (face_no, translate_subface_no(face, subface_no));
+ else if (face->child(subface_no)->has_children())
+ for (unsigned int subsub_no=0; subsub_no<face->child(subface_no)->n_children(); ++subsub_no)
+ if (face->child(subface_no)->child_index(subsub_no)==this_face_index)
+ // call a helper function, that
+ // translates the current subface
+ // number and subsubface number to
+ // a subface number for the current
+ // FaceRefineCase
+ return std::make_pair (face_no, translate_subface_no(face, subface_no, subsub_no));
+ }
+ }
+
+ // we should never get here,
+ // since then we did not find
+ // our way back...
+ Assert (false, ExcInternalError());
+ return std::make_pair (numbers::invalid_unsigned_int,
+ numbers::invalid_unsigned_int);
}
default:
{
- Assert(false, ExcImpossibleInDim(1));
- return std::make_pair (numbers::invalid_unsigned_int,
- numbers::invalid_unsigned_int);
+ Assert(false, ExcImpossibleInDim(1));
+ return std::make_pair (numbers::invalid_unsigned_int,
+ numbers::invalid_unsigned_int);
}
}
}
{
Assert (this->used(), TriaAccessorExceptions::ExcCellNotUsed());
Assert (i<GeometryInfo<dim>::faces_per_cell,
- ExcIndexRange (i,0,GeometryInfo<dim>::faces_per_cell));
+ ExcIndexRange (i,0,GeometryInfo<dim>::faces_per_cell));
return (neighbor_index(i) == -1);
}
else
{
for (unsigned int l=0; l<GeometryInfo<dim>::lines_per_cell; ++l)
- if (this->line(l)->at_boundary())
- return true;
+ if (this->line(l)->at_boundary())
+ return true;
return false;
}
TriaIterator<CellAccessor<dim,spacedim> >
CellAccessor<dim, spacedim>::
neighbor_child_on_subface (const unsigned int face,
- const unsigned int subface) const
+ const unsigned int subface) const
{
Assert (!this->has_children(),
ExcMessage ("The present cell must not have children!"));
{
case 2:
{
- const unsigned int neighbor_neighbor
- = this->neighbor_of_neighbor (face);
- const unsigned int neighbor_child_index
- = GeometryInfo<dim>::child_cell_on_face(
- this->neighbor(face)->refinement_case(),neighbor_neighbor,subface);
-
- TriaIterator<CellAccessor<dim,spacedim> > sub_neighbor
- = this->neighbor(face)->child(neighbor_child_index);
- // the neighbors child can have children,
- // which are not further refined along the
- // face under consideration. as we are
- // normally interested in one of this
- // child's child, search for the right one.
- while(sub_neighbor->has_children())
- {
- Assert ((GeometryInfo<dim>::face_refinement_case(sub_neighbor->refinement_case(),
- neighbor_neighbor) ==
- RefinementCase<dim>::no_refinement),
- ExcInternalError());
- sub_neighbor = sub_neighbor->child(GeometryInfo<dim>::child_cell_on_face(
- sub_neighbor->refinement_case(),neighbor_neighbor,0));
-
- }
-
- return sub_neighbor;
+ const unsigned int neighbor_neighbor
+ = this->neighbor_of_neighbor (face);
+ const unsigned int neighbor_child_index
+ = GeometryInfo<dim>::child_cell_on_face(
+ this->neighbor(face)->refinement_case(),neighbor_neighbor,subface);
+
+ TriaIterator<CellAccessor<dim,spacedim> > sub_neighbor
+ = this->neighbor(face)->child(neighbor_child_index);
+ // the neighbors child can have children,
+ // which are not further refined along the
+ // face under consideration. as we are
+ // normally interested in one of this
+ // child's child, search for the right one.
+ while(sub_neighbor->has_children())
+ {
+ Assert ((GeometryInfo<dim>::face_refinement_case(sub_neighbor->refinement_case(),
+ neighbor_neighbor) ==
+ RefinementCase<dim>::no_refinement),
+ ExcInternalError());
+ sub_neighbor = sub_neighbor->child(GeometryInfo<dim>::child_cell_on_face(
+ sub_neighbor->refinement_case(),neighbor_neighbor,0));
+
+ }
+
+ return sub_neighbor;
}
case 3:
{
- // this function returns the neighbor's
- // child on a given face and
- // subface.
-
- // we have to consider one other aspect here:
- // The face might be refined
- // anisotropically. In this case, the subface
- // number refers to the following, where we
- // look at the face from the current cell,
- // thus the subfaces are in standard
- // orientation concerning the cell
- //
- // for isotropic refinement
- //
- // *---*---*
- // | 2 | 3 |
- // *---*---*
- // | 0 | 1 |
- // *---*---*
- //
- // for 2*anisotropic refinement
- // (first cut_y, then cut_x)
- //
- // *---*---*
- // | 2 | 3 |
- // *---*---*
- // | 0 | 1 |
- // *---*---*
- //
- // for 2*anisotropic refinement
- // (first cut_x, then cut_y)
- //
- // *---*---*
- // | 1 | 3 |
- // *---*---*
- // | 0 | 2 |
- // *---*---*
- //
- // for purely anisotropic refinement:
- //
- // *---*---* *-------*
- // | | | | 1 |
- // | 0 | 1 | or *-------*
- // | | | | 0 |
- // *---*---* *-------*
- //
- // for "mixed" refinement:
- //
- // *---*---* *---*---* *---*---* *-------*
- // | | 2 | | 1 | | | 1 | 2 | | 2 |
- // | 0 *---* or *---* 2 | or *---*---* or *---*---*
- // | | 1 | | 0 | | | 0 | | 0 | 1 |
- // *---*---* *---*---* *-------* *---*---*
-
- const typename Triangulation<3,spacedim>::face_iterator
- mother_face = this->face(face);
- const unsigned int total_children=mother_face->number_of_children();
- Assert (subface<total_children,ExcIndexRange(subface,0,total_children));
- Assert (total_children<=GeometryInfo<3>::max_children_per_face, ExcInternalError());
-
- unsigned int neighbor_neighbor;
- TriaIterator<CellAccessor<3,spacedim> > neighbor_child;
- const TriaIterator<CellAccessor<3,spacedim> > neighbor
- = this->neighbor(face);
-
-
- const RefinementCase<2> mother_face_ref_case
- = mother_face->refinement_case();
- if (mother_face_ref_case==RefinementCase<2>::cut_xy) // total_children==4
- {
- // this case is quite easy. we are sure,
- // that the neighbor is not coarser.
-
- // get the neighbor's number for the given
- // face and the neighbor
- neighbor_neighbor
- = this->neighbor_of_neighbor (face);
-
- // now use the info provided by GeometryInfo
- // to extract the neighbors child number
- const unsigned int neighbor_child_index
- = GeometryInfo<3>::child_cell_on_face(neighbor->refinement_case(),
- neighbor_neighbor, subface,
- neighbor->face_orientation(neighbor_neighbor),
- neighbor->face_flip(neighbor_neighbor),
- neighbor->face_rotation(neighbor_neighbor));
- neighbor_child = neighbor->child(neighbor_child_index);
-
- // make sure that the neighbor child cell we
- // have found shares the desired subface.
- Assert((this->face(face)->child(subface) ==
- neighbor_child->face(neighbor_neighbor)),
- ExcInternalError());
- }
- else //-> the face is refined anisotropically
- {
- // first of all, we have to find the
- // neighbor at one of the anisotropic
- // children of the
- // mother_face. determine, which of
- // these we need.
- unsigned int first_child_to_find;
- unsigned int neighbor_child_index;
- if (total_children==2)
- first_child_to_find=subface;
- else
- {
- first_child_to_find=subface/2;
- if (total_children==3 &&
- subface==1 &&
- !mother_face->child(0)->has_children())
- first_child_to_find=1;
- }
- if (neighbor_is_coarser(face))
- {
- std::pair<unsigned int, unsigned int> indices=neighbor_of_coarser_neighbor(face);
- neighbor_neighbor=indices.first;
-
-
- // we have to translate our
- // subface_index according to the
- // RefineCase and subface index of
- // the coarser face (our face is an
- // anisotropic child of the coarser
- // face), 'a' denotes our
- // subface_index 0 and 'b' denotes
- // our subface_index 1, whereas 0...3
- // denote isotropic subfaces of the
- // coarser face
- //
- // cut_x and coarser_subface_index=0
- //
- // *---*---*
- // |b=2| |
- // | | |
- // |a=0| |
- // *---*---*
- //
- // cut_x and coarser_subface_index=1
- //
- // *---*---*
- // | |b=3|
- // | | |
- // | |a=1|
- // *---*---*
- //
- // cut_y and coarser_subface_index=0
- //
- // *-------*
- // | |
- // *-------*
- // |a=0 b=1|
- // *-------*
- //
- // cut_y and coarser_subface_index=1
- //
- // *-------*
- // |a=2 b=3|
- // *-------*
- // | |
- // *-------*
- unsigned int iso_subface;
- if (neighbor->face(neighbor_neighbor)->refinement_case()==RefinementCase<2>::cut_x)
- iso_subface=2*first_child_to_find + indices.second;
- else
- {
- Assert(neighbor->face(neighbor_neighbor)->refinement_case()==RefinementCase<2>::cut_y,
- ExcInternalError());
- iso_subface=first_child_to_find + 2*indices.second;
- }
- neighbor_child_index
- = GeometryInfo<3>::child_cell_on_face(neighbor->refinement_case(),
- neighbor_neighbor,
- iso_subface,
- neighbor->face_orientation(neighbor_neighbor),
- neighbor->face_flip(neighbor_neighbor),
- neighbor->face_rotation(neighbor_neighbor));
- }
- else //neighbor is not coarser
- {
- neighbor_neighbor=neighbor_of_neighbor(face);
- neighbor_child_index
- = GeometryInfo<3>::child_cell_on_face(neighbor->refinement_case(),
- neighbor_neighbor,
- first_child_to_find,
- neighbor->face_orientation(neighbor_neighbor),
- neighbor->face_flip(neighbor_neighbor),
- neighbor->face_rotation(neighbor_neighbor),
- mother_face_ref_case);
- }
-
- neighbor_child=neighbor->child(neighbor_child_index);
- // it might be, that the neighbor_child
- // has children, which are not refined
- // along the given subface. go down that
- // list and deliver the last of those.
- while (neighbor_child->has_children() &&
- GeometryInfo<3>::face_refinement_case(neighbor_child->refinement_case(),
- neighbor_neighbor)
- == RefinementCase<2>::no_refinement)
- neighbor_child =
- neighbor_child->child(GeometryInfo<3>::
- child_cell_on_face(neighbor_child->refinement_case(),
- neighbor_neighbor,
- 0));
-
- // if there are two total subfaces, we
- // are finished. if there are four we
- // have to get a child of our current
- // neighbor_child. If there are three,
- // we have to check which of the two
- // possibilities applies.
- if (total_children==3)
- {
- if (mother_face->child(0)->has_children())
- {
- if (subface<2)
- neighbor_child =
- neighbor_child->child(GeometryInfo<3>::
- child_cell_on_face(neighbor_child->refinement_case(),
- neighbor_neighbor,subface,
- neighbor_child->face_orientation(neighbor_neighbor),
- neighbor_child->face_flip(neighbor_neighbor),
- neighbor_child->face_rotation(neighbor_neighbor),
- mother_face->child(0)->refinement_case()));
- }
- else
- {
- Assert(mother_face->child(1)->has_children(), ExcInternalError());
- if (subface>0)
- neighbor_child =
- neighbor_child->child(GeometryInfo<3>::
- child_cell_on_face(neighbor_child->refinement_case(),
- neighbor_neighbor,subface-1,
- neighbor_child->face_orientation(neighbor_neighbor),
- neighbor_child->face_flip(neighbor_neighbor),
- neighbor_child->face_rotation(neighbor_neighbor),
- mother_face->child(1)->refinement_case()));
- }
- }
- else if (total_children==4)
- {
- neighbor_child =
- neighbor_child->child(GeometryInfo<3>::
- child_cell_on_face(neighbor_child->refinement_case(),
- neighbor_neighbor,subface%2,
- neighbor_child->face_orientation(neighbor_neighbor),
- neighbor_child->face_flip(neighbor_neighbor),
- neighbor_child->face_rotation(neighbor_neighbor),
- mother_face->child(subface/2)->refinement_case()));
- }
- }
-
- // it might be, that the neighbor_child has
- // children, which are not refined along the
- // given subface. go down that list and
- // deliver the last of those.
- while (neighbor_child->has_children())
- neighbor_child
- = neighbor_child->child(GeometryInfo<3>::
- child_cell_on_face(neighbor_child->refinement_case(),
- neighbor_neighbor,
- 0));
+ // this function returns the neighbor's
+ // child on a given face and
+ // subface.
+
+ // we have to consider one other aspect here:
+ // The face might be refined
+ // anisotropically. In this case, the subface
+ // number refers to the following, where we
+ // look at the face from the current cell,
+ // thus the subfaces are in standard
+ // orientation concerning the cell
+ //
+ // for isotropic refinement
+ //
+ // *---*---*
+ // | 2 | 3 |
+ // *---*---*
+ // | 0 | 1 |
+ // *---*---*
+ //
+ // for 2*anisotropic refinement
+ // (first cut_y, then cut_x)
+ //
+ // *---*---*
+ // | 2 | 3 |
+ // *---*---*
+ // | 0 | 1 |
+ // *---*---*
+ //
+ // for 2*anisotropic refinement
+ // (first cut_x, then cut_y)
+ //
+ // *---*---*
+ // | 1 | 3 |
+ // *---*---*
+ // | 0 | 2 |
+ // *---*---*
+ //
+ // for purely anisotropic refinement:
+ //
+ // *---*---* *-------*
+ // | | | | 1 |
+ // | 0 | 1 | or *-------*
+ // | | | | 0 |
+ // *---*---* *-------*
+ //
+ // for "mixed" refinement:
+ //
+ // *---*---* *---*---* *---*---* *-------*
+ // | | 2 | | 1 | | | 1 | 2 | | 2 |
+ // | 0 *---* or *---* 2 | or *---*---* or *---*---*
+ // | | 1 | | 0 | | | 0 | | 0 | 1 |
+ // *---*---* *---*---* *-------* *---*---*
+
+ const typename Triangulation<3,spacedim>::face_iterator
+ mother_face = this->face(face);
+ const unsigned int total_children=mother_face->number_of_children();
+ Assert (subface<total_children,ExcIndexRange(subface,0,total_children));
+ Assert (total_children<=GeometryInfo<3>::max_children_per_face, ExcInternalError());
+
+ unsigned int neighbor_neighbor;
+ TriaIterator<CellAccessor<3,spacedim> > neighbor_child;
+ const TriaIterator<CellAccessor<3,spacedim> > neighbor
+ = this->neighbor(face);
+
+
+ const RefinementCase<2> mother_face_ref_case
+ = mother_face->refinement_case();
+ if (mother_face_ref_case==RefinementCase<2>::cut_xy) // total_children==4
+ {
+ // this case is quite easy. we are sure,
+ // that the neighbor is not coarser.
+
+ // get the neighbor's number for the given
+ // face and the neighbor
+ neighbor_neighbor
+ = this->neighbor_of_neighbor (face);
+
+ // now use the info provided by GeometryInfo
+ // to extract the neighbors child number
+ const unsigned int neighbor_child_index
+ = GeometryInfo<3>::child_cell_on_face(neighbor->refinement_case(),
+ neighbor_neighbor, subface,
+ neighbor->face_orientation(neighbor_neighbor),
+ neighbor->face_flip(neighbor_neighbor),
+ neighbor->face_rotation(neighbor_neighbor));
+ neighbor_child = neighbor->child(neighbor_child_index);
+
+ // make sure that the neighbor child cell we
+ // have found shares the desired subface.
+ Assert((this->face(face)->child(subface) ==
+ neighbor_child->face(neighbor_neighbor)),
+ ExcInternalError());
+ }
+ else //-> the face is refined anisotropically
+ {
+ // first of all, we have to find the
+ // neighbor at one of the anisotropic
+ // children of the
+ // mother_face. determine, which of
+ // these we need.
+ unsigned int first_child_to_find;
+ unsigned int neighbor_child_index;
+ if (total_children==2)
+ first_child_to_find=subface;
+ else
+ {
+ first_child_to_find=subface/2;
+ if (total_children==3 &&
+ subface==1 &&
+ !mother_face->child(0)->has_children())
+ first_child_to_find=1;
+ }
+ if (neighbor_is_coarser(face))
+ {
+ std::pair<unsigned int, unsigned int> indices=neighbor_of_coarser_neighbor(face);
+ neighbor_neighbor=indices.first;
+
+
+ // we have to translate our
+ // subface_index according to the
+ // RefineCase and subface index of
+ // the coarser face (our face is an
+ // anisotropic child of the coarser
+ // face), 'a' denotes our
+ // subface_index 0 and 'b' denotes
+ // our subface_index 1, whereas 0...3
+ // denote isotropic subfaces of the
+ // coarser face
+ //
+ // cut_x and coarser_subface_index=0
+ //
+ // *---*---*
+ // |b=2| |
+ // | | |
+ // |a=0| |
+ // *---*---*
+ //
+ // cut_x and coarser_subface_index=1
+ //
+ // *---*---*
+ // | |b=3|
+ // | | |
+ // | |a=1|
+ // *---*---*
+ //
+ // cut_y and coarser_subface_index=0
+ //
+ // *-------*
+ // | |
+ // *-------*
+ // |a=0 b=1|
+ // *-------*
+ //
+ // cut_y and coarser_subface_index=1
+ //
+ // *-------*
+ // |a=2 b=3|
+ // *-------*
+ // | |
+ // *-------*
+ unsigned int iso_subface;
+ if (neighbor->face(neighbor_neighbor)->refinement_case()==RefinementCase<2>::cut_x)
+ iso_subface=2*first_child_to_find + indices.second;
+ else
+ {
+ Assert(neighbor->face(neighbor_neighbor)->refinement_case()==RefinementCase<2>::cut_y,
+ ExcInternalError());
+ iso_subface=first_child_to_find + 2*indices.second;
+ }
+ neighbor_child_index
+ = GeometryInfo<3>::child_cell_on_face(neighbor->refinement_case(),
+ neighbor_neighbor,
+ iso_subface,
+ neighbor->face_orientation(neighbor_neighbor),
+ neighbor->face_flip(neighbor_neighbor),
+ neighbor->face_rotation(neighbor_neighbor));
+ }
+ else //neighbor is not coarser
+ {
+ neighbor_neighbor=neighbor_of_neighbor(face);
+ neighbor_child_index
+ = GeometryInfo<3>::child_cell_on_face(neighbor->refinement_case(),
+ neighbor_neighbor,
+ first_child_to_find,
+ neighbor->face_orientation(neighbor_neighbor),
+ neighbor->face_flip(neighbor_neighbor),
+ neighbor->face_rotation(neighbor_neighbor),
+ mother_face_ref_case);
+ }
+
+ neighbor_child=neighbor->child(neighbor_child_index);
+ // it might be, that the neighbor_child
+ // has children, which are not refined
+ // along the given subface. go down that
+ // list and deliver the last of those.
+ while (neighbor_child->has_children() &&
+ GeometryInfo<3>::face_refinement_case(neighbor_child->refinement_case(),
+ neighbor_neighbor)
+ == RefinementCase<2>::no_refinement)
+ neighbor_child =
+ neighbor_child->child(GeometryInfo<3>::
+ child_cell_on_face(neighbor_child->refinement_case(),
+ neighbor_neighbor,
+ 0));
+
+ // if there are two total subfaces, we
+ // are finished. if there are four we
+ // have to get a child of our current
+ // neighbor_child. If there are three,
+ // we have to check which of the two
+ // possibilities applies.
+ if (total_children==3)
+ {
+ if (mother_face->child(0)->has_children())
+ {
+ if (subface<2)
+ neighbor_child =
+ neighbor_child->child(GeometryInfo<3>::
+ child_cell_on_face(neighbor_child->refinement_case(),
+ neighbor_neighbor,subface,
+ neighbor_child->face_orientation(neighbor_neighbor),
+ neighbor_child->face_flip(neighbor_neighbor),
+ neighbor_child->face_rotation(neighbor_neighbor),
+ mother_face->child(0)->refinement_case()));
+ }
+ else
+ {
+ Assert(mother_face->child(1)->has_children(), ExcInternalError());
+ if (subface>0)
+ neighbor_child =
+ neighbor_child->child(GeometryInfo<3>::
+ child_cell_on_face(neighbor_child->refinement_case(),
+ neighbor_neighbor,subface-1,
+ neighbor_child->face_orientation(neighbor_neighbor),
+ neighbor_child->face_flip(neighbor_neighbor),
+ neighbor_child->face_rotation(neighbor_neighbor),
+ mother_face->child(1)->refinement_case()));
+ }
+ }
+ else if (total_children==4)
+ {
+ neighbor_child =
+ neighbor_child->child(GeometryInfo<3>::
+ child_cell_on_face(neighbor_child->refinement_case(),
+ neighbor_neighbor,subface%2,
+ neighbor_child->face_orientation(neighbor_neighbor),
+ neighbor_child->face_flip(neighbor_neighbor),
+ neighbor_child->face_rotation(neighbor_neighbor),
+ mother_face->child(subface/2)->refinement_case()));
+ }
+ }
+
+ // it might be, that the neighbor_child has
+ // children, which are not refined along the
+ // given subface. go down that list and
+ // deliver the last of those.
+ while (neighbor_child->has_children())
+ neighbor_child
+ = neighbor_child->child(GeometryInfo<3>::
+ child_cell_on_face(neighbor_child->refinement_case(),
+ neighbor_neighbor,
+ 0));
#ifdef DEBUG
- // check, whether the face neighbor_child
- // matches the requested subface
- typename Triangulation<3,spacedim>::face_iterator requested;
- switch (this->subface_case(face))
- {
- case internal::SubfaceCase<3>::case_x:
- case internal::SubfaceCase<3>::case_y:
- case internal::SubfaceCase<3>::case_xy:
- requested = mother_face->child(subface);
- break;
- case internal::SubfaceCase<3>::case_x1y2y:
- case internal::SubfaceCase<3>::case_y1x2x:
- requested = mother_face->child(subface/2)->child(subface%2);
- break;
-
- case internal::SubfaceCase<3>::case_x1y:
- case internal::SubfaceCase<3>::case_y1x:
- switch (subface)
- {
- case 0:
- case 1:
- requested = mother_face->child(0)->child(subface);
- break;
- case 2:
- requested = mother_face->child(1);
- break;
- default:
- Assert(false, ExcInternalError());
- }
- break;
- case internal::SubfaceCase<3>::case_x2y:
- case internal::SubfaceCase<3>::case_y2x:
- switch (subface)
- {
- case 0:
- requested=mother_face->child(0);
- break;
- case 1:
- case 2:
- requested=mother_face->child(1)->child(subface-1);
- break;
- default:
- Assert(false, ExcInternalError());
- }
- break;
- default:
- Assert(false, ExcInternalError());
- break;
- }
- Assert (requested==neighbor_child->face(neighbor_neighbor),
- ExcInternalError());
+ // check, whether the face neighbor_child
+ // matches the requested subface
+ typename Triangulation<3,spacedim>::face_iterator requested;
+ switch (this->subface_case(face))
+ {
+ case internal::SubfaceCase<3>::case_x:
+ case internal::SubfaceCase<3>::case_y:
+ case internal::SubfaceCase<3>::case_xy:
+ requested = mother_face->child(subface);
+ break;
+ case internal::SubfaceCase<3>::case_x1y2y:
+ case internal::SubfaceCase<3>::case_y1x2x:
+ requested = mother_face->child(subface/2)->child(subface%2);
+ break;
+
+ case internal::SubfaceCase<3>::case_x1y:
+ case internal::SubfaceCase<3>::case_y1x:
+ switch (subface)
+ {
+ case 0:
+ case 1:
+ requested = mother_face->child(0)->child(subface);
+ break;
+ case 2:
+ requested = mother_face->child(1);
+ break;
+ default:
+ Assert(false, ExcInternalError());
+ }
+ break;
+ case internal::SubfaceCase<3>::case_x2y:
+ case internal::SubfaceCase<3>::case_y2x:
+ switch (subface)
+ {
+ case 0:
+ requested=mother_face->child(0);
+ break;
+ case 1:
+ case 2:
+ requested=mother_face->child(1)->child(subface-1);
+ break;
+ default:
+ Assert(false, ExcInternalError());
+ }
+ break;
+ default:
+ Assert(false, ExcInternalError());
+ break;
+ }
+ Assert (requested==neighbor_child->face(neighbor_neighbor),
+ ExcInternalError());
#endif
- return neighbor_child;
+ return neighbor_child;
}
default:
- // 1d or more than 3d
- Assert (false, ExcNotImplemented());
- return TriaIterator<CellAccessor<dim,spacedim> >();
+ // 1d or more than 3d
+ Assert (false, ExcNotImplemented());
+ return TriaIterator<CellAccessor<dim,spacedim> >();
}
}
void
Boundary<dim, spacedim>::
get_intermediate_points_on_line (const typename Triangulation<dim, spacedim>::line_iterator &,
- std::vector<Point<spacedim> > &) const
+ std::vector<Point<spacedim> > &) const
{
Assert (false, ExcPureFunctionCalled());
}
void
Boundary<dim, spacedim>::
get_intermediate_points_on_quad (const typename Triangulation<dim, spacedim>::quad_iterator &,
- std::vector<Point<spacedim> > &) const
+ std::vector<Point<spacedim> > &) const
{
Assert (false, ExcPureFunctionCalled());
}
switch (dim)
{
case 2:
- return get_new_point_on_line (face);
+ return get_new_point_on_line (face);
case 3:
- return get_new_point_on_quad (face);
+ return get_new_point_on_quad (face);
}
return Point<spacedim>();
void
Boundary<dim,spacedim>::
get_intermediate_points_on_face (const typename Triangulation<dim,spacedim>::face_iterator &face,
- std::vector<Point<spacedim> > &points) const
+ std::vector<Point<spacedim> > &points) const
{
Assert (dim>1, ExcImpossibleInDim(dim));
switch (dim)
{
case 2:
- get_intermediate_points_on_line (face, points);
- break;
+ get_intermediate_points_on_line (face, points);
+ break;
case 3:
- get_intermediate_points_on_quad (face, points);
- break;
+ get_intermediate_points_on_quad (face, points);
+ break;
default:
- Assert (false, ExcNotImplemented());
+ Assert (false, ExcNotImplemented());
}
}
void
Boundary<1,1>::
get_intermediate_points_on_face (const Triangulation<1,1>::face_iterator &,
- std::vector<Point<1> > &) const
+ std::vector<Point<1> > &) const
{
Assert (false, ExcImpossibleInDim(1));
}
void
Boundary<1,2>::
get_intermediate_points_on_face (const Triangulation<1,2>::face_iterator &,
- std::vector<Point<2> > &) const
+ std::vector<Point<2> > &) const
{
Assert (false, ExcImpossibleInDim(1));
}
void
Boundary<1,3>::
get_intermediate_points_on_face (const Triangulation<1,3>::face_iterator &,
- std::vector<Point<3> > &) const
+ std::vector<Point<3> > &) const
{
Assert (false, ExcImpossibleInDim(1));
}
Tensor<1,spacedim>
Boundary<dim, spacedim>::
normal_vector (const typename Triangulation<dim, spacedim>::face_iterator &,
- const Point<spacedim> &) const
+ const Point<spacedim> &) const
{
Assert (false, ExcPureFunctionCalled());
return Tensor<1,spacedim>();
void
Boundary<dim, spacedim>::
get_normals_at_vertices (const typename Triangulation<dim, spacedim>::face_iterator &,
- FaceVertexNormals &) const
+ FaceVertexNormals &) const
{
Assert (false, ExcPureFunctionCalled());
}
Point<spacedim>
Boundary<dim, spacedim>::
project_to_surface (const typename Triangulation<dim, spacedim>::line_iterator &,
- const Point<spacedim> &trial_point) const
+ const Point<spacedim> &trial_point) const
{
if (spacedim <= 1)
return trial_point;
Point<spacedim>
Boundary<dim, spacedim>::
project_to_surface (const typename Triangulation<dim, spacedim>::quad_iterator &,
- const Point<spacedim> &trial_point) const
+ const Point<spacedim> &trial_point) const
{
if (spacedim <= 2)
return trial_point;
Point<spacedim>
Boundary<dim, spacedim>::
project_to_surface (const typename Triangulation<dim, spacedim>::hex_iterator &,
- const Point<spacedim> &trial_point) const
+ const Point<spacedim> &trial_point) const
{
if (spacedim <= 3)
return trial_point;
namespace
{
- // compute the new midpoint of a quad --
- // either of a 2d cell on a manifold in 3d
- // or of a face of a 3d triangulation in 3d
+ // compute the new midpoint of a quad --
+ // either of a 2d cell on a manifold in 3d
+ // or of a face of a 3d triangulation in 3d
template <int dim>
Point<3>
compute_new_point_on_quad (const typename Triangulation<dim, 3>::quad_iterator &quad)
{
- // generate a new point in the middle of
- // the face based on the points on the
- // edges and the vertices.
- //
- // there is a pathological situation when
- // this face is on a straight boundary, but
- // one of its edges and the face behind it
- // are not; if that face is refined first,
- // the new point in the middle of that edge
- // may not be at the same position as
- // quad->line(.)->center() would have been,
- // but would have been moved to the
- // non-straight boundary. We cater to that
- // situation by using existing edge
- // midpoints if available, or center() if
- // not
- //
- // note that this situation can not happen
- // during mesh refinement, as there the
- // edges are refined first and only then
- // the face. thus, the check whether a line
- // has children does not lead to the
- // situation where the new face midpoints
- // have different positions depending on
- // which of the two cells is refined first.
- //
- // the situation where the edges aren't
- // refined happens when a higher order
- // MappingQ requests the midpoint of a
- // face, though, and it is for these cases
- // that we need to have the check available
- //
- // note that the factor of 1/8 for each
- // of the 8 surrounding points isn't
- // chosen arbitrarily. rather, we may ask
- // where the harmonic map would place the
- // point (0,0) if we map the square
- // [-1,1]^2 onto the domain that is
- // described using the 4 vertices and 4
- // edge point points of this quad. we can
- // then discretize the harmonic map using
- // four cells and Q1 elements on each of
- // the quadrants of the square [-1,1]^2
- // and see where the midpoint would land
- // (this is the procedure we choose, for
- // example, in
- // GridGenerator::laplace_solve) and it
- // turns out that it will land at the
- // mean of the 8 surrounding
- // points. whether a discretization of
- // the harmonic map with only 4 cells is
- // adequate is a different question
- // altogether, of course.
+ // generate a new point in the middle of
+ // the face based on the points on the
+ // edges and the vertices.
+ //
+ // there is a pathological situation when
+ // this face is on a straight boundary, but
+ // one of its edges and the face behind it
+ // are not; if that face is refined first,
+ // the new point in the middle of that edge
+ // may not be at the same position as
+ // quad->line(.)->center() would have been,
+ // but would have been moved to the
+ // non-straight boundary. We cater to that
+ // situation by using existing edge
+ // midpoints if available, or center() if
+ // not
+ //
+ // note that this situation can not happen
+ // during mesh refinement, as there the
+ // edges are refined first and only then
+ // the face. thus, the check whether a line
+ // has children does not lead to the
+ // situation where the new face midpoints
+ // have different positions depending on
+ // which of the two cells is refined first.
+ //
+ // the situation where the edges aren't
+ // refined happens when a higher order
+ // MappingQ requests the midpoint of a
+ // face, though, and it is for these cases
+ // that we need to have the check available
+ //
+ // note that the factor of 1/8 for each
+ // of the 8 surrounding points isn't
+ // chosen arbitrarily. rather, we may ask
+ // where the harmonic map would place the
+ // point (0,0) if we map the square
+ // [-1,1]^2 onto the domain that is
+ // described using the 4 vertices and 4
+ // edge point points of this quad. we can
+ // then discretize the harmonic map using
+ // four cells and Q1 elements on each of
+ // the quadrants of the square [-1,1]^2
+ // and see where the midpoint would land
+ // (this is the procedure we choose, for
+ // example, in
+ // GridGenerator::laplace_solve) and it
+ // turns out that it will land at the
+ // mean of the 8 surrounding
+ // points. whether a discretization of
+ // the harmonic map with only 4 cells is
+ // adequate is a different question
+ // altogether, of course.
return (quad->vertex(0) + quad->vertex(1) +
- quad->vertex(2) + quad->vertex(3) +
- (quad->line(0)->has_children() ?
- quad->line(0)->child(0)->vertex(1) :
- quad->line(0)->center()) +
- (quad->line(1)->has_children() ?
- quad->line(1)->child(0)->vertex(1) :
- quad->line(1)->center()) +
- (quad->line(2)->has_children() ?
- quad->line(2)->child(0)->vertex(1) :
- quad->line(2)->center()) +
- (quad->line(3)->has_children() ?
- quad->line(3)->child(0)->vertex(1) :
- quad->line(3)->center()) ) / 8;
+ quad->vertex(2) + quad->vertex(3) +
+ (quad->line(0)->has_children() ?
+ quad->line(0)->child(0)->vertex(1) :
+ quad->line(0)->center()) +
+ (quad->line(1)->has_children() ?
+ quad->line(1)->child(0)->vertex(1) :
+ quad->line(1)->center()) +
+ (quad->line(2)->has_children() ?
+ quad->line(2)->child(0)->vertex(1) :
+ quad->line(2)->center()) +
+ (quad->line(3)->has_children() ?
+ quad->line(3)->child(0)->vertex(1) :
+ quad->line(3)->center()) ) / 8;
}
}
void
StraightBoundary<1>::
get_intermediate_points_on_line (const Triangulation<1>::line_iterator &,
- std::vector<Point<1> > &) const
+ std::vector<Point<1> > &) const
{
Assert(false, ExcImpossibleInDim(1));
}
void
StraightBoundary<1, 2>::
get_intermediate_points_on_line (const Triangulation<1, 2>::line_iterator &line,
- std::vector<Point<2> > &points) const
+ std::vector<Point<2> > &points) const
{
const unsigned int spacedim = 2;
const unsigned int n=points.size();
double x=dx;
const Point<spacedim> vertices[2] = { line->vertex(0),
- line->vertex(1) };
+ line->vertex(1) };
for (unsigned int i=0; i<n; ++i, x+=dx)
points[i] = (1-x)*vertices[0] + x*vertices[1];
void
StraightBoundary<dim, spacedim>::
get_intermediate_points_on_line (const typename Triangulation<dim, spacedim>::line_iterator &line,
- std::vector<Point<spacedim> > &points) const
+ std::vector<Point<spacedim> > &points) const
{
const unsigned int n=points.size();
Assert(n>0, ExcInternalError());
double x=dx;
const Point<spacedim> vertices[2] = { line->vertex(0),
- line->vertex(1) };
+ line->vertex(1) };
for (unsigned int i=0; i<n; ++i, x+=dx)
points[i] = (1-x)*vertices[0] + x*vertices[1];
void
StraightBoundary<dim, spacedim>::
get_intermediate_points_on_quad (const typename Triangulation<dim, spacedim>::quad_iterator &,
- std::vector<Point<spacedim> > &) const
+ std::vector<Point<spacedim> > &) const
{
Assert(false, ExcImpossibleInDim(dim));
}
void
StraightBoundary<3>::
get_intermediate_points_on_quad (const Triangulation<3>::quad_iterator &quad,
- std::vector<Point<3> > &points) const
+ std::vector<Point<3> > &points) const
{
const unsigned int spacedim = 3;
const unsigned int n=points.size(),
- m=static_cast<unsigned int>(std::sqrt(static_cast<double>(n)));
- // is n a square number
+ m=static_cast<unsigned int>(std::sqrt(static_cast<double>(n)));
+ // is n a square number
Assert(m*m==n, ExcInternalError());
const double ds=1./(m+1);
double y=ds;
const Point<spacedim> vertices[4] = { quad->vertex(0),
- quad->vertex(1),
- quad->vertex(2),
- quad->vertex(3) };
+ quad->vertex(1),
+ quad->vertex(2),
+ quad->vertex(3) };
for (unsigned int i=0; i<m; ++i, y+=ds)
{
double x=ds;
for (unsigned int j=0; j<m; ++j, x+=ds)
- points[i*m+j]=((1-x) * vertices[0] +
- x * vertices[1]) * (1-y) +
- ((1-x) * vertices[2] +
- x * vertices[3]) * y;
+ points[i*m+j]=((1-x) * vertices[0] +
+ x * vertices[1]) * (1-y) +
+ ((1-x) * vertices[2] +
+ x * vertices[3]) * y;
}
}
void
StraightBoundary<2,3>::
get_intermediate_points_on_quad (const Triangulation<2,3>::quad_iterator &quad,
- std::vector<Point<3> > &points) const
+ std::vector<Point<3> > &points) const
{
const unsigned int spacedim = 3;
const unsigned int n=points.size(),
- m=static_cast<unsigned int>(std::sqrt(static_cast<double>(n)));
- // is n a square number
+ m=static_cast<unsigned int>(std::sqrt(static_cast<double>(n)));
+ // is n a square number
Assert(m*m==n, ExcInternalError());
const double ds=1./(m+1);
double y=ds;
const Point<spacedim> vertices[4] = { quad->vertex(0),
- quad->vertex(1),
- quad->vertex(2),
- quad->vertex(3) };
+ quad->vertex(1),
+ quad->vertex(2),
+ quad->vertex(3) };
for (unsigned int i=0; i<m; ++i, y+=ds)
{
double x=ds;
for (unsigned int j=0; j<m; ++j, x+=ds)
- points[i*m+j]=((1-x) * vertices[0] +
- x * vertices[1]) * (1-y) +
- ((1-x) * vertices[2] +
- x * vertices[3]) * y;
+ points[i*m+j]=((1-x) * vertices[0] +
+ x * vertices[1]) * (1-y) +
+ ((1-x) * vertices[2] +
+ x * vertices[3]) * y;
}
}
Tensor<1,1>
StraightBoundary<1,1>::
normal_vector (const Triangulation<1,1>::face_iterator &,
- const Point<1> &) const
+ const Point<1> &) const
{
Assert (false, ExcNotImplemented());
return Tensor<1,1>();
Tensor<1,2>
StraightBoundary<1,2>::
normal_vector (const Triangulation<1,2>::face_iterator &,
- const Point<2> &) const
+ const Point<2> &) const
{
Assert (false, ExcNotImplemented());
return Tensor<1,2>();
Tensor<1,3>
StraightBoundary<1,3>::
normal_vector (const Triangulation<1,3>::face_iterator &,
- const Point<3> &) const
+ const Point<3> &) const
{
Assert (false, ExcNotImplemented());
return Tensor<1,3>();
Tensor<1,spacedim>
StraightBoundary<dim,spacedim>::
normal_vector (const typename Triangulation<dim,spacedim>::face_iterator &face,
- const Point<spacedim> &p) const
+ const Point<spacedim> &p) const
{
// I don't think the implementation below will work when dim!=spacedim;
// in fact, I believe that we don't even have enough information here,
{
grad_F[i] = 0;
for (unsigned int v=0; v<GeometryInfo<facedim>::vertices_per_cell; ++v)
- grad_F[i] += face->vertex(v) * linear_fe.shape_grad(v, xi)[i];
+ grad_F[i] += face->vertex(v) * linear_fe.shape_grad(v, xi)[i];
}
Tensor<1,facedim> J;
Tensor<2,facedim> H;
for (unsigned int i=0; i<facedim; ++i)
for (unsigned int j=0; j<facedim; ++j)
- for (unsigned int k=0; k<spacedim; ++k)
+ for (unsigned int k=0; k<spacedim; ++k)
H[i][j] += grad_F[i][k] * grad_F[j][k];
const Point<facedim> delta_xi = -invert(H) * J;
void
StraightBoundary<1>::
get_normals_at_vertices (const Triangulation<1>::face_iterator &,
- Boundary<1,1>::FaceVertexNormals &) const
+ Boundary<1,1>::FaceVertexNormals &) const
{
Assert (false, ExcImpossibleInDim(1));
}
void
StraightBoundary<1,2>::
get_normals_at_vertices (const Triangulation<1,2>::face_iterator &,
- Boundary<1,2>::FaceVertexNormals &) const
+ Boundary<1,2>::FaceVertexNormals &) const
{
Assert (false, ExcNotImplemented());
}
void
StraightBoundary<1,3>::
get_normals_at_vertices (const Triangulation<1,3>::face_iterator &,
- Boundary<1,3>::FaceVertexNormals &) const
+ Boundary<1,3>::FaceVertexNormals &) const
{
Assert (false, ExcNotImplemented());
}
void
StraightBoundary<2>::
get_normals_at_vertices (const Triangulation<2>::face_iterator &face,
- Boundary<2,2>::FaceVertexNormals &face_vertex_normals) const
+ Boundary<2,2>::FaceVertexNormals &face_vertex_normals) const
{
const Tensor<1,2> tangent = face->vertex(1) - face->vertex(0);
for (unsigned int vertex=0; vertex<GeometryInfo<2>::vertices_per_face; ++vertex)
- // compute normals from tangent
+ // compute normals from tangent
face_vertex_normals[vertex] = Point<2>(tangent[1],
-tangent[0]);
}
void
StraightBoundary<2,3>::
get_normals_at_vertices (const Triangulation<2,3>::face_iterator &face,
- Boundary<2,3>::FaceVertexNormals &face_vertex_normals) const
+ Boundary<2,3>::FaceVertexNormals &face_vertex_normals) const
{
const Tensor<1,3> tangent = face->vertex(1) - face->vertex(0);
for (unsigned int vertex=0; vertex<GeometryInfo<2>::vertices_per_face; ++vertex)
- // compute normals from tangent
+ // compute normals from tangent
face_vertex_normals[vertex] = Point<3>(tangent[1],
-tangent[0],0);
Assert(false, ExcNotImplemented());
void
StraightBoundary<3>::
get_normals_at_vertices (const Triangulation<3>::face_iterator &face,
- Boundary<3>::FaceVertexNormals &face_vertex_normals) const
+ Boundary<3>::FaceVertexNormals &face_vertex_normals) const
{
const unsigned int vertices_per_face = GeometryInfo<3>::vertices_per_face;
{ {1,2},{3,0},{0,3},{2,1}};
for (unsigned int vertex=0; vertex<vertices_per_face; ++vertex)
{
- // first define the two tangent
- // vectors at the vertex by
- // using the two lines
- // radiating away from this
- // vertex
+ // first define the two tangent
+ // vectors at the vertex by
+ // using the two lines
+ // radiating away from this
+ // vertex
const Tensor<1,3> tangents[2]
- = { face->vertex(neighboring_vertices[vertex][0])
- - face->vertex(vertex),
- face->vertex(neighboring_vertices[vertex][1])
- - face->vertex(vertex) };
-
- // then compute the normal by
- // taking the cross
- // product. since the normal is
- // not required to be
- // normalized, no problem here
+ = { face->vertex(neighboring_vertices[vertex][0])
+ - face->vertex(vertex),
+ face->vertex(neighboring_vertices[vertex][1])
+ - face->vertex(vertex) };
+
+ // then compute the normal by
+ // taking the cross
+ // product. since the normal is
+ // not required to be
+ // normalized, no problem here
cross_product (face_vertex_normals[vertex],
- tangents[0], tangents[1]);
+ tangents[0], tangents[1]);
};
}
Point<spacedim>
StraightBoundary<dim, spacedim>::
project_to_surface (const typename Triangulation<dim, spacedim>::line_iterator &line,
- const Point<spacedim> &trial_point) const
+ const Point<spacedim> &trial_point) const
{
if (spacedim <= 1)
return trial_point;
else
{
- // find the point that lies on
- // the line p1--p2. the
- // formulas pan out to
- // something rather simple
- // because the mapping to the
- // line is linear
+ // find the point that lies on
+ // the line p1--p2. the
+ // formulas pan out to
+ // something rather simple
+ // because the mapping to the
+ // line is linear
const Point<spacedim> p1 = line->vertex(0),
- p2 = line->vertex(1);
+ p2 = line->vertex(1);
const double s = (trial_point-p1)*(p2-p1) / ((p2-p1)*(p2-p1));
return p1 + s*(p2-p1);
}
template <typename Iterator, int spacedim, int dim>
Point<spacedim>
compute_projection (const Iterator &object,
- const Point<spacedim> &y,
- internal::int2type<dim>)
+ const Point<spacedim> &y,
+ internal::int2type<dim>)
{
- // let's look at this for
- // simplicity for a quad (dim==2)
- // in a space with spacedim>2:
-
- // all points on the surface are given by
- // x(\xi) = sum_i v_i phi_x(\xi)
- // where v_i are the vertices of the quad,
- // and \xi=(\xi_1,\xi_2) are the reference
- // coordinates of the quad. so what we are
- // trying to do is find a point x on
- // the surface that is closest to the point
- // y. there are different ways
- // to solve this problem, but in the end
- // it's a nonlinear problem and we have to
- // find reference coordinates \xi so that
- // J(\xi) = 1/2 || x(\xi)-y ||^2
- // is minimal. x(\xi) is a function that
- // is dim-linear in \xi, so J(\xi) is
- // a polynomial of degree 2*dim that
- // we'd like to minimize. unless dim==1,
- // we'll have to use a Newton
- // method to find the
- // answer. This leads to the
- // following formulation of
- // Newton steps:
- //
- // Given \xi_k, find \delta\xi_k so that
- // H_k \delta\xi_k = - F_k
- // where H_k is an approximation to the
- // second derivatives of J at \xi_k, and
- // F_k is the first derivative of J.
- // We'll iterate this a number of times
- // until the right hand side is small
- // enough. As a stopping criterion, we
- // terminate if ||\delta\xi||<eps.
- //
- // As for the Hessian, the best choice
- // would be
- // H_k = J''(\xi_k)
- // but we'll opt for the simpler
- // Gauss-Newton form
- // H_k = A^T A
- // i.e.
- // (H_k)_{nm} = \sum_{i,j} v_i*v_j *
- // \partial_n phi_i *
- // \partial_m phi_j
- // we start at xi=(0.5,0.5).
+ // let's look at this for
+ // simplicity for a quad (dim==2)
+ // in a space with spacedim>2:
+
+ // all points on the surface are given by
+ // x(\xi) = sum_i v_i phi_x(\xi)
+ // where v_i are the vertices of the quad,
+ // and \xi=(\xi_1,\xi_2) are the reference
+ // coordinates of the quad. so what we are
+ // trying to do is find a point x on
+ // the surface that is closest to the point
+ // y. there are different ways
+ // to solve this problem, but in the end
+ // it's a nonlinear problem and we have to
+ // find reference coordinates \xi so that
+ // J(\xi) = 1/2 || x(\xi)-y ||^2
+ // is minimal. x(\xi) is a function that
+ // is dim-linear in \xi, so J(\xi) is
+ // a polynomial of degree 2*dim that
+ // we'd like to minimize. unless dim==1,
+ // we'll have to use a Newton
+ // method to find the
+ // answer. This leads to the
+ // following formulation of
+ // Newton steps:
+ //
+ // Given \xi_k, find \delta\xi_k so that
+ // H_k \delta\xi_k = - F_k
+ // where H_k is an approximation to the
+ // second derivatives of J at \xi_k, and
+ // F_k is the first derivative of J.
+ // We'll iterate this a number of times
+ // until the right hand side is small
+ // enough. As a stopping criterion, we
+ // terminate if ||\delta\xi||<eps.
+ //
+ // As for the Hessian, the best choice
+ // would be
+ // H_k = J''(\xi_k)
+ // but we'll opt for the simpler
+ // Gauss-Newton form
+ // H_k = A^T A
+ // i.e.
+ // (H_k)_{nm} = \sum_{i,j} v_i*v_j *
+ // \partial_n phi_i *
+ // \partial_m phi_j
+ // we start at xi=(0.5,0.5).
Point<dim> xi;
for (unsigned int d=0; d<dim; ++d)
xi[d] = 0.5;
Point<spacedim> x_k;
for (unsigned int i=0; i<GeometryInfo<dim>::vertices_per_cell; ++i)
x_k += object->vertex(i) *
- GeometryInfo<dim>::d_linear_shape_function (xi, i);
+ GeometryInfo<dim>::d_linear_shape_function (xi, i);
do
{
- Tensor<1,dim> F_k;
- for (unsigned int i=0; i<GeometryInfo<dim>::vertices_per_cell; ++i)
- F_k += (x_k-y)*object->vertex(i) *
- GeometryInfo<dim>::d_linear_shape_function_gradient (xi, i);
-
- Tensor<2,dim> H_k;
- for (unsigned int i=0; i<GeometryInfo<dim>::vertices_per_cell; ++i)
- for (unsigned int j=0; j<GeometryInfo<dim>::vertices_per_cell; ++j)
- {
- Tensor<2,dim> tmp;
- outer_product (tmp,
- GeometryInfo<dim>::d_linear_shape_function_gradient (xi, i),
- GeometryInfo<dim>::d_linear_shape_function_gradient (xi, j));
- H_k += (object->vertex(i) * object->vertex(j)) * tmp;
- }
-
- const Point<dim> delta_xi = - invert(H_k) * F_k;
- xi += delta_xi;
-
- x_k = Point<spacedim>();
- for (unsigned int i=0; i<GeometryInfo<dim>::vertices_per_cell; ++i)
- x_k += object->vertex(i) *
- GeometryInfo<dim>::d_linear_shape_function (xi, i);
-
- if (delta_xi.norm() < 1e-5)
- break;
+ Tensor<1,dim> F_k;
+ for (unsigned int i=0; i<GeometryInfo<dim>::vertices_per_cell; ++i)
+ F_k += (x_k-y)*object->vertex(i) *
+ GeometryInfo<dim>::d_linear_shape_function_gradient (xi, i);
+
+ Tensor<2,dim> H_k;
+ for (unsigned int i=0; i<GeometryInfo<dim>::vertices_per_cell; ++i)
+ for (unsigned int j=0; j<GeometryInfo<dim>::vertices_per_cell; ++j)
+ {
+ Tensor<2,dim> tmp;
+ outer_product (tmp,
+ GeometryInfo<dim>::d_linear_shape_function_gradient (xi, i),
+ GeometryInfo<dim>::d_linear_shape_function_gradient (xi, j));
+ H_k += (object->vertex(i) * object->vertex(j)) * tmp;
+ }
+
+ const Point<dim> delta_xi = - invert(H_k) * F_k;
+ xi += delta_xi;
+
+ x_k = Point<spacedim>();
+ for (unsigned int i=0; i<GeometryInfo<dim>::vertices_per_cell; ++i)
+ x_k += object->vertex(i) *
+ GeometryInfo<dim>::d_linear_shape_function (xi, i);
+
+ if (delta_xi.norm() < 1e-5)
+ break;
}
while (true);
}
- // specialization for a quad in 1d
+ // specialization for a quad in 1d
template <typename Iterator>
Point<1>
compute_projection (const Iterator &,
- const Point<1> &y,
- /* it's a quad: */internal::int2type<2>)
+ const Point<1> &y,
+ /* it's a quad: */internal::int2type<2>)
{
return y;
}
- // specialization for a quad in 2d
+ // specialization for a quad in 2d
template <typename Iterator>
Point<2>
compute_projection (const Iterator &,
- const Point<2> &y,
- /* it's a quad: */internal::int2type<2>)
+ const Point<2> &y,
+ /* it's a quad: */internal::int2type<2>)
{
return y;
}
Point<3>
StraightBoundary<1,3>::
project_to_surface (const Triangulation<1, 3>::quad_iterator &,
- const Point<3> &y) const
+ const Point<3> &y) const
{
return y;
}
Point<spacedim>
StraightBoundary<dim, spacedim>::
project_to_surface (const typename Triangulation<dim, spacedim>::quad_iterator &quad,
- const Point<spacedim> &y) const
+ const Point<spacedim> &y) const
{
if (spacedim <= 2)
return y;
else
return internal::compute_projection (quad, y,
- /* it's a quad */internal::int2type<2>());
+ /* it's a quad */internal::int2type<2>());
}
Point<spacedim>
StraightBoundary<dim, spacedim>::
project_to_surface (const typename Triangulation<dim, spacedim>::hex_iterator &,
- const Point<spacedim> &trial_point) const
+ const Point<spacedim> &trial_point) const
{
if (spacedim <= 3)
return trial_point;
else
{
- // we can presumably call the
- // same function as above (it's
- // written in a generic way)
- // but someone needs to check
- // whether that actually yields
- // the correct result
+ // we can presumably call the
+ // same function as above (it's
+ // written in a generic way)
+ // but someone needs to check
+ // whether that actually yields
+ // the correct result
Assert (false, ExcNotImplemented());
return Point<spacedim>();
}
template <int dim, int spacedim>
CylinderBoundary<dim,spacedim>::CylinderBoundary (const double radius,
- const unsigned int axis)
- :
- radius(radius),
- direction (get_axis_vector (axis)),
- point_on_axis (Point<spacedim>())
+ const unsigned int axis)
+ :
+ radius(radius),
+ direction (get_axis_vector (axis)),
+ point_on_axis (Point<spacedim>())
{}
template <int dim, int spacedim>
CylinderBoundary<dim,spacedim>::CylinderBoundary (const double radius,
- const Point<spacedim> direction,
- const Point<spacedim> point_on_axis)
- :
- radius(radius),
- direction (direction / direction.norm()),
- point_on_axis (point_on_axis)
+ const Point<spacedim> direction,
+ const Point<spacedim> point_on_axis)
+ :
+ radius(radius),
+ direction (direction / direction.norm()),
+ point_on_axis (point_on_axis)
{}
CylinderBoundary<dim,spacedim>::
get_new_point_on_line (const typename Triangulation<dim,spacedim>::line_iterator &line) const
{
- // compute a proposed new point
+ // compute a proposed new point
const Point<spacedim> middle = StraightBoundary<dim,spacedim>::get_new_point_on_line (line);
- // we then have to project this
- // point out to the given radius
- // from the axis. to this end, we
- // have to take into account the
- // offset point_on_axis and the
- // direction of the axis
+ // we then have to project this
+ // point out to the given radius
+ // from the axis. to this end, we
+ // have to take into account the
+ // offset point_on_axis and the
+ // direction of the axis
const Point<spacedim> vector_from_axis = (middle-point_on_axis) -
- ((middle-point_on_axis) * direction) * direction;
- // scale it to the desired length
- // and put everything back
- // together, unless we have a point
- // on the axis
+ ((middle-point_on_axis) * direction) * direction;
+ // scale it to the desired length
+ // and put everything back
+ // together, unless we have a point
+ // on the axis
if (vector_from_axis.norm() <= 1e-10 * middle.norm())
return middle;
else
return (vector_from_axis / vector_from_axis.norm() * radius +
- ((middle-point_on_axis) * direction) * direction +
- point_on_axis);
+ ((middle-point_on_axis) * direction) * direction +
+ point_on_axis);
}
{
const Point<3> middle = StraightBoundary<3>::get_new_point_on_quad (quad);
- // same algorithm as above
+ // same algorithm as above
const unsigned int spacedim = 3;
const Point<spacedim> vector_from_axis = (middle-point_on_axis) -
- ((middle-point_on_axis) * direction) * direction;
+ ((middle-point_on_axis) * direction) * direction;
if (vector_from_axis.norm() <= 1e-10 * middle.norm())
return middle;
else
return (vector_from_axis / vector_from_axis.norm() * radius +
- ((middle-point_on_axis) * direction) * direction +
- point_on_axis);
+ ((middle-point_on_axis) * direction) * direction +
+ point_on_axis);
}
template<>
{
const Point<3> middle = StraightBoundary<2,3>::get_new_point_on_quad (quad);
- // same algorithm as above
+ // same algorithm as above
const unsigned int spacedim = 3;
const Point<spacedim> vector_from_axis = (middle-point_on_axis) -
- ((middle-point_on_axis) * direction) * direction;
+ ((middle-point_on_axis) * direction) * direction;
if (vector_from_axis.norm() <= 1e-10 * middle.norm())
return middle;
else
return (vector_from_axis / vector_from_axis.norm() * radius +
- ((middle-point_on_axis) * direction) * direction +
- point_on_axis);
+ ((middle-point_on_axis) * direction) * direction +
+ point_on_axis);
}
const unsigned int n=points.size();
Assert(n>0, ExcInternalError());
- // Do a simple linear interpolation
- // followed by projection, using
- // the same algorithm as above
+ // Do a simple linear interpolation
+ // followed by projection, using
+ // the same algorithm as above
const Point<spacedim> ds = (v1-v0) / (n+1);
for (unsigned int i=0; i<n; ++i)
const Point<spacedim> middle = v0 + (i+1)*ds;
const Point<spacedim> vector_from_axis = (middle-point_on_axis) -
- ((middle-point_on_axis) * direction) * direction;
+ ((middle-point_on_axis) * direction) * direction;
if (vector_from_axis.norm() <= 1e-10 * middle.norm())
- points[i] = middle;
+ points[i] = middle;
else
- points[i] = (vector_from_axis / vector_from_axis.norm() * radius +
- ((middle-point_on_axis) * direction) * direction +
- point_on_axis);
+ points[i] = (vector_from_axis / vector_from_axis.norm() * radius +
+ ((middle-point_on_axis) * direction) * direction +
+ point_on_axis);
}
}
std::vector<Point<3> > lps(m);
for (unsigned int i=0; i<m; ++i)
- {
- get_intermediate_points_between_points(lp0[i], lp1[i], lps);
+ {
+ get_intermediate_points_between_points(lp0[i], lp1[i], lps);
- for (unsigned int j=0; j<m; ++j)
- points[i*m+j]=lps[j];
- }
+ for (unsigned int j=0; j<m; ++j)
+ points[i*m+j]=lps[j];
+ }
}
}
void
CylinderBoundary<1>::
get_normals_at_vertices (const Triangulation<1>::face_iterator &,
- Boundary<1,1>::FaceVertexNormals &) const
+ Boundary<1,1>::FaceVertexNormals &) const
{
Assert (false, ExcImpossibleInDim(1));
}
void
CylinderBoundary<dim,spacedim>::
get_normals_at_vertices (const typename Triangulation<dim,spacedim>::face_iterator &face,
- typename Boundary<dim,spacedim>::FaceVertexNormals &face_vertex_normals) const
+ typename Boundary<dim,spacedim>::FaceVertexNormals &face_vertex_normals) const
{
for (unsigned int v=0; v<GeometryInfo<dim>::vertices_per_face; ++v)
{
const Point<spacedim> vertex = face->vertex(v);
const Point<spacedim> vector_from_axis = (vertex-point_on_axis) -
- ((vertex-point_on_axis) * direction) * direction;
+ ((vertex-point_on_axis) * direction) * direction;
face_vertex_normals[v] = (vector_from_axis / vector_from_axis.norm());
}
template<int dim>
ConeBoundary<dim>::ConeBoundary (const double radius_0,
- const double radius_1,
- const Point<dim> x_0,
- const Point<dim> x_1)
- :
- radius_0 (radius_0),
- radius_1 (radius_1),
- x_0 (x_0),
- x_1 (x_1)
+ const double radius_1,
+ const Point<dim> x_0,
+ const Point<dim> x_1)
+ :
+ radius_0 (radius_0),
+ radius_1 (radius_1),
+ x_0 (x_0),
+ x_1 (x_1)
{}
void
ConeBoundary<dim>::
get_intermediate_points_between_points (const Point<dim> &p0,
- const Point<dim> &p1,
- std::vector<Point<dim> > &points) const
+ const Point<dim> &p1,
+ std::vector<Point<dim> > &points) const
{
const unsigned int n = points.size ();
const Point<dim> axis = x_1 - x_0;
for (unsigned int i = 0; i < n; ++i)
{
- // Compute the current point.
+ // Compute the current point.
const Point<dim> x_i = p0 + (i + 1) * dx;
- // To project this point on the
- // boundary of the cone we first
- // compute the orthogonal
- // projection of this point onto
- // the axis of the cone.
+ // To project this point on the
+ // boundary of the cone we first
+ // compute the orthogonal
+ // projection of this point onto
+ // the axis of the cone.
const double c = (x_i - x_0) * axis / axis.square ();
const Point<dim> x_ip = x_0 + c * axis;
- // Compute the projection of
- // the middle point on the
- // boundary of the cone.
+ // Compute the projection of
+ // the middle point on the
+ // boundary of the cone.
points[i] = x_ip + get_radius (x_ip) * (x_i - x_ip) / (x_i - x_ip).norm ();
}
}
get_new_point_on_line (const typename Triangulation<dim>::line_iterator &line) const
{
const Point<dim> axis = x_1 - x_0;
- // Compute the middle point of the line.
+ // Compute the middle point of the line.
const Point<dim> middle = StraightBoundary<dim>::get_new_point_on_line (line);
- // To project it on the boundary of
- // the cone we first compute the
- // orthogonal projection of the
- // middle point onto the axis of
- // the cone.
+ // To project it on the boundary of
+ // the cone we first compute the
+ // orthogonal projection of the
+ // middle point onto the axis of
+ // the cone.
const double c = (middle - x_0) * axis / axis.square ();
const Point<dim> middle_p = x_0 + c * axis;
- // Compute the projection of the
- // middle point on the boundary
- // of the cone.
+ // Compute the projection of the
+ // middle point on the boundary
+ // of the cone.
return middle_p + get_radius (middle_p) * (middle - middle_p) / (middle - middle_p).norm ();
}
const int dim = 3;
const Point<dim> axis = x_1 - x_0;
- // Compute the middle point of the
- // quad.
+ // Compute the middle point of the
+ // quad.
const Point<dim> middle = StraightBoundary<3>::get_new_point_on_quad (quad);
- // Same algorithm as above: To
- // project it on the boundary of
- // the cone we first compute the
- // orthogonal projection of the
- // middle point onto the axis of
- // the cone.
+ // Same algorithm as above: To
+ // project it on the boundary of
+ // the cone we first compute the
+ // orthogonal projection of the
+ // middle point onto the axis of
+ // the cone.
const double c = (middle - x_0) * axis / axis.square ();
const Point<dim> middle_p = x_0 + c * axis;
- // Compute the projection of the
- // middle point on the boundary
- // of the cone.
+ // Compute the projection of the
+ // middle point on the boundary
+ // of the cone.
return middle_p + get_radius (middle_p) * (middle - middle_p) / (middle - middle_p).norm ();
}
void
ConeBoundary<dim>::
get_intermediate_points_on_line (const typename Triangulation<dim>::line_iterator &line,
- std::vector<Point<dim> > &points) const
+ std::vector<Point<dim> > &points) const
{
if (points.size () == 1)
points[0] = get_new_point_on_line (line);
void
ConeBoundary<3>::
get_intermediate_points_on_quad (const Triangulation<3>::quad_iterator &quad,
- std::vector<Point<3> > &points) const
+ std::vector<Point<3> > &points) const
{
if (points.size () == 1)
points[0] = get_new_point_on_quad (quad);
std::vector<Point<3> > points_line_segment (n);
for (unsigned int i = 0; i < n; ++i)
- {
- get_intermediate_points_between_points (points_line_0[i],
- points_line_1[i],
- points_line_segment);
-
- for (unsigned int j = 0; j < n; ++j)
- points[i * n + j] = points_line_segment[j];
- }
+ {
+ get_intermediate_points_between_points (points_line_0[i],
+ points_line_1[i],
+ points_line_segment);
+
+ for (unsigned int j = 0; j < n; ++j)
+ points[i * n + j] = points_line_segment[j];
+ }
}
}
void
ConeBoundary<dim>::
get_intermediate_points_on_quad (const typename Triangulation<dim>::quad_iterator &,
- std::vector<Point<dim> > &) const
+ std::vector<Point<dim> > &) const
{
Assert (false, ExcImpossibleInDim (dim));
}
void
ConeBoundary<1>::
get_normals_at_vertices (const Triangulation<1>::face_iterator &,
- Boundary<1,1>::FaceVertexNormals &) const
+ Boundary<1,1>::FaceVertexNormals &) const
{
Assert (false, ExcImpossibleInDim (1));
}
void
ConeBoundary<dim>::
get_normals_at_vertices (const typename Triangulation<dim>::face_iterator &face,
- typename Boundary<dim>::FaceVertexNormals &face_vertex_normals) const
+ typename Boundary<dim>::FaceVertexNormals &face_vertex_normals) const
{
const Point<dim> axis = x_1 - x_0;
for (unsigned int vertex = 0; vertex < GeometryInfo<dim>::vertices_per_cell; ++vertex)
{
- // Compute the orthogonal
- // projection of the vertex onto
- // the axis of the cone.
+ // Compute the orthogonal
+ // projection of the vertex onto
+ // the axis of the cone.
const double c = (face->vertex (vertex) - x_0) * axis / axis.square ();
const Point<dim> vertex_p = x_0 + c * axis;
- // Then compute the vector
- // pointing from the point
- // <tt>vertex_p</tt> on the axis
- // to the vertex.
+ // Then compute the vector
+ // pointing from the point
+ // <tt>vertex_p</tt> on the axis
+ // to the vertex.
const Point<dim> axis_to_vertex = face->vertex (vertex) - vertex_p;
face_vertex_normals[vertex] = axis_to_vertex / axis_to_vertex.norm ();
template <int dim, int spacedim>
HyperBallBoundary<dim,spacedim>::HyperBallBoundary (const Point<spacedim> p,
- const double radius)
- :
- center(p),
- radius(radius),
- compute_radius_automatically(false)
+ const double radius)
+ :
+ center(p),
+ radius(radius),
+ compute_radius_automatically(false)
{}
}
else
r=radius;
- // project to boundary
+ // project to boundary
middle *= r / std::sqrt(middle.square());
middle += center;
return middle;
}
else
r=radius;
- // project to boundary
+ // project to boundary
middle *= r / std::sqrt(middle.square());
middle += center;
Assert(n>0, ExcInternalError());
const Point<spacedim> v0=p0-center,
- v1=p1-center;
+ v1=p1-center;
const double length=std::sqrt((v1-v0).square());
double eps=1e-12;
unsigned int left_index=0, right_index=0;
if ((n+1)%2==0)
{
- // if the number of
- // parts is even insert
- // the midpoint
+ // if the number of
+ // parts is even insert
+ // the midpoint
left_index=(n-1)/2;
right_index=left_index;
points[left_index]=pm;
left_index=n/2-1;
}
- // n even: m=n/2,
- // n odd: m=(n-1)/2
+ // n even: m=n/2,
+ // n odd: m=(n-1)/2
const unsigned int m=n/2;
for (unsigned int i=0; i<m ; ++i, ++right_index, --left_index, beta+=d_alpha)
{
}
- // project the points from the
- // straight line to the
- // HyperBallBoundary
+ // project the points from the
+ // straight line to the
+ // HyperBallBoundary
for (unsigned int i=0; i<n; ++i)
{
points[i] *= r / std::sqrt(points[i].square());
std::vector<Point<3> > lps(m);
for (unsigned int i=0; i<m; ++i)
- {
- get_intermediate_points_between_points(lp0[i], lp1[i], lps);
+ {
+ get_intermediate_points_between_points(lp0[i], lp1[i], lps);
- for (unsigned int j=0; j<m; ++j)
- points[i*m+j]=lps[j];
- }
+ for (unsigned int j=0; j<m; ++j)
+ points[i*m+j]=lps[j];
+ }
}
}
std::vector<Point<3> > lps(m);
for (unsigned int i=0; i<m; ++i)
- {
- get_intermediate_points_between_points(lp0[i], lp1[i], lps);
+ {
+ get_intermediate_points_between_points(lp0[i], lp1[i], lps);
- for (unsigned int j=0; j<m; ++j)
- points[i*m+j]=lps[j];
- }
+ for (unsigned int j=0; j<m; ++j)
+ points[i*m+j]=lps[j];
+ }
}
}
Tensor<1,spacedim>
HyperBallBoundary<dim,spacedim>::
normal_vector (const typename Triangulation<dim,spacedim>::face_iterator &,
- const Point<spacedim> &p) const
+ const Point<spacedim> &p) const
{
const Tensor<1,spacedim> unnormalized_normal = p-center;
return unnormalized_normal/unnormalized_normal.norm();
void
HyperBallBoundary<1>::
get_normals_at_vertices (const Triangulation<1>::face_iterator &,
- Boundary<1,1>::FaceVertexNormals &) const
+ Boundary<1,1>::FaceVertexNormals &) const
{
Assert (false, ExcImpossibleInDim(1));
}
void
HyperBallBoundary<1,2>::
get_normals_at_vertices (const Triangulation<1,2>::face_iterator &,
- Boundary<1,2>::FaceVertexNormals &) const
+ Boundary<1,2>::FaceVertexNormals &) const
{
Assert (false, ExcImpossibleInDim(1));
}
void
HyperBallBoundary<dim,spacedim>::
get_normals_at_vertices (const typename Triangulation<dim,spacedim>::face_iterator &face,
- typename Boundary<dim,spacedim>::FaceVertexNormals &face_vertex_normals) const
+ typename Boundary<dim,spacedim>::FaceVertexNormals &face_vertex_normals) const
{
for (unsigned int vertex=0; vertex<GeometryInfo<dim>::vertices_per_face; ++vertex)
face_vertex_normals[vertex] = face->vertex(vertex)-center;
template <int dim>
HalfHyperBallBoundary<dim>::HalfHyperBallBoundary (const Point<dim> center,
- const double radius) :
- HyperBallBoundary<dim> (center, radius)
+ const double radius) :
+ HyperBallBoundary<dim> (center, radius)
{}
HalfHyperBallBoundary<dim>::
get_new_point_on_line (const typename Triangulation<dim>::line_iterator &line) const
{
- // check whether center of object is
- // at x==0, since then it belongs
- // to the plane part of the
- // boundary
+ // check whether center of object is
+ // at x==0, since then it belongs
+ // to the plane part of the
+ // boundary
const Point<dim> line_center = line->center();
if (line_center(0) == this->center(0))
return line_center;
void
HalfHyperBallBoundary<dim>::
get_intermediate_points_on_line (const typename Triangulation<dim>::line_iterator &line,
- std::vector<Point<dim> > &points) const
+ std::vector<Point<dim> > &points) const
{
- // check whether center of object is
- // at x==0, since then it belongs
- // to the plane part of the
- // boundary
+ // check whether center of object is
+ // at x==0, since then it belongs
+ // to the plane part of the
+ // boundary
const Point<dim> line_center = line->center();
if (line_center(0) == this->center(0))
return StraightBoundary<dim>::get_intermediate_points_on_line (line, points);
void
HalfHyperBallBoundary<dim>::
get_intermediate_points_on_quad (const typename Triangulation<dim>::quad_iterator &quad,
- std::vector<Point<dim> > &points) const
+ std::vector<Point<dim> > &points) const
{
if (points.size()==1)
points[0]=get_new_point_on_quad(quad);
else
{
- // check whether center of
- // object is at x==0, since
- // then it belongs to the plane
- // part of the boundary
+ // check whether center of
+ // object is at x==0, since
+ // then it belongs to the plane
+ // part of the boundary
const Point<dim> quad_center = quad->center();
if (quad_center(0) == this->center(0))
- StraightBoundary<dim>::get_intermediate_points_on_quad (quad, points);
+ StraightBoundary<dim>::get_intermediate_points_on_quad (quad, points);
else
- HyperBallBoundary<dim>::get_intermediate_points_on_quad (quad, points);
+ HyperBallBoundary<dim>::get_intermediate_points_on_quad (quad, points);
}
}
void
HalfHyperBallBoundary<1>::
get_intermediate_points_on_quad (const Triangulation<1>::quad_iterator &,
- std::vector<Point<1> > &) const
+ std::vector<Point<1> > &) const
{
Assert (false, ExcInternalError());
}
void
HalfHyperBallBoundary<1>::
get_normals_at_vertices (const Triangulation<1>::face_iterator &,
- Boundary<1,1>::FaceVertexNormals &) const
+ Boundary<1,1>::FaceVertexNormals &) const
{
Assert (false, ExcImpossibleInDim(1));
}
void
HalfHyperBallBoundary<dim>::
get_normals_at_vertices (const typename Triangulation<dim>::face_iterator &face,
- typename Boundary<dim>::FaceVertexNormals &face_vertex_normals) const
+ typename Boundary<dim>::FaceVertexNormals &face_vertex_normals) const
{
- // check whether center of object is
- // at x==0, since then it belongs
- // to the plane part of the
- // boundary
+ // check whether center of object is
+ // at x==0, since then it belongs
+ // to the plane part of the
+ // boundary
const Point<dim> quad_center = face->center();
if (quad_center(0) == this->center(0))
StraightBoundary<dim>::get_normals_at_vertices (face, face_vertex_normals);
template <int dim>
HyperShellBoundary<dim>::HyperShellBoundary (const Point<dim> ¢er)
- :
- HyperBallBoundary<dim>(center, 0.)
+ :
+ HyperBallBoundary<dim>(center, 0.)
{
this->compute_radius_automatically=true;
}
template <int dim>
HalfHyperShellBoundary<dim>::HalfHyperShellBoundary (const Point<dim> ¢er,
- const double inner_radius,
- const double outer_radius)
- :
- HyperShellBoundary<dim> (center),
- inner_radius (inner_radius),
- outer_radius (outer_radius)
+ const double inner_radius,
+ const double outer_radius)
+ :
+ HyperShellBoundary<dim> (center),
+ inner_radius (inner_radius),
+ outer_radius (outer_radius)
{
if (dim > 2)
Assert ((inner_radius >= 0) &&
- (outer_radius > 0) &&
- (outer_radius > inner_radius),
- ExcMessage ("Inner and outer radii must be specified explicitly in 3d."));
+ (outer_radius > 0) &&
+ (outer_radius > inner_radius),
+ ExcMessage ("Inner and outer radii must be specified explicitly in 3d."));
}
{
switch (dim)
{
- // in 2d, first check whether the two
- // end points of the line are on the
- // axis of symmetry. if so, then return
- // the mid point
+ // in 2d, first check whether the two
+ // end points of the line are on the
+ // axis of symmetry. if so, then return
+ // the mid point
case 2:
{
- if ((line->vertex(0)(0) == this->center(0))
- &&
- (line->vertex(1)(0) == this->center(0)))
- return (line->vertex(0) + line->vertex(1))/2;
- else
- // otherwise we are on the outer or
- // inner part of the shell. proceed
- // as in the base class
- return HyperShellBoundary<dim>::get_new_point_on_line (line);
+ if ((line->vertex(0)(0) == this->center(0))
+ &&
+ (line->vertex(1)(0) == this->center(0)))
+ return (line->vertex(0) + line->vertex(1))/2;
+ else
+ // otherwise we are on the outer or
+ // inner part of the shell. proceed
+ // as in the base class
+ return HyperShellBoundary<dim>::get_new_point_on_line (line);
}
- // in 3d, a line is a straight
- // line if it is on the symmetry
- // plane and if not both of its
- // end points are on either the
- // inner or outer sphere
+ // in 3d, a line is a straight
+ // line if it is on the symmetry
+ // plane and if not both of its
+ // end points are on either the
+ // inner or outer sphere
case 3:
{
- if (((line->vertex(0)(0) == this->center(0))
- &&
- (line->vertex(1)(0) == this->center(0)))
- &&
- !(((std::fabs (line->vertex(0).distance (this->center)
- - inner_radius) < 1e-12 * outer_radius)
- &&
- (std::fabs (line->vertex(1).distance (this->center)
- - inner_radius) < 1e-12 * outer_radius))
- ||
- ((std::fabs (line->vertex(0).distance (this->center)
- - outer_radius) < 1e-12 * outer_radius)
- &&
- (std::fabs (line->vertex(1).distance (this->center)
- - outer_radius) < 1e-12 * outer_radius))))
- return (line->vertex(0) + line->vertex(1))/2;
- else
- // otherwise we are on the outer or
- // inner part of the shell. proceed
- // as in the base class
- return HyperShellBoundary<dim>::get_new_point_on_line (line);
+ if (((line->vertex(0)(0) == this->center(0))
+ &&
+ (line->vertex(1)(0) == this->center(0)))
+ &&
+ !(((std::fabs (line->vertex(0).distance (this->center)
+ - inner_radius) < 1e-12 * outer_radius)
+ &&
+ (std::fabs (line->vertex(1).distance (this->center)
+ - inner_radius) < 1e-12 * outer_radius))
+ ||
+ ((std::fabs (line->vertex(0).distance (this->center)
+ - outer_radius) < 1e-12 * outer_radius)
+ &&
+ (std::fabs (line->vertex(1).distance (this->center)
+ - outer_radius) < 1e-12 * outer_radius))))
+ return (line->vertex(0) + line->vertex(1))/2;
+ else
+ // otherwise we are on the outer or
+ // inner part of the shell. proceed
+ // as in the base class
+ return HyperShellBoundary<dim>::get_new_point_on_line (line);
}
default:
- Assert (false, ExcNotImplemented());
+ Assert (false, ExcNotImplemented());
}
return Point<dim>();
HalfHyperShellBoundary<dim>::
get_new_point_on_quad (const typename Triangulation<dim>::quad_iterator &quad) const
{
- // if this quad is on the symmetry plane,
- // take the center point and project it
- // outward to the same radius as the
- // centers of the two radial lines
+ // if this quad is on the symmetry plane,
+ // take the center point and project it
+ // outward to the same radius as the
+ // centers of the two radial lines
if ((quad->vertex(0)(0) == this->center(0)) &&
(quad->vertex(1)(0) == this->center(0)) &&
(quad->vertex(2)(0) == this->center(0)) &&
(quad->vertex(3)(0) == this->center(0)))
{
const Point<dim> quad_center = (quad->vertex(0) + quad->vertex(1) +
- quad->vertex(2) + quad->vertex(3) )/4;
+ quad->vertex(2) + quad->vertex(3) )/4;
const Point<dim> quad_center_offset = quad_center - this->center;
if (std::fabs (quad->line(0)->center().distance(this->center) -
- quad->line(1)->center().distance(this->center))
- < 1e-12 * outer_radius)
- {
- // lines 0 and 1 are radial
- const double needed_radius
- = quad->line(0)->center().distance(this->center);
-
- return (this->center +
- quad_center_offset/quad_center_offset.norm() * needed_radius);
- }
+ quad->line(1)->center().distance(this->center))
+ < 1e-12 * outer_radius)
+ {
+ // lines 0 and 1 are radial
+ const double needed_radius
+ = quad->line(0)->center().distance(this->center);
+
+ return (this->center +
+ quad_center_offset/quad_center_offset.norm() * needed_radius);
+ }
else if (std::fabs (quad->line(2)->center().distance(this->center) -
- quad->line(3)->center().distance(this->center))
- < 1e-12 * outer_radius)
- {
- // lines 2 and 3 are radial
- const double needed_radius
- = quad->line(2)->center().distance(this->center);
-
- return (this->center +
- quad_center_offset/quad_center_offset.norm() * needed_radius);
- }
+ quad->line(3)->center().distance(this->center))
+ < 1e-12 * outer_radius)
+ {
+ // lines 2 and 3 are radial
+ const double needed_radius
+ = quad->line(2)->center().distance(this->center);
+
+ return (this->center +
+ quad_center_offset/quad_center_offset.norm() * needed_radius);
+ }
else
- Assert (false, ExcInternalError());
+ Assert (false, ExcInternalError());
}
- // otherwise we are on the outer or
- // inner part of the shell. proceed
- // as in the base class
+ // otherwise we are on the outer or
+ // inner part of the shell. proceed
+ // as in the base class
return HyperShellBoundary<dim>::get_new_point_on_quad (quad);
}
void
HalfHyperShellBoundary<dim>::
get_intermediate_points_on_line (const typename Triangulation<dim>::line_iterator &line,
- std::vector<Point<dim> > &points) const
+ std::vector<Point<dim> > &points) const
{
switch (dim)
{
- // in 2d, first check whether the two
- // end points of the line are on the
- // axis of symmetry. if so, then return
- // the mid point
+ // in 2d, first check whether the two
+ // end points of the line are on the
+ // axis of symmetry. if so, then return
+ // the mid point
case 2:
{
- if ((line->vertex(0)(0) == this->center(0))
- &&
- (line->vertex(1)(0) == this->center(0)))
- StraightBoundary<dim>::get_intermediate_points_on_line (line, points);
- else
- // otherwise we are on the outer or
- // inner part of the shell. proceed
- // as in the base class
- HyperShellBoundary<dim>::get_intermediate_points_on_line (line, points);
+ if ((line->vertex(0)(0) == this->center(0))
+ &&
+ (line->vertex(1)(0) == this->center(0)))
+ StraightBoundary<dim>::get_intermediate_points_on_line (line, points);
+ else
+ // otherwise we are on the outer or
+ // inner part of the shell. proceed
+ // as in the base class
+ HyperShellBoundary<dim>::get_intermediate_points_on_line (line, points);
}
- // in 3d, a line is a straight
- // line if it is on the symmetry
- // plane and if not both of its
- // end points are on either the
- // inner or outer sphere
+ // in 3d, a line is a straight
+ // line if it is on the symmetry
+ // plane and if not both of its
+ // end points are on either the
+ // inner or outer sphere
case 3:
{
- if (((line->vertex(0)(0) == this->center(0))
- &&
- (line->vertex(1)(0) == this->center(0)))
- &&
- !(((std::fabs (line->vertex(0).distance (this->center)
- - inner_radius) < 1e-12 * outer_radius)
- &&
- (std::fabs (line->vertex(1).distance (this->center)
- - inner_radius) < 1e-12 * outer_radius))
- ||
- ((std::fabs (line->vertex(0).distance (this->center)
- - outer_radius) < 1e-12 * outer_radius)
- &&
- (std::fabs (line->vertex(1).distance (this->center)
- - outer_radius) < 1e-12 * outer_radius))))
- StraightBoundary<dim>::get_intermediate_points_on_line (line, points);
- else
- // otherwise we are on the outer or
- // inner part of the shell. proceed
- // as in the base class
- HyperShellBoundary<dim>::get_intermediate_points_on_line (line, points);
+ if (((line->vertex(0)(0) == this->center(0))
+ &&
+ (line->vertex(1)(0) == this->center(0)))
+ &&
+ !(((std::fabs (line->vertex(0).distance (this->center)
+ - inner_radius) < 1e-12 * outer_radius)
+ &&
+ (std::fabs (line->vertex(1).distance (this->center)
+ - inner_radius) < 1e-12 * outer_radius))
+ ||
+ ((std::fabs (line->vertex(0).distance (this->center)
+ - outer_radius) < 1e-12 * outer_radius)
+ &&
+ (std::fabs (line->vertex(1).distance (this->center)
+ - outer_radius) < 1e-12 * outer_radius))))
+ StraightBoundary<dim>::get_intermediate_points_on_line (line, points);
+ else
+ // otherwise we are on the outer or
+ // inner part of the shell. proceed
+ // as in the base class
+ HyperShellBoundary<dim>::get_intermediate_points_on_line (line, points);
}
default:
- Assert (false, ExcNotImplemented());
+ Assert (false, ExcNotImplemented());
}
}
void
HalfHyperShellBoundary<dim>::
get_intermediate_points_on_quad (const typename Triangulation<dim>::quad_iterator &quad,
- std::vector<Point<dim> > &points) const
+ std::vector<Point<dim> > &points) const
{
Assert (dim < 3, ExcNotImplemented());
- // check whether center of object is
- // at x==0, since then it belongs
- // to the plane part of the
- // boundary
+ // check whether center of object is
+ // at x==0, since then it belongs
+ // to the plane part of the
+ // boundary
const Point<dim> quad_center = quad->center();
if (quad_center(0) == this->center(0))
StraightBoundary<dim>::get_intermediate_points_on_quad (quad, points);
void
HalfHyperShellBoundary<1>::
get_intermediate_points_on_quad (const Triangulation<1>::quad_iterator &,
- std::vector<Point<1> > &) const
+ std::vector<Point<1> > &) const
{
Assert (false, ExcInternalError());
}
void
HalfHyperShellBoundary<1>::
get_normals_at_vertices (const Triangulation<1>::face_iterator &,
- Boundary<1,1>::FaceVertexNormals &) const
+ Boundary<1,1>::FaceVertexNormals &) const
{
Assert (false, ExcImpossibleInDim(1));
}
void
HalfHyperShellBoundary<dim>::
get_normals_at_vertices (const typename Triangulation<dim>::face_iterator &face,
- typename Boundary<dim>::FaceVertexNormals &face_vertex_normals) const
+ typename Boundary<dim>::FaceVertexNormals &face_vertex_normals) const
{
if (face->center()(0) == this->center(0))
StraightBoundary<dim>::get_normals_at_vertices (face, face_vertex_normals);
template <int dim, int spacedim>
TorusBoundary<dim,spacedim>::TorusBoundary (const double R__,
- const double r__)
- :
- R(R__),
- r(r__)
+ const double r__)
+ :
+ R(R__),
+ r(r__)
{
Assert (false, ExcNotImplemented());
}
template <>
TorusBoundary<2,3>::TorusBoundary (const double R__,
- const double r__)
- :
- R(R__),
- r(r__)
+ const double r__)
+ :
+ R(R__),
+ r(r__)
{
Assert (R>r, ExcMessage("Outer radius must be greater than inner radius."));
}
template <int dim, int spacedim>
double
TorusBoundary<dim,spacedim>::get_correct_angle(const double angle,
- const double x,
- const double y) const
+ const double x,
+ const double y) const
{
if(y>=0)
{
if (x >=0)
- return angle;
+ return angle;
return numbers::PI-angle;
}
const double phi=surfP(1);
return Point<3> ((R+r*std::cos(phi))*std::cos(theta),
- r*std::sin(phi),
- (R+r*std::cos(phi))*std::sin(theta));
+ r*std::sin(phi),
+ (R+r*std::cos(phi))*std::sin(theta));
}
if(std::abs(p(0))<1.E-5)
{
if(p(2)>=0)
- surfP(0) = numbers::PI*0.5;
+ surfP(0) = numbers::PI*0.5;
else
- surfP(0) = -numbers::PI*0.5;
+ surfP(0) = -numbers::PI*0.5;
}
else
{
Point<3>
TorusBoundary<2,3>::get_new_point_on_line (const Triangulation<2,3>::line_iterator &line) const
{
- //Just get the average
+ //Just get the average
Point<2> p0=get_surf_coord(line->vertex(0));
Point<2> p1=get_surf_coord(line->vertex(1));
Point<2> middle(0,0);
- //Take care for periodic conditions,
- //For instance phi0= 0, phi1= 3/2*Pi middle has to be 7/4*Pi not 3/4*Pi
- //This also works for -Pi/2 + Pi, middle is 5/4*Pi
+ //Take care for periodic conditions,
+ //For instance phi0= 0, phi1= 3/2*Pi middle has to be 7/4*Pi not 3/4*Pi
+ //This also works for -Pi/2 + Pi, middle is 5/4*Pi
for(unsigned i=0; i<2;i++)
if(std::abs(p0(i)-p1(i))> numbers::PI)
middle(i)=2*numbers::PI;
Point<3>
TorusBoundary<2,3>::get_new_point_on_quad (const Triangulation<2,3>::quad_iterator &quad) const
{
- //Just get the average
+ //Just get the average
Point<2> p[4];
for(unsigned i=0;i<4;i++)
Point<2> middle(0,0);
- //Take care for periodic conditions, see get_new_point_on_line() above
- //For instance phi0= 0, phi1= 3/2*Pi middle has to be 7/4*Pi not 3/4*Pi
- //This also works for -Pi/2 + Pi + Pi- Pi/2, middle is 5/4*Pi
+ //Take care for periodic conditions, see get_new_point_on_line() above
+ //For instance phi0= 0, phi1= 3/2*Pi middle has to be 7/4*Pi not 3/4*Pi
+ //This also works for -Pi/2 + Pi + Pi- Pi/2, middle is 5/4*Pi
for(unsigned i=0;i<2;i++)
for(unsigned j=1;j<4;j++){
if(std::abs(p[0](i)-p[j](i))> numbers::PI){
- middle(i)+=2*numbers::PI;
+ middle(i)+=2*numbers::PI;
}
}
void
TorusBoundary<2,3>::
get_intermediate_points_on_line (const Triangulation<2, 3>::line_iterator & line,
- std::vector< Point< 3 > > & points) const
+ std::vector< Point< 3 > > & points) const
{
- //Almost the same implementation as StraightBoundary<2,3>
+ //Almost the same implementation as StraightBoundary<2,3>
unsigned npoints=points.size();
if(npoints==0) return;
offset[0]=0;
offset[1]=0;
- //Take care for periodic conditions & negative angles,
- //see get_new_point_on_line() above
- //Because we dont have a symmetric interpolation (just the middle) we need to
- //add 2*Pi to each almost zero and negative angles.
+ //Take care for periodic conditions & negative angles,
+ //see get_new_point_on_line() above
+ //Because we dont have a symmetric interpolation (just the middle) we need to
+ //add 2*Pi to each almost zero and negative angles.
for(unsigned i=0;i<2;i++)
for(unsigned j=1;j<2;j++){
if(std::abs(p[0](i)-p[j](i))> numbers::PI){
- offset[i]++;
- break;
+ offset[i]++;
+ break;
}
}
for(unsigned i=0;i<2;i++)
for(unsigned j=0;j<2;j++)
if(p[j](i)<1.E-12 ) //Take care for periodic conditions & negative angles
- p[j](i)+=2*numbers::PI*offset[i];
+ p[j](i)+=2*numbers::PI*offset[i];
double dx=1.0/(npoints+1);
void
TorusBoundary<2,3>::
get_intermediate_points_on_quad (const Triangulation< 2, 3 >::quad_iterator &quad,
- std::vector< Point< 3 > > & points )const
+ std::vector< Point< 3 > > & points )const
{
- //Almost the same implementation as StraightBoundary<2,3>
+ //Almost the same implementation as StraightBoundary<2,3>
const unsigned int n=points.size(),
- m=static_cast<unsigned int>(std::sqrt(static_cast<double>(n)));
- // is n a square number
+ m=static_cast<unsigned int>(std::sqrt(static_cast<double>(n)));
+ // is n a square number
Assert(m*m==n, ExcInternalError());
const double ds=1./(m+1);
offset[0]=0;
offset[1]=0;
- //Take care for periodic conditions & negative angles,
- //see get_new_point_on_line() above
- //Because we dont have a symmetric interpolation (just the middle) we need to
- //add 2*Pi to each almost zero and negative angles.
+ //Take care for periodic conditions & negative angles,
+ //see get_new_point_on_line() above
+ //Because we dont have a symmetric interpolation (just the middle) we need to
+ //add 2*Pi to each almost zero and negative angles.
for(unsigned i=0;i<2;i++)
for(unsigned j=1;j<4;j++){
if(std::abs(p[0](i)-p[j](i))> numbers::PI){
- offset[i]++;
- break;
+ offset[i]++;
+ break;
}
}
for(unsigned i=0;i<2;i++)
for(unsigned j=0;j<4;j++)
if(p[j](i)<1.E-12 ) //Take care for periodic conditions & negative angles
- p[j](i)+=2*numbers::PI*offset[i];
+ p[j](i)+=2*numbers::PI*offset[i];
for (unsigned i=0; i<m; ++i, y+=ds)
{
double x=ds;
for (unsigned j=0; j<m; ++j, x+=ds){
- target=((1-x) * p[0] +
- x * p[1]) * (1-y) +
- ((1-x) * p[2] +
- x * p[3]) * y;
+ target=((1-x) * p[0] +
+ x * p[1]) * (1-y) +
+ ((1-x) * p[2] +
+ x * p[3]) * y;
- points[i*m+j]=get_real_coord(target);
+ points[i*m+j]=get_real_coord(target);
}
}
}
void
TorusBoundary<2,3>::
get_normals_at_vertices (const Triangulation<2,3 >::face_iterator &face,
- Boundary<2,3>::FaceVertexNormals &face_vertex_normals) const
+ Boundary<2,3>::FaceVertexNormals &face_vertex_normals) const
{
for(unsigned i=0; i<GeometryInfo<2>::vertices_per_face; i++)
face_vertex_normals[i]=get_surf_norm(face->vertex(i));
// $Id$
// Version: $Name$
//
-// Copyright (C) 2006, 2010, 2011 by the deal.II authors
+// Copyright (C) 2006, 2010, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
TriaFaces<3>::memory_consumption () const
{
return (MemoryConsumption::memory_consumption (quads) +
- MemoryConsumption::memory_consumption (lines) );
+ MemoryConsumption::memory_consumption (lines) );
}
}
}
// $Id$
// Version: $Name$
//
-// Copyright (C) 2006, 2007, 2010, 2011 by the deal.II authors
+// Copyright (C) 2006, 2007, 2010, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
template <int dim>
void
TriaLevel<dim>::reserve_space (const unsigned int total_cells,
- const unsigned int dimension,
- const unsigned int space_dimension)
+ const unsigned int dimension,
+ const unsigned int space_dimension)
{
// we need space for total_cells
// cells. Maybe we have more already
total_cells - subdomain_ids.size(),
0);
- if (dimension < space_dimension)
- {
- direction_flags.reserve (total_cells);
- direction_flags.insert (direction_flags.end(),
- total_cells - direction_flags.size(),
- true);
- }
- else
- direction_flags.clear ();
+ if (dimension < space_dimension)
+ {
+ direction_flags.reserve (total_cells);
+ direction_flags.insert (direction_flags.end(),
+ total_cells - direction_flags.size(),
+ true);
+ }
+ else
+ direction_flags.clear ();
parents.reserve ((int) (total_cells + 1) / 2);
parents.insert (parents.end (),
// as many elements as an integer
// has bits
Assert (refine_flags.size() <=
- refine_flags.capacity() + DEAL_II_MIN_VECTOR_CAPACITY,
+ refine_flags.capacity() + DEAL_II_MIN_VECTOR_CAPACITY,
ExcMemoryWasted ("refine_flags",
refine_flags.size(), refine_flags.capacity()));
Assert (coarsen_flags.size() <= coarsen_flags.capacity() + sizeof(int)*8 ||
ExcMemoryWasted ("coarsen_flags",
coarsen_flags.size(), coarsen_flags.capacity()));
Assert (neighbors.size() <=
- neighbors.capacity() + DEAL_II_MIN_VECTOR_CAPACITY,
+ neighbors.capacity() + DEAL_II_MIN_VECTOR_CAPACITY,
ExcMemoryWasted ("neighbors",
neighbors.size(), neighbors.capacity()));
Assert (subdomain_ids.size() <=
- subdomain_ids.capacity() + DEAL_II_MIN_VECTOR_CAPACITY,
+ subdomain_ids.capacity() + DEAL_II_MIN_VECTOR_CAPACITY,
ExcMemoryWasted ("subdomain_ids",
subdomain_ids.size(), subdomain_ids.capacity()));
Assert (direction_flags.size() <=
- direction_flags.capacity() + DEAL_II_MIN_VECTOR_CAPACITY,
+ direction_flags.capacity() + DEAL_II_MIN_VECTOR_CAPACITY,
ExcMemoryWasted ("direction_flags",
direction_flags.size(), direction_flags.capacity()));
TriaLevel<dim>::memory_consumption () const
{
return (MemoryConsumption::memory_consumption (refine_flags) +
- MemoryConsumption::memory_consumption (coarsen_flags) +
+ MemoryConsumption::memory_consumption (coarsen_flags) +
MemoryConsumption::memory_consumption (neighbors) +
- MemoryConsumption::memory_consumption (subdomain_ids) +
- MemoryConsumption::memory_consumption (parents) +
- MemoryConsumption::memory_consumption (direction_flags) +
+ MemoryConsumption::memory_consumption (subdomain_ids) +
+ MemoryConsumption::memory_consumption (parents) +
+ MemoryConsumption::memory_consumption (direction_flags) +
MemoryConsumption::memory_consumption (cells));
}
void
TriaLevel<3>::reserve_space (const unsigned int total_cells,
- const unsigned int dimension,
- const unsigned int space_dimension)
+ const unsigned int dimension,
+ const unsigned int space_dimension)
{
// we need space for total_cells
// cells. Maybe we have more already
total_cells - subdomain_ids.size(),
0);
- if (dimension < space_dimension)
- {
- direction_flags.reserve (total_cells);
- direction_flags.insert (direction_flags.end(),
- total_cells - direction_flags.size(),
- true);
- }
- else
- direction_flags.clear ();
+ if (dimension < space_dimension)
+ {
+ direction_flags.reserve (total_cells);
+ direction_flags.insert (direction_flags.end(),
+ total_cells - direction_flags.size(),
+ true);
+ }
+ else
+ direction_flags.clear ();
parents.reserve ((int) (total_cells + 1) / 2);
parents.insert (parents.end (),
// as many elements as an integer
// has bits
Assert (refine_flags.size() <=
- refine_flags.capacity() + DEAL_II_MIN_VECTOR_CAPACITY,
+ refine_flags.capacity() + DEAL_II_MIN_VECTOR_CAPACITY,
ExcMemoryWasted ("refine_flags",
refine_flags.size(), refine_flags.capacity()));
Assert (coarsen_flags.size() <= coarsen_flags.capacity() + sizeof(int)*8 ||
ExcMemoryWasted ("coarsen_flags",
coarsen_flags.size(), coarsen_flags.capacity()));
Assert (neighbors.size() <=
- neighbors.capacity() + DEAL_II_MIN_VECTOR_CAPACITY,
+ neighbors.capacity() + DEAL_II_MIN_VECTOR_CAPACITY,
ExcMemoryWasted ("neighbors",
neighbors.size(), neighbors.capacity()));
Assert (subdomain_ids.size () <=
- subdomain_ids.capacity() + DEAL_II_MIN_VECTOR_CAPACITY,
+ subdomain_ids.capacity() + DEAL_II_MIN_VECTOR_CAPACITY,
ExcMemoryWasted ("subdomain_ids",
subdomain_ids.size(), subdomain_ids.capacity()));
Assert (direction_flags.size() <=
- direction_flags.capacity() + DEAL_II_MIN_VECTOR_CAPACITY,
+ direction_flags.capacity() + DEAL_II_MIN_VECTOR_CAPACITY,
ExcMemoryWasted ("direction_flags",
direction_flags.size(), direction_flags.capacity()));
Assert (2*true_dimension*refine_flags.size() == neighbors.size(),
TriaLevel<3>::memory_consumption () const
{
return (MemoryConsumption::memory_consumption (refine_flags) +
- MemoryConsumption::memory_consumption (coarsen_flags) +
+ MemoryConsumption::memory_consumption (coarsen_flags) +
MemoryConsumption::memory_consumption (neighbors) +
- MemoryConsumption::memory_consumption (subdomain_ids) +
- MemoryConsumption::memory_consumption (parents) +
- MemoryConsumption::memory_consumption (direction_flags) +
+ MemoryConsumption::memory_consumption (subdomain_ids) +
+ MemoryConsumption::memory_consumption (parents) +
+ MemoryConsumption::memory_consumption (direction_flags) +
MemoryConsumption::memory_consumption (cells));
}
}
// $Id$
// Version: $Name$
//
-// Copyright (C) 2006, 2007, 2010, 2011 by the deal.II authors
+// Copyright (C) 2006, 2007, 2010, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
template<>
void
TriaObjects<TriaObject<1> >::reserve_space (const unsigned int new_lines_in_pairs,
- const unsigned int new_lines_single)
+ const unsigned int new_lines_single)
{
Assert(new_lines_in_pairs%2==0, ExcInternalError());
next_free_pair=0;
reverse_order_next_free_single=false;
- // count the number of lines, of
- // unused single lines and of
- // unused pairs of lines
+ // count the number of lines, of
+ // unused single lines and of
+ // unused pairs of lines
unsigned int n_lines=0;
unsigned int n_unused_pairs=0;
unsigned int n_unused_singles=0;
for (unsigned int i=0; i<used.size(); ++i)
- {
- if (used[i])
- ++n_lines;
- else if (i+1<used.size())
- {
- if (used[i+1])
- {
- ++n_unused_singles;
- if (next_free_single==0)
- next_free_single=i;
- }
- else
- {
- ++n_unused_pairs;
- if (next_free_pair==0)
- next_free_pair=i;
- ++i;
- }
- }
- else
- ++n_unused_singles;
- }
+ {
+ if (used[i])
+ ++n_lines;
+ else if (i+1<used.size())
+ {
+ if (used[i+1])
+ {
+ ++n_unused_singles;
+ if (next_free_single==0)
+ next_free_single=i;
+ }
+ else
+ {
+ ++n_unused_pairs;
+ if (next_free_pair==0)
+ next_free_pair=i;
+ ++i;
+ }
+ }
+ else
+ ++n_unused_singles;
+ }
Assert(n_lines+2*n_unused_pairs+n_unused_singles==used.size(),
- ExcInternalError());
+ ExcInternalError());
- // how many single lines are needed in
- // addition to n_unused_singles?
+ // how many single lines are needed in
+ // addition to n_unused_singles?
const int additional_single_lines=
- new_lines_single-n_unused_singles;
+ new_lines_single-n_unused_singles;
unsigned int new_size=
- used.size() + new_lines_in_pairs - 2*n_unused_pairs;
+ used.size() + new_lines_in_pairs - 2*n_unused_pairs;
if (additional_single_lines>0)
- new_size+=additional_single_lines;
+ new_size+=additional_single_lines;
// only allocate space if necessary
if (new_size>cells.size())
{
cells.reserve (new_size);
cells.insert (cells.end(),
- new_size-cells.size(),
- TriaObject<1> ());
+ new_size-cells.size(),
+ TriaObject<1> ());
used.reserve (new_size);
used.insert (used.end(),
- new_size-used.size(),
- false);
+ new_size-used.size(),
+ false);
user_flags.reserve (new_size);
user_flags.insert (user_flags.end(),
- new_size-user_flags.size(),
- false);
+ new_size-user_flags.size(),
+ false);
children.reserve (new_size);
children.insert (children.end(),
- new_size-children.size(),
- -1);
+ new_size-children.size(),
+ -1);
boundary_or_material_id.reserve (new_size);
boundary_or_material_id.insert (boundary_or_material_id.end(),
- new_size-boundary_or_material_id.size(),
- BoundaryOrMaterialId());
+ new_size-boundary_or_material_id.size(),
+ BoundaryOrMaterialId());
user_data.reserve (new_size);
user_data.insert (user_data.end(),
- new_size-user_data.size(),
- UserData());
- }
+ new_size-user_data.size(),
+ UserData());
+ }
if (n_unused_singles==0)
- {
- next_free_single=new_size-1;
- reverse_order_next_free_single=true;
- }
+ {
+ next_free_single=new_size-1;
+ reverse_order_next_free_single=true;
+ }
}
typename dealii::Triangulation<dim,spacedim>::raw_line_iterator
TriaObjects<TriaObject<1> >::next_free_single_line (const dealii::Triangulation<dim,spacedim> &tria)
{
- // TODO: Think of a way to ensure that we are using the correct triangulation, i.e. the one containing *this.
+ // TODO: Think of a way to ensure that we are using the correct triangulation, i.e. the one containing *this.
int pos=next_free_single,
- last=used.size()-1;
+ last=used.size()-1;
if (!reverse_order_next_free_single)
- {
- // first sweep forward, only use
- // really single slots, do not use
- // pair slots
- for (; pos<last; ++pos)
- if (!used[pos])
- if (used[++pos])
- {
- // this was a single slot
- pos-=1;
- break;
- }
- if (pos>=last)
- {
- reverse_order_next_free_single=true;
- next_free_single=used.size()-1;
- pos=used.size()-1;
- }
- else
- next_free_single=pos+1;
- }
+ {
+ // first sweep forward, only use
+ // really single slots, do not use
+ // pair slots
+ for (; pos<last; ++pos)
+ if (!used[pos])
+ if (used[++pos])
+ {
+ // this was a single slot
+ pos-=1;
+ break;
+ }
+ if (pos>=last)
+ {
+ reverse_order_next_free_single=true;
+ next_free_single=used.size()-1;
+ pos=used.size()-1;
+ }
+ else
+ next_free_single=pos+1;
+ }
if(reverse_order_next_free_single)
- {
- // second sweep, use all slots, even
- // in pairs
- for(;pos>=0;--pos)
- if (!used[pos])
- break;
- if (pos>0)
- next_free_single=pos-1;
- else
- // no valid single line anymore
- return tria.end_line();
- }
+ {
+ // second sweep, use all slots, even
+ // in pairs
+ for(;pos>=0;--pos)
+ if (!used[pos])
+ break;
+ if (pos>0)
+ next_free_single=pos-1;
+ else
+ // no valid single line anymore
+ return tria.end_line();
+ }
return typename dealii::Triangulation<dim,spacedim>::raw_line_iterator(&tria,0,pos);
}
typename dealii::Triangulation<dim,spacedim>::raw_line_iterator
TriaObjects<TriaObject<1> >::next_free_pair_line (const dealii::Triangulation<dim,spacedim> &tria)
{
- // TODO: Think of a way to ensure that we are using the correct triangulation, i.e. the one containing *this.
+ // TODO: Think of a way to ensure that we are using the correct triangulation, i.e. the one containing *this.
int pos=next_free_pair,
- last=used.size()-1;
+ last=used.size()-1;
for (; pos<last; ++pos)
- if (!used[pos])
- if (!used[++pos])
- {
- // this was a pair slot
- pos-=1;
- break;
- }
+ if (!used[pos])
+ if (!used[++pos])
+ {
+ // this was a pair slot
+ pos-=1;
+ break;
+ }
if (pos>=last)
- // no free slot
- return tria.end_line();
+ // no free slot
+ return tria.end_line();
else
- next_free_pair=pos+2;
+ next_free_pair=pos+2;
return typename dealii::Triangulation<dim,spacedim>::raw_line_iterator(&tria,0,pos);
}
template<>
void
TriaObjects<TriaObject<2> >::reserve_space (const unsigned int new_quads_in_pairs,
- const unsigned int new_quads_single)
+ const unsigned int new_quads_single)
{
Assert(new_quads_in_pairs%2==0, ExcInternalError());
next_free_pair=0;
reverse_order_next_free_single=false;
- // count the number of lines, of
- // unused single lines and of
- // unused pairs of lines
+ // count the number of lines, of
+ // unused single lines and of
+ // unused pairs of lines
unsigned int n_quads=0;
unsigned int n_unused_pairs=0;
unsigned int n_unused_singles=0;
for (unsigned int i=0; i<used.size(); ++i)
- {
- if (used[i])
- ++n_quads;
- else if (i+1<used.size())
- {
- if (used[i+1])
- {
- ++n_unused_singles;
- if (next_free_single==0)
- next_free_single=i;
- }
- else
- {
- ++n_unused_pairs;
- if (next_free_pair==0)
- next_free_pair=i;
- ++i;
- }
- }
- else
- ++n_unused_singles;
- }
+ {
+ if (used[i])
+ ++n_quads;
+ else if (i+1<used.size())
+ {
+ if (used[i+1])
+ {
+ ++n_unused_singles;
+ if (next_free_single==0)
+ next_free_single=i;
+ }
+ else
+ {
+ ++n_unused_pairs;
+ if (next_free_pair==0)
+ next_free_pair=i;
+ ++i;
+ }
+ }
+ else
+ ++n_unused_singles;
+ }
Assert(n_quads+2*n_unused_pairs+n_unused_singles==used.size(),
- ExcInternalError());
+ ExcInternalError());
- // how many single quads are needed in
- // addition to n_unused_quads?
+ // how many single quads are needed in
+ // addition to n_unused_quads?
const int additional_single_quads=
- new_quads_single-n_unused_singles;
+ new_quads_single-n_unused_singles;
unsigned int new_size=
- used.size() + new_quads_in_pairs - 2*n_unused_pairs;
+ used.size() + new_quads_in_pairs - 2*n_unused_pairs;
if (additional_single_quads>0)
- new_size+=additional_single_quads;
+ new_size+=additional_single_quads;
// only allocate space if necessary
if (new_size>cells.size())
{
cells.reserve (new_size);
cells.insert (cells.end(),
- new_size-cells.size(),
- TriaObject<2> ());
+ new_size-cells.size(),
+ TriaObject<2> ());
used.reserve (new_size);
used.insert (used.end(),
- new_size-used.size(),
- false);
+ new_size-used.size(),
+ false);
user_flags.reserve (new_size);
user_flags.insert (user_flags.end(),
- new_size-user_flags.size(),
- false);
+ new_size-user_flags.size(),
+ false);
children.reserve (2*new_size);
children.insert (children.end(),
- 2*new_size-children.size(),
- -1);
+ 2*new_size-children.size(),
+ -1);
- refinement_cases.reserve (new_size);
- refinement_cases.insert (refinement_cases.end(),
- new_size - refinement_cases.size(),
- RefinementCase<2>::no_refinement);
+ refinement_cases.reserve (new_size);
+ refinement_cases.insert (refinement_cases.end(),
+ new_size - refinement_cases.size(),
+ RefinementCase<2>::no_refinement);
boundary_or_material_id.reserve (new_size);
boundary_or_material_id.insert (boundary_or_material_id.end(),
- new_size-boundary_or_material_id.size(),
- BoundaryOrMaterialId());
+ new_size-boundary_or_material_id.size(),
+ BoundaryOrMaterialId());
user_data.reserve (new_size);
user_data.insert (user_data.end(),
- new_size-user_data.size(),
- UserData());
+ new_size-user_data.size(),
+ UserData());
}
if (n_unused_singles==0)
- {
- next_free_single=new_size-1;
- reverse_order_next_free_single=true;
- }
+ {
+ next_free_single=new_size-1;
+ reverse_order_next_free_single=true;
+ }
}
typename dealii::Triangulation<dim,spacedim>::raw_quad_iterator
TriaObjects<TriaObject<2> >::next_free_single_quad (const dealii::Triangulation<dim,spacedim> &tria)
{
- // TODO: Think of a way to ensure that we are using the correct triangulation, i.e. the one containing *this.
+ // TODO: Think of a way to ensure that we are using the correct triangulation, i.e. the one containing *this.
int pos=next_free_single,
- last=used.size()-1;
+ last=used.size()-1;
if (!reverse_order_next_free_single)
- {
- // first sweep forward, only use
- // really single slots, do not use
- // pair slots
- for (; pos<last; ++pos)
- if (!used[pos])
- if (used[++pos])
- {
- // this was a single slot
- pos-=1;
- break;
- }
- if (pos>=last)
- {
- reverse_order_next_free_single=true;
- next_free_single=used.size()-1;
- pos=used.size()-1;
- }
- else
- next_free_single=pos+1;
- }
+ {
+ // first sweep forward, only use
+ // really single slots, do not use
+ // pair slots
+ for (; pos<last; ++pos)
+ if (!used[pos])
+ if (used[++pos])
+ {
+ // this was a single slot
+ pos-=1;
+ break;
+ }
+ if (pos>=last)
+ {
+ reverse_order_next_free_single=true;
+ next_free_single=used.size()-1;
+ pos=used.size()-1;
+ }
+ else
+ next_free_single=pos+1;
+ }
if(reverse_order_next_free_single)
- {
- // second sweep, use all slots, even
- // in pairs
- for(;pos>=0;--pos)
- if (!used[pos])
- break;
- if (pos>0)
- next_free_single=pos-1;
- else
- // no valid single quad anymore
- return tria.end_quad();
- }
+ {
+ // second sweep, use all slots, even
+ // in pairs
+ for(;pos>=0;--pos)
+ if (!used[pos])
+ break;
+ if (pos>0)
+ next_free_single=pos-1;
+ else
+ // no valid single quad anymore
+ return tria.end_quad();
+ }
return typename dealii::Triangulation<dim,spacedim>::raw_quad_iterator(&tria,0,pos);
}
typename dealii::Triangulation<dim,spacedim>::raw_quad_iterator
TriaObjects<TriaObject<2> >::next_free_pair_quad (const dealii::Triangulation<dim,spacedim> &tria)
{
- // TODO: Think of a way to ensure that we are using the correct triangulation, i.e. the one containing *this.
+ // TODO: Think of a way to ensure that we are using the correct triangulation, i.e. the one containing *this.
int pos=next_free_pair,
- last=used.size()-1;
+ last=used.size()-1;
for (; pos<last; ++pos)
- if (!used[pos])
- if (!used[++pos])
- {
- // this was a pair slot
- pos-=1;
- break;
- }
+ if (!used[pos])
+ if (!used[++pos])
+ {
+ // this was a pair slot
+ pos-=1;
+ break;
+ }
if (pos>=last)
- // no free slot
- return tria.end_quad();
+ // no free slot
+ return tria.end_quad();
else
- next_free_pair=pos+2;
+ next_free_pair=pos+2;
return typename dealii::Triangulation<dim,spacedim>::raw_quad_iterator(&tria,0,pos);
}
template <int dim, int spacedim>
typename dealii::Triangulation<dim,spacedim>::raw_hex_iterator
TriaObjects<TriaObject<3> >::next_free_hex (const dealii::Triangulation<dim,spacedim> &tria,
- const unsigned int level)
+ const unsigned int level)
{
- // TODO: Think of a way to ensure that we are using the correct triangulation, i.e. the one containing *this.
+ // TODO: Think of a way to ensure that we are using the correct triangulation, i.e. the one containing *this.
int pos=next_free_pair,
- last=used.size()-1;
+ last=used.size()-1;
for (; pos<last; ++pos)
- if (!used[pos])
- {
- // this should be a pair slot
- Assert(!used[pos+1], ExcInternalError());
- break;
- }
+ if (!used[pos])
+ {
+ // this should be a pair slot
+ Assert(!used[pos+1], ExcInternalError());
+ break;
+ }
if (pos>=last)
- // no free slot
- return tria.end_hex();
+ // no free slot
+ return tria.end_hex();
else
- next_free_pair=pos+2;
+ next_free_pair=pos+2;
return typename dealii::Triangulation<dim,spacedim>::raw_hex_iterator(&tria,level,pos);
}
{
cells.reserve (new_size);
cells.insert (cells.end(),
- new_size-cells.size(),
- TriaObject<3> ());
+ new_size-cells.size(),
+ TriaObject<3> ());
used.reserve (new_size);
used.insert (used.end(),
- new_size-used.size(),
- false);
+ new_size-used.size(),
+ false);
user_flags.reserve (new_size);
user_flags.insert (user_flags.end(),
- new_size-user_flags.size(),
- false);
+ new_size-user_flags.size(),
+ false);
children.reserve (4*new_size);
children.insert (children.end(),
- 4*new_size-children.size(),
- -1);
+ 4*new_size-children.size(),
+ -1);
boundary_or_material_id.reserve (new_size);
boundary_or_material_id.insert (boundary_or_material_id.end(),
- new_size-boundary_or_material_id.size(),
- BoundaryOrMaterialId());
+ new_size-boundary_or_material_id.size(),
+ BoundaryOrMaterialId());
user_data.reserve (new_size);
user_data.insert (user_data.end(),
- new_size-user_data.size(),
- UserData());
+ new_size-user_data.size(),
+ UserData());
face_orientations.reserve (new_size * GeometryInfo<3>::faces_per_cell);
face_orientations.insert (face_orientations.end(),
- new_size * GeometryInfo<3>::faces_per_cell
- - face_orientations.size(),
- true);
+ new_size * GeometryInfo<3>::faces_per_cell
+ - face_orientations.size(),
+ true);
- refinement_cases.reserve (new_size);
- refinement_cases.insert (refinement_cases.end(),
- new_size-refinement_cases.size(),
- RefinementCase<3>::no_refinement);
+ refinement_cases.reserve (new_size);
+ refinement_cases.insert (refinement_cases.end(),
+ new_size-refinement_cases.size(),
+ RefinementCase<3>::no_refinement);
face_flips.reserve (new_size * GeometryInfo<3>::faces_per_cell);
face_flips.insert (face_flips.end(),
- new_size * GeometryInfo<3>::faces_per_cell
- - face_flips.size(),
- false);
+ new_size * GeometryInfo<3>::faces_per_cell
+ - face_flips.size(),
+ false);
face_rotations.reserve (new_size * GeometryInfo<3>::faces_per_cell);
face_rotations.insert (face_rotations.end(),
- new_size * GeometryInfo<3>::faces_per_cell
- - face_rotations.size(),
- false);
+ new_size * GeometryInfo<3>::faces_per_cell
+ - face_rotations.size(),
+ false);
}
next_free_single=next_free_pair=0;
}
void
TriaObjectsQuad3D::reserve_space (const unsigned int new_quads_in_pairs,
- const unsigned int new_quads_single)
+ const unsigned int new_quads_single)
{
Assert(new_quads_in_pairs%2==0, ExcInternalError());
next_free_pair=0;
reverse_order_next_free_single=false;
- // count the number of lines, of unused
- // single lines and of unused pairs of
- // lines
+ // count the number of lines, of unused
+ // single lines and of unused pairs of
+ // lines
unsigned int n_quads=0;
unsigned int n_unused_pairs=0;
unsigned int n_unused_singles=0;
for (unsigned int i=0; i<used.size(); ++i)
- {
- if (used[i])
- ++n_quads;
- else if (i+1<used.size())
- {
- if (used[i+1])
- {
- ++n_unused_singles;
- if (next_free_single==0)
- next_free_single=i;
- }
- else
- {
- ++n_unused_pairs;
- if (next_free_pair==0)
- next_free_pair=i;
- ++i;
- }
- }
- else
- ++n_unused_singles;
- }
+ {
+ if (used[i])
+ ++n_quads;
+ else if (i+1<used.size())
+ {
+ if (used[i+1])
+ {
+ ++n_unused_singles;
+ if (next_free_single==0)
+ next_free_single=i;
+ }
+ else
+ {
+ ++n_unused_pairs;
+ if (next_free_pair==0)
+ next_free_pair=i;
+ ++i;
+ }
+ }
+ else
+ ++n_unused_singles;
+ }
Assert(n_quads+2*n_unused_pairs+n_unused_singles==used.size(),
- ExcInternalError());
+ ExcInternalError());
- // how many single quads are needed in
- // addition to n_unused_quads?
+ // how many single quads are needed in
+ // addition to n_unused_quads?
const int additional_single_quads=
- new_quads_single-n_unused_singles;
+ new_quads_single-n_unused_singles;
unsigned int new_size=
- used.size() + new_quads_in_pairs - 2*n_unused_pairs;
+ used.size() + new_quads_in_pairs - 2*n_unused_pairs;
if (additional_single_quads>0)
- new_size+=additional_single_quads;
+ new_size+=additional_single_quads;
// see above...
if (new_size>cells.size())
{
- // reseve space for the base class
- TriaObjects<TriaObject<2> >::reserve_space(new_quads_in_pairs,new_quads_single);
- // reserve the field of the derived
- // class
+ // reseve space for the base class
+ TriaObjects<TriaObject<2> >::reserve_space(new_quads_in_pairs,new_quads_single);
+ // reserve the field of the derived
+ // class
line_orientations.reserve (new_size * GeometryInfo<2>::lines_per_cell);
line_orientations.insert (line_orientations.end(),
- new_size * GeometryInfo<2>::lines_per_cell
- - line_orientations.size(),
- true);
+ new_size * GeometryInfo<2>::lines_per_cell
+ - line_orientations.size(),
+ true);
}
if (n_unused_singles==0)
- {
- next_free_single=new_size-1;
- reverse_order_next_free_single=true;
- }
+ {
+ next_free_single=new_size-1;
+ reverse_order_next_free_single=true;
+ }
}
// as many elements as an integer
// has bits
Assert (cells.size() <=
- cells.capacity() + DEAL_II_MIN_VECTOR_CAPACITY,
+ cells.capacity() + DEAL_II_MIN_VECTOR_CAPACITY,
ExcMemoryWasted ("lines",
cells.size(), cells.capacity()));
Assert (children.size() <=
- children.capacity() + DEAL_II_MIN_VECTOR_CAPACITY,
+ children.capacity() + DEAL_II_MIN_VECTOR_CAPACITY,
ExcMemoryWasted ("children",
children.size(), children.capacity()));
Assert (used.size() <= used.capacity() + sizeof(int)*8 ||
// as many elements as an integer
// has bits
Assert (cells.size() <=
- cells.capacity() + DEAL_II_MIN_VECTOR_CAPACITY,
+ cells.capacity() + DEAL_II_MIN_VECTOR_CAPACITY,
ExcMemoryWasted ("quads",
cells.size(), cells.capacity()));
Assert (children.size() <=
- children.capacity() + DEAL_II_MIN_VECTOR_CAPACITY,
+ children.capacity() + DEAL_II_MIN_VECTOR_CAPACITY,
ExcMemoryWasted ("children",
children.size(), children.capacity()));
Assert (used.size() <= used.capacity() + sizeof(int)*8 ||
// as many elements as an integer
// has bits
Assert (cells.size() <=
- cells.capacity() + DEAL_II_MIN_VECTOR_CAPACITY,
+ cells.capacity() + DEAL_II_MIN_VECTOR_CAPACITY,
ExcMemoryWasted ("hexes",
cells.size(), cells.capacity()));
Assert (children.size() <=
- children.capacity() + DEAL_II_MIN_VECTOR_CAPACITY,
+ children.capacity() + DEAL_II_MIN_VECTOR_CAPACITY,
ExcMemoryWasted ("children",
children.size(), children.capacity()));
Assert (used.size() <= used.capacity() + sizeof(int)*8 ||
MemoryConsumption::memory_consumption (user_flags) +
MemoryConsumption::memory_consumption (boundary_or_material_id) +
MemoryConsumption::memory_consumption (refinement_cases) +
- user_data.capacity() * sizeof(UserData) + sizeof(user_data));
+ user_data.capacity() * sizeof(UserData) + sizeof(user_data));
}
TriaObjectsHex::memory_consumption () const
{
return (MemoryConsumption::memory_consumption (face_orientations) +
- MemoryConsumption::memory_consumption (face_flips) +
- MemoryConsumption::memory_consumption (face_rotations) +
- TriaObjects<TriaObject<3> >::memory_consumption() );
+ MemoryConsumption::memory_consumption (face_flips) +
+ MemoryConsumption::memory_consumption (face_rotations) +
+ TriaObjects<TriaObject<3> >::memory_consumption() );
}
TriaObjectsQuad3D::memory_consumption () const
{
return (MemoryConsumption::memory_consumption (line_orientations) +
- this->TriaObjects<TriaObject<2> >::memory_consumption() );
+ this->TriaObjects<TriaObject<2> >::memory_consumption() );
}
// $Id$
// Version: $Name$
//
-// Copyright (C) 2006, 2011 by the deal.II authors
+// Copyright (C) 2006, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
DoFFaces<3>::memory_consumption () const
{
return (MemoryConsumption::memory_consumption (quads) +
- MemoryConsumption::memory_consumption (quads) );
+ MemoryConsumption::memory_consumption (quads) );
}
}
// $Id$
// Version: $Name$
//
-// Copyright (C) 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011 by the deal.II authors
+// Copyright (C) 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
std::vector<std::pair<unsigned int, unsigned int> > DoFIdentities;
- /**
- * Make sure that the given @p
- * identities pointer points to a
- * valid array. If the pointer is
- * zero beforehand, create an
- * entry with the correct
- * data. If it is nonzero, don't
- * touch it.
- *
- * @p structdim denotes the
- * dimension of the objects on
- * which identities are to be
- * represented, i.e. zero for
- * vertices, one for lines, etc.
- */
+ /**
+ * Make sure that the given @p
+ * identities pointer points to a
+ * valid array. If the pointer is
+ * zero beforehand, create an
+ * entry with the correct
+ * data. If it is nonzero, don't
+ * touch it.
+ *
+ * @p structdim denotes the
+ * dimension of the objects on
+ * which identities are to be
+ * represented, i.e. zero for
+ * vertices, one for lines, etc.
+ */
template <int structdim, int dim, int spacedim>
void
ensure_existence_of_dof_identities (const FiniteElement<dim,spacedim> &fe1,
- const FiniteElement<dim,spacedim> &fe2,
- std_cxx1x::shared_ptr<DoFIdentities> &identities)
+ const FiniteElement<dim,spacedim> &fe2,
+ std_cxx1x::shared_ptr<DoFIdentities> &identities)
{
- // see if we need to fill this
- // entry, or whether it already
- // exists
+ // see if we need to fill this
+ // entry, or whether it already
+ // exists
if (identities.get() == 0)
- {
- switch (structdim)
- {
- case 0:
- {
- identities =
- std_cxx1x::shared_ptr<DoFIdentities>
- (new DoFIdentities(fe1.hp_vertex_dof_identities(fe2)));
- break;
- }
-
- case 1:
- {
- identities =
- std_cxx1x::shared_ptr<DoFIdentities>
- (new DoFIdentities(fe1.hp_line_dof_identities(fe2)));
- break;
- }
-
- case 2:
- {
- identities =
- std_cxx1x::shared_ptr<DoFIdentities>
- (new DoFIdentities(fe1.hp_quad_dof_identities(fe2)));
- break;
- }
-
- default:
- Assert (false, ExcNotImplemented());
- }
-
- // double check whether the
- // newly created entries
- // make any sense at all
- for (unsigned int i=0; i<identities->size(); ++i)
- {
- Assert ((*identities)[i].first < fe1.template n_dofs_per_object<structdim>(),
- ExcInternalError());
- Assert ((*identities)[i].second < fe2.template n_dofs_per_object<structdim>(),
- ExcInternalError());
- }
- }
+ {
+ switch (structdim)
+ {
+ case 0:
+ {
+ identities =
+ std_cxx1x::shared_ptr<DoFIdentities>
+ (new DoFIdentities(fe1.hp_vertex_dof_identities(fe2)));
+ break;
+ }
+
+ case 1:
+ {
+ identities =
+ std_cxx1x::shared_ptr<DoFIdentities>
+ (new DoFIdentities(fe1.hp_line_dof_identities(fe2)));
+ break;
+ }
+
+ case 2:
+ {
+ identities =
+ std_cxx1x::shared_ptr<DoFIdentities>
+ (new DoFIdentities(fe1.hp_quad_dof_identities(fe2)));
+ break;
+ }
+
+ default:
+ Assert (false, ExcNotImplemented());
+ }
+
+ // double check whether the
+ // newly created entries
+ // make any sense at all
+ for (unsigned int i=0; i<identities->size(); ++i)
+ {
+ Assert ((*identities)[i].first < fe1.template n_dofs_per_object<structdim>(),
+ ExcInternalError());
+ Assert ((*identities)[i].second < fe2.template n_dofs_per_object<structdim>(),
+ ExcInternalError());
+ }
+ }
}
if (other_fe_index != dominating_fe_index)
{
const FiniteElement<dim, spacedim>
- &that_fe
+ &that_fe
= object->get_fe (object->nth_active_fe_index(other_fe_index));
domination = domination &
{
namespace DoFHandler
{
- // access class
- // dealii::hp::DoFHandler instead of
- // namespace internal::hp::DoFHandler, etc
+ // access class
+ // dealii::hp::DoFHandler instead of
+ // namespace internal::hp::DoFHandler, etc
using dealii::hp::DoFHandler;
/**
*/
struct Implementation
{
- /**
- * Do that part of reserving
- * space that pertains to
- * vertices, since this is the
- * same in all space
- * dimensions.
- */
- template<int dim, int spacedim>
- static
- void
- reserve_space_vertices (DoFHandler<dim,spacedim> &dof_handler)
- {
- // The final step is allocating
- // memory is to set up vertex dof
- // information. since vertices
- // are sequentially numbered,
- // what we do first is to set up
- // an array in which we record
- // whether a vertex is associated
- // with any of the given fe's, by
- // setting a bit. in a later
- // step, we then actually
- // allocate memory for the
- // required dofs
- std::vector<std::vector<bool> >
- vertex_fe_association (dof_handler.finite_elements->size(),
- std::vector<bool> (dof_handler.tria->n_vertices(), false));
-
- for (typename DoFHandler<dim,spacedim>::active_cell_iterator
- cell=dof_handler.begin_active(); cell!=dof_handler.end(); ++cell)
- for (unsigned int v=0; v<GeometryInfo<dim>::vertices_per_cell; ++v)
- vertex_fe_association[cell->active_fe_index()][cell->vertex_index(v)]
- = true;
-
- // in debug mode, make sure
- // that each vertex is
- // associated with at least one
- // fe (note that except for
- // unused vertices, all
- // vertices are actually
- // active)
+ /**
+ * Do that part of reserving
+ * space that pertains to
+ * vertices, since this is the
+ * same in all space
+ * dimensions.
+ */
+ template<int dim, int spacedim>
+ static
+ void
+ reserve_space_vertices (DoFHandler<dim,spacedim> &dof_handler)
+ {
+ // The final step is allocating
+ // memory is to set up vertex dof
+ // information. since vertices
+ // are sequentially numbered,
+ // what we do first is to set up
+ // an array in which we record
+ // whether a vertex is associated
+ // with any of the given fe's, by
+ // setting a bit. in a later
+ // step, we then actually
+ // allocate memory for the
+ // required dofs
+ std::vector<std::vector<bool> >
+ vertex_fe_association (dof_handler.finite_elements->size(),
+ std::vector<bool> (dof_handler.tria->n_vertices(), false));
+
+ for (typename DoFHandler<dim,spacedim>::active_cell_iterator
+ cell=dof_handler.begin_active(); cell!=dof_handler.end(); ++cell)
+ for (unsigned int v=0; v<GeometryInfo<dim>::vertices_per_cell; ++v)
+ vertex_fe_association[cell->active_fe_index()][cell->vertex_index(v)]
+ = true;
+
+ // in debug mode, make sure
+ // that each vertex is
+ // associated with at least one
+ // fe (note that except for
+ // unused vertices, all
+ // vertices are actually
+ // active)
#ifdef DEBUG
- for (unsigned int v=0; v<dof_handler.tria->n_vertices(); ++v)
- if (dof_handler.tria->vertex_used(v) == true)
- {
- unsigned int fe=0;
- for (; fe<dof_handler.finite_elements->size(); ++fe)
- if (vertex_fe_association[fe][v] == true)
- break;
- Assert (fe != dof_handler.finite_elements->size(), ExcInternalError());
- }
+ for (unsigned int v=0; v<dof_handler.tria->n_vertices(); ++v)
+ if (dof_handler.tria->vertex_used(v) == true)
+ {
+ unsigned int fe=0;
+ for (; fe<dof_handler.finite_elements->size(); ++fe)
+ if (vertex_fe_association[fe][v] == true)
+ break;
+ Assert (fe != dof_handler.finite_elements->size(), ExcInternalError());
+ }
#endif
- // next count how much memory
- // we actually need. for each
- // vertex, we need one slot per
- // fe to store the fe_index,
- // plus dofs_per_vertex for
- // this fe. in addition, we
- // need one slot as the end
- // marker for the
- // fe_indices. at the same time
- // already fill the
- // vertex_dofs_offsets field
- dof_handler.vertex_dofs_offsets.resize (dof_handler.tria->n_vertices(),
- numbers::invalid_unsigned_int);
-
- unsigned int vertex_slots_needed = 0;
- for (unsigned int v=0; v<dof_handler.tria->n_vertices(); ++v)
- if (dof_handler.tria->vertex_used(v) == true)
- {
- dof_handler.vertex_dofs_offsets[v] = vertex_slots_needed;
-
- for (unsigned int fe=0; fe<dof_handler.finite_elements->size(); ++fe)
- if (vertex_fe_association[fe][v] == true)
- vertex_slots_needed += (*dof_handler.finite_elements)[fe].dofs_per_vertex + 1;
- ++vertex_slots_needed;
- }
-
- // now allocate the space we
- // have determined we need, and
- // set up the linked lists for
- // each of the vertices
- dof_handler.vertex_dofs.resize (vertex_slots_needed,
- DoFHandler<dim,spacedim>::invalid_dof_index);
- for (unsigned int v=0; v<dof_handler.tria->n_vertices(); ++v)
- if (dof_handler.tria->vertex_used(v) == true)
- {
- unsigned int pointer = dof_handler.vertex_dofs_offsets[v];
- for (unsigned int fe=0; fe<dof_handler.finite_elements->size(); ++fe)
- if (vertex_fe_association[fe][v] == true)
- {
- // if this vertex
- // uses this fe,
- // then set the
- // fe_index and
- // move the pointer
- // ahead
- dof_handler.vertex_dofs[pointer] = fe;
- pointer += (*dof_handler.finite_elements)[fe].dofs_per_vertex + 1;
- }
- // finally place the end
- // marker
- dof_handler.vertex_dofs[pointer] = numbers::invalid_unsigned_int;
- }
- }
-
-
-
- /**
- * Distribute dofs on the given cell,
- * with new dofs starting with index
- * @p next_free_dof. Return the next
- * unused index number. The finite
- * element used is the one given to
- * @p distribute_dofs, which is copied
- * to @p selected_fe.
- *
- * This function is excluded from the
- * @p distribute_dofs function since
- * it can not be implemented dimension
- * independent.
- */
- template <int spacedim>
- static
- unsigned int
- distribute_dofs_on_cell (const typename DoFHandler<1,spacedim>::active_cell_iterator &cell,
- unsigned int next_free_dof)
- {
- const unsigned int dim = 1;
-
- const FiniteElement<dim,spacedim> &fe = cell->get_fe();
- const unsigned int fe_index = cell->active_fe_index ();
-
- // number dofs on vertices. to do
- // so, check whether dofs for
- // this vertex have been
- // distributed and for the
- // present fe (only check the
- // first dof), and if this isn't
- // the case distribute new ones
- // there
- if (fe.dofs_per_vertex > 0)
- for (unsigned int vertex=0; vertex<GeometryInfo<1>::vertices_per_cell; ++vertex)
- if (cell->vertex_dof_index(vertex, 0, fe_index) ==
- DoFHandler<dim,spacedim>::invalid_dof_index)
- for (unsigned int d=0; d<fe.dofs_per_vertex; ++d, ++next_free_dof)
- cell->set_vertex_dof_index (vertex, d, next_free_dof, fe_index);
-
- // finally for the line. this one
- // shouldn't be numbered yet
- if (fe.dofs_per_line > 0)
- {
- Assert ((cell->dof_index(0, fe_index) ==
- DoFHandler<dim,spacedim>::invalid_dof_index),
- ExcInternalError());
-
- for (unsigned int d=0; d<fe.dofs_per_line; ++d, ++next_free_dof)
- cell->set_dof_index (d, next_free_dof, fe_index);
- }
-
- // note that this cell has been processed
- cell->set_user_flag ();
-
- return next_free_dof;
- }
-
-
- template <int spacedim>
- static
- unsigned int
- distribute_dofs_on_cell (const typename DoFHandler<2,spacedim>::active_cell_iterator &cell,
- unsigned int next_free_dof)
- {
- const unsigned int dim = 2;
-
- const FiniteElement<dim,spacedim> &fe = cell->get_fe();
- const unsigned int fe_index = cell->active_fe_index ();
-
- // number dofs on vertices. to do
- // so, check whether dofs for
- // this vertex have been
- // distributed and for the
- // present fe (only check the
- // first dof), and if this isn't
- // the case distribute new ones
- // there
- if (fe.dofs_per_vertex > 0)
- for (unsigned int vertex=0; vertex<GeometryInfo<2>::vertices_per_cell; ++vertex)
- if (cell->vertex_dof_index(vertex, 0, fe_index) ==
- DoFHandler<dim,spacedim>::invalid_dof_index)
- for (unsigned int d=0; d<fe.dofs_per_vertex; ++d, ++next_free_dof)
- cell->set_vertex_dof_index (vertex, d, next_free_dof, fe_index);
-
- // next the sides. do the
- // same as above: check whether
- // the line is already numbered
- // for the present fe_index, and
- // if not do it
- if (fe.dofs_per_line > 0)
- for (unsigned int l=0; l<GeometryInfo<2>::lines_per_cell; ++l)
- {
- typename DoFHandler<dim,spacedim>::line_iterator
- line = cell->line(l);
-
- if (line->dof_index(0,fe_index) ==
- DoFHandler<dim,spacedim>::invalid_dof_index)
- for (unsigned int d=0; d<fe.dofs_per_line; ++d, ++next_free_dof)
- line->set_dof_index (d, next_free_dof, fe_index);
- }
-
-
- // finally for the quad. this one
- // shouldn't be numbered yet
- if (fe.dofs_per_quad > 0)
- {
- Assert ((cell->dof_index(0, fe_index) ==
- DoFHandler<dim,spacedim>::invalid_dof_index),
- ExcInternalError());
-
- for (unsigned int d=0; d<fe.dofs_per_quad; ++d, ++next_free_dof)
- cell->set_dof_index (d, next_free_dof, fe_index);
- }
-
- // note that this cell has been processed
- cell->set_user_flag ();
-
- return next_free_dof;
- }
-
-
- template <int spacedim>
- static
- unsigned int
- distribute_dofs_on_cell (const typename DoFHandler<3,spacedim>::active_cell_iterator &cell,
- unsigned int next_free_dof)
- {
- const unsigned int dim = 3;
-
- const FiniteElement<dim,spacedim> &fe = cell->get_fe();
- const unsigned int fe_index = cell->active_fe_index ();
-
- // number dofs on vertices. to do
- // so, check whether dofs for
- // this vertex have been
- // distributed and for the
- // present fe (only check the
- // first dof), and if this isn't
- // the case distribute new ones
- // there
- if (fe.dofs_per_vertex > 0)
- for (unsigned int vertex=0; vertex<GeometryInfo<3>::vertices_per_cell; ++vertex)
- if (cell->vertex_dof_index(vertex, 0, fe_index) ==
- DoFHandler<dim,spacedim>::invalid_dof_index)
- for (unsigned int d=0; d<fe.dofs_per_vertex; ++d, ++next_free_dof)
- cell->set_vertex_dof_index (vertex, d, next_free_dof, fe_index);
-
- // next the four lines. do the
- // same as above: check whether
- // the line is already numbered
- // for the present fe_index, and
- // if not do it
- if (fe.dofs_per_line > 0)
- for (unsigned int l=0; l<GeometryInfo<3>::lines_per_cell; ++l)
- {
- typename DoFHandler<dim,spacedim>::line_iterator
- line = cell->line(l);
-
- if (line->dof_index(0,fe_index) ==
- DoFHandler<dim,spacedim>::invalid_dof_index)
- for (unsigned int d=0; d<fe.dofs_per_line; ++d, ++next_free_dof)
- line->set_dof_index (d, next_free_dof, fe_index);
- }
-
- // same for quads
- if (fe.dofs_per_quad > 0)
- for (unsigned int q=0; q<GeometryInfo<3>::quads_per_cell; ++q)
- {
- typename DoFHandler<dim,spacedim>::quad_iterator
- quad = cell->quad(q);
-
- if (quad->dof_index(0,fe_index) ==
- DoFHandler<dim,spacedim>::invalid_dof_index)
- for (unsigned int d=0; d<fe.dofs_per_quad; ++d, ++next_free_dof)
- quad->set_dof_index (d, next_free_dof, fe_index);
- }
-
-
- // finally for the hex. this one
- // shouldn't be numbered yet
- if (fe.dofs_per_hex > 0)
- {
- Assert ((cell->dof_index(0, fe_index) ==
- DoFHandler<dim,spacedim>::invalid_dof_index),
- ExcInternalError());
-
- for (unsigned int d=0; d<fe.dofs_per_hex; ++d, ++next_free_dof)
- cell->set_dof_index (d, next_free_dof, fe_index);
- }
-
- // note that this cell has been processed
- cell->set_user_flag ();
-
- return next_free_dof;
- }
-
-
- /**
- * Reserve enough space in the
- * <tt>levels[]</tt> objects to store the
- * numbers of the degrees of freedom
- * needed for the given element. The
- * given element is that one which
- * was selected when calling
- * @p distribute_dofs the last time.
- */
- template <int spacedim>
- static
- void
- reserve_space (DoFHandler<1,spacedim> &dof_handler)
- {
- const unsigned int dim = 1;
-
- typedef DoFHandler<dim,spacedim> BaseClass;
-
- Assert (dof_handler.finite_elements != 0,
- typename BaseClass::ExcNoFESelected());
- Assert (dof_handler.finite_elements->size() > 0,
- typename BaseClass::ExcNoFESelected());
- Assert (dof_handler.tria->n_levels() > 0,
- typename
- BaseClass::ExcInvalidTriangulation());
- Assert (dof_handler.tria->n_levels() == dof_handler.levels.size (),
- ExcInternalError ());
-
- // Release all space except the
- // active_fe_indices field which
- // we have to backup before
- {
- std::vector<std::vector<unsigned int> >
- active_fe_backup(dof_handler.levels.size ());
- for (unsigned int level = 0; level<dof_handler.levels.size (); ++level)
- std::swap (dof_handler.levels[level]->active_fe_indices, active_fe_backup[level]);
-
- // delete all levels and set them up
- // newly, since vectors are
- // troublesome if you want to change
- // their size
- dof_handler.clear_space ();
-
- for (unsigned int level=0; level<dof_handler.tria->n_levels(); ++level)
- {
- dof_handler.levels.push_back (new internal::hp::DoFLevel<dim>);
- std::swap (active_fe_backup[level],
- dof_handler.levels[level]->active_fe_indices);
- }
- }
-
- // LINE (CELL) DOFs
-
- // count how much space we need
- // on each level for the cell
- // dofs and set the
- // dof_*_offsets
- // data. initially set the latter
- // to an invalid index, and only
- // later set it to something
- // reasonable for active dof_handler.cells
- //
- // note that for dof_handler.cells, the
- // situation is simpler than for
- // other (lower dimensional)
- // objects since exactly one
- // finite element is used for it
- for (unsigned int level=0; level<dof_handler.tria->n_levels(); ++level)
- {
- dof_handler.levels[level]->lines.dof_offsets
- = std::vector<unsigned int> (dof_handler.tria->n_raw_lines(level),
- DoFHandler<dim,spacedim>::invalid_dof_index);
-
- unsigned int next_free_dof = 0;
- for (typename DoFHandler<dim,spacedim>::active_cell_iterator
- cell=dof_handler.begin_active(level);
- cell!=dof_handler.end_active(level); ++cell)
- if (!cell->has_children())
- {
- dof_handler.levels[level]->lines.dof_offsets[cell->index()] = next_free_dof;
- next_free_dof += cell->get_fe().dofs_per_line;
- }
-
- dof_handler.levels[level]->lines.dofs
- = std::vector<unsigned int> (next_free_dof,
- DoFHandler<dim,spacedim>::invalid_dof_index);
- }
-
- // safety check: make sure that
- // the number of DoFs we
- // allocated is actually correct
- // (above we have also set the
- // dof_*_offsets field, so
- // we couldn't use this simpler
- // algorithm)
+ // next count how much memory
+ // we actually need. for each
+ // vertex, we need one slot per
+ // fe to store the fe_index,
+ // plus dofs_per_vertex for
+ // this fe. in addition, we
+ // need one slot as the end
+ // marker for the
+ // fe_indices. at the same time
+ // already fill the
+ // vertex_dofs_offsets field
+ dof_handler.vertex_dofs_offsets.resize (dof_handler.tria->n_vertices(),
+ numbers::invalid_unsigned_int);
+
+ unsigned int vertex_slots_needed = 0;
+ for (unsigned int v=0; v<dof_handler.tria->n_vertices(); ++v)
+ if (dof_handler.tria->vertex_used(v) == true)
+ {
+ dof_handler.vertex_dofs_offsets[v] = vertex_slots_needed;
+
+ for (unsigned int fe=0; fe<dof_handler.finite_elements->size(); ++fe)
+ if (vertex_fe_association[fe][v] == true)
+ vertex_slots_needed += (*dof_handler.finite_elements)[fe].dofs_per_vertex + 1;
+ ++vertex_slots_needed;
+ }
+
+ // now allocate the space we
+ // have determined we need, and
+ // set up the linked lists for
+ // each of the vertices
+ dof_handler.vertex_dofs.resize (vertex_slots_needed,
+ DoFHandler<dim,spacedim>::invalid_dof_index);
+ for (unsigned int v=0; v<dof_handler.tria->n_vertices(); ++v)
+ if (dof_handler.tria->vertex_used(v) == true)
+ {
+ unsigned int pointer = dof_handler.vertex_dofs_offsets[v];
+ for (unsigned int fe=0; fe<dof_handler.finite_elements->size(); ++fe)
+ if (vertex_fe_association[fe][v] == true)
+ {
+ // if this vertex
+ // uses this fe,
+ // then set the
+ // fe_index and
+ // move the pointer
+ // ahead
+ dof_handler.vertex_dofs[pointer] = fe;
+ pointer += (*dof_handler.finite_elements)[fe].dofs_per_vertex + 1;
+ }
+ // finally place the end
+ // marker
+ dof_handler.vertex_dofs[pointer] = numbers::invalid_unsigned_int;
+ }
+ }
+
+
+
+ /**
+ * Distribute dofs on the given cell,
+ * with new dofs starting with index
+ * @p next_free_dof. Return the next
+ * unused index number. The finite
+ * element used is the one given to
+ * @p distribute_dofs, which is copied
+ * to @p selected_fe.
+ *
+ * This function is excluded from the
+ * @p distribute_dofs function since
+ * it can not be implemented dimension
+ * independent.
+ */
+ template <int spacedim>
+ static
+ unsigned int
+ distribute_dofs_on_cell (const typename DoFHandler<1,spacedim>::active_cell_iterator &cell,
+ unsigned int next_free_dof)
+ {
+ const unsigned int dim = 1;
+
+ const FiniteElement<dim,spacedim> &fe = cell->get_fe();
+ const unsigned int fe_index = cell->active_fe_index ();
+
+ // number dofs on vertices. to do
+ // so, check whether dofs for
+ // this vertex have been
+ // distributed and for the
+ // present fe (only check the
+ // first dof), and if this isn't
+ // the case distribute new ones
+ // there
+ if (fe.dofs_per_vertex > 0)
+ for (unsigned int vertex=0; vertex<GeometryInfo<1>::vertices_per_cell; ++vertex)
+ if (cell->vertex_dof_index(vertex, 0, fe_index) ==
+ DoFHandler<dim,spacedim>::invalid_dof_index)
+ for (unsigned int d=0; d<fe.dofs_per_vertex; ++d, ++next_free_dof)
+ cell->set_vertex_dof_index (vertex, d, next_free_dof, fe_index);
+
+ // finally for the line. this one
+ // shouldn't be numbered yet
+ if (fe.dofs_per_line > 0)
+ {
+ Assert ((cell->dof_index(0, fe_index) ==
+ DoFHandler<dim,spacedim>::invalid_dof_index),
+ ExcInternalError());
+
+ for (unsigned int d=0; d<fe.dofs_per_line; ++d, ++next_free_dof)
+ cell->set_dof_index (d, next_free_dof, fe_index);
+ }
+
+ // note that this cell has been processed
+ cell->set_user_flag ();
+
+ return next_free_dof;
+ }
+
+
+ template <int spacedim>
+ static
+ unsigned int
+ distribute_dofs_on_cell (const typename DoFHandler<2,spacedim>::active_cell_iterator &cell,
+ unsigned int next_free_dof)
+ {
+ const unsigned int dim = 2;
+
+ const FiniteElement<dim,spacedim> &fe = cell->get_fe();
+ const unsigned int fe_index = cell->active_fe_index ();
+
+ // number dofs on vertices. to do
+ // so, check whether dofs for
+ // this vertex have been
+ // distributed and for the
+ // present fe (only check the
+ // first dof), and if this isn't
+ // the case distribute new ones
+ // there
+ if (fe.dofs_per_vertex > 0)
+ for (unsigned int vertex=0; vertex<GeometryInfo<2>::vertices_per_cell; ++vertex)
+ if (cell->vertex_dof_index(vertex, 0, fe_index) ==
+ DoFHandler<dim,spacedim>::invalid_dof_index)
+ for (unsigned int d=0; d<fe.dofs_per_vertex; ++d, ++next_free_dof)
+ cell->set_vertex_dof_index (vertex, d, next_free_dof, fe_index);
+
+ // next the sides. do the
+ // same as above: check whether
+ // the line is already numbered
+ // for the present fe_index, and
+ // if not do it
+ if (fe.dofs_per_line > 0)
+ for (unsigned int l=0; l<GeometryInfo<2>::lines_per_cell; ++l)
+ {
+ typename DoFHandler<dim,spacedim>::line_iterator
+ line = cell->line(l);
+
+ if (line->dof_index(0,fe_index) ==
+ DoFHandler<dim,spacedim>::invalid_dof_index)
+ for (unsigned int d=0; d<fe.dofs_per_line; ++d, ++next_free_dof)
+ line->set_dof_index (d, next_free_dof, fe_index);
+ }
+
+
+ // finally for the quad. this one
+ // shouldn't be numbered yet
+ if (fe.dofs_per_quad > 0)
+ {
+ Assert ((cell->dof_index(0, fe_index) ==
+ DoFHandler<dim,spacedim>::invalid_dof_index),
+ ExcInternalError());
+
+ for (unsigned int d=0; d<fe.dofs_per_quad; ++d, ++next_free_dof)
+ cell->set_dof_index (d, next_free_dof, fe_index);
+ }
+
+ // note that this cell has been processed
+ cell->set_user_flag ();
+
+ return next_free_dof;
+ }
+
+
+ template <int spacedim>
+ static
+ unsigned int
+ distribute_dofs_on_cell (const typename DoFHandler<3,spacedim>::active_cell_iterator &cell,
+ unsigned int next_free_dof)
+ {
+ const unsigned int dim = 3;
+
+ const FiniteElement<dim,spacedim> &fe = cell->get_fe();
+ const unsigned int fe_index = cell->active_fe_index ();
+
+ // number dofs on vertices. to do
+ // so, check whether dofs for
+ // this vertex have been
+ // distributed and for the
+ // present fe (only check the
+ // first dof), and if this isn't
+ // the case distribute new ones
+ // there
+ if (fe.dofs_per_vertex > 0)
+ for (unsigned int vertex=0; vertex<GeometryInfo<3>::vertices_per_cell; ++vertex)
+ if (cell->vertex_dof_index(vertex, 0, fe_index) ==
+ DoFHandler<dim,spacedim>::invalid_dof_index)
+ for (unsigned int d=0; d<fe.dofs_per_vertex; ++d, ++next_free_dof)
+ cell->set_vertex_dof_index (vertex, d, next_free_dof, fe_index);
+
+ // next the four lines. do the
+ // same as above: check whether
+ // the line is already numbered
+ // for the present fe_index, and
+ // if not do it
+ if (fe.dofs_per_line > 0)
+ for (unsigned int l=0; l<GeometryInfo<3>::lines_per_cell; ++l)
+ {
+ typename DoFHandler<dim,spacedim>::line_iterator
+ line = cell->line(l);
+
+ if (line->dof_index(0,fe_index) ==
+ DoFHandler<dim,spacedim>::invalid_dof_index)
+ for (unsigned int d=0; d<fe.dofs_per_line; ++d, ++next_free_dof)
+ line->set_dof_index (d, next_free_dof, fe_index);
+ }
+
+ // same for quads
+ if (fe.dofs_per_quad > 0)
+ for (unsigned int q=0; q<GeometryInfo<3>::quads_per_cell; ++q)
+ {
+ typename DoFHandler<dim,spacedim>::quad_iterator
+ quad = cell->quad(q);
+
+ if (quad->dof_index(0,fe_index) ==
+ DoFHandler<dim,spacedim>::invalid_dof_index)
+ for (unsigned int d=0; d<fe.dofs_per_quad; ++d, ++next_free_dof)
+ quad->set_dof_index (d, next_free_dof, fe_index);
+ }
+
+
+ // finally for the hex. this one
+ // shouldn't be numbered yet
+ if (fe.dofs_per_hex > 0)
+ {
+ Assert ((cell->dof_index(0, fe_index) ==
+ DoFHandler<dim,spacedim>::invalid_dof_index),
+ ExcInternalError());
+
+ for (unsigned int d=0; d<fe.dofs_per_hex; ++d, ++next_free_dof)
+ cell->set_dof_index (d, next_free_dof, fe_index);
+ }
+
+ // note that this cell has been processed
+ cell->set_user_flag ();
+
+ return next_free_dof;
+ }
+
+
+ /**
+ * Reserve enough space in the
+ * <tt>levels[]</tt> objects to store the
+ * numbers of the degrees of freedom
+ * needed for the given element. The
+ * given element is that one which
+ * was selected when calling
+ * @p distribute_dofs the last time.
+ */
+ template <int spacedim>
+ static
+ void
+ reserve_space (DoFHandler<1,spacedim> &dof_handler)
+ {
+ const unsigned int dim = 1;
+
+ typedef DoFHandler<dim,spacedim> BaseClass;
+
+ Assert (dof_handler.finite_elements != 0,
+ typename BaseClass::ExcNoFESelected());
+ Assert (dof_handler.finite_elements->size() > 0,
+ typename BaseClass::ExcNoFESelected());
+ Assert (dof_handler.tria->n_levels() > 0,
+ typename
+ BaseClass::ExcInvalidTriangulation());
+ Assert (dof_handler.tria->n_levels() == dof_handler.levels.size (),
+ ExcInternalError ());
+
+ // Release all space except the
+ // active_fe_indices field which
+ // we have to backup before
+ {
+ std::vector<std::vector<unsigned int> >
+ active_fe_backup(dof_handler.levels.size ());
+ for (unsigned int level = 0; level<dof_handler.levels.size (); ++level)
+ std::swap (dof_handler.levels[level]->active_fe_indices, active_fe_backup[level]);
+
+ // delete all levels and set them up
+ // newly, since vectors are
+ // troublesome if you want to change
+ // their size
+ dof_handler.clear_space ();
+
+ for (unsigned int level=0; level<dof_handler.tria->n_levels(); ++level)
+ {
+ dof_handler.levels.push_back (new internal::hp::DoFLevel<dim>);
+ std::swap (active_fe_backup[level],
+ dof_handler.levels[level]->active_fe_indices);
+ }
+ }
+
+ // LINE (CELL) DOFs
+
+ // count how much space we need
+ // on each level for the cell
+ // dofs and set the
+ // dof_*_offsets
+ // data. initially set the latter
+ // to an invalid index, and only
+ // later set it to something
+ // reasonable for active dof_handler.cells
+ //
+ // note that for dof_handler.cells, the
+ // situation is simpler than for
+ // other (lower dimensional)
+ // objects since exactly one
+ // finite element is used for it
+ for (unsigned int level=0; level<dof_handler.tria->n_levels(); ++level)
+ {
+ dof_handler.levels[level]->lines.dof_offsets
+ = std::vector<unsigned int> (dof_handler.tria->n_raw_lines(level),
+ DoFHandler<dim,spacedim>::invalid_dof_index);
+
+ unsigned int next_free_dof = 0;
+ for (typename DoFHandler<dim,spacedim>::active_cell_iterator
+ cell=dof_handler.begin_active(level);
+ cell!=dof_handler.end_active(level); ++cell)
+ if (!cell->has_children())
+ {
+ dof_handler.levels[level]->lines.dof_offsets[cell->index()] = next_free_dof;
+ next_free_dof += cell->get_fe().dofs_per_line;
+ }
+
+ dof_handler.levels[level]->lines.dofs
+ = std::vector<unsigned int> (next_free_dof,
+ DoFHandler<dim,spacedim>::invalid_dof_index);
+ }
+
+ // safety check: make sure that
+ // the number of DoFs we
+ // allocated is actually correct
+ // (above we have also set the
+ // dof_*_offsets field, so
+ // we couldn't use this simpler
+ // algorithm)
#ifdef DEBUG
- for (unsigned int level=0; level<dof_handler.tria->n_levels(); ++level)
- {
- unsigned int counter = 0;
- for (typename DoFHandler<dim,spacedim>::cell_iterator
- cell=dof_handler.begin_active(level);
- cell!=dof_handler.end_active(level); ++cell)
- if (!cell->has_children())
- counter += cell->get_fe().dofs_per_line;
-
- Assert (dof_handler.levels[level]->lines.dofs.size() == counter,
- ExcInternalError());
- Assert (static_cast<unsigned int>
- (std::count (dof_handler.levels[level]->lines.dof_offsets.begin(),
- dof_handler.levels[level]->lines.dof_offsets.end(),
- DoFHandler<dim,spacedim>::invalid_dof_index))
- ==
- dof_handler.tria->n_raw_lines(level) - dof_handler.tria->n_active_lines(level),
- ExcInternalError());
- }
+ for (unsigned int level=0; level<dof_handler.tria->n_levels(); ++level)
+ {
+ unsigned int counter = 0;
+ for (typename DoFHandler<dim,spacedim>::cell_iterator
+ cell=dof_handler.begin_active(level);
+ cell!=dof_handler.end_active(level); ++cell)
+ if (!cell->has_children())
+ counter += cell->get_fe().dofs_per_line;
+
+ Assert (dof_handler.levels[level]->lines.dofs.size() == counter,
+ ExcInternalError());
+ Assert (static_cast<unsigned int>
+ (std::count (dof_handler.levels[level]->lines.dof_offsets.begin(),
+ dof_handler.levels[level]->lines.dof_offsets.end(),
+ DoFHandler<dim,spacedim>::invalid_dof_index))
+ ==
+ dof_handler.tria->n_raw_lines(level) - dof_handler.tria->n_active_lines(level),
+ ExcInternalError());
+ }
#endif
- // VERTEX DOFS
- reserve_space_vertices (dof_handler);
- }
-
-
- template <int spacedim>
- static
- void
- reserve_space (DoFHandler<2,spacedim> &dof_handler)
- {
- const unsigned int dim = 2;
-
- typedef DoFHandler<dim,spacedim> BaseClass;
-
- Assert (dof_handler.finite_elements != 0,
- typename BaseClass::ExcNoFESelected());
- Assert (dof_handler.finite_elements->size() > 0,
- typename BaseClass::ExcNoFESelected());
- Assert (dof_handler.tria->n_levels() > 0,
- typename BaseClass::ExcInvalidTriangulation());
- Assert (dof_handler.tria->n_levels() == dof_handler.levels.size (),
- ExcInternalError ());
-
- // Release all space except the
- // active_fe_indices field which
- // we have to backup before
- {
- std::vector<std::vector<unsigned int> >
- active_fe_backup(dof_handler.levels.size ());
- for (unsigned int level = 0; level<dof_handler.levels.size (); ++level)
- std::swap (dof_handler.levels[level]->active_fe_indices,
- active_fe_backup[level]);
-
- // delete all levels and set them up
- // newly, since vectors are
- // troublesome if you want to change
- // their size
- dof_handler.clear_space ();
-
- for (unsigned int level=0; level<dof_handler.tria->n_levels(); ++level)
- {
- dof_handler.levels.push_back (new internal::hp::DoFLevel<dim>);
- std::swap (active_fe_backup[level],
- dof_handler.levels[level]->active_fe_indices);
- }
- dof_handler.faces = new internal::hp::DoFFaces<2>;
- }
-
-
- // QUAD (CELL) DOFs
-
- // count how much space we need
- // on each level for the cell
- // dofs and set the
- // dof_*_offsets
- // data. initially set the latter
- // to an invalid index, and only
- // later set it to something
- // reasonable for active dof_handler.cells
- //
- // note that for dof_handler.cells, the
- // situation is simpler than for
- // other (lower dimensional)
- // objects since exactly one
- // finite element is used for it
- for (unsigned int level=0; level<dof_handler.tria->n_levels(); ++level)
- {
- dof_handler.levels[level]->quads.dof_offsets
- = std::vector<unsigned int> (dof_handler.tria->n_raw_quads(level),
- DoFHandler<dim,spacedim>::invalid_dof_index);
-
- unsigned int next_free_dof = 0;
- for (typename DoFHandler<dim,spacedim>::active_cell_iterator
- cell=dof_handler.begin_active(level);
- cell!=dof_handler.end_active(level); ++cell)
- if (!cell->has_children())
- {
- dof_handler.levels[level]->quads.dof_offsets[cell->index()] = next_free_dof;
- next_free_dof += cell->get_fe().dofs_per_quad;
- }
-
- dof_handler.levels[level]->quads.dofs
- = std::vector<unsigned int> (next_free_dof,
- DoFHandler<dim,spacedim>::invalid_dof_index);
- }
-
- // safety check: make sure that
- // the number of DoFs we
- // allocated is actually correct
- // (above we have also set the
- // dof_*_offsets field, so
- // we couldn't use this simpler
- // algorithm)
+ // VERTEX DOFS
+ reserve_space_vertices (dof_handler);
+ }
+
+
+ template <int spacedim>
+ static
+ void
+ reserve_space (DoFHandler<2,spacedim> &dof_handler)
+ {
+ const unsigned int dim = 2;
+
+ typedef DoFHandler<dim,spacedim> BaseClass;
+
+ Assert (dof_handler.finite_elements != 0,
+ typename BaseClass::ExcNoFESelected());
+ Assert (dof_handler.finite_elements->size() > 0,
+ typename BaseClass::ExcNoFESelected());
+ Assert (dof_handler.tria->n_levels() > 0,
+ typename BaseClass::ExcInvalidTriangulation());
+ Assert (dof_handler.tria->n_levels() == dof_handler.levels.size (),
+ ExcInternalError ());
+
+ // Release all space except the
+ // active_fe_indices field which
+ // we have to backup before
+ {
+ std::vector<std::vector<unsigned int> >
+ active_fe_backup(dof_handler.levels.size ());
+ for (unsigned int level = 0; level<dof_handler.levels.size (); ++level)
+ std::swap (dof_handler.levels[level]->active_fe_indices,
+ active_fe_backup[level]);
+
+ // delete all levels and set them up
+ // newly, since vectors are
+ // troublesome if you want to change
+ // their size
+ dof_handler.clear_space ();
+
+ for (unsigned int level=0; level<dof_handler.tria->n_levels(); ++level)
+ {
+ dof_handler.levels.push_back (new internal::hp::DoFLevel<dim>);
+ std::swap (active_fe_backup[level],
+ dof_handler.levels[level]->active_fe_indices);
+ }
+ dof_handler.faces = new internal::hp::DoFFaces<2>;
+ }
+
+
+ // QUAD (CELL) DOFs
+
+ // count how much space we need
+ // on each level for the cell
+ // dofs and set the
+ // dof_*_offsets
+ // data. initially set the latter
+ // to an invalid index, and only
+ // later set it to something
+ // reasonable for active dof_handler.cells
+ //
+ // note that for dof_handler.cells, the
+ // situation is simpler than for
+ // other (lower dimensional)
+ // objects since exactly one
+ // finite element is used for it
+ for (unsigned int level=0; level<dof_handler.tria->n_levels(); ++level)
+ {
+ dof_handler.levels[level]->quads.dof_offsets
+ = std::vector<unsigned int> (dof_handler.tria->n_raw_quads(level),
+ DoFHandler<dim,spacedim>::invalid_dof_index);
+
+ unsigned int next_free_dof = 0;
+ for (typename DoFHandler<dim,spacedim>::active_cell_iterator
+ cell=dof_handler.begin_active(level);
+ cell!=dof_handler.end_active(level); ++cell)
+ if (!cell->has_children())
+ {
+ dof_handler.levels[level]->quads.dof_offsets[cell->index()] = next_free_dof;
+ next_free_dof += cell->get_fe().dofs_per_quad;
+ }
+
+ dof_handler.levels[level]->quads.dofs
+ = std::vector<unsigned int> (next_free_dof,
+ DoFHandler<dim,spacedim>::invalid_dof_index);
+ }
+
+ // safety check: make sure that
+ // the number of DoFs we
+ // allocated is actually correct
+ // (above we have also set the
+ // dof_*_offsets field, so
+ // we couldn't use this simpler
+ // algorithm)
#ifdef DEBUG
- for (unsigned int level=0; level<dof_handler.tria->n_levels(); ++level)
- {
- unsigned int counter = 0;
- for (typename DoFHandler<dim,spacedim>::cell_iterator
- cell=dof_handler.begin_active(level);
- cell!=dof_handler.end_active(level); ++cell)
- if (!cell->has_children())
- counter += cell->get_fe().dofs_per_quad;
-
- Assert (dof_handler.levels[level]->quads.dofs.size() == counter,
- ExcInternalError());
- Assert (static_cast<unsigned int>
- (std::count (dof_handler.levels[level]->quads.dof_offsets.begin(),
- dof_handler.levels[level]->quads.dof_offsets.end(),
- DoFHandler<dim,spacedim>::invalid_dof_index))
- ==
- dof_handler.tria->n_raw_quads(level) - dof_handler.tria->n_active_quads(level),
- ExcInternalError());
- }
+ for (unsigned int level=0; level<dof_handler.tria->n_levels(); ++level)
+ {
+ unsigned int counter = 0;
+ for (typename DoFHandler<dim,spacedim>::cell_iterator
+ cell=dof_handler.begin_active(level);
+ cell!=dof_handler.end_active(level); ++cell)
+ if (!cell->has_children())
+ counter += cell->get_fe().dofs_per_quad;
+
+ Assert (dof_handler.levels[level]->quads.dofs.size() == counter,
+ ExcInternalError());
+ Assert (static_cast<unsigned int>
+ (std::count (dof_handler.levels[level]->quads.dof_offsets.begin(),
+ dof_handler.levels[level]->quads.dof_offsets.end(),
+ DoFHandler<dim,spacedim>::invalid_dof_index))
+ ==
+ dof_handler.tria->n_raw_quads(level) - dof_handler.tria->n_active_quads(level),
+ ExcInternalError());
+ }
#endif
- // LINE DOFS
- //
- // same here: count line dofs,
- // then allocate as much space as
- // we need and prime the linked
- // list for lines (see the
- // description in hp::DoFLevels)
- // with the indices we will
- // need. note that our task is
- // more complicated since two
- // adjacent dof_handler.cells may have
- // different active_fe_indices,
- // in which case we need to
- // allocate *two* sets of line
- // dofs for the same line
- //
- // the way we do things is that
- // we loop over all active dof_handler.cells
- // (these are the ones that have
- // DoFs only anyway) and all
- // their dof_handler.faces. We note in the
- // user flags whether we have
- // previously visited a face and
- // if so skip it (consequently,
- // we have to save and later
- // restore the line flags)
- {
- std::vector<bool> saved_line_user_flags;
- const_cast<dealii::Triangulation<dim,spacedim>&>(*dof_handler.tria)
- .save_user_flags_line (saved_line_user_flags);
- const_cast<dealii::Triangulation<dim,spacedim>&>(*dof_handler.tria)
- .clear_user_flags_line ();
-
- // an array to hold how many
- // slots (see the hp::DoFLevel
- // class) we will have to store
- // on each level
- unsigned int n_line_slots = 0;
-
- for (typename DoFHandler<dim,spacedim>::active_cell_iterator
- cell=dof_handler.begin_active(); cell!=dof_handler.end(); ++cell)
- for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
- if (! cell->face(face)->user_flag_set())
- {
- // ok, face has not been
- // visited. so we need to
- // allocate space for it. let's
- // see how much we need: we need
- // one set if a) there is no
- // neighbor behind this face, or
- // b) the neighbor is either
- // coarser or finer than we are,
- // or c) the neighbor is neither
- // coarser nor finer, but has
- // happens to have the same
- // active_fe_index:
- if (cell->at_boundary(face)
- ||
- cell->face(face)->has_children()
- ||
- cell->neighbor_is_coarser(face)
- ||
- (!cell->at_boundary(face)
- &&
- (cell->active_fe_index() == cell->neighbor(face)->active_fe_index())))
- // ok, one set of
- // dofs. that makes
- // one index, 1 times
- // dofs_per_line
- // dofs, and one stop
- // index
- n_line_slots
- += (*dof_handler.finite_elements)[cell->active_fe_index()].dofs_per_line + 2;
-
- // otherwise we do
- // indeed need two
- // sets, i.e. two
- // indices, two sets of
- // dofs, and one stop
- // index:
- else
- n_line_slots
- += ((*dof_handler.finite_elements)[cell->active_fe_index()].dofs_per_line
- +
- (*dof_handler.finite_elements)[cell->neighbor(face)->active_fe_index()]
- .dofs_per_line
- +
- 3);
-
- // mark this face as
- // visited
- cell->face(face)->set_user_flag ();
- }
-
- // now that we know how many
- // line dofs we will have to
- // have on each level, allocate
- // the memory. note that we
- // allocate offsets for all
- // lines, though only the
- // active ones will have a
- // non-invalid value later on
- dof_handler.faces->lines.dof_offsets
- = std::vector<unsigned int> (dof_handler.tria->n_raw_lines(),
- DoFHandler<dim,spacedim>::invalid_dof_index);
- dof_handler.faces->lines.dofs
- = std::vector<unsigned int> (n_line_slots,
- DoFHandler<dim,spacedim>::invalid_dof_index);
-
- // with the memory now
- // allocated, loop over the
- // dof_handler.cells again and prime the
- // _offset values as well as
- // the fe_index fields
- const_cast<dealii::Triangulation<dim,spacedim>&>(*dof_handler.tria)
- .clear_user_flags_line ();
-
- unsigned int next_free_line_slot = 0;
-
- for (typename DoFHandler<dim,spacedim>::active_cell_iterator
- cell=dof_handler.begin_active(); cell!=dof_handler.end(); ++cell)
- for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
- if (! cell->face(face)->user_flag_set())
- {
- // same decision tree
- // as before
- if (cell->at_boundary(face)
- ||
- cell->face(face)->has_children()
- ||
- cell->neighbor_is_coarser(face)
- ||
- (!cell->at_boundary(face)
- &&
- (cell->active_fe_index() == cell->neighbor(face)->active_fe_index())))
- {
- dof_handler.faces
- ->lines.dof_offsets[cell->face(face)->index()]
- = next_free_line_slot;
-
- // set first slot
- // for this line to
- // active_fe_index
- // of this face
- dof_handler.faces
- ->lines.dofs[next_free_line_slot]
- = cell->active_fe_index();
-
- // the next
- // dofs_per_line
- // indices remain
- // unset for the
- // moment (i.e. at
- // invalid_dof_index).
- // following this
- // comes the stop
- // index, which
- // also is
- // invalid_dof_index
- // and therefore
- // does not have to
- // be explicitly
- // set
-
- // finally, mark
- // those slots as
- // used
- next_free_line_slot
- += (*dof_handler.finite_elements)[cell->active_fe_index()].dofs_per_line + 2;
- }
- else
- {
- dof_handler.faces
- ->lines.dof_offsets[cell->face(face)->index()]
- = next_free_line_slot;
-
- // set first slot
- // for this line to
- // active_fe_index
- // of this face
- dof_handler.faces
- ->lines.dofs[next_free_line_slot]
- = cell->active_fe_index();
-
- // the next
- // dofs_per_line
- // indices remain
- // unset for the
- // moment (i.e. at
- // invalid_dof_index).
- //
- // then comes the
- // fe_index for the
- // neighboring
- // cell:
- dof_handler.faces
- ->lines.dofs[next_free_line_slot
- +
- (*dof_handler.finite_elements)[cell->active_fe_index()].dofs_per_line
- +
- 1]
- = cell->neighbor(face)->active_fe_index();
- // then again a set
- // of dofs that we
- // need not set
- // right now
- //
- // following this
- // comes the stop
- // index, which
- // also is
- // invalid_dof_index
- // and therefore
- // does not have to
- // be explicitly
- // set
-
- // finally, mark
- // those slots as
- // used
- next_free_line_slot
- += ((*dof_handler.finite_elements)[cell->active_fe_index()].dofs_per_line
- +
- (*dof_handler.finite_elements)[cell->neighbor(face)->active_fe_index()]
- .dofs_per_line
- +
- 3);
- }
-
- // mark this face as
- // visited
- cell->face(face)->set_user_flag ();
- }
-
- // we should have moved the
- // cursor for each level to the
- // total number of dofs on that
- // level. check that
- Assert (next_free_line_slot == n_line_slots,
- ExcInternalError());
-
- // at the end, restore the user
- // flags for the lines
- const_cast<dealii::Triangulation<dim,spacedim>&>(*dof_handler.tria)
- .load_user_flags_line (saved_line_user_flags);
- }
-
-
- // VERTEX DOFS
- reserve_space_vertices (dof_handler);
- }
-
-
- template <int spacedim>
- static
- void
- reserve_space (DoFHandler<3,spacedim> &dof_handler)
- {
- const unsigned int dim = 3;
-
- typedef DoFHandler<dim,spacedim> BaseClass;
-
- Assert (dof_handler.finite_elements != 0,
- typename BaseClass::ExcNoFESelected());
- Assert (dof_handler.finite_elements->size() > 0,
- typename BaseClass::ExcNoFESelected());
- Assert (dof_handler.tria->n_levels() > 0,
- typename BaseClass::ExcInvalidTriangulation());
- Assert (dof_handler.tria->n_levels() == dof_handler.levels.size (),
- ExcInternalError ());
-
- // Release all space except the
- // active_fe_indices field which
- // we have to backup before
- {
- std::vector<std::vector<unsigned int> >
- active_fe_backup(dof_handler.levels.size ());
- for (unsigned int level = 0; level<dof_handler.levels.size (); ++level)
- std::swap (dof_handler.levels[level]->active_fe_indices,
- active_fe_backup[level]);
-
- // delete all levels and set them up
- // newly, since vectors are
- // troublesome if you want to change
- // their size
- dof_handler.clear_space ();
-
- for (unsigned int level=0; level<dof_handler.tria->n_levels(); ++level)
- {
- dof_handler.levels.push_back (new internal::hp::DoFLevel<dim>);
- std::swap (active_fe_backup[level],
- dof_handler.levels[level]->active_fe_indices);
- }
- dof_handler.faces = new internal::hp::DoFFaces<3>;
- }
-
-
- // HEX (CELL) DOFs
-
- // count how much space we need
- // on each level for the cell
- // dofs and set the
- // dof_*_offsets
- // data. initially set the latter
- // to an invalid index, and only
- // later set it to something
- // reasonable for active dof_handler.cells
- //
- // note that for dof_handler.cells, the
- // situation is simpler than for
- // other (lower dimensional)
- // objects since exactly one
- // finite element is used for it
- for (unsigned int level=0; level<dof_handler.tria->n_levels(); ++level)
- {
- dof_handler.levels[level]->hexes.dof_offsets
- = std::vector<unsigned int> (dof_handler.tria->n_raw_hexs(level),
- DoFHandler<dim,spacedim>::invalid_dof_index);
-
- unsigned int next_free_dof = 0;
- for (typename DoFHandler<dim,spacedim>::active_cell_iterator
- cell=dof_handler.begin_active(level);
- cell!=dof_handler.end_active(level); ++cell)
- if (!cell->has_children())
- {
- dof_handler.levels[level]->hexes.dof_offsets[cell->index()] = next_free_dof;
- next_free_dof += cell->get_fe().dofs_per_hex;
- }
-
- dof_handler.levels[level]->hexes.dofs
- = std::vector<unsigned int> (next_free_dof,
- DoFHandler<dim,spacedim>::invalid_dof_index);
- }
-
- // safety check: make sure that
- // the number of DoFs we
- // allocated is actually correct
- // (above we have also set the
- // dof_*_offsets field, so
- // we couldn't use this simpler
- // algorithm)
+ // LINE DOFS
+ //
+ // same here: count line dofs,
+ // then allocate as much space as
+ // we need and prime the linked
+ // list for lines (see the
+ // description in hp::DoFLevels)
+ // with the indices we will
+ // need. note that our task is
+ // more complicated since two
+ // adjacent dof_handler.cells may have
+ // different active_fe_indices,
+ // in which case we need to
+ // allocate *two* sets of line
+ // dofs for the same line
+ //
+ // the way we do things is that
+ // we loop over all active dof_handler.cells
+ // (these are the ones that have
+ // DoFs only anyway) and all
+ // their dof_handler.faces. We note in the
+ // user flags whether we have
+ // previously visited a face and
+ // if so skip it (consequently,
+ // we have to save and later
+ // restore the line flags)
+ {
+ std::vector<bool> saved_line_user_flags;
+ const_cast<dealii::Triangulation<dim,spacedim>&>(*dof_handler.tria)
+ .save_user_flags_line (saved_line_user_flags);
+ const_cast<dealii::Triangulation<dim,spacedim>&>(*dof_handler.tria)
+ .clear_user_flags_line ();
+
+ // an array to hold how many
+ // slots (see the hp::DoFLevel
+ // class) we will have to store
+ // on each level
+ unsigned int n_line_slots = 0;
+
+ for (typename DoFHandler<dim,spacedim>::active_cell_iterator
+ cell=dof_handler.begin_active(); cell!=dof_handler.end(); ++cell)
+ for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
+ if (! cell->face(face)->user_flag_set())
+ {
+ // ok, face has not been
+ // visited. so we need to
+ // allocate space for it. let's
+ // see how much we need: we need
+ // one set if a) there is no
+ // neighbor behind this face, or
+ // b) the neighbor is either
+ // coarser or finer than we are,
+ // or c) the neighbor is neither
+ // coarser nor finer, but has
+ // happens to have the same
+ // active_fe_index:
+ if (cell->at_boundary(face)
+ ||
+ cell->face(face)->has_children()
+ ||
+ cell->neighbor_is_coarser(face)
+ ||
+ (!cell->at_boundary(face)
+ &&
+ (cell->active_fe_index() == cell->neighbor(face)->active_fe_index())))
+ // ok, one set of
+ // dofs. that makes
+ // one index, 1 times
+ // dofs_per_line
+ // dofs, and one stop
+ // index
+ n_line_slots
+ += (*dof_handler.finite_elements)[cell->active_fe_index()].dofs_per_line + 2;
+
+ // otherwise we do
+ // indeed need two
+ // sets, i.e. two
+ // indices, two sets of
+ // dofs, and one stop
+ // index:
+ else
+ n_line_slots
+ += ((*dof_handler.finite_elements)[cell->active_fe_index()].dofs_per_line
+ +
+ (*dof_handler.finite_elements)[cell->neighbor(face)->active_fe_index()]
+ .dofs_per_line
+ +
+ 3);
+
+ // mark this face as
+ // visited
+ cell->face(face)->set_user_flag ();
+ }
+
+ // now that we know how many
+ // line dofs we will have to
+ // have on each level, allocate
+ // the memory. note that we
+ // allocate offsets for all
+ // lines, though only the
+ // active ones will have a
+ // non-invalid value later on
+ dof_handler.faces->lines.dof_offsets
+ = std::vector<unsigned int> (dof_handler.tria->n_raw_lines(),
+ DoFHandler<dim,spacedim>::invalid_dof_index);
+ dof_handler.faces->lines.dofs
+ = std::vector<unsigned int> (n_line_slots,
+ DoFHandler<dim,spacedim>::invalid_dof_index);
+
+ // with the memory now
+ // allocated, loop over the
+ // dof_handler.cells again and prime the
+ // _offset values as well as
+ // the fe_index fields
+ const_cast<dealii::Triangulation<dim,spacedim>&>(*dof_handler.tria)
+ .clear_user_flags_line ();
+
+ unsigned int next_free_line_slot = 0;
+
+ for (typename DoFHandler<dim,spacedim>::active_cell_iterator
+ cell=dof_handler.begin_active(); cell!=dof_handler.end(); ++cell)
+ for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
+ if (! cell->face(face)->user_flag_set())
+ {
+ // same decision tree
+ // as before
+ if (cell->at_boundary(face)
+ ||
+ cell->face(face)->has_children()
+ ||
+ cell->neighbor_is_coarser(face)
+ ||
+ (!cell->at_boundary(face)
+ &&
+ (cell->active_fe_index() == cell->neighbor(face)->active_fe_index())))
+ {
+ dof_handler.faces
+ ->lines.dof_offsets[cell->face(face)->index()]
+ = next_free_line_slot;
+
+ // set first slot
+ // for this line to
+ // active_fe_index
+ // of this face
+ dof_handler.faces
+ ->lines.dofs[next_free_line_slot]
+ = cell->active_fe_index();
+
+ // the next
+ // dofs_per_line
+ // indices remain
+ // unset for the
+ // moment (i.e. at
+ // invalid_dof_index).
+ // following this
+ // comes the stop
+ // index, which
+ // also is
+ // invalid_dof_index
+ // and therefore
+ // does not have to
+ // be explicitly
+ // set
+
+ // finally, mark
+ // those slots as
+ // used
+ next_free_line_slot
+ += (*dof_handler.finite_elements)[cell->active_fe_index()].dofs_per_line + 2;
+ }
+ else
+ {
+ dof_handler.faces
+ ->lines.dof_offsets[cell->face(face)->index()]
+ = next_free_line_slot;
+
+ // set first slot
+ // for this line to
+ // active_fe_index
+ // of this face
+ dof_handler.faces
+ ->lines.dofs[next_free_line_slot]
+ = cell->active_fe_index();
+
+ // the next
+ // dofs_per_line
+ // indices remain
+ // unset for the
+ // moment (i.e. at
+ // invalid_dof_index).
+ //
+ // then comes the
+ // fe_index for the
+ // neighboring
+ // cell:
+ dof_handler.faces
+ ->lines.dofs[next_free_line_slot
+ +
+ (*dof_handler.finite_elements)[cell->active_fe_index()].dofs_per_line
+ +
+ 1]
+ = cell->neighbor(face)->active_fe_index();
+ // then again a set
+ // of dofs that we
+ // need not set
+ // right now
+ //
+ // following this
+ // comes the stop
+ // index, which
+ // also is
+ // invalid_dof_index
+ // and therefore
+ // does not have to
+ // be explicitly
+ // set
+
+ // finally, mark
+ // those slots as
+ // used
+ next_free_line_slot
+ += ((*dof_handler.finite_elements)[cell->active_fe_index()].dofs_per_line
+ +
+ (*dof_handler.finite_elements)[cell->neighbor(face)->active_fe_index()]
+ .dofs_per_line
+ +
+ 3);
+ }
+
+ // mark this face as
+ // visited
+ cell->face(face)->set_user_flag ();
+ }
+
+ // we should have moved the
+ // cursor for each level to the
+ // total number of dofs on that
+ // level. check that
+ Assert (next_free_line_slot == n_line_slots,
+ ExcInternalError());
+
+ // at the end, restore the user
+ // flags for the lines
+ const_cast<dealii::Triangulation<dim,spacedim>&>(*dof_handler.tria)
+ .load_user_flags_line (saved_line_user_flags);
+ }
+
+
+ // VERTEX DOFS
+ reserve_space_vertices (dof_handler);
+ }
+
+
+ template <int spacedim>
+ static
+ void
+ reserve_space (DoFHandler<3,spacedim> &dof_handler)
+ {
+ const unsigned int dim = 3;
+
+ typedef DoFHandler<dim,spacedim> BaseClass;
+
+ Assert (dof_handler.finite_elements != 0,
+ typename BaseClass::ExcNoFESelected());
+ Assert (dof_handler.finite_elements->size() > 0,
+ typename BaseClass::ExcNoFESelected());
+ Assert (dof_handler.tria->n_levels() > 0,
+ typename BaseClass::ExcInvalidTriangulation());
+ Assert (dof_handler.tria->n_levels() == dof_handler.levels.size (),
+ ExcInternalError ());
+
+ // Release all space except the
+ // active_fe_indices field which
+ // we have to backup before
+ {
+ std::vector<std::vector<unsigned int> >
+ active_fe_backup(dof_handler.levels.size ());
+ for (unsigned int level = 0; level<dof_handler.levels.size (); ++level)
+ std::swap (dof_handler.levels[level]->active_fe_indices,
+ active_fe_backup[level]);
+
+ // delete all levels and set them up
+ // newly, since vectors are
+ // troublesome if you want to change
+ // their size
+ dof_handler.clear_space ();
+
+ for (unsigned int level=0; level<dof_handler.tria->n_levels(); ++level)
+ {
+ dof_handler.levels.push_back (new internal::hp::DoFLevel<dim>);
+ std::swap (active_fe_backup[level],
+ dof_handler.levels[level]->active_fe_indices);
+ }
+ dof_handler.faces = new internal::hp::DoFFaces<3>;
+ }
+
+
+ // HEX (CELL) DOFs
+
+ // count how much space we need
+ // on each level for the cell
+ // dofs and set the
+ // dof_*_offsets
+ // data. initially set the latter
+ // to an invalid index, and only
+ // later set it to something
+ // reasonable for active dof_handler.cells
+ //
+ // note that for dof_handler.cells, the
+ // situation is simpler than for
+ // other (lower dimensional)
+ // objects since exactly one
+ // finite element is used for it
+ for (unsigned int level=0; level<dof_handler.tria->n_levels(); ++level)
+ {
+ dof_handler.levels[level]->hexes.dof_offsets
+ = std::vector<unsigned int> (dof_handler.tria->n_raw_hexs(level),
+ DoFHandler<dim,spacedim>::invalid_dof_index);
+
+ unsigned int next_free_dof = 0;
+ for (typename DoFHandler<dim,spacedim>::active_cell_iterator
+ cell=dof_handler.begin_active(level);
+ cell!=dof_handler.end_active(level); ++cell)
+ if (!cell->has_children())
+ {
+ dof_handler.levels[level]->hexes.dof_offsets[cell->index()] = next_free_dof;
+ next_free_dof += cell->get_fe().dofs_per_hex;
+ }
+
+ dof_handler.levels[level]->hexes.dofs
+ = std::vector<unsigned int> (next_free_dof,
+ DoFHandler<dim,spacedim>::invalid_dof_index);
+ }
+
+ // safety check: make sure that
+ // the number of DoFs we
+ // allocated is actually correct
+ // (above we have also set the
+ // dof_*_offsets field, so
+ // we couldn't use this simpler
+ // algorithm)
#ifdef DEBUG
- for (unsigned int level=0; level<dof_handler.tria->n_levels(); ++level)
- {
- unsigned int counter = 0;
- for (typename DoFHandler<dim,spacedim>::cell_iterator
- cell=dof_handler.begin_active(level);
- cell!=dof_handler.end_active(level); ++cell)
- if (!cell->has_children())
- counter += cell->get_fe().dofs_per_hex;
-
- Assert (dof_handler.levels[level]->hexes.dofs.size() == counter,
- ExcInternalError());
- Assert (static_cast<unsigned int>
- (std::count (dof_handler.levels[level]->hexes.dof_offsets.begin(),
- dof_handler.levels[level]->hexes.dof_offsets.end(),
- DoFHandler<dim,spacedim>::invalid_dof_index))
- ==
- dof_handler.tria->n_raw_hexs(level) - dof_handler.tria->n_active_hexs(level),
- ExcInternalError());
- }
+ for (unsigned int level=0; level<dof_handler.tria->n_levels(); ++level)
+ {
+ unsigned int counter = 0;
+ for (typename DoFHandler<dim,spacedim>::cell_iterator
+ cell=dof_handler.begin_active(level);
+ cell!=dof_handler.end_active(level); ++cell)
+ if (!cell->has_children())
+ counter += cell->get_fe().dofs_per_hex;
+
+ Assert (dof_handler.levels[level]->hexes.dofs.size() == counter,
+ ExcInternalError());
+ Assert (static_cast<unsigned int>
+ (std::count (dof_handler.levels[level]->hexes.dof_offsets.begin(),
+ dof_handler.levels[level]->hexes.dof_offsets.end(),
+ DoFHandler<dim,spacedim>::invalid_dof_index))
+ ==
+ dof_handler.tria->n_raw_hexs(level) - dof_handler.tria->n_active_hexs(level),
+ ExcInternalError());
+ }
#endif
- // QUAD DOFS
- //
- // same here: count quad dofs,
- // then allocate as much space as
- // we need and prime the linked
- // list for quad (see the
- // description in hp::DoFLevels)
- // with the indices we will
- // need. note that our task is
- // more complicated since two
- // adjacent dof_handler.cells may have
- // different active_fe_indices,
- // in which case we need to
- // allocate *two* sets of line
- // dofs for the same line
- //
- // the way we do things is that
- // we loop over all active dof_handler.cells
- // (these are the ones that have
- // DoFs only anyway) and all
- // their dof_handler.faces. We note in the
- // user flags whether we have
- // previously visited a face and
- // if so skip it (consequently,
- // we have to save and later
- // restore the line flags)
- {
- std::vector<bool> saved_quad_user_flags;
- const_cast<dealii::Triangulation<dim,spacedim>&>(*dof_handler.tria)
- .save_user_flags_quad (saved_quad_user_flags);
- const_cast<dealii::Triangulation<dim,spacedim>&>(*dof_handler.tria)
- .clear_user_flags_quad ();
-
- // examine, how how many
- // slots (see the hp::DoFLevel
- // class) we will have to store
- unsigned int n_quad_slots = 0;
-
- for (typename DoFHandler<dim,spacedim>::active_cell_iterator
- cell=dof_handler.begin_active(); cell!=dof_handler.end(); ++cell)
- for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
- if (! cell->face(face)->user_flag_set())
- {
- // ok, face has not been
- // visited. so we need to
- // allocate space for
- // it. let's see how much
- // we need: we need one
- // set if a) there is no
- // neighbor behind this
- // face, or b) the
- // neighbor is not on the
- // same level or further
- // refined, or c) the
- // neighbor is on the
- // same level, but
- // happens to have the
- // same active_fe_index:
- if (cell->at_boundary(face)
- ||
- cell->face(face)->has_children()
- ||
- cell->neighbor_is_coarser(face)
- ||
- (!cell->at_boundary(face)
- &&
- (cell->active_fe_index() == cell->neighbor(face)->active_fe_index())))
- // ok, one set of
- // dofs. that makes
- // one index, 1 times
- // dofs_per_quad
- // dofs, and one stop
- // index
- n_quad_slots
- += (*dof_handler.finite_elements)[cell->active_fe_index()].dofs_per_quad + 2;
-
- // otherwise we do
- // indeed need two
- // sets, i.e. two
- // indices, two sets of
- // dofs, and one stop
- // index:
- else
- n_quad_slots
- += ((*dof_handler.finite_elements)[cell->active_fe_index()].dofs_per_quad
- +
- (*dof_handler.finite_elements)[cell->neighbor(face)->active_fe_index()]
- .dofs_per_quad
- +
- 3);
-
- // mark this face as
- // visited
- cell->face(face)->set_user_flag ();
- }
-
- // now that we know how many
- // quad dofs we will have to
- // have, allocate
- // the memory. note that we
- // allocate offsets for all
- // quads, though only the
- // active ones will have a
- // non-invalid value later on
- if (true)
- {
- dof_handler.faces->quads.dof_offsets
- = std::vector<unsigned int> (dof_handler.tria->n_raw_quads(),
- DoFHandler<dim,spacedim>::invalid_dof_index);
- dof_handler.faces->quads.dofs
- = std::vector<unsigned int> (n_quad_slots,
- DoFHandler<dim,spacedim>::invalid_dof_index);
- }
-
- // with the memory now
- // allocated, loop over the
- // dof_handler.cells again and prime the
- // _offset values as well as
- // the fe_index fields
- const_cast<dealii::Triangulation<dim,spacedim>&>(*dof_handler.tria)
- .clear_user_flags_quad ();
-
- unsigned int next_free_quad_slot = 0;
-
- for (typename DoFHandler<dim,spacedim>::active_cell_iterator
- cell=dof_handler.begin_active(); cell!=dof_handler.end(); ++cell)
- for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
- if (! cell->face(face)->user_flag_set())
- {
- // same decision tree
- // as before
- if (cell->at_boundary(face)
- ||
- cell->face(face)->has_children()
- ||
- cell->neighbor_is_coarser(face)
- ||
- (!cell->at_boundary(face)
- &&
- (cell->active_fe_index() == cell->neighbor(face)->active_fe_index())))
- {
- dof_handler.faces
- ->quads.dof_offsets[cell->face(face)->index()]
- = next_free_quad_slot;
-
- // set first slot
- // for this quad to
- // active_fe_index
- // of this face
- dof_handler.faces
- ->quads.dofs[next_free_quad_slot]
- = cell->active_fe_index();
-
- // the next
- // dofs_per_quad
- // indices remain
- // unset for the
- // moment (i.e. at
- // invalid_dof_index).
- // following this
- // comes the stop
- // index, which
- // also is
- // invalid_dof_index
- // and therefore
- // does not have to
- // be explicitly
- // set
-
- // finally, mark
- // those slots as
- // used
- next_free_quad_slot
- += (*dof_handler.finite_elements)[cell->active_fe_index()].dofs_per_quad + 2;
- }
- else
- {
- dof_handler.faces
- ->quads.dof_offsets[cell->face(face)->index()]
- = next_free_quad_slot;
-
- // set first slot
- // for this quad to
- // active_fe_index
- // of this face
- dof_handler.faces
- ->quads.dofs[next_free_quad_slot]
- = cell->active_fe_index();
-
- // the next
- // dofs_per_quad
- // indices remain
- // unset for the
- // moment (i.e. at
- // invalid_dof_index).
- //
- // then comes the
- // fe_index for the
- // neighboring
- // cell:
- dof_handler.faces
- ->quads.dofs[next_free_quad_slot
- +
- (*dof_handler.finite_elements)[cell->active_fe_index()].dofs_per_quad
- +
- 1]
- = cell->neighbor(face)->active_fe_index();
- // then again a set
- // of dofs that we
- // need not set
- // right now
- //
- // following this
- // comes the stop
- // index, which
- // also is
- // invalid_dof_index
- // and therefore
- // does not have to
- // be explicitly
- // set
-
- // finally, mark
- // those slots as
- // used
- next_free_quad_slot
- += ((*dof_handler.finite_elements)[cell->active_fe_index()].dofs_per_quad
- +
- (*dof_handler.finite_elements)[cell->neighbor(face)->active_fe_index()]
- .dofs_per_quad
- +
- 3);
- }
-
- // mark this face as
- // visited
- cell->face(face)->set_user_flag ();
- }
-
- // we should have moved the
- // cursor to the total number
- // of dofs. check that
- Assert (next_free_quad_slot == n_quad_slots,
- ExcInternalError());
-
- // at the end, restore the user
- // flags for the quads
- const_cast<dealii::Triangulation<dim,spacedim>&>(*dof_handler.tria)
- .load_user_flags_quad (saved_quad_user_flags);
- }
-
-
- // LINE DOFS
-
- // the situation here is pretty
- // much like with vertices: there
- // can be an arbitrary number of
- // finite elements associated
- // with each line.
- //
- // the algorithm we use is
- // somewhat similar to what we do
- // in reserve_space_vertices()
- if (true)
- {
- // what we do first is to set up
- // an array in which we record
- // whether a line is associated
- // with any of the given fe's, by
- // setting a bit. in a later
- // step, we then actually
- // allocate memory for the
- // required dofs
- std::vector<std::vector<bool> >
- line_fe_association (dof_handler.finite_elements->size(),
- std::vector<bool> (dof_handler.tria->n_raw_lines(),
- false));
-
- for (typename DoFHandler<dim,spacedim>::active_cell_iterator
- cell=dof_handler.begin_active();
- cell!=dof_handler.end(); ++cell)
- for (unsigned int l=0; l<GeometryInfo<dim>::lines_per_cell; ++l)
- line_fe_association[cell->active_fe_index()][cell->line_index(l)]
- = true;
-
- // first check which of the
- // lines is used at all,
- // i.e. is associated with a
- // finite element. we do this
- // since not all lines may
- // actually be used, in which
- // case we do not have to
- // allocate any memory at
- // all
- std::vector<bool> line_is_used (dof_handler.tria->n_raw_lines(), false);
- for (unsigned int line=0; line<dof_handler.tria->n_raw_lines(); ++line)
- for (unsigned int fe=0; fe<dof_handler.finite_elements->size(); ++fe)
- if (line_fe_association[fe][line] == true)
- {
- line_is_used[line] = true;
- break;
- }
-
- // next count how much memory
- // we actually need. for each
- // line, we need one slot per
- // fe to store the fe_index,
- // plus dofs_per_line for
- // this fe. in addition, we
- // need one slot as the end
- // marker for the
- // fe_indices. at the same
- // time already fill the
- // line_dofs_offsets field
- dof_handler.faces->lines.dof_offsets
- .resize (dof_handler.tria->n_raw_lines(),
- numbers::invalid_unsigned_int);
-
- unsigned int line_slots_needed = 0;
- for (unsigned int line=0; line<dof_handler.tria->n_raw_lines(); ++line)
- if (line_is_used[line] == true)
- {
- dof_handler.faces->lines.dof_offsets[line] = line_slots_needed;
-
- for (unsigned int fe=0; fe<dof_handler.finite_elements->size(); ++fe)
- if (line_fe_association[fe][line] == true)
- line_slots_needed += (*dof_handler.finite_elements)[fe].dofs_per_line + 1;
- ++line_slots_needed;
- }
-
- // now allocate the space we
- // have determined we need, and
- // set up the linked lists for
- // each of the lines
- dof_handler.faces->lines.dofs.resize (line_slots_needed,
- DoFHandler<dim,spacedim>::invalid_dof_index);
- for (unsigned int line=0; line<dof_handler.tria->n_raw_lines(); ++line)
- if (line_is_used[line] == true)
- {
- unsigned int pointer = dof_handler.faces->lines.dof_offsets[line];
- for (unsigned int fe=0; fe<dof_handler.finite_elements->size(); ++fe)
- if (line_fe_association[fe][line] == true)
- {
- // if this line
- // uses this fe,
- // then set the
- // fe_index and
- // move the
- // pointer ahead
- dof_handler.faces->lines.dofs[pointer] = fe;
- pointer += (*dof_handler.finite_elements)[fe].dofs_per_line + 1;
- }
- // finally place the end
- // marker
- dof_handler.faces->lines.dofs[pointer] = numbers::invalid_unsigned_int;
- }
- }
-
-
-
- // VERTEX DOFS
- reserve_space_vertices (dof_handler);
- }
-
-
- /**
- * Implement the function of same name
- * in the mother class.
- */
- template <int spacedim>
- static
- unsigned int
- max_couplings_between_dofs (const DoFHandler<1,spacedim> &dof_handler)
- {
- return std::min(3*dof_handler.finite_elements->max_dofs_per_vertex() +
- 2*dof_handler.finite_elements->max_dofs_per_line(), dof_handler.n_dofs());
- }
-
-
-
- template <int spacedim>
- static
- unsigned int
- max_couplings_between_dofs (const DoFHandler<2,spacedim> &dof_handler)
- {
- // get these numbers by drawing pictures
- // and counting...
- // example:
- // | | |
- // --x-----x--x--X--
- // | | | |
- // | x--x--x
- // | | | |
- // --x--x--*--x--x--
- // | | | |
- // x--x--x |
- // | | | |
- // --X--x--x-----x--
- // | | |
- // x = vertices connected with center vertex *;
- // = total of 19
- // (the X vertices are connected with * if
- // the vertices adjacent to X are hanging
- // nodes)
- // count lines -> 28 (don't forget to count
- // mother and children separately!)
- unsigned int max_couplings;
- switch (dof_handler.tria->max_adjacent_cells())
- {
- case 4:
- max_couplings=19*dof_handler.finite_elements->max_dofs_per_vertex() +
- 28*dof_handler.finite_elements->max_dofs_per_line() +
- 8*dof_handler.finite_elements->max_dofs_per_quad();
- break;
- case 5:
- max_couplings=21*dof_handler.finite_elements->max_dofs_per_vertex() +
- 31*dof_handler.finite_elements->max_dofs_per_line() +
- 9*dof_handler.finite_elements->max_dofs_per_quad();
- break;
- case 6:
- max_couplings=28*dof_handler.finite_elements->max_dofs_per_vertex() +
- 42*dof_handler.finite_elements->max_dofs_per_line() +
- 12*dof_handler.finite_elements->max_dofs_per_quad();
- break;
- case 7:
- max_couplings=30*dof_handler.finite_elements->max_dofs_per_vertex() +
- 45*dof_handler.finite_elements->max_dofs_per_line() +
- 13*dof_handler.finite_elements->max_dofs_per_quad();
- break;
- case 8:
- max_couplings=37*dof_handler.finite_elements->max_dofs_per_vertex() +
- 56*dof_handler.finite_elements->max_dofs_per_line() +
- 16*dof_handler.finite_elements->max_dofs_per_quad();
- break;
- default:
- Assert (false, ExcNotImplemented());
- max_couplings=0;
- };
- return std::min(max_couplings,dof_handler.n_dofs());
- }
-
-
- template <int spacedim>
- static
- unsigned int
- max_couplings_between_dofs (const DoFHandler<3,spacedim> &dof_handler)
- {
+ // QUAD DOFS
+ //
+ // same here: count quad dofs,
+ // then allocate as much space as
+ // we need and prime the linked
+ // list for quad (see the
+ // description in hp::DoFLevels)
+ // with the indices we will
+ // need. note that our task is
+ // more complicated since two
+ // adjacent dof_handler.cells may have
+ // different active_fe_indices,
+ // in which case we need to
+ // allocate *two* sets of line
+ // dofs for the same line
+ //
+ // the way we do things is that
+ // we loop over all active dof_handler.cells
+ // (these are the ones that have
+ // DoFs only anyway) and all
+ // their dof_handler.faces. We note in the
+ // user flags whether we have
+ // previously visited a face and
+ // if so skip it (consequently,
+ // we have to save and later
+ // restore the line flags)
+ {
+ std::vector<bool> saved_quad_user_flags;
+ const_cast<dealii::Triangulation<dim,spacedim>&>(*dof_handler.tria)
+ .save_user_flags_quad (saved_quad_user_flags);
+ const_cast<dealii::Triangulation<dim,spacedim>&>(*dof_handler.tria)
+ .clear_user_flags_quad ();
+
+ // examine, how how many
+ // slots (see the hp::DoFLevel
+ // class) we will have to store
+ unsigned int n_quad_slots = 0;
+
+ for (typename DoFHandler<dim,spacedim>::active_cell_iterator
+ cell=dof_handler.begin_active(); cell!=dof_handler.end(); ++cell)
+ for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
+ if (! cell->face(face)->user_flag_set())
+ {
+ // ok, face has not been
+ // visited. so we need to
+ // allocate space for
+ // it. let's see how much
+ // we need: we need one
+ // set if a) there is no
+ // neighbor behind this
+ // face, or b) the
+ // neighbor is not on the
+ // same level or further
+ // refined, or c) the
+ // neighbor is on the
+ // same level, but
+ // happens to have the
+ // same active_fe_index:
+ if (cell->at_boundary(face)
+ ||
+ cell->face(face)->has_children()
+ ||
+ cell->neighbor_is_coarser(face)
+ ||
+ (!cell->at_boundary(face)
+ &&
+ (cell->active_fe_index() == cell->neighbor(face)->active_fe_index())))
+ // ok, one set of
+ // dofs. that makes
+ // one index, 1 times
+ // dofs_per_quad
+ // dofs, and one stop
+ // index
+ n_quad_slots
+ += (*dof_handler.finite_elements)[cell->active_fe_index()].dofs_per_quad + 2;
+
+ // otherwise we do
+ // indeed need two
+ // sets, i.e. two
+ // indices, two sets of
+ // dofs, and one stop
+ // index:
+ else
+ n_quad_slots
+ += ((*dof_handler.finite_elements)[cell->active_fe_index()].dofs_per_quad
+ +
+ (*dof_handler.finite_elements)[cell->neighbor(face)->active_fe_index()]
+ .dofs_per_quad
+ +
+ 3);
+
+ // mark this face as
+ // visited
+ cell->face(face)->set_user_flag ();
+ }
+
+ // now that we know how many
+ // quad dofs we will have to
+ // have, allocate
+ // the memory. note that we
+ // allocate offsets for all
+ // quads, though only the
+ // active ones will have a
+ // non-invalid value later on
+ if (true)
+ {
+ dof_handler.faces->quads.dof_offsets
+ = std::vector<unsigned int> (dof_handler.tria->n_raw_quads(),
+ DoFHandler<dim,spacedim>::invalid_dof_index);
+ dof_handler.faces->quads.dofs
+ = std::vector<unsigned int> (n_quad_slots,
+ DoFHandler<dim,spacedim>::invalid_dof_index);
+ }
+
+ // with the memory now
+ // allocated, loop over the
+ // dof_handler.cells again and prime the
+ // _offset values as well as
+ // the fe_index fields
+ const_cast<dealii::Triangulation<dim,spacedim>&>(*dof_handler.tria)
+ .clear_user_flags_quad ();
+
+ unsigned int next_free_quad_slot = 0;
+
+ for (typename DoFHandler<dim,spacedim>::active_cell_iterator
+ cell=dof_handler.begin_active(); cell!=dof_handler.end(); ++cell)
+ for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
+ if (! cell->face(face)->user_flag_set())
+ {
+ // same decision tree
+ // as before
+ if (cell->at_boundary(face)
+ ||
+ cell->face(face)->has_children()
+ ||
+ cell->neighbor_is_coarser(face)
+ ||
+ (!cell->at_boundary(face)
+ &&
+ (cell->active_fe_index() == cell->neighbor(face)->active_fe_index())))
+ {
+ dof_handler.faces
+ ->quads.dof_offsets[cell->face(face)->index()]
+ = next_free_quad_slot;
+
+ // set first slot
+ // for this quad to
+ // active_fe_index
+ // of this face
+ dof_handler.faces
+ ->quads.dofs[next_free_quad_slot]
+ = cell->active_fe_index();
+
+ // the next
+ // dofs_per_quad
+ // indices remain
+ // unset for the
+ // moment (i.e. at
+ // invalid_dof_index).
+ // following this
+ // comes the stop
+ // index, which
+ // also is
+ // invalid_dof_index
+ // and therefore
+ // does not have to
+ // be explicitly
+ // set
+
+ // finally, mark
+ // those slots as
+ // used
+ next_free_quad_slot
+ += (*dof_handler.finite_elements)[cell->active_fe_index()].dofs_per_quad + 2;
+ }
+ else
+ {
+ dof_handler.faces
+ ->quads.dof_offsets[cell->face(face)->index()]
+ = next_free_quad_slot;
+
+ // set first slot
+ // for this quad to
+ // active_fe_index
+ // of this face
+ dof_handler.faces
+ ->quads.dofs[next_free_quad_slot]
+ = cell->active_fe_index();
+
+ // the next
+ // dofs_per_quad
+ // indices remain
+ // unset for the
+ // moment (i.e. at
+ // invalid_dof_index).
+ //
+ // then comes the
+ // fe_index for the
+ // neighboring
+ // cell:
+ dof_handler.faces
+ ->quads.dofs[next_free_quad_slot
+ +
+ (*dof_handler.finite_elements)[cell->active_fe_index()].dofs_per_quad
+ +
+ 1]
+ = cell->neighbor(face)->active_fe_index();
+ // then again a set
+ // of dofs that we
+ // need not set
+ // right now
+ //
+ // following this
+ // comes the stop
+ // index, which
+ // also is
+ // invalid_dof_index
+ // and therefore
+ // does not have to
+ // be explicitly
+ // set
+
+ // finally, mark
+ // those slots as
+ // used
+ next_free_quad_slot
+ += ((*dof_handler.finite_elements)[cell->active_fe_index()].dofs_per_quad
+ +
+ (*dof_handler.finite_elements)[cell->neighbor(face)->active_fe_index()]
+ .dofs_per_quad
+ +
+ 3);
+ }
+
+ // mark this face as
+ // visited
+ cell->face(face)->set_user_flag ();
+ }
+
+ // we should have moved the
+ // cursor to the total number
+ // of dofs. check that
+ Assert (next_free_quad_slot == n_quad_slots,
+ ExcInternalError());
+
+ // at the end, restore the user
+ // flags for the quads
+ const_cast<dealii::Triangulation<dim,spacedim>&>(*dof_handler.tria)
+ .load_user_flags_quad (saved_quad_user_flags);
+ }
+
+
+ // LINE DOFS
+
+ // the situation here is pretty
+ // much like with vertices: there
+ // can be an arbitrary number of
+ // finite elements associated
+ // with each line.
+ //
+ // the algorithm we use is
+ // somewhat similar to what we do
+ // in reserve_space_vertices()
+ if (true)
+ {
+ // what we do first is to set up
+ // an array in which we record
+ // whether a line is associated
+ // with any of the given fe's, by
+ // setting a bit. in a later
+ // step, we then actually
+ // allocate memory for the
+ // required dofs
+ std::vector<std::vector<bool> >
+ line_fe_association (dof_handler.finite_elements->size(),
+ std::vector<bool> (dof_handler.tria->n_raw_lines(),
+ false));
+
+ for (typename DoFHandler<dim,spacedim>::active_cell_iterator
+ cell=dof_handler.begin_active();
+ cell!=dof_handler.end(); ++cell)
+ for (unsigned int l=0; l<GeometryInfo<dim>::lines_per_cell; ++l)
+ line_fe_association[cell->active_fe_index()][cell->line_index(l)]
+ = true;
+
+ // first check which of the
+ // lines is used at all,
+ // i.e. is associated with a
+ // finite element. we do this
+ // since not all lines may
+ // actually be used, in which
+ // case we do not have to
+ // allocate any memory at
+ // all
+ std::vector<bool> line_is_used (dof_handler.tria->n_raw_lines(), false);
+ for (unsigned int line=0; line<dof_handler.tria->n_raw_lines(); ++line)
+ for (unsigned int fe=0; fe<dof_handler.finite_elements->size(); ++fe)
+ if (line_fe_association[fe][line] == true)
+ {
+ line_is_used[line] = true;
+ break;
+ }
+
+ // next count how much memory
+ // we actually need. for each
+ // line, we need one slot per
+ // fe to store the fe_index,
+ // plus dofs_per_line for
+ // this fe. in addition, we
+ // need one slot as the end
+ // marker for the
+ // fe_indices. at the same
+ // time already fill the
+ // line_dofs_offsets field
+ dof_handler.faces->lines.dof_offsets
+ .resize (dof_handler.tria->n_raw_lines(),
+ numbers::invalid_unsigned_int);
+
+ unsigned int line_slots_needed = 0;
+ for (unsigned int line=0; line<dof_handler.tria->n_raw_lines(); ++line)
+ if (line_is_used[line] == true)
+ {
+ dof_handler.faces->lines.dof_offsets[line] = line_slots_needed;
+
+ for (unsigned int fe=0; fe<dof_handler.finite_elements->size(); ++fe)
+ if (line_fe_association[fe][line] == true)
+ line_slots_needed += (*dof_handler.finite_elements)[fe].dofs_per_line + 1;
+ ++line_slots_needed;
+ }
+
+ // now allocate the space we
+ // have determined we need, and
+ // set up the linked lists for
+ // each of the lines
+ dof_handler.faces->lines.dofs.resize (line_slots_needed,
+ DoFHandler<dim,spacedim>::invalid_dof_index);
+ for (unsigned int line=0; line<dof_handler.tria->n_raw_lines(); ++line)
+ if (line_is_used[line] == true)
+ {
+ unsigned int pointer = dof_handler.faces->lines.dof_offsets[line];
+ for (unsigned int fe=0; fe<dof_handler.finite_elements->size(); ++fe)
+ if (line_fe_association[fe][line] == true)
+ {
+ // if this line
+ // uses this fe,
+ // then set the
+ // fe_index and
+ // move the
+ // pointer ahead
+ dof_handler.faces->lines.dofs[pointer] = fe;
+ pointer += (*dof_handler.finite_elements)[fe].dofs_per_line + 1;
+ }
+ // finally place the end
+ // marker
+ dof_handler.faces->lines.dofs[pointer] = numbers::invalid_unsigned_int;
+ }
+ }
+
+
+
+ // VERTEX DOFS
+ reserve_space_vertices (dof_handler);
+ }
+
+
+ /**
+ * Implement the function of same name
+ * in the mother class.
+ */
+ template <int spacedim>
+ static
+ unsigned int
+ max_couplings_between_dofs (const DoFHandler<1,spacedim> &dof_handler)
+ {
+ return std::min(3*dof_handler.finite_elements->max_dofs_per_vertex() +
+ 2*dof_handler.finite_elements->max_dofs_per_line(), dof_handler.n_dofs());
+ }
+
+
+
+ template <int spacedim>
+ static
+ unsigned int
+ max_couplings_between_dofs (const DoFHandler<2,spacedim> &dof_handler)
+ {
+ // get these numbers by drawing pictures
+ // and counting...
+ // example:
+ // | | |
+ // --x-----x--x--X--
+ // | | | |
+ // | x--x--x
+ // | | | |
+ // --x--x--*--x--x--
+ // | | | |
+ // x--x--x |
+ // | | | |
+ // --X--x--x-----x--
+ // | | |
+ // x = vertices connected with center vertex *;
+ // = total of 19
+ // (the X vertices are connected with * if
+ // the vertices adjacent to X are hanging
+ // nodes)
+ // count lines -> 28 (don't forget to count
+ // mother and children separately!)
+ unsigned int max_couplings;
+ switch (dof_handler.tria->max_adjacent_cells())
+ {
+ case 4:
+ max_couplings=19*dof_handler.finite_elements->max_dofs_per_vertex() +
+ 28*dof_handler.finite_elements->max_dofs_per_line() +
+ 8*dof_handler.finite_elements->max_dofs_per_quad();
+ break;
+ case 5:
+ max_couplings=21*dof_handler.finite_elements->max_dofs_per_vertex() +
+ 31*dof_handler.finite_elements->max_dofs_per_line() +
+ 9*dof_handler.finite_elements->max_dofs_per_quad();
+ break;
+ case 6:
+ max_couplings=28*dof_handler.finite_elements->max_dofs_per_vertex() +
+ 42*dof_handler.finite_elements->max_dofs_per_line() +
+ 12*dof_handler.finite_elements->max_dofs_per_quad();
+ break;
+ case 7:
+ max_couplings=30*dof_handler.finite_elements->max_dofs_per_vertex() +
+ 45*dof_handler.finite_elements->max_dofs_per_line() +
+ 13*dof_handler.finite_elements->max_dofs_per_quad();
+ break;
+ case 8:
+ max_couplings=37*dof_handler.finite_elements->max_dofs_per_vertex() +
+ 56*dof_handler.finite_elements->max_dofs_per_line() +
+ 16*dof_handler.finite_elements->max_dofs_per_quad();
+ break;
+ default:
+ Assert (false, ExcNotImplemented());
+ max_couplings=0;
+ };
+ return std::min(max_couplings,dof_handler.n_dofs());
+ }
+
+
+ template <int spacedim>
+ static
+ unsigned int
+ max_couplings_between_dofs (const DoFHandler<3,spacedim> &dof_handler)
+ {
//TODO:[?] Invent significantly better estimates than the ones in this function
- // doing the same thing here is a rather
- // complicated thing, compared to the 2d
- // case, since it is hard to draw pictures
- // with several refined hexahedra :-) so I
- // presently only give a coarse estimate
- // for the case that at most 8 hexes meet
- // at each vertex
- //
- // can anyone give better estimate here?
- const unsigned int max_adjacent_cells = dof_handler.tria->max_adjacent_cells();
-
- unsigned int max_couplings;
- if (max_adjacent_cells <= 8)
- max_couplings=7*7*7*dof_handler.finite_elements->max_dofs_per_vertex() +
- 7*6*7*3*dof_handler.finite_elements->max_dofs_per_line() +
- 9*4*7*3*dof_handler.finite_elements->max_dofs_per_quad() +
- 27*dof_handler.finite_elements->max_dofs_per_hex();
- else
- {
- Assert (false, ExcNotImplemented());
- max_couplings=0;
- }
-
- return std::min(max_couplings,dof_handler.n_dofs());
- }
+ // doing the same thing here is a rather
+ // complicated thing, compared to the 2d
+ // case, since it is hard to draw pictures
+ // with several refined hexahedra :-) so I
+ // presently only give a coarse estimate
+ // for the case that at most 8 hexes meet
+ // at each vertex
+ //
+ // can anyone give better estimate here?
+ const unsigned int max_adjacent_cells = dof_handler.tria->max_adjacent_cells();
+
+ unsigned int max_couplings;
+ if (max_adjacent_cells <= 8)
+ max_couplings=7*7*7*dof_handler.finite_elements->max_dofs_per_vertex() +
+ 7*6*7*3*dof_handler.finite_elements->max_dofs_per_line() +
+ 9*4*7*3*dof_handler.finite_elements->max_dofs_per_quad() +
+ 27*dof_handler.finite_elements->max_dofs_per_hex();
+ else
+ {
+ Assert (false, ExcNotImplemented());
+ max_couplings=0;
+ }
+
+ return std::min(max_couplings,dof_handler.n_dofs());
+ }
};
}
}
DoFHandler<dim,spacedim>::DoFHandler (const Triangulation<dim,spacedim> &tria)
:
tria(&tria, typeid(*this).name()),
- faces (NULL)
+ faces (NULL)
{
Assert ((dynamic_cast<const parallel::distributed::Triangulation< dim, spacedim >*>
- (&tria)
- == 0),
- ExcMessage ("The given triangulation is parallel distributed but "
- "this class does not currently support this."));
+ (&tria)
+ == 0),
+ ExcMessage ("The given triangulation is parallel distributed but "
+ "this class does not currently support this."));
create_active_fe_table ();
tria_listeners.push_back
(tria.signals.pre_refinement
.connect (std_cxx1x::bind (&DoFHandler<dim,spacedim>::pre_refinement_action,
- std_cxx1x::ref(*this))));
+ std_cxx1x::ref(*this))));
tria_listeners.push_back
(tria.signals.post_refinement
.connect (std_cxx1x::bind (&DoFHandler<dim,spacedim>::post_refinement_action,
- std_cxx1x::ref(*this))));
+ std_cxx1x::ref(*this))));
tria_listeners.push_back
(tria.signals.create
.connect (std_cxx1x::bind (&DoFHandler<dim,spacedim>::post_refinement_action,
- std_cxx1x::ref(*this))));
+ std_cxx1x::ref(*this))));
}
{
switch (dim)
{
- case 1:
- return begin_raw_line (level);
- case 2:
- return begin_raw_quad (level);
- case 3:
- return begin_raw_hex (level);
- default:
- Assert (false, ExcNotImplemented());
- return raw_cell_iterator();
+ case 1:
+ return begin_raw_line (level);
+ case 2:
+ return begin_raw_quad (level);
+ case 3:
+ return begin_raw_hex (level);
+ default:
+ Assert (false, ExcNotImplemented());
+ return raw_cell_iterator();
}
}
{
switch (dim)
{
- case 1:
- return begin_line (level);
- case 2:
- return begin_quad (level);
- case 3:
- return begin_hex (level);
- default:
- Assert (false, ExcImpossibleInDim(dim));
- return cell_iterator();
+ case 1:
+ return begin_line (level);
+ case 2:
+ return begin_quad (level);
+ case 3:
+ return begin_hex (level);
+ default:
+ Assert (false, ExcImpossibleInDim(dim));
+ return cell_iterator();
}
}
{
switch (dim)
{
- case 1:
- return begin_active_line (level);
- case 2:
- return begin_active_quad (level);
- case 3:
- return begin_active_hex (level);
- default:
- Assert (false, ExcNotImplemented());
- return active_cell_iterator();
+ case 1:
+ return begin_active_line (level);
+ case 2:
+ return begin_active_quad (level);
+ case 3:
+ return begin_active_hex (level);
+ default:
+ Assert (false, ExcNotImplemented());
+ return active_cell_iterator();
}
}
{
switch (dim)
{
- case 1:
- return last_raw_line ();
- case 2:
- return last_raw_quad ();
- case 3:
- return last_raw_hex ();
- default:
- Assert (false, ExcNotImplemented());
- return raw_cell_iterator();
+ case 1:
+ return last_raw_line ();
+ case 2:
+ return last_raw_quad ();
+ case 3:
+ return last_raw_hex ();
+ default:
+ Assert (false, ExcNotImplemented());
+ return raw_cell_iterator();
}
}
{
switch (dim)
{
- case 1:
- return last_raw_line (level);
- case 2:
- return last_raw_quad (level);
- case 3:
- return last_raw_hex (level);
- default:
- Assert (false, ExcNotImplemented());
- return raw_cell_iterator();
+ case 1:
+ return last_raw_line (level);
+ case 2:
+ return last_raw_quad (level);
+ case 3:
+ return last_raw_hex (level);
+ default:
+ Assert (false, ExcNotImplemented());
+ return raw_cell_iterator();
}
}
{
switch (dim)
{
- case 1:
- return last_line ();
- case 2:
- return last_quad ();
- case 3:
- return last_hex ();
- default:
- Assert (false, ExcNotImplemented());
- return cell_iterator();
+ case 1:
+ return last_line ();
+ case 2:
+ return last_quad ();
+ case 3:
+ return last_hex ();
+ default:
+ Assert (false, ExcNotImplemented());
+ return cell_iterator();
}
}
{
switch (dim)
{
- case 1:
- return last_line (level);
- case 2:
- return last_quad (level);
- case 3:
- return last_hex (level);
- default:
- Assert (false, ExcNotImplemented());
- return cell_iterator();
+ case 1:
+ return last_line (level);
+ case 2:
+ return last_quad (level);
+ case 3:
+ return last_hex (level);
+ default:
+ Assert (false, ExcNotImplemented());
+ return cell_iterator();
}
}
{
switch (dim)
{
- case 1:
- return last_active_line ();
- case 2:
- return last_active_quad ();
- case 3:
- return last_active_hex ();
- default:
- Assert (false, ExcNotImplemented());
- return active_cell_iterator();
+ case 1:
+ return last_active_line ();
+ case 2:
+ return last_active_quad ();
+ case 3:
+ return last_active_hex ();
+ default:
+ Assert (false, ExcNotImplemented());
+ return active_cell_iterator();
}
}
{
switch (dim)
{
- case 1:
- return last_active_line (level);
- case 2:
- return last_active_quad (level);
- case 3:
- return last_active_hex (level);
- default:
- Assert (false, ExcNotImplemented());
- return active_cell_iterator();
+ case 1:
+ return last_active_line (level);
+ case 2:
+ return last_active_quad (level);
+ case 3:
+ return last_active_hex (level);
+ default:
+ Assert (false, ExcNotImplemented());
+ return active_cell_iterator();
}
}
{
switch (dim)
{
- case 1:
- return end_line();
- case 2:
- return end_quad();
- case 3:
- return end_hex();
- default:
- Assert (false, ExcImpossibleInDim(dim));
- return raw_cell_iterator();
+ case 1:
+ return end_line();
+ case 2:
+ return end_quad();
+ case 3:
+ return end_hex();
+ default:
+ Assert (false, ExcImpossibleInDim(dim));
+ return raw_cell_iterator();
}
}
DoFHandler<dim, spacedim>::end_raw (const unsigned int level) const
{
return (level == tria->n_levels()-1 ?
- end() :
- begin_raw (level+1));
+ end() :
+ begin_raw (level+1));
}
DoFHandler<dim, spacedim>::end (const unsigned int level) const
{
return (level == tria->n_levels()-1 ?
- cell_iterator(end()) :
- begin (level+1));
+ cell_iterator(end()) :
+ begin (level+1));
}
DoFHandler<dim, spacedim>::end_active (const unsigned int level) const
{
return (level == tria->n_levels()-1 ?
- active_cell_iterator(end()) :
- begin_active (level+1));
+ active_cell_iterator(end()) :
+ begin_active (level+1));
}
{
switch (dim)
{
- case 1:
- Assert (false, ExcImpossibleInDim(1));
- return raw_face_iterator();
- case 2:
- return begin_raw_line ();
- case 3:
- return begin_raw_quad ();
- default:
- Assert (false, ExcNotImplemented());
- return raw_face_iterator ();
+ case 1:
+ Assert (false, ExcImpossibleInDim(1));
+ return raw_face_iterator();
+ case 2:
+ return begin_raw_line ();
+ case 3:
+ return begin_raw_quad ();
+ default:
+ Assert (false, ExcNotImplemented());
+ return raw_face_iterator ();
}
}
{
switch (dim)
{
- case 1:
- Assert (false, ExcImpossibleInDim(1));
- return raw_face_iterator();
- case 2:
- return begin_line ();
- case 3:
- return begin_quad ();
- default:
- Assert (false, ExcNotImplemented());
- return face_iterator ();
+ case 1:
+ Assert (false, ExcImpossibleInDim(1));
+ return raw_face_iterator();
+ case 2:
+ return begin_line ();
+ case 3:
+ return begin_quad ();
+ default:
+ Assert (false, ExcNotImplemented());
+ return face_iterator ();
}
}
{
switch (dim)
{
- case 1:
- Assert (false, ExcImpossibleInDim(1));
- return raw_face_iterator();
- case 2:
- return begin_active_line ();
- case 3:
- return begin_active_quad ();
- default:
- Assert (false, ExcNotImplemented());
- return active_face_iterator ();
+ case 1:
+ Assert (false, ExcImpossibleInDim(1));
+ return raw_face_iterator();
+ case 2:
+ return begin_active_line ();
+ case 3:
+ return begin_active_quad ();
+ default:
+ Assert (false, ExcNotImplemented());
+ return active_face_iterator ();
}
}
{
switch (dim)
{
- case 1:
- Assert (false, ExcImpossibleInDim(1));
- return raw_face_iterator();
- case 2:
- return end_line ();
- case 3:
- return end_quad ();
- default:
- Assert (false, ExcNotImplemented());
- return raw_face_iterator ();
+ case 1:
+ Assert (false, ExcImpossibleInDim(1));
+ return raw_face_iterator();
+ case 2:
+ return end_line ();
+ case 3:
+ return end_quad ();
+ default:
+ Assert (false, ExcNotImplemented());
+ return raw_face_iterator ();
}
}
{
switch (dim)
{
- case 1:
- Assert (false, ExcImpossibleInDim(1));
- return raw_face_iterator();
- case 2:
- return last_raw_line ();
- case 3:
- return last_raw_quad ();
- default:
- Assert (false, ExcNotImplemented());
- return raw_face_iterator ();
+ case 1:
+ Assert (false, ExcImpossibleInDim(1));
+ return raw_face_iterator();
+ case 2:
+ return last_raw_line ();
+ case 3:
+ return last_raw_quad ();
+ default:
+ Assert (false, ExcNotImplemented());
+ return raw_face_iterator ();
}
}
{
switch (dim)
{
- case 1:
- Assert (false, ExcImpossibleInDim(1));
- return raw_face_iterator();
- case 2:
- return last_line ();
- case 3:
- return last_quad ();
- default:
- Assert (false, ExcNotImplemented());
- return raw_face_iterator ();
+ case 1:
+ Assert (false, ExcImpossibleInDim(1));
+ return raw_face_iterator();
+ case 2:
+ return last_line ();
+ case 3:
+ return last_quad ();
+ default:
+ Assert (false, ExcNotImplemented());
+ return raw_face_iterator ();
}
}
{
switch (dim)
{
- case 1:
- Assert (false, ExcImpossibleInDim(1));
- return raw_face_iterator();
- case 2:
- return last_active_line ();
- case 3:
- return last_active_quad ();
- default:
- Assert (false, ExcNotImplemented());
- return raw_face_iterator ();
+ case 1:
+ Assert (false, ExcImpossibleInDim(1));
+ return raw_face_iterator();
+ case 2:
+ return last_active_line ();
+ case 3:
+ return last_active_quad ();
+ default:
+ Assert (false, ExcNotImplemented());
+ return raw_face_iterator ();
}
}
{
switch (dim)
{
- case 1:
- Assert (level<tria->n_levels(), ExcInvalidLevel(level));
-
- if (tria->n_raw_lines(level) == 0)
- return end_line ();
-
- return raw_line_iterator (tria,
- level,
- 0,
- this);
-
- default:
- Assert (level == 0, ExcFacesHaveNoLevel());
- return raw_line_iterator (tria,
- 0,
- 0,
- this);
+ case 1:
+ Assert (level<tria->n_levels(), ExcInvalidLevel(level));
+
+ if (tria->n_raw_lines(level) == 0)
+ return end_line ();
+
+ return raw_line_iterator (tria,
+ level,
+ 0,
+ this);
+
+ default:
+ Assert (level == 0, ExcFacesHaveNoLevel());
+ return raw_line_iterator (tria,
+ 0,
+ 0,
+ this);
}
}
typename DoFHandler<dim, spacedim>::line_iterator
DoFHandler<dim, spacedim>::begin_line (const unsigned int level) const
{
- // level is checked in begin_raw
+ // level is checked in begin_raw
raw_line_iterator ri = begin_raw_line (level);
if (ri.state() != IteratorState::valid)
return ri;
while (ri->used() == false)
if ((++ri).state() != IteratorState::valid)
- return ri;
+ return ri;
return ri;
}
typename DoFHandler<dim, spacedim>::active_line_iterator
DoFHandler<dim, spacedim>::begin_active_line (const unsigned int level) const
{
- // level is checked in begin_raw
+ // level is checked in begin_raw
line_iterator i = begin_line (level);
if (i.state() != IteratorState::valid)
return i;
while (i->has_children())
if ((++i).state() != IteratorState::valid)
- return i;
+ return i;
return i;
}
DoFHandler<dim, spacedim>::end_line () const
{
return raw_line_iterator (tria,
- -1,
- -1,
- this);
+ -1,
+ -1,
+ this);
}
{
switch (dim)
{
- case 1:
- Assert (level<tria->n_levels(), ExcInvalidLevel(level));
- Assert (tria->n_raw_lines(level) != 0,
- ExcEmptyLevel (level));
-
- return raw_line_iterator (tria,
- level,
- tria->n_raw_lines(level)-1,
- this);
-
- default:
- Assert (level == 0, ExcFacesHaveNoLevel());
- return raw_line_iterator (tria,
- 0,
- tria->n_raw_lines()-1,
- this);
+ case 1:
+ Assert (level<tria->n_levels(), ExcInvalidLevel(level));
+ Assert (tria->n_raw_lines(level) != 0,
+ ExcEmptyLevel (level));
+
+ return raw_line_iterator (tria,
+ level,
+ tria->n_raw_lines(level)-1,
+ this);
+
+ default:
+ Assert (level == 0, ExcFacesHaveNoLevel());
+ return raw_line_iterator (tria,
+ 0,
+ tria->n_raw_lines()-1,
+ this);
}
}
typename DoFHandler<dim, spacedim>::line_iterator
DoFHandler<dim, spacedim>::last_line (const unsigned int level) const
{
- // level is checked in last_raw
+ // level is checked in last_raw
raw_line_iterator ri = last_raw_line(level);
if (ri->used()==true)
return ri;
while ((--ri).state() == IteratorState::valid)
if (ri->used()==true)
- return ri;
+ return ri;
return ri;
}
typename DoFHandler<dim, spacedim>::active_line_iterator
DoFHandler<dim, spacedim>::last_active_line (const unsigned int level) const
{
- // level is checked in last_raw
+ // level is checked in last_raw
line_iterator i = last_line(level);
if (i->has_children()==false)
return i;
while ((--i).state() == IteratorState::valid)
if (i->has_children()==false)
- return i;
+ return i;
return i;
}
Assert (dim == 1 || level == 0, ExcFacesHaveNoLevel());
if (dim == 1)
return (level == tria->n_levels()-1 ?
- end_line() :
- begin_raw_line (level+1));
+ end_line() :
+ begin_raw_line (level+1));
else
return end_line();
}
Assert (dim == 1 || level == 0, ExcFacesHaveNoLevel());
if (dim == 1)
return (level == tria->n_levels()-1 ?
- line_iterator(end_line()) :
- begin_line (level+1));
+ line_iterator(end_line()) :
+ begin_line (level+1));
else
return line_iterator(end_line());
}
Assert (dim == 1 || level == 0, ExcFacesHaveNoLevel());
if (dim == 1)
return (level == tria->n_levels()-1 ?
- active_line_iterator(end_line()) :
- begin_active_line (level+1));
+ active_line_iterator(end_line()) :
+ begin_active_line (level+1));
else
return active_line_iterator(end_line());
}
{
switch (dim)
{
- case 1:
- Assert (false, ExcImpossibleInDim(1));
- return raw_hex_iterator();
- case 2:
- {
- Assert (level<tria->n_levels(), ExcInvalidLevel(level));
-
- if (tria->n_raw_quads(level) == 0)
- return end_quad();
-
- return raw_quad_iterator (tria,
- level,
- 0,
- this);
- }
-
- case 3:
- {
- Assert (level == 0, ExcFacesHaveNoLevel());
-
- return raw_quad_iterator (tria,
- 0,
- 0,
- this);
- }
-
-
- default:
- Assert (false, ExcNotImplemented());
- return raw_hex_iterator();
+ case 1:
+ Assert (false, ExcImpossibleInDim(1));
+ return raw_hex_iterator();
+ case 2:
+ {
+ Assert (level<tria->n_levels(), ExcInvalidLevel(level));
+
+ if (tria->n_raw_quads(level) == 0)
+ return end_quad();
+
+ return raw_quad_iterator (tria,
+ level,
+ 0,
+ this);
+ }
+
+ case 3:
+ {
+ Assert (level == 0, ExcFacesHaveNoLevel());
+
+ return raw_quad_iterator (tria,
+ 0,
+ 0,
+ this);
+ }
+
+
+ default:
+ Assert (false, ExcNotImplemented());
+ return raw_hex_iterator();
}
}
typename DoFHandler<dim,spacedim>::quad_iterator
DoFHandler<dim,spacedim>::begin_quad (const unsigned int level) const
{
- // level is checked in begin_raw
+ // level is checked in begin_raw
raw_quad_iterator ri = begin_raw_quad (level);
if (ri.state() != IteratorState::valid)
return ri;
while (ri->used() == false)
if ((++ri).state() != IteratorState::valid)
- return ri;
+ return ri;
return ri;
}
typename DoFHandler<dim,spacedim>::active_quad_iterator
DoFHandler<dim,spacedim>::begin_active_quad (const unsigned int level) const
{
- // level is checked in begin_raw
+ // level is checked in begin_raw
quad_iterator i = begin_quad (level);
if (i.state() != IteratorState::valid)
return i;
while (i->has_children())
if ((++i).state() != IteratorState::valid)
- return i;
+ return i;
return i;
}
Assert (dim == 2 || level == 0, ExcFacesHaveNoLevel());
if (dim == 2)
return (level == tria->n_levels()-1 ?
- end_quad() :
- begin_raw_quad (level+1));
+ end_quad() :
+ begin_raw_quad (level+1));
else
return end_quad();
}
Assert (dim == 2 || level == 0, ExcFacesHaveNoLevel());
if (dim == 2)
return (level == tria->n_levels()-1 ?
- quad_iterator(end_quad()) :
- begin_quad (level+1));
+ quad_iterator(end_quad()) :
+ begin_quad (level+1));
else
return quad_iterator(end_quad());
}
Assert(dim == 2 || level == 0, ExcFacesHaveNoLevel());
if (dim == 2)
return (level == tria->n_levels()-1 ?
- active_quad_iterator(end_quad()) :
- begin_active_quad (level+1));
+ active_quad_iterator(end_quad()) :
+ begin_active_quad (level+1));
else
return active_quad_iterator(end_quad());
}
DoFHandler<dim,spacedim>::end_quad () const
{
return raw_quad_iterator (tria,
- -1,
- -1,
- this);
+ -1,
+ -1,
+ this);
}
{
switch (dim)
{
- case 1:
- Assert (false, ExcImpossibleInDim(1));
- return raw_quad_iterator();
- case 2:
- Assert (level<tria->n_levels(),
- ExcInvalidLevel(level));
- Assert (tria->n_raw_quads(level) != 0,
- ExcEmptyLevel (level));
- return raw_quad_iterator (tria,
- level,
- tria->n_raw_quads(level)-1,
- this);
- case 3:
- Assert (level == 0, ExcFacesHaveNoLevel());
- return raw_quad_iterator (tria,
- 0,
- tria->n_raw_quads()-1,
- this);
- default:
- Assert (false, ExcNotImplemented());
- return raw_quad_iterator();
+ case 1:
+ Assert (false, ExcImpossibleInDim(1));
+ return raw_quad_iterator();
+ case 2:
+ Assert (level<tria->n_levels(),
+ ExcInvalidLevel(level));
+ Assert (tria->n_raw_quads(level) != 0,
+ ExcEmptyLevel (level));
+ return raw_quad_iterator (tria,
+ level,
+ tria->n_raw_quads(level)-1,
+ this);
+ case 3:
+ Assert (level == 0, ExcFacesHaveNoLevel());
+ return raw_quad_iterator (tria,
+ 0,
+ tria->n_raw_quads()-1,
+ this);
+ default:
+ Assert (false, ExcNotImplemented());
+ return raw_quad_iterator();
}
}
typename DoFHandler<dim,spacedim>::quad_iterator
DoFHandler<dim,spacedim>::last_quad (const unsigned int level) const
{
- // level is checked in last_raw
+ // level is checked in last_raw
raw_quad_iterator ri = last_raw_quad(level);
if (ri->used()==true)
return ri;
while ((--ri).state() == IteratorState::valid)
if (ri->used()==true)
- return ri;
+ return ri;
return ri;
}
typename DoFHandler<dim,spacedim>::active_quad_iterator
DoFHandler<dim,spacedim>::last_active_quad (const unsigned int level) const
{
- // level is checked in last_raw
+ // level is checked in last_raw
quad_iterator i = last_quad(level);
if (i->has_children()==false)
return i;
while ((--i).state() == IteratorState::valid)
if (i->has_children()==false)
- return i;
+ return i;
return i;
}
{
switch (dim)
{
- case 1:
- case 2:
- Assert (false, ExcImpossibleInDim(1));
- return raw_hex_iterator();
- case 3:
- {
- Assert (level<tria->n_levels(), ExcInvalidLevel(level));
-
- if (tria->n_raw_hexs(level) == 0)
- return end_hex();
-
- return raw_hex_iterator (tria,
- level,
- 0,
- this);
- }
-
- default:
- Assert (false, ExcNotImplemented());
- return raw_hex_iterator();
+ case 1:
+ case 2:
+ Assert (false, ExcImpossibleInDim(1));
+ return raw_hex_iterator();
+ case 3:
+ {
+ Assert (level<tria->n_levels(), ExcInvalidLevel(level));
+
+ if (tria->n_raw_hexs(level) == 0)
+ return end_hex();
+
+ return raw_hex_iterator (tria,
+ level,
+ 0,
+ this);
+ }
+
+ default:
+ Assert (false, ExcNotImplemented());
+ return raw_hex_iterator();
}
}
typename DoFHandler<dim,spacedim>::hex_iterator
DoFHandler<dim,spacedim>::begin_hex (const unsigned int level) const
{
- // level is checked in begin_raw
+ // level is checked in begin_raw
raw_hex_iterator ri = begin_raw_hex (level);
if (ri.state() != IteratorState::valid)
return ri;
while (ri->used() == false)
if ((++ri).state() != IteratorState::valid)
- return ri;
+ return ri;
return ri;
}
typename DoFHandler<dim, spacedim>::active_hex_iterator
DoFHandler<dim, spacedim>::begin_active_hex (const unsigned int level) const
{
- // level is checked in begin_raw
+ // level is checked in begin_raw
hex_iterator i = begin_hex (level);
if (i.state() != IteratorState::valid)
return i;
while (i->has_children())
if ((++i).state() != IteratorState::valid)
- return i;
+ return i;
return i;
}
DoFHandler<dim, spacedim>::end_raw_hex (const unsigned int level) const
{
return (level == tria->n_levels()-1 ?
- end_hex() :
- begin_raw_hex (level+1));
+ end_hex() :
+ begin_raw_hex (level+1));
}
DoFHandler<dim, spacedim>::end_hex (const unsigned int level) const
{
return (level == tria->n_levels()-1 ?
- hex_iterator(end_hex()) :
- begin_hex (level+1));
+ hex_iterator(end_hex()) :
+ begin_hex (level+1));
}
DoFHandler<dim, spacedim>::end_active_hex (const unsigned int level) const
{
return (level == tria->n_levels()-1 ?
- active_hex_iterator(end_hex()) :
- begin_active_hex (level+1));
+ active_hex_iterator(end_hex()) :
+ begin_active_hex (level+1));
}
DoFHandler<dim, spacedim>::end_hex () const
{
return raw_hex_iterator (tria,
- -1,
- -1,
- this);
+ -1,
+ -1,
+ this);
}
{
switch (dim)
{
- case 1:
- case 2:
- Assert (false, ExcImpossibleInDim(dim));
- return raw_hex_iterator();
-
- case 3:
- Assert (level<tria->n_levels(),
- ExcInvalidLevel(level));
- Assert (tria->n_raw_hexs(level) != 0,
- ExcEmptyLevel (level));
-
- return raw_hex_iterator (tria,
- level,
- tria->n_raw_hexs(level)-1,
- this);
- default:
- Assert (false, ExcNotImplemented());
- return raw_hex_iterator();
+ case 1:
+ case 2:
+ Assert (false, ExcImpossibleInDim(dim));
+ return raw_hex_iterator();
+
+ case 3:
+ Assert (level<tria->n_levels(),
+ ExcInvalidLevel(level));
+ Assert (tria->n_raw_hexs(level) != 0,
+ ExcEmptyLevel (level));
+
+ return raw_hex_iterator (tria,
+ level,
+ tria->n_raw_hexs(level)-1,
+ this);
+ default:
+ Assert (false, ExcNotImplemented());
+ return raw_hex_iterator();
}
}
typename DoFHandler<dim, spacedim>::hex_iterator
DoFHandler<dim, spacedim>::last_hex (const unsigned int level) const
{
- // level is checked in last_raw
+ // level is checked in last_raw
raw_hex_iterator ri = last_raw_hex(level);
if (ri->used()==true)
return ri;
while ((--ri).state() == IteratorState::valid)
if (ri->used()==true)
- return ri;
+ return ri;
return ri;
}
typename DoFHandler<dim, spacedim>::active_hex_iterator
DoFHandler<dim, spacedim>::last_active_hex (const unsigned int level) const
{
- // level is checked in last_raw
+ // level is checked in last_raw
hex_iterator i = last_hex(level);
if (i->has_children()==false)
return i;
while ((--i).state() == IteratorState::valid)
if (i->has_children()==false)
- return i;
+ return i;
return i;
}
Assert(false,ExcNotImplemented());
return 0;
}
-
+
template<int dim, int spacedim>
unsigned int DoFHandler<dim,spacedim>::n_boundary_dofs () const
dofs_on_face.resize (dofs_per_face);
cell->face(f)->get_dof_indices (dofs_on_face,
- cell->active_fe_index());
+ cell->active_fe_index());
for (unsigned int i=0; i<dofs_per_face; ++i)
boundary_dofs.insert(dofs_on_face[i]);
};
dofs_on_face.resize (dofs_per_face);
cell->face(f)->get_dof_indices (dofs_on_face,
- cell->active_fe_index());
+ cell->active_fe_index());
for (unsigned int i=0; i<dofs_per_face; ++i)
boundary_dofs.insert(dofs_on_face[i]);
}
DoFHandler<dim,spacedim>::memory_consumption () const
{
std::size_t mem = (MemoryConsumption::memory_consumption (tria) +
- MemoryConsumption::memory_consumption (finite_elements) +
- MemoryConsumption::memory_consumption (tria) +
- MemoryConsumption::memory_consumption (levels) +
- MemoryConsumption::memory_consumption (*faces) +
- MemoryConsumption::memory_consumption (number_cache) +
- MemoryConsumption::memory_consumption (vertex_dofs) +
- MemoryConsumption::memory_consumption (vertex_dofs_offsets) +
- MemoryConsumption::memory_consumption (has_children));
+ MemoryConsumption::memory_consumption (finite_elements) +
+ MemoryConsumption::memory_consumption (tria) +
+ MemoryConsumption::memory_consumption (levels) +
+ MemoryConsumption::memory_consumption (*faces) +
+ MemoryConsumption::memory_consumption (number_cache) +
+ MemoryConsumption::memory_consumption (vertex_dofs) +
+ MemoryConsumption::memory_consumption (vertex_dofs_offsets) +
+ MemoryConsumption::memory_consumption (has_children));
for (unsigned int i=0; i<levels.size(); ++i)
mem += MemoryConsumption::memory_consumption (*levels[i]);
mem += MemoryConsumption::memory_consumption (*faces);
// make that necessary...
Table<2,std_cxx1x::shared_ptr<internal::hp::DoFIdentities> >
vertex_dof_identities (get_fe().size(),
- get_fe().size());
+ get_fe().size());
- // loop over all vertices and
- // see which one we need to
- // work on
+ // loop over all vertices and
+ // see which one we need to
+ // work on
for (unsigned int vertex_index=0; vertex_index<get_tria().n_vertices();
- ++vertex_index)
+ ++vertex_index)
{
- const unsigned int n_active_fe_indices
- = internal::DoFAccessor::Implementation::
- n_active_vertex_fe_indices (*this, vertex_index);
- if (n_active_fe_indices > 1)
- {
- const unsigned int
- first_fe_index
- = internal::DoFAccessor::Implementation::
- nth_active_vertex_fe_index (*this, vertex_index, 0);
-
- // loop over all the
- // other FEs with which
- // we want to identify
- // the DoF indices of
- // the first FE of
- for (unsigned int f=1; f<n_active_fe_indices; ++f)
- {
- const unsigned int
- other_fe_index
- = internal::DoFAccessor::Implementation::
- nth_active_vertex_fe_index (*this, vertex_index, f);
-
- // make sure the
- // entry in the
- // equivalence
- // table exists
- internal::hp::ensure_existence_of_dof_identities<0>
- (get_fe()[first_fe_index],
- get_fe()[other_fe_index],
- vertex_dof_identities[first_fe_index][other_fe_index]);
-
- // then loop
- // through the
- // identities we
- // have. first get
- // the global
- // numbers of the
- // dofs we want to
- // identify and
- // make sure they
- // are not yet
- // constrained to
- // anything else,
- // except for to
- // each other. use
- // the rule that we
- // will always
- // constrain the
- // dof with the
- // higher fe
- // index to the
- // one with the
- // lower, to avoid
- // circular
- // reasoning.
- internal::hp::DoFIdentities &identities
- = *vertex_dof_identities[first_fe_index][other_fe_index];
- for (unsigned int i=0; i<identities.size(); ++i)
- {
- const unsigned int lower_dof_index
- = internal::DoFAccessor::Implementation::
- get_vertex_dof_index (*this,
- vertex_index,
- first_fe_index,
- identities[i].first);
- const unsigned int higher_dof_index
- = internal::DoFAccessor::Implementation::
- get_vertex_dof_index (*this,
- vertex_index,
- other_fe_index,
- identities[i].second);
-
- Assert ((new_dof_indices[higher_dof_index] ==
- numbers::invalid_unsigned_int)
- ||
- (new_dof_indices[higher_dof_index] ==
- lower_dof_index),
- ExcInternalError());
-
- new_dof_indices[higher_dof_index] = lower_dof_index;
- }
- }
- }
+ const unsigned int n_active_fe_indices
+ = internal::DoFAccessor::Implementation::
+ n_active_vertex_fe_indices (*this, vertex_index);
+ if (n_active_fe_indices > 1)
+ {
+ const unsigned int
+ first_fe_index
+ = internal::DoFAccessor::Implementation::
+ nth_active_vertex_fe_index (*this, vertex_index, 0);
+
+ // loop over all the
+ // other FEs with which
+ // we want to identify
+ // the DoF indices of
+ // the first FE of
+ for (unsigned int f=1; f<n_active_fe_indices; ++f)
+ {
+ const unsigned int
+ other_fe_index
+ = internal::DoFAccessor::Implementation::
+ nth_active_vertex_fe_index (*this, vertex_index, f);
+
+ // make sure the
+ // entry in the
+ // equivalence
+ // table exists
+ internal::hp::ensure_existence_of_dof_identities<0>
+ (get_fe()[first_fe_index],
+ get_fe()[other_fe_index],
+ vertex_dof_identities[first_fe_index][other_fe_index]);
+
+ // then loop
+ // through the
+ // identities we
+ // have. first get
+ // the global
+ // numbers of the
+ // dofs we want to
+ // identify and
+ // make sure they
+ // are not yet
+ // constrained to
+ // anything else,
+ // except for to
+ // each other. use
+ // the rule that we
+ // will always
+ // constrain the
+ // dof with the
+ // higher fe
+ // index to the
+ // one with the
+ // lower, to avoid
+ // circular
+ // reasoning.
+ internal::hp::DoFIdentities &identities
+ = *vertex_dof_identities[first_fe_index][other_fe_index];
+ for (unsigned int i=0; i<identities.size(); ++i)
+ {
+ const unsigned int lower_dof_index
+ = internal::DoFAccessor::Implementation::
+ get_vertex_dof_index (*this,
+ vertex_index,
+ first_fe_index,
+ identities[i].first);
+ const unsigned int higher_dof_index
+ = internal::DoFAccessor::Implementation::
+ get_vertex_dof_index (*this,
+ vertex_index,
+ other_fe_index,
+ identities[i].second);
+
+ Assert ((new_dof_indices[higher_dof_index] ==
+ numbers::invalid_unsigned_int)
+ ||
+ (new_dof_indices[higher_dof_index] ==
+ lower_dof_index),
+ ExcInternalError());
+
+ new_dof_indices[higher_dof_index] = lower_dof_index;
+ }
+ }
+ }
}
}
// for quads only in 4d and
// higher, so this isn't a
// particularly frequent case
- //
- // there is one case, however, that we
- // would like to handle (see, for
- // example, the hp/crash_15 testcase): if
- // we have FESystem(FE_Q(2),FE_DGQ(i))
- // elements for a bunch of values 'i',
- // then we should be able to handle this
- // because we can simply unify *all*
- // dofs, not only a some. so what we do
- // is to first treat all pairs of finite
- // elements that have *identical* dofs,
- // and then only deal with those that are
- // not identical of which we can handle
- // at most 2
+ //
+ // there is one case, however, that we
+ // would like to handle (see, for
+ // example, the hp/crash_15 testcase): if
+ // we have FESystem(FE_Q(2),FE_DGQ(i))
+ // elements for a bunch of values 'i',
+ // then we should be able to handle this
+ // because we can simply unify *all*
+ // dofs, not only a some. so what we do
+ // is to first treat all pairs of finite
+ // elements that have *identical* dofs,
+ // and then only deal with those that are
+ // not identical of which we can handle
+ // at most 2
Table<2,std_cxx1x::shared_ptr<internal::hp::DoFIdentities> >
line_dof_identities (finite_elements->size(),
- finite_elements->size());
+ finite_elements->size());
for (line_iterator line=begin_line(); line!=end_line(); ++line)
{
- unsigned int unique_sets_of_dofs
- = line->n_active_fe_indices();
-
- // do a first loop over all sets of
- // dofs and do identity
- // uniquification
- for (unsigned int f=0; f<line->n_active_fe_indices(); ++f)
- for (unsigned int g=f+1; g<line->n_active_fe_indices(); ++g)
- {
- const unsigned int fe_index_1 = line->nth_active_fe_index (f),
- fe_index_2 = line->nth_active_fe_index (g);
-
- if (((*finite_elements)[fe_index_1].dofs_per_line
- ==
- (*finite_elements)[fe_index_2].dofs_per_line)
- &&
- ((*finite_elements)[fe_index_1].dofs_per_line > 0))
- {
- internal::hp::ensure_existence_of_dof_identities<1>
- ((*finite_elements)[fe_index_1],
- (*finite_elements)[fe_index_2],
- line_dof_identities[fe_index_1][fe_index_2]);
- // see if these sets of dofs
- // are identical. the first
- // condition for this is that
- // indeed there are n
- // identities
- if (line_dof_identities[fe_index_1][fe_index_2]->size()
- ==
- (*finite_elements)[fe_index_1].dofs_per_line)
- {
- unsigned int i=0;
- for (; i<(*finite_elements)[fe_index_1].dofs_per_line; ++i)
- if (((*(line_dof_identities[fe_index_1][fe_index_2]))[i].first != i)
- &&
- ((*(line_dof_identities[fe_index_1][fe_index_2]))[i].second != i))
- // not an identity
- break;
-
- if (i == (*finite_elements)[fe_index_1].dofs_per_line)
- {
- // the dofs of these
- // two finite
- // elements are
- // identical. as a
- // safety check,
- // ensure that none
- // of the two FEs is
- // trying to dominate
- // the other, which
- // wouldn't make any
- // sense in this case
- Assert ((*finite_elements)[fe_index_1].compare_for_face_domination
- ((*finite_elements)[fe_index_2])
- ==
- FiniteElementDomination::either_element_can_dominate,
- ExcInternalError());
-
- --unique_sets_of_dofs;
-
- for (unsigned int j=0; j<(*finite_elements)[fe_index_1].dofs_per_line; ++j)
- {
- const unsigned int master_dof_index
- = line->dof_index (j, fe_index_1);
- const unsigned int slave_dof_index
- = line->dof_index (j, fe_index_2);
-
- // if master dof
- // was already
- // constrained,
- // constrain to
- // that one,
- // otherwise
- // constrain
- // slave to
- // master
- if (new_dof_indices[master_dof_index] !=
- numbers::invalid_unsigned_int)
- {
- Assert (new_dof_indices[new_dof_indices[master_dof_index]] ==
- numbers::invalid_unsigned_int,
- ExcInternalError());
-
- new_dof_indices[slave_dof_index]
- = new_dof_indices[master_dof_index];
- }
- else
- {
- Assert ((new_dof_indices[master_dof_index] ==
- numbers::invalid_unsigned_int)
- ||
- (new_dof_indices[slave_dof_index] ==
- master_dof_index),
- ExcInternalError());
-
- new_dof_indices[slave_dof_index] = master_dof_index;
- }
- }
- }
- }
- }
- }
-
- // if at this point, there is only
- // one unique set of dofs left, then
- // we have taken care of everything
- // above. if there are two, then we
- // need to deal with them here. if
- // there are more, then we punt, as
- // described in the paper (and
- // mentioned above)
+ unsigned int unique_sets_of_dofs
+ = line->n_active_fe_indices();
+
+ // do a first loop over all sets of
+ // dofs and do identity
+ // uniquification
+ for (unsigned int f=0; f<line->n_active_fe_indices(); ++f)
+ for (unsigned int g=f+1; g<line->n_active_fe_indices(); ++g)
+ {
+ const unsigned int fe_index_1 = line->nth_active_fe_index (f),
+ fe_index_2 = line->nth_active_fe_index (g);
+
+ if (((*finite_elements)[fe_index_1].dofs_per_line
+ ==
+ (*finite_elements)[fe_index_2].dofs_per_line)
+ &&
+ ((*finite_elements)[fe_index_1].dofs_per_line > 0))
+ {
+ internal::hp::ensure_existence_of_dof_identities<1>
+ ((*finite_elements)[fe_index_1],
+ (*finite_elements)[fe_index_2],
+ line_dof_identities[fe_index_1][fe_index_2]);
+ // see if these sets of dofs
+ // are identical. the first
+ // condition for this is that
+ // indeed there are n
+ // identities
+ if (line_dof_identities[fe_index_1][fe_index_2]->size()
+ ==
+ (*finite_elements)[fe_index_1].dofs_per_line)
+ {
+ unsigned int i=0;
+ for (; i<(*finite_elements)[fe_index_1].dofs_per_line; ++i)
+ if (((*(line_dof_identities[fe_index_1][fe_index_2]))[i].first != i)
+ &&
+ ((*(line_dof_identities[fe_index_1][fe_index_2]))[i].second != i))
+ // not an identity
+ break;
+
+ if (i == (*finite_elements)[fe_index_1].dofs_per_line)
+ {
+ // the dofs of these
+ // two finite
+ // elements are
+ // identical. as a
+ // safety check,
+ // ensure that none
+ // of the two FEs is
+ // trying to dominate
+ // the other, which
+ // wouldn't make any
+ // sense in this case
+ Assert ((*finite_elements)[fe_index_1].compare_for_face_domination
+ ((*finite_elements)[fe_index_2])
+ ==
+ FiniteElementDomination::either_element_can_dominate,
+ ExcInternalError());
+
+ --unique_sets_of_dofs;
+
+ for (unsigned int j=0; j<(*finite_elements)[fe_index_1].dofs_per_line; ++j)
+ {
+ const unsigned int master_dof_index
+ = line->dof_index (j, fe_index_1);
+ const unsigned int slave_dof_index
+ = line->dof_index (j, fe_index_2);
+
+ // if master dof
+ // was already
+ // constrained,
+ // constrain to
+ // that one,
+ // otherwise
+ // constrain
+ // slave to
+ // master
+ if (new_dof_indices[master_dof_index] !=
+ numbers::invalid_unsigned_int)
+ {
+ Assert (new_dof_indices[new_dof_indices[master_dof_index]] ==
+ numbers::invalid_unsigned_int,
+ ExcInternalError());
+
+ new_dof_indices[slave_dof_index]
+ = new_dof_indices[master_dof_index];
+ }
+ else
+ {
+ Assert ((new_dof_indices[master_dof_index] ==
+ numbers::invalid_unsigned_int)
+ ||
+ (new_dof_indices[slave_dof_index] ==
+ master_dof_index),
+ ExcInternalError());
+
+ new_dof_indices[slave_dof_index] = master_dof_index;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // if at this point, there is only
+ // one unique set of dofs left, then
+ // we have taken care of everything
+ // above. if there are two, then we
+ // need to deal with them here. if
+ // there are more, then we punt, as
+ // described in the paper (and
+ // mentioned above)
//TODO: The check for 'dim==2' was inserted by intuition. It fixes
// the previous problems with step-27 in 3D. But an explanation
// for this is still required, and what we do here is not what we
// describe in the paper!.
- if ((unique_sets_of_dofs == 2) && (dim == 2))
- {
- // find out which is the
- // most dominating finite
- // element of the ones that
- // are used on this line
- const unsigned int most_dominating_fe_index
- = internal::hp::get_most_dominating_fe_index<dim,spacedim> (line);
-
- const unsigned int n_active_fe_indices
- = line->n_active_fe_indices ();
-
- // loop over the indices of
- // all the finite elements
- // that are not dominating,
- // and identify their dofs
- // to the most dominating
- // one
- for (unsigned int f=0; f<n_active_fe_indices; ++f)
- if (line->nth_active_fe_index (f) !=
- most_dominating_fe_index)
- {
- const unsigned int
- other_fe_index = line->nth_active_fe_index (f);
-
- internal::hp::ensure_existence_of_dof_identities<1>
- ((*finite_elements)[most_dominating_fe_index],
- (*finite_elements)[other_fe_index],
- line_dof_identities[most_dominating_fe_index][other_fe_index]);
-
- internal::hp::DoFIdentities &identities
- = *line_dof_identities[most_dominating_fe_index][other_fe_index];
- for (unsigned int i=0; i<identities.size(); ++i)
- {
- const unsigned int master_dof_index
- = line->dof_index (identities[i].first, most_dominating_fe_index);
- const unsigned int slave_dof_index
- = line->dof_index (identities[i].second, other_fe_index);
-
- Assert ((new_dof_indices[master_dof_index] ==
- numbers::invalid_unsigned_int)
- ||
- (new_dof_indices[slave_dof_index] ==
- master_dof_index),
- ExcInternalError());
-
- new_dof_indices[slave_dof_index] = master_dof_index;
- }
- }
- }
+ if ((unique_sets_of_dofs == 2) && (dim == 2))
+ {
+ // find out which is the
+ // most dominating finite
+ // element of the ones that
+ // are used on this line
+ const unsigned int most_dominating_fe_index
+ = internal::hp::get_most_dominating_fe_index<dim,spacedim> (line);
+
+ const unsigned int n_active_fe_indices
+ = line->n_active_fe_indices ();
+
+ // loop over the indices of
+ // all the finite elements
+ // that are not dominating,
+ // and identify their dofs
+ // to the most dominating
+ // one
+ for (unsigned int f=0; f<n_active_fe_indices; ++f)
+ if (line->nth_active_fe_index (f) !=
+ most_dominating_fe_index)
+ {
+ const unsigned int
+ other_fe_index = line->nth_active_fe_index (f);
+
+ internal::hp::ensure_existence_of_dof_identities<1>
+ ((*finite_elements)[most_dominating_fe_index],
+ (*finite_elements)[other_fe_index],
+ line_dof_identities[most_dominating_fe_index][other_fe_index]);
+
+ internal::hp::DoFIdentities &identities
+ = *line_dof_identities[most_dominating_fe_index][other_fe_index];
+ for (unsigned int i=0; i<identities.size(); ++i)
+ {
+ const unsigned int master_dof_index
+ = line->dof_index (identities[i].first, most_dominating_fe_index);
+ const unsigned int slave_dof_index
+ = line->dof_index (identities[i].second, other_fe_index);
+
+ Assert ((new_dof_indices[master_dof_index] ==
+ numbers::invalid_unsigned_int)
+ ||
+ (new_dof_indices[slave_dof_index] ==
+ master_dof_index),
+ ExcInternalError());
+
+ new_dof_indices[slave_dof_index] = master_dof_index;
+ }
+ }
+ }
}
}
// particularly frequent case
Table<2,std_cxx1x::shared_ptr<internal::hp::DoFIdentities> >
quad_dof_identities (finite_elements->size(),
- finite_elements->size());
+ finite_elements->size());
for (quad_iterator quad=begin_quad(); quad!=end_quad(); ++quad)
if (quad->n_active_fe_indices() == 2)
- {
+ {
// find out which is the
// most dominating finite
// element of the ones that
const unsigned int most_dominating_fe_index
= internal::hp::get_most_dominating_fe_index<dim,spacedim> (quad);
- const unsigned int n_active_fe_indices
- = quad->n_active_fe_indices ();
+ const unsigned int n_active_fe_indices
+ = quad->n_active_fe_indices ();
// loop over the indices of
// all the finite elements
ExcInternalError());
new_dof_indices[slave_dof_index] = master_dof_index;
- }
- }
- }
+ }
+ }
+ }
}
void DoFHandler<dim,spacedim>::set_active_fe_indices (const std::vector<unsigned int>& active_fe_indices)
{
Assert(active_fe_indices.size()==get_tria().n_active_cells(),
- ExcDimensionMismatch(active_fe_indices.size(), get_tria().n_active_cells()));
+ ExcDimensionMismatch(active_fe_indices.size(), get_tria().n_active_cells()));
create_active_fe_table ();
- // we could set the values directly, since
- // they are stored as protected data of
- // this object, but for simplicity we use
- // the cell-wise access. this way we also
- // have to pass some debug-mode tests which
- // we would have to duplicate ourselves
- // otherwise
+ // we could set the values directly, since
+ // they are stored as protected data of
+ // this object, but for simplicity we use
+ // the cell-wise access. this way we also
+ // have to pass some debug-mode tests which
+ // we would have to duplicate ourselves
+ // otherwise
active_cell_iterator cell=begin_active(),
- endc=end();
+ endc=end();
for (unsigned int i=0; cell!=endc; ++cell, ++i)
cell->set_active_fe_index(active_fe_indices[i]);
}
{
active_fe_indices.resize(get_tria().n_active_cells());
- // we could try to extract the values directly, since
- // they are stored as protected data of
- // this object, but for simplicity we use
- // the cell-wise access.
+ // we could try to extract the values directly, since
+ // they are stored as protected data of
+ // this object, but for simplicity we use
+ // the cell-wise access.
active_cell_iterator cell=begin_active(),
- endc=end();
+ endc=end();
for (unsigned int i=0; cell!=endc; ++cell, ++i)
active_fe_indices[i]=cell->active_fe_index();
}
// initialized correctly.
create_active_fe_table ();
- // up front make sure that the fe
- // collection is large enough to
- // cover all fe indices presently
- // in use on the mesh
+ // up front make sure that the fe
+ // collection is large enough to
+ // cover all fe indices presently
+ // in use on the mesh
for (active_cell_iterator cell = begin_active(); cell != end(); ++cell)
Assert (cell->active_fe_index() < finite_elements->size(),
- ExcInvalidFEIndex (cell->active_fe_index(),
- finite_elements->size()));
+ ExcInvalidFEIndex (cell->active_fe_index(),
+ finite_elements->size()));
// then allocate space for all
const_cast<Triangulation<dim,spacedim> &>(*tria).clear_user_flags ();
- /////////////////////////////////
+ /////////////////////////////////
- // Step 1: distribute DoFs on all
- // active entities
+ // Step 1: distribute DoFs on all
+ // active entities
{
unsigned int next_free_dof = 0;
active_cell_iterator cell = begin_active(),
- endc = end();
+ endc = end();
for (; cell != endc; ++cell)
- next_free_dof
- = internal::hp::DoFHandler::Implementation::template distribute_dofs_on_cell<spacedim> (cell,
- next_free_dof);
+ next_free_dof
+ = internal::hp::DoFHandler::Implementation::template distribute_dofs_on_cell<spacedim> (cell,
+ next_free_dof);
number_cache.n_global_dofs = next_free_dof;
}
- /////////////////////////////////
+ /////////////////////////////////
- // Step 2: identify certain dofs
- // if the finite element tells us
- // that they should have the same
- // value. only pertinent for
- // faces and other
- // lower-dimensional objects
- // where elements come together
+ // Step 2: identify certain dofs
+ // if the finite element tells us
+ // that they should have the same
+ // value. only pertinent for
+ // faces and other
+ // lower-dimensional objects
+ // where elements come together
std::vector<unsigned int>
constrained_indices (number_cache.n_global_dofs, numbers::invalid_unsigned_int);
compute_vertex_dof_identities (constrained_indices);
compute_line_dof_identities (constrained_indices);
compute_quad_dof_identities (constrained_indices);
- // loop over all dofs and assign
- // new numbers to those which are
- // not constrained
+ // loop over all dofs and assign
+ // new numbers to those which are
+ // not constrained
std::vector<unsigned int>
new_dof_indices (number_cache.n_global_dofs, numbers::invalid_unsigned_int);
unsigned int next_free_dof = 0;
for (unsigned int i=0; i<number_cache.n_global_dofs; ++i)
if (constrained_indices[i] == numbers::invalid_unsigned_int)
- {
- new_dof_indices[i] = next_free_dof;
- ++next_free_dof;
- }
-
- // then loop over all those that
- // are constrained and record the
- // new dof number for those:
+ {
+ new_dof_indices[i] = next_free_dof;
+ ++next_free_dof;
+ }
+
+ // then loop over all those that
+ // are constrained and record the
+ // new dof number for those:
for (unsigned int i=0; i<number_cache.n_global_dofs; ++i)
if (constrained_indices[i] != numbers::invalid_unsigned_int)
- {
- Assert (new_dof_indices[constrained_indices[i]] !=
- numbers::invalid_unsigned_int,
- ExcInternalError());
+ {
+ Assert (new_dof_indices[constrained_indices[i]] !=
+ numbers::invalid_unsigned_int,
+ ExcInternalError());
- new_dof_indices[i] = new_dof_indices[constrained_indices[i]];
- }
+ new_dof_indices[i] = new_dof_indices[constrained_indices[i]];
+ }
for (unsigned int i=0; i<number_cache.n_global_dofs; ++i)
{
- Assert (new_dof_indices[i] != numbers::invalid_unsigned_int,
- ExcInternalError());
- Assert (new_dof_indices[i] < next_free_dof,
- ExcInternalError());
+ Assert (new_dof_indices[i] != numbers::invalid_unsigned_int,
+ ExcInternalError());
+ Assert (new_dof_indices[i] < next_free_dof,
+ ExcInternalError());
}
- // finally, do the renumbering
- // and set the number of actually
- // used dof indices
+ // finally, do the renumbering
+ // and set the number of actually
+ // used dof indices
renumber_dofs_internal (new_dof_indices, internal::int2type<dim>());
- // now set the elements of the
- // number cache appropriately
+ // now set the elements of the
+ // number cache appropriately
number_cache.n_global_dofs = next_free_dof;
number_cache.n_locally_owned_dofs = number_cache.n_global_dofs;
number_cache.locally_owned_dofs
= IndexSet (number_cache.n_global_dofs);
number_cache.locally_owned_dofs.add_range (0,
- number_cache.n_global_dofs);
+ number_cache.n_global_dofs);
number_cache.n_locally_owned_dofs_per_processor
= std::vector<unsigned int> (1,
- number_cache.n_global_dofs);
+ number_cache.n_global_dofs);
number_cache.locally_owned_dofs_per_processor
= std::vector<IndexSet> (1,
- number_cache.locally_owned_dofs);
+ number_cache.locally_owned_dofs);
// finally restore the user flags
const_cast<Triangulation<dim,spacedim> &>(*tria).load_user_flags(user_flags);
void
DoFHandler<dim,spacedim>::
renumber_dofs_internal (const std::vector<unsigned int> &new_numbers,
- internal::int2type<0>)
+ internal::int2type<0>)
{
Assert (new_numbers.size() == n_dofs(), ExcRenumberingIncomplete());
for (unsigned int vertex_index=0; vertex_index<get_tria().n_vertices();
- ++vertex_index)
+ ++vertex_index)
{
- const unsigned int n_active_fe_indices
- = internal::DoFAccessor::Implementation::
- n_active_vertex_fe_indices (*this, vertex_index);
-
- for (unsigned int f=0; f<n_active_fe_indices; ++f)
- {
- const unsigned int fe_index
- = internal::DoFAccessor::Implementation::
- nth_active_vertex_fe_index (*this, vertex_index, f);
-
- for (unsigned int d=0; d<(*finite_elements)[fe_index].dofs_per_vertex; ++d)
- {
- const unsigned int vertex_dof_index
- = internal::DoFAccessor::Implementation::
- get_vertex_dof_index(*this,
- vertex_index,
- fe_index,
- d);
- internal::DoFAccessor::Implementation::
- set_vertex_dof_index (*this,
- vertex_index,
- fe_index,
- d,
- new_numbers[vertex_dof_index]);
- }
- }
+ const unsigned int n_active_fe_indices
+ = internal::DoFAccessor::Implementation::
+ n_active_vertex_fe_indices (*this, vertex_index);
+
+ for (unsigned int f=0; f<n_active_fe_indices; ++f)
+ {
+ const unsigned int fe_index
+ = internal::DoFAccessor::Implementation::
+ nth_active_vertex_fe_index (*this, vertex_index, f);
+
+ for (unsigned int d=0; d<(*finite_elements)[fe_index].dofs_per_vertex; ++d)
+ {
+ const unsigned int vertex_dof_index
+ = internal::DoFAccessor::Implementation::
+ get_vertex_dof_index(*this,
+ vertex_index,
+ fe_index,
+ d);
+ internal::DoFAccessor::Implementation::
+ set_vertex_dof_index (*this,
+ vertex_index,
+ fe_index,
+ d,
+ new_numbers[vertex_dof_index]);
+ }
+ }
}
}
void
DoFHandler<dim,spacedim>::
renumber_dofs_internal (const std::vector<unsigned int> &new_numbers,
- internal::int2type<1>)
+ internal::int2type<1>)
{
Assert (new_numbers.size() == n_dofs(), ExcRenumberingIncomplete());
for (line_iterator line=begin_line(); line!=end_line(); ++line)
{
- const unsigned int n_active_fe_indices
- = line->n_active_fe_indices ();
-
- for (unsigned int f=0; f<n_active_fe_indices; ++f)
- {
- const unsigned int fe_index
- = line->nth_active_fe_index (f);
-
- for (unsigned int d=0; d<(*finite_elements)[fe_index].dofs_per_line; ++d)
- line->set_dof_index (d,
- new_numbers[line->dof_index(d,fe_index)],
- fe_index);
- }
+ const unsigned int n_active_fe_indices
+ = line->n_active_fe_indices ();
+
+ for (unsigned int f=0; f<n_active_fe_indices; ++f)
+ {
+ const unsigned int fe_index
+ = line->nth_active_fe_index (f);
+
+ for (unsigned int d=0; d<(*finite_elements)[fe_index].dofs_per_line; ++d)
+ line->set_dof_index (d,
+ new_numbers[line->dof_index(d,fe_index)],
+ fe_index);
+ }
}
}
- // TODO: should be simplified a bit
+ // TODO: should be simplified a bit
template<>
void
DoFHandler<2,2>::
renumber_dofs_internal (const std::vector<unsigned int> &new_numbers,
- internal::int2type<2>)
+ internal::int2type<2>)
{
Assert (new_numbers.size() == n_dofs(), ExcRenumberingIncomplete());
for (quad_iterator quad=begin_quad(); quad!=end_quad(); ++quad)
{
- const unsigned int n_active_fe_indices
- = quad->n_active_fe_indices ();
-
- for (unsigned int f=0; f<n_active_fe_indices; ++f)
- {
- const unsigned int fe_index
- = quad->nth_active_fe_index (f);
-
- for (unsigned int d=0; d<(*finite_elements)[fe_index].dofs_per_quad; ++d)
- quad->set_dof_index (d,
- new_numbers[quad->dof_index(d,fe_index)],
- fe_index);
- }
+ const unsigned int n_active_fe_indices
+ = quad->n_active_fe_indices ();
+
+ for (unsigned int f=0; f<n_active_fe_indices; ++f)
+ {
+ const unsigned int fe_index
+ = quad->nth_active_fe_index (f);
+
+ for (unsigned int d=0; d<(*finite_elements)[fe_index].dofs_per_quad; ++d)
+ quad->set_dof_index (d,
+ new_numbers[quad->dof_index(d,fe_index)],
+ fe_index);
+ }
}
}
void
DoFHandler<2,3>::
renumber_dofs_internal (const std::vector<unsigned int> &new_numbers,
- internal::int2type<2>)
+ internal::int2type<2>)
{
Assert (new_numbers.size() == n_dofs(), ExcRenumberingIncomplete());
for (quad_iterator quad=begin_quad(); quad!=end_quad(); ++quad)
{
- const unsigned int n_active_fe_indices
- = quad->n_active_fe_indices ();
-
- for (unsigned int f=0; f<n_active_fe_indices; ++f)
- {
- const unsigned int fe_index
- = quad->nth_active_fe_index (f);
-
- for (unsigned int d=0; d<(*finite_elements)[fe_index].dofs_per_quad; ++d)
- quad->set_dof_index (d,
- new_numbers[quad->dof_index(d,fe_index)],
- fe_index);
- }
+ const unsigned int n_active_fe_indices
+ = quad->n_active_fe_indices ();
+
+ for (unsigned int f=0; f<n_active_fe_indices; ++f)
+ {
+ const unsigned int fe_index
+ = quad->nth_active_fe_index (f);
+
+ for (unsigned int d=0; d<(*finite_elements)[fe_index].dofs_per_quad; ++d)
+ quad->set_dof_index (d,
+ new_numbers[quad->dof_index(d,fe_index)],
+ fe_index);
+ }
}
}
void
DoFHandler<3,3>::
renumber_dofs_internal (const std::vector<unsigned int> &new_numbers,
- internal::int2type<2>)
+ internal::int2type<2>)
{
Assert (new_numbers.size() == n_dofs(), ExcRenumberingIncomplete());
for (quad_iterator quad=begin_quad(); quad!=end_quad(); ++quad)
{
- const unsigned int n_active_fe_indices
- = quad->n_active_fe_indices ();
-
- for (unsigned int f=0; f<n_active_fe_indices; ++f)
- {
- const unsigned int fe_index
- = quad->nth_active_fe_index (f);
-
- for (unsigned int d=0; d<(*finite_elements)[fe_index].dofs_per_quad; ++d)
- quad->set_dof_index (d,
- new_numbers[quad->dof_index(d,fe_index)],
- fe_index);
- }
+ const unsigned int n_active_fe_indices
+ = quad->n_active_fe_indices ();
+
+ for (unsigned int f=0; f<n_active_fe_indices; ++f)
+ {
+ const unsigned int fe_index
+ = quad->nth_active_fe_index (f);
+
+ for (unsigned int d=0; d<(*finite_elements)[fe_index].dofs_per_quad; ++d)
+ quad->set_dof_index (d,
+ new_numbers[quad->dof_index(d,fe_index)],
+ fe_index);
+ }
}
}
void
DoFHandler<3,3>::
renumber_dofs_internal (const std::vector<unsigned int> &new_numbers,
- internal::int2type<3>)
+ internal::int2type<3>)
{
Assert (new_numbers.size() == n_dofs(), ExcRenumberingIncomplete());
for (hex_iterator hex=begin_hex(); hex!=end_hex(); ++hex)
{
- const unsigned int n_active_fe_indices
- = hex->n_active_fe_indices ();
-
- for (unsigned int f=0; f<n_active_fe_indices; ++f)
- {
- const unsigned int fe_index
- = hex->nth_active_fe_index (f);
-
- for (unsigned int d=0; d<(*finite_elements)[fe_index].dofs_per_hex; ++d)
- hex->set_dof_index (d,
- new_numbers[hex->dof_index(d,fe_index)],
- fe_index);
- }
+ const unsigned int n_active_fe_indices
+ = hex->n_active_fe_indices ();
+
+ for (unsigned int f=0; f<n_active_fe_indices; ++f)
+ {
+ const unsigned int fe_index
+ = hex->nth_active_fe_index (f);
+
+ for (unsigned int d=0; d<(*finite_elements)[fe_index].dofs_per_hex; ++d)
+ hex->set_dof_index (d,
+ new_numbers[hex->dof_index(d,fe_index)],
+ fe_index);
+ }
}
}
switch (dim)
{
- case 1:
- return finite_elements->max_dofs_per_vertex();
- case 2:
- return (3*finite_elements->max_dofs_per_vertex()
- +
- 2*finite_elements->max_dofs_per_line());
- case 3:
- // we need to take refinement of
- // one boundary face into consideration
- // here; in fact, this function returns
- // what #max_coupling_between_dofs<2>
- // returns
- //
- // we assume here, that only four faces
- // meet at the boundary; this assumption
- // is not justified and needs to be
- // fixed some time. fortunately, ommitting
- // it for now does no harm since the
- // matrix will cry foul if its requirements
- // are not satisfied
- return (19*finite_elements->max_dofs_per_vertex() +
- 28*finite_elements->max_dofs_per_line() +
- 8*finite_elements->max_dofs_per_quad());
- default:
- Assert (false, ExcNotImplemented());
- return 0;
+ case 1:
+ return finite_elements->max_dofs_per_vertex();
+ case 2:
+ return (3*finite_elements->max_dofs_per_vertex()
+ +
+ 2*finite_elements->max_dofs_per_line());
+ case 3:
+ // we need to take refinement of
+ // one boundary face into consideration
+ // here; in fact, this function returns
+ // what #max_coupling_between_dofs<2>
+ // returns
+ //
+ // we assume here, that only four faces
+ // meet at the boundary; this assumption
+ // is not justified and needs to be
+ // fixed some time. fortunately, ommitting
+ // it for now does no harm since the
+ // matrix will cry foul if its requirements
+ // are not satisfied
+ return (19*finite_elements->max_dofs_per_vertex() +
+ 28*finite_elements->max_dofs_per_line() +
+ 8*finite_elements->max_dofs_per_quad());
+ default:
+ Assert (false, ExcNotImplemented());
+ return 0;
}
}
Assert (has_children.size () == 0, ExcInternalError ());
for (unsigned int i=0; i<levels.size(); ++i)
{
- const unsigned int cells_on_level = tria->n_raw_cells(i);
- std::vector<bool> *has_children_level =
+ const unsigned int cells_on_level = tria->n_raw_cells(i);
+ std::vector<bool> *has_children_level =
new std::vector<bool> (cells_on_level);
// Check for each cell, if it has children.
- std::transform (tria->levels[i]->cells.refinement_cases.begin (),
- tria->levels[i]->cells.refinement_cases.end (),
- has_children_level->begin (),
- std::bind2nd (std::not_equal_to<unsigned char>(),
- static_cast<unsigned char>(RefinementCase<dim>::no_refinement)));
+ std::transform (tria->levels[i]->cells.refinement_cases.begin (),
+ tria->levels[i]->cells.refinement_cases.end (),
+ has_children_level->begin (),
+ std::bind2nd (std::not_equal_to<unsigned char>(),
+ static_cast<unsigned char>(RefinementCase<dim>::no_refinement)));
- has_children.push_back (has_children_level);
+ has_children.push_back (has_children_level);
}
}
Assert (has_children.size () == 0, ExcInternalError ());
for (unsigned int i=0; i<levels.size(); ++i)
{
- const unsigned int cells_on_level = tria->n_raw_cells (i);
- std::vector<bool> *has_children_level =
+ const unsigned int cells_on_level = tria->n_raw_cells (i);
+ std::vector<bool> *has_children_level =
new std::vector<bool> (cells_on_level);
// Check for each cell, if it has
// 1d (as there is only one choice
// anyway). use the 'children' vector
// instead
- std::transform (tria->levels[i]->cells.children.begin (),
- tria->levels[i]->cells.children.end (),
- has_children_level->begin (),
- std::bind2nd (std::not_equal_to<int>(), -1));
+ std::transform (tria->levels[i]->cells.children.begin (),
+ tria->levels[i]->cells.children.end (),
+ has_children_level->begin (),
+ std::bind2nd (std::not_equal_to<int>(), -1));
- has_children.push_back (has_children_level);
+ has_children.push_back (has_children_level);
}
}
Assert (has_children.size () == 0, ExcInternalError ());
for (unsigned int i=0; i<levels.size(); ++i)
{
- const unsigned int lines_on_level = tria->n_raw_lines(i);
- std::vector<bool> *has_children_level =
+ const unsigned int lines_on_level = tria->n_raw_lines(i);
+ std::vector<bool> *has_children_level =
new std::vector<bool> (lines_on_level);
// Check for each cell, if it has children.
- std::transform (tria->levels[i]->cells.children.begin (),
- tria->levels[i]->cells.children.end (),
- has_children_level->begin (),
- std::bind2nd (std::not_equal_to<int>(), -1));
+ std::transform (tria->levels[i]->cells.children.begin (),
+ tria->levels[i]->cells.children.end (),
+ has_children_level->begin (),
+ std::bind2nd (std::not_equal_to<int>(), -1));
- has_children.push_back (has_children_level);
+ has_children.push_back (has_children_level);
}
}
Assert (has_children.size () == 0, ExcInternalError ());
for (unsigned int i=0; i<levels.size(); ++i)
{
- const unsigned int lines_on_level = tria->n_raw_lines(i);
- std::vector<bool> *has_children_level =
+ const unsigned int lines_on_level = tria->n_raw_lines(i);
+ std::vector<bool> *has_children_level =
new std::vector<bool> (lines_on_level);
// Check for each cell, if it has children.
- std::transform (tria->levels[i]->cells.children.begin (),
- tria->levels[i]->cells.children.end (),
- has_children_level->begin (),
- std::bind2nd (std::not_equal_to<int>(), -1));
+ std::transform (tria->levels[i]->cells.children.begin (),
+ tria->levels[i]->cells.children.end (),
+ has_children_level->begin (),
+ std::bind2nd (std::not_equal_to<int>(), -1));
- has_children.push_back (has_children_level);
+ has_children.push_back (has_children_level);
}
}
-
+
template<int dim, int spacedim>
void
DoFHandler<dim,spacedim>::post_refinement_action ()
// of levels. Hence remove them.
while (levels.size () > tria->n_levels ())
{
- delete levels[levels.size ()-1];
- levels.pop_back ();
+ delete levels[levels.size ()-1];
+ levels.pop_back ();
}
// Resize active_fe_indices
// Free buffer objects
std::vector<std::vector<bool> *>::iterator children_level;
for (children_level = has_children.begin ();
- children_level != has_children.end ();
- ++children_level)
+ children_level != has_children.end ();
+ ++children_level)
delete (*children_level);
/*
for_each (has_children.begin (),
// $Id$
// Version: $Name$
//
-// Copyright (C) 2003, 2006, 2011 by the deal.II authors
+// Copyright (C) 2003, 2006, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
return (DoFLevel<0>::memory_consumption() +
MemoryConsumption::memory_consumption (lines));
}
-
+
std::size_t
{
return MemoryConsumption::memory_consumption (active_fe_indices);
}
-
+
}
}
// $Id$
// Version: $Name$
//
-// Copyright (C) 2006, 2011 by the deal.II authors
+// Copyright (C) 2006, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
}
- // explicit instantiations
+ // explicit instantiations
template
std::size_t
DoFObjects<1>::memory_consumption () const;
-
+
template
std::size_t
DoFObjects<2>::memory_consumption () const;
-
+
template
std::size_t
DoFObjects<3>::memory_consumption () const;
// $Id$
// Version: $Name$
//
-// Copyright (C) 2003, 2004, 2006, 2011 by the deal.II authors
+// Copyright (C) 2003, 2004, 2006, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
// $Id$
// Version: $Name$
//
-// Copyright (C) 2003, 2006, 2007, 2008, 2009, 2010 by the deal.II authors
+// Copyright (C) 2003, 2006, 2007, 2008, 2009, 2010, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
template <int dim, int q_dim, class FEValues>
FEValuesBase<dim,q_dim,FEValues>::
FEValuesBase (const dealii::hp::FECollection<dim,FEValues::space_dimension> &fe_collection,
- const dealii::hp::QCollection<q_dim> &q_collection,
- const UpdateFlags update_flags)
+ const dealii::hp::QCollection<q_dim> &q_collection,
+ const UpdateFlags update_flags)
:
- fe_collection (&fe_collection),
- mapping_collection (&dealii::hp::StaticMappingQ1<dim,FEValues::space_dimension>::
- mapping_collection),
+ fe_collection (&fe_collection),
+ mapping_collection (&dealii::hp::StaticMappingQ1<dim,FEValues::space_dimension>::
+ mapping_collection),
q_collection (q_collection),
fe_values_table (fe_collection.size(),
1,
template <int dim, int spacedim>
FEValues<dim,spacedim>::FEValues (const hp::MappingCollection<dim,spacedim> &mapping,
- const hp::FECollection<dim,spacedim> &fe_collection,
- const hp::QCollection<dim> &q_collection,
- const UpdateFlags update_flags)
+ const hp::FECollection<dim,spacedim> &fe_collection,
+ const hp::QCollection<dim> &q_collection,
+ const UpdateFlags update_flags)
:
internal::hp::FEValuesBase<dim,dim,dealii::FEValues<dim,spacedim> > (mapping,
- fe_collection,
- q_collection,
- update_flags)
+ fe_collection,
+ q_collection,
+ update_flags)
{}
template <int dim, int spacedim>
FEValues<dim,spacedim>::FEValues (const hp::FECollection<dim,spacedim> &fe_collection,
- const hp::QCollection<dim> &q_collection,
- const UpdateFlags update_flags)
+ const hp::QCollection<dim> &q_collection,
+ const UpdateFlags update_flags)
:
internal::hp::FEValuesBase<dim,dim,dealii::FEValues<dim,spacedim> > (fe_collection,
- q_collection,
- update_flags)
+ q_collection,
+ update_flags)
{}
template <int dim, int spacedim>
void
FEValues<dim,spacedim>::reinit (const typename hp::DoFHandler<dim,spacedim>::cell_iterator &cell,
- const unsigned int q_index,
- const unsigned int mapping_index,
- const unsigned int fe_index)
+ const unsigned int q_index,
+ const unsigned int mapping_index,
+ const unsigned int fe_index)
{
// determine which indices we
// should actually use
if (real_q_index == numbers::invalid_unsigned_int)
{
- if (this->q_collection.size() > 1)
- real_q_index = cell->active_fe_index();
- else
- real_q_index = 0;
+ if (this->q_collection.size() > 1)
+ real_q_index = cell->active_fe_index();
+ else
+ real_q_index = 0;
}
if (real_mapping_index == numbers::invalid_unsigned_int)
{
- if (this->mapping_collection->size() > 1)
- real_mapping_index = cell->active_fe_index();
- else
- real_mapping_index = 0;
+ if (this->mapping_collection->size() > 1)
+ real_mapping_index = cell->active_fe_index();
+ else
+ real_mapping_index = 0;
}
if (real_fe_index == numbers::invalid_unsigned_int)
template <int dim, int spacedim>
void
FEValues<dim,spacedim>::reinit (const typename dealii::DoFHandler<dim,spacedim>::cell_iterator &cell,
- const unsigned int q_index,
- const unsigned int mapping_index,
- const unsigned int fe_index)
+ const unsigned int q_index,
+ const unsigned int mapping_index,
+ const unsigned int fe_index)
{
// determine which indices we
// should actually use
template <int dim, int spacedim>
void
FEValues<dim,spacedim>::reinit (const typename MGDoFHandler<dim,spacedim>::cell_iterator &cell,
- const unsigned int q_index,
- const unsigned int mapping_index,
- const unsigned int fe_index)
+ const unsigned int q_index,
+ const unsigned int mapping_index,
+ const unsigned int fe_index)
{
// determine which indices we
// should actually use
template <int dim, int spacedim>
void
FEValues<dim,spacedim>::reinit (const typename Triangulation<dim,spacedim>::cell_iterator &cell,
- const unsigned int q_index,
- const unsigned int mapping_index,
- const unsigned int fe_index)
+ const unsigned int q_index,
+ const unsigned int mapping_index,
+ const unsigned int fe_index)
{
// determine which indices we
// should actually use
const UpdateFlags update_flags)
:
internal::hp::FEValuesBase<dim,dim-1,dealii::FEFaceValues<dim,spacedim> > (mapping,
- fe_collection,
- q_collection,
- update_flags)
+ fe_collection,
+ q_collection,
+ update_flags)
{}
const UpdateFlags update_flags)
:
internal::hp::FEValuesBase<dim,dim-1,dealii::FEFaceValues<dim,spacedim> > (fe_collection,
- q_collection,
- update_flags)
+ q_collection,
+ update_flags)
{}
template <int dim, int spacedim>
void
FEFaceValues<dim,spacedim>::reinit (const typename hp::DoFHandler<dim,spacedim>::cell_iterator &cell,
- const unsigned int face_no,
- const unsigned int q_index,
- const unsigned int mapping_index,
- const unsigned int fe_index)
+ const unsigned int face_no,
+ const unsigned int q_index,
+ const unsigned int mapping_index,
+ const unsigned int fe_index)
{
// determine which indices we
// should actually use
if (real_q_index == numbers::invalid_unsigned_int)
{
- if (this->q_collection.size() > 1)
- real_q_index = cell->active_fe_index();
- else
- real_q_index = 0;
+ if (this->q_collection.size() > 1)
+ real_q_index = cell->active_fe_index();
+ else
+ real_q_index = 0;
}
if (real_mapping_index == numbers::invalid_unsigned_int)
{
- if (this->mapping_collection->size() > 1)
- real_mapping_index = cell->active_fe_index();
- else
- real_mapping_index = 0;
+ if (this->mapping_collection->size() > 1)
+ real_mapping_index = cell->active_fe_index();
+ else
+ real_mapping_index = 0;
}
if (real_fe_index == numbers::invalid_unsigned_int)
template <int dim, int spacedim>
void
FEFaceValues<dim,spacedim>::reinit (const typename dealii::DoFHandler<dim,spacedim>::cell_iterator &cell,
- const unsigned int face_no,
- const unsigned int q_index,
- const unsigned int mapping_index,
- const unsigned int fe_index)
+ const unsigned int face_no,
+ const unsigned int q_index,
+ const unsigned int mapping_index,
+ const unsigned int fe_index)
{
// determine which indices we
// should actually use
template <int dim, int spacedim>
void
FEFaceValues<dim,spacedim>::reinit (const typename MGDoFHandler<dim,spacedim>::cell_iterator &cell,
- const unsigned int face_no,
- const unsigned int q_index,
- const unsigned int mapping_index,
- const unsigned int fe_index)
+ const unsigned int face_no,
+ const unsigned int q_index,
+ const unsigned int mapping_index,
+ const unsigned int fe_index)
{
// determine which indices we
// should actually use
template <int dim, int spacedim>
void
FEFaceValues<dim,spacedim>::reinit (const typename Triangulation<dim,spacedim>::cell_iterator &cell,
- const unsigned int face_no,
- const unsigned int q_index,
- const unsigned int mapping_index,
- const unsigned int fe_index)
+ const unsigned int face_no,
+ const unsigned int q_index,
+ const unsigned int mapping_index,
+ const unsigned int fe_index)
{
// determine which indices we
// should actually use
const UpdateFlags update_flags)
:
internal::hp::FEValuesBase<dim,dim-1,dealii::FESubfaceValues<dim,spacedim> > (mapping,
- fe_collection,
- q_collection,
- update_flags)
+ fe_collection,
+ q_collection,
+ update_flags)
{}
const UpdateFlags update_flags)
:
internal::hp::FEValuesBase<dim,dim-1,dealii::FESubfaceValues<dim,spacedim> > (fe_collection,
- q_collection,
- update_flags)
+ q_collection,
+ update_flags)
{}
template <int dim, int spacedim>
void
FESubfaceValues<dim,spacedim>::reinit (const typename hp::DoFHandler<dim,spacedim>::cell_iterator &cell,
- const unsigned int face_no,
- const unsigned int subface_no,
- const unsigned int q_index,
- const unsigned int mapping_index,
- const unsigned int fe_index)
+ const unsigned int face_no,
+ const unsigned int subface_no,
+ const unsigned int q_index,
+ const unsigned int mapping_index,
+ const unsigned int fe_index)
{
// determine which indices we
// should actually use
if (real_q_index == numbers::invalid_unsigned_int)
{
- if (this->q_collection.size() > 1)
- real_q_index = cell->active_fe_index();
- else
- real_q_index = 0;
+ if (this->q_collection.size() > 1)
+ real_q_index = cell->active_fe_index();
+ else
+ real_q_index = 0;
}
if (real_mapping_index == numbers::invalid_unsigned_int)
{
- if (this->mapping_collection->size() > 1)
- real_mapping_index = cell->active_fe_index();
- else
- real_mapping_index = 0;
+ if (this->mapping_collection->size() > 1)
+ real_mapping_index = cell->active_fe_index();
+ else
+ real_mapping_index = 0;
}
if (real_fe_index == numbers::invalid_unsigned_int)
template <int dim, int spacedim>
void
FESubfaceValues<dim,spacedim>::reinit (const typename dealii::DoFHandler<dim,spacedim>::cell_iterator &cell,
- const unsigned int face_no,
- const unsigned int subface_no,
- const unsigned int q_index,
- const unsigned int mapping_index,
- const unsigned int fe_index)
+ const unsigned int face_no,
+ const unsigned int subface_no,
+ const unsigned int q_index,
+ const unsigned int mapping_index,
+ const unsigned int fe_index)
{
// determine which indices we
// should actually use
template <int dim, int spacedim>
void
FESubfaceValues<dim,spacedim>::reinit (const typename MGDoFHandler<dim,spacedim>::cell_iterator &cell,
- const unsigned int face_no,
- const unsigned int subface_no,
- const unsigned int q_index,
- const unsigned int mapping_index,
- const unsigned int fe_index)
+ const unsigned int face_no,
+ const unsigned int subface_no,
+ const unsigned int q_index,
+ const unsigned int mapping_index,
+ const unsigned int fe_index)
{
// determine which indices we
// should actually use
template <int dim, int spacedim>
void
FESubfaceValues<dim,spacedim>::reinit (const typename Triangulation<dim,spacedim>::cell_iterator &cell,
- const unsigned int face_no,
- const unsigned int subface_no,
- const unsigned int q_index,
- const unsigned int mapping_index,
- const unsigned int fe_index)
+ const unsigned int face_no,
+ const unsigned int subface_no,
+ const unsigned int q_index,
+ const unsigned int mapping_index,
+ const unsigned int fe_index)
{
// determine which indices we
// should actually use
// $Id$
// Version: $Name$
//
-// Copyright (C) 2003, 2006, 2011 by the deal.II authors
+// Copyright (C) 2003, 2006, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
MappingCollection<dim,spacedim>::memory_consumption () const
{
return (sizeof(*this) +
- MemoryConsumption::memory_consumption (mappings));
+ MemoryConsumption::memory_consumption (mappings));
}
//---------------------------------------------------------------------------
// $Id$
//
-// Copyright (C) 2005, 2006, 2008, 2010, 2011 by the deal.II authors
+// Copyright (C) 2005, 2006, 2008, 2010, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
template <typename number>
BlockMatrixArray<number>::Entry::Entry (const Entry& e)
- :
- row(e.row),
- col(e.col),
- prefix(e.prefix),
- transpose(e.transpose),
- matrix(e.matrix)
+ :
+ row(e.row),
+ col(e.col),
+ prefix(e.prefix),
+ transpose(e.transpose),
+ matrix(e.matrix)
{
Entry& e2 = const_cast<Entry&>(e);
e2.matrix = 0;
template <typename number>
BlockMatrixArray<number>::BlockMatrixArray ()
- : block_rows (0),
- block_cols (0)
+ : block_rows (0),
+ block_cols (0)
{}
BlockMatrixArray<number>::BlockMatrixArray (
const unsigned int n_block_rows,
const unsigned int n_block_cols)
- : block_rows (n_block_rows),
- block_cols (n_block_cols)
+ : block_rows (n_block_rows),
+ block_cols (n_block_cols)
{}
const unsigned int n_block_rows,
const unsigned int n_block_cols,
VectorMemory<Vector<number> >&)
- : block_rows (n_block_rows),
- block_cols (n_block_cols)
+ : block_rows (n_block_rows),
+ block_cols (n_block_cols)
{}
template <typename number>
void
BlockMatrixArray<number>::vmult_add (BlockVector<number>& dst,
- const BlockVector<number>& src) const
+ const BlockVector<number>& src) const
{
GrowingVectorMemory<Vector<number> > mem;
Assert (dst.n_blocks() == block_rows,
- ExcDimensionMismatch(dst.n_blocks(), block_rows));
+ ExcDimensionMismatch(dst.n_blocks(), block_rows));
Assert (src.n_blocks() == block_cols,
- ExcDimensionMismatch(src.n_blocks(), block_cols));
+ ExcDimensionMismatch(src.n_blocks(), block_cols));
typename VectorMemory<Vector<number> >::Pointer p_aux(mem);
Vector<number>& aux = *p_aux;
{
aux.reinit(dst.block(m->row));
if (m->transpose)
- m->matrix->Tvmult(aux, src.block(m->col));
+ m->matrix->Tvmult(aux, src.block(m->col));
else
- m->matrix->vmult(aux, src.block(m->col));
+ m->matrix->vmult(aux, src.block(m->col));
dst.block(m->row).add (m->prefix, aux);
}
}
template <typename number>
void
BlockMatrixArray<number>::vmult (BlockVector<number>& dst,
- const BlockVector<number>& src) const
+ const BlockVector<number>& src) const
{
dst = 0.;
vmult_add (dst, src);
template <typename number>
void
BlockMatrixArray<number>::Tvmult_add (BlockVector<number>& dst,
- const BlockVector<number>& src) const
+ const BlockVector<number>& src) const
{
GrowingVectorMemory<Vector<number> > mem;
Assert (dst.n_blocks() == block_cols,
- ExcDimensionMismatch(dst.n_blocks(), block_cols));
+ ExcDimensionMismatch(dst.n_blocks(), block_cols));
Assert (src.n_blocks() == block_rows,
- ExcDimensionMismatch(src.n_blocks(), block_rows));
+ ExcDimensionMismatch(src.n_blocks(), block_rows));
typename std::vector<Entry>::const_iterator m = entries.begin();
typename std::vector<Entry>::const_iterator end = entries.end();
{
aux.reinit(dst.block(m->col));
if (m->transpose)
- m->matrix->vmult(aux, src.block(m->row));
+ m->matrix->vmult(aux, src.block(m->row));
else
- m->matrix->Tvmult(aux, src.block(m->row));
+ m->matrix->Tvmult(aux, src.block(m->row));
dst.block(m->col).add (m->prefix, aux);
}
}
template <typename number>
void
BlockMatrixArray<number>::Tvmult (BlockVector<number>& dst,
- const BlockVector<number>& src) const
+ const BlockVector<number>& src) const
{
dst = 0.;
Tvmult_add (dst, src);
{
GrowingVectorMemory<Vector<number> > mem;
Assert (u.n_blocks() == block_rows,
- ExcDimensionMismatch(u.n_blocks(), block_rows));
+ ExcDimensionMismatch(u.n_blocks(), block_rows));
Assert (v.n_blocks() == block_cols,
- ExcDimensionMismatch(v.n_blocks(), block_cols));
+ ExcDimensionMismatch(v.n_blocks(), block_cols));
typename VectorMemory<Vector<number> >::Pointer p_aux(mem);
Vector<number>& aux = *p_aux;
{
aux.reinit(u.block(i));
for (m = entries.begin(); m != end ; ++m)
- {
- if (m->row != i)
- continue;
- if (m->transpose)
- m->matrix->Tvmult_add(aux, v.block(m->col));
- else
- m->matrix->vmult(aux, v.block(m->col));
- }
+ {
+ if (m->row != i)
+ continue;
+ if (m->transpose)
+ m->matrix->Tvmult_add(aux, v.block(m->col));
+ else
+ m->matrix->vmult(aux, v.block(m->col));
+ }
result += u.block(i)*aux;
}
template <typename number>
BlockTrianglePrecondition<number>::BlockTrianglePrecondition()
- : BlockMatrixArray<number> (),
- backward(false)
+ : BlockMatrixArray<number> (),
+ backward(false)
{}
unsigned int block_rows,
VectorMemory<Vector<number> >& mem,
bool backward)
- :
- BlockMatrixArray<number> (block_rows, block_rows, mem),
- backward(backward)
+ :
+ BlockMatrixArray<number> (block_rows, block_rows, mem),
+ backward(backward)
{}
template <typename number>
BlockTrianglePrecondition<number>::BlockTrianglePrecondition(
unsigned int block_rows)
- :
- BlockMatrixArray<number> (block_rows, block_rows),
- backward(false)
+ :
+ BlockMatrixArray<number> (block_rows, block_rows),
+ backward(false)
{}
aux.reinit(dst.block(row_num), true);
- // Loop over all entries, since
- // they are not ordered by rows.
+ // Loop over all entries, since
+ // they are not ordered by rows.
for (; m != end ; ++m)
{
const unsigned int i=m->row;
- // Ignore everything not in
- // this row
+ // Ignore everything not in
+ // this row
if (i != row_num)
- continue;
+ continue;
const unsigned int j=m->col;
- // Only use the lower (upper)
- // triangle for forward
- // (backward) substitution
+ // Only use the lower (upper)
+ // triangle for forward
+ // (backward) substitution
if (((j > i) && !backward) || ((j < i) && backward))
- continue;
+ continue;
if (j == i)
- {
- diagonals.push_back(m);
- } else {
- if (m->transpose)
- m->matrix->Tvmult(aux, dst.block(j));
- else
- m->matrix->vmult(aux, dst.block(j));
- dst.block(i).add (-1 * m->prefix, aux);
- }
+ {
+ diagonals.push_back(m);
+ } else {
+ if (m->transpose)
+ m->matrix->Tvmult(aux, dst.block(j));
+ else
+ m->matrix->vmult(aux, dst.block(j));
+ dst.block(i).add (-1 * m->prefix, aux);
+ }
}
Assert (diagonals.size() != 0, ExcNoDiagonal(row_num));
- // Inverting the diagonal block is
- // simple, if there is only one
- // matrix
+ // Inverting the diagonal block is
+ // simple, if there is only one
+ // matrix
if (diagonals.size() == 1)
{
if (diagonals[0]->transpose)
- diagonals[0]->matrix->Tvmult(aux, dst.block(row_num));
+ diagonals[0]->matrix->Tvmult(aux, dst.block(row_num));
else
- diagonals[0]->matrix->vmult(aux, dst.block(row_num));
+ diagonals[0]->matrix->vmult(aux, dst.block(row_num));
dst.block(row_num).equ (diagonals[0]->prefix, aux);
}
else
{
aux = 0.;
for (unsigned int i=0;i<diagonals.size();++i)
- {
- m = diagonals[i];
- // First, divide by the current
- // factor, such that we can
- // multiply by it later.
- aux.scale(1./m->prefix);
- if (m->transpose)
- m->matrix->Tvmult_add(aux, dst.block(row_num));
- else
- m->matrix->vmult_add(aux, dst.block(row_num));
- aux.scale(m->prefix);
- }
+ {
+ m = diagonals[i];
+ // First, divide by the current
+ // factor, such that we can
+ // multiply by it later.
+ aux.scale(1./m->prefix);
+ if (m->transpose)
+ m->matrix->Tvmult_add(aux, dst.block(row_num));
+ else
+ m->matrix->vmult_add(aux, dst.block(row_num));
+ aux.scale(m->prefix);
+ }
dst.block(row_num) = aux;
}
}
const BlockVector<number>& src) const
{
Assert (dst.n_blocks() == n_block_rows(),
- ExcDimensionMismatch(dst.n_blocks(), n_block_rows()));
+ ExcDimensionMismatch(dst.n_blocks(), n_block_rows()));
Assert (src.n_blocks() == n_block_cols(),
- ExcDimensionMismatch(src.n_blocks(), n_block_cols()));
+ ExcDimensionMismatch(src.n_blocks(), n_block_cols()));
BlockVector<number> aux;
aux.reinit(dst);
const BlockVector<number>& src) const
{
Assert (dst.n_blocks() == n_block_rows(),
- ExcDimensionMismatch(dst.n_blocks(), n_block_rows()));
+ ExcDimensionMismatch(dst.n_blocks(), n_block_rows()));
Assert (src.n_blocks() == n_block_cols(),
- ExcDimensionMismatch(src.n_blocks(), n_block_cols()));
+ ExcDimensionMismatch(src.n_blocks(), n_block_cols()));
dst.equ(1., src);
if (backward)
{
for (unsigned int i=n_block_rows(); i>0;)
- do_row(dst, --i);
+ do_row(dst, --i);
} else {
for (unsigned int i=0; i<n_block_rows(); ++i)
- do_row(dst, i);
+ do_row(dst, i);
}
}
// $Id$
// Version: $Name$
//
-// Copyright (C) 2000, 2001, 2002, 2004, 2005, 2006, 2011 by the deal.II authors
+// Copyright (C) 2000, 2001, 2002, 2004, 2005, 2006, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
// $Id$
// Version: $Name$
//
-// Copyright (C) 2003, 2005, 2006 by the deal.II authors
+// Copyright (C) 2003, 2005, 2006, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
// $Id$
// Version: $Name$
//
-// Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009, 2010, 2011 by the deal.II authors
+// Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009, 2010, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
template <class SparsityPatternBase>
BlockSparsityPatternBase<SparsityPatternBase>::BlockSparsityPatternBase ()
- :
- rows (0),
- columns (0)
+ :
+ rows (0),
+ columns (0)
{}
BlockSparsityPatternBase<SparsityPatternBase>::
BlockSparsityPatternBase (const unsigned int n_block_rows,
const unsigned int n_block_columns)
- :
- rows (0),
- columns (0)
+ :
+ rows (0),
+ columns (0)
{
reinit (n_block_rows, n_block_columns);
}
BlockSparsityPatternBase<SparsityPatternBase>::
BlockSparsityPatternBase (const BlockSparsityPatternBase &s)
:
- Subscriptor ()
+ Subscriptor ()
{
Assert(s.rows==0, ExcInvalidConstructorCall());
Assert(s.columns==0, ExcInvalidConstructorCall());
template <class SparsityPatternBase>
BlockSparsityPatternBase<SparsityPatternBase>::~BlockSparsityPatternBase ()
{
- // clear all memory
+ // clear all memory
reinit (0,0);
}
reinit (const unsigned int n_block_rows,
const unsigned int n_block_columns)
{
- // delete previous content and
- // clean the sub_objects array
- // completely
+ // delete previous content and
+ // clean the sub_objects array
+ // completely
for (unsigned int i=0; i<rows; ++i)
for (unsigned int j=0; j<columns; ++j)
{
- SparsityPatternBase * sp = sub_objects[i][j];
- sub_objects[i][j] = 0;
- delete sp;
+ SparsityPatternBase * sp = sub_objects[i][j];
+ sub_objects[i][j] = 0;
+ delete sp;
};
sub_objects.reinit (0,0);
- // then set new sizes
+ // then set new sizes
rows = n_block_rows;
columns = n_block_columns;
sub_objects.reinit (rows, columns);
- // allocate new objects
+ // allocate new objects
for (unsigned int i=0; i<rows; ++i)
for (unsigned int j=0; j<columns; ++j)
{
{
Assert (rows == bsp.rows, ExcDimensionMismatch(rows, bsp.rows));
Assert (columns == bsp.columns, ExcDimensionMismatch(columns, bsp.columns));
- // copy objects
+ // copy objects
for (unsigned int i=0; i<rows; ++i)
for (unsigned int j=0; j<columns; ++j)
*sub_objects[i][j] = *bsp.sub_objects[i][j];
- // update index objects
+ // update index objects
collect_sizes ();
return *this;
std::vector<unsigned int> row_sizes (rows);
std::vector<unsigned int> col_sizes (columns);
- // first find out the row sizes
- // from the first block column
+ // first find out the row sizes
+ // from the first block column
for (unsigned int r=0; r<rows; ++r)
row_sizes[r] = sub_objects[r][0]->n_rows();
- // then check that the following
- // block columns have the same
- // sizes
+ // then check that the following
+ // block columns have the same
+ // sizes
for (unsigned int c=1; c<columns; ++c)
for (unsigned int r=0; r<rows; ++r)
Assert (row_sizes[r] == sub_objects[r][c]->n_rows(),
- ExcIncompatibleRowNumbers (r,0,r,c));
+ ExcIncompatibleRowNumbers (r,0,r,c));
- // finally initialize the row
- // indices with this array
+ // finally initialize the row
+ // indices with this array
row_indices.reinit (row_sizes);
- // then do the same with the columns
+ // then do the same with the columns
for (unsigned int c=0; c<columns; ++c)
col_sizes[c] = sub_objects[0][c]->n_cols();
for (unsigned int r=1; r<rows; ++r)
for (unsigned int c=0; c<columns; ++c)
Assert (col_sizes[c] == sub_objects[r][c]->n_cols(),
- ExcIncompatibleRowNumbers (0,c,r,c));
+ ExcIncompatibleRowNumbers (0,c,r,c));
- // finally initialize the row
- // indices with this array
+ // finally initialize the row
+ // indices with this array
column_indices.reinit (col_sizes);
}
for (unsigned int i=0; i<rows; ++i)
for (unsigned int j=0; j<columns; ++j)
if (sub_objects[i][j]->empty () == false)
- return false;
+ return false;
return true;
}
{
unsigned int this_row = 0;
for (unsigned int c=0; c<columns; ++c)
- this_row += sub_objects[block_row][c]->max_entries_per_row ();
+ this_row += sub_objects[block_row][c]->max_entries_per_row ();
if (this_row > max_entries)
- max_entries = this_row;
+ max_entries = this_row;
};
return max_entries;
}
unsigned int
BlockSparsityPatternBase<SparsityPatternBase>::n_rows () const
{
- // only count in first column, since
- // all rows should be equivalent
+ // only count in first column, since
+ // all rows should be equivalent
unsigned int count = 0;
for (unsigned int r=0; r<rows; ++r)
count += sub_objects[r][0]->n_rows();
unsigned int
BlockSparsityPatternBase<SparsityPatternBase>::n_cols () const
{
- // only count in first row, since
- // all rows should be equivalent
+ // only count in first row, since
+ // all rows should be equivalent
unsigned int count = 0;
for (unsigned int c=0; c<columns; ++c)
count += sub_objects[0][c]->n_cols();
for (unsigned int ib=0;ib<n_block_rows();++ib)
{
for (unsigned int i=0;i<block(ib,0).n_rows();++i)
- {
- out << '[' << i+k;
- unsigned int l=0;
- for (unsigned int jb=0;jb<n_block_cols();++jb)
- {
- const SparsityPatternBase& b = block(ib,jb);
- for (unsigned int j=0;j<b.n_cols();++j)
- if (b.exists(i,j))
- out << ',' << l+j;
- l += b.n_cols();
- }
- out << ']' << std::endl;
- }
+ {
+ out << '[' << i+k;
+ unsigned int l=0;
+ for (unsigned int jb=0;jb<n_block_cols();++jb)
+ {
+ const SparsityPatternBase& b = block(ib,jb);
+ for (unsigned int j=0;j<b.n_cols();++j)
+ if (b.exists(i,j))
+ out << ',' << l+j;
+ l += b.n_cols();
+ }
+ out << ']' << std::endl;
+ }
k += block(ib,0).n_rows();
}
}
for (unsigned int ib=0;ib<n_block_rows();++ib)
{
for (unsigned int i=0;i<block(ib,0).n_rows();++i)
- {
- out << '[' << i+k;
- unsigned int l=0;
- for (unsigned int jb=0;jb<n_block_cols();++jb)
- {
- const CompressedSimpleSparsityPattern & b = block(ib,jb);
- if (b.row_index_set().size()==0 || b.row_index_set().is_element(i))
- for (unsigned int j=0;j<b.n_cols();++j)
- if (b.exists(i,j))
- out << ',' << l+j;
- l += b.n_cols();
- }
- out << ']' << std::endl;
- }
+ {
+ out << '[' << i+k;
+ unsigned int l=0;
+ for (unsigned int jb=0;jb<n_block_cols();++jb)
+ {
+ const CompressedSimpleSparsityPattern & b = block(ib,jb);
+ if (b.row_index_set().size()==0 || b.row_index_set().is_element(i))
+ for (unsigned int j=0;j<b.n_cols();++j)
+ if (b.exists(i,j))
+ out << ',' << l+j;
+ l += b.n_cols();
+ }
+ out << ']' << std::endl;
+ }
k += block(ib,0).n_rows();
}
}
for (unsigned int ib=0;ib<n_block_rows();++ib)
{
for (unsigned int i=0;i<block(ib,0).n_rows();++i)
- {
- unsigned int l=0;
- for (unsigned int jb=0;jb<n_block_cols();++jb)
- {
- const SparsityPatternBase& b = block(ib,jb);
- for (unsigned int j=0;j<b.n_cols();++j)
- if (b.exists(i,j))
- out << l+j << " " << -static_cast<signed int>(i+k) << std::endl;;
- l += b.n_cols();
- }
- }
+ {
+ unsigned int l=0;
+ for (unsigned int jb=0;jb<n_block_cols();++jb)
+ {
+ const SparsityPatternBase& b = block(ib,jb);
+ for (unsigned int j=0;j<b.n_cols();++j)
+ if (b.exists(i,j))
+ out << l+j << " " << -static_cast<signed int>(i+k) << std::endl;;
+ l += b.n_cols();
+ }
+ }
k += block(ib,0).n_rows();
}
}
BlockSparsityPattern::BlockSparsityPattern (const unsigned int n_rows,
- const unsigned int n_columns)
- :
- BlockSparsityPatternBase<SparsityPattern>(n_rows,
- n_columns)
+ const unsigned int n_columns)
+ :
+ BlockSparsityPatternBase<SparsityPattern>(n_rows,
+ n_columns)
{}
const std::vector<std::vector<unsigned int> >& row_lengths)
{
AssertDimension (row_lengths.size(), cols.size());
-
+
this->reinit(rows.size(), cols.size());
for (unsigned int j=0;j<cols.size();++j)
for (unsigned int i=0;i<rows.size();++i)
{
- const unsigned int start = rows.local_to_global(i, 0);
- const unsigned int length = rows.block_size(i);
-
- if (row_lengths[j].size()==1)
- block(i,j).reinit(rows.block_size(i),
- cols.block_size(j), row_lengths[j][0], i==j);
- else
- {
- VectorSlice<const std::vector<unsigned int> >
- block_rows(row_lengths[j], start, length);
- block(i,j).reinit(rows.block_size(i),
- cols.block_size(j),
- block_rows);
- }
+ const unsigned int start = rows.local_to_global(i, 0);
+ const unsigned int length = rows.block_size(i);
+
+ if (row_lengths[j].size()==1)
+ block(i,j).reinit(rows.block_size(i),
+ cols.block_size(j), row_lengths[j][0], i==j);
+ else
+ {
+ VectorSlice<const std::vector<unsigned int> >
+ block_rows(row_lengths[j], start, length);
+ block(i,j).reinit(rows.block_size(i),
+ cols.block_size(j),
+ block_rows);
+ }
}
this->collect_sizes();
Assert (this->row_indices == rows, ExcInternalError());
for (unsigned int i=0; i<rows; ++i)
for (unsigned int j=0; j<columns; ++j)
if (sub_objects[i][j]->is_compressed () == false)
- return false;
+ return false;
return true;
}
{
std::size_t mem = 0;
mem += (MemoryConsumption::memory_consumption (rows) +
- MemoryConsumption::memory_consumption (columns) +
- MemoryConsumption::memory_consumption (sub_objects) +
- MemoryConsumption::memory_consumption (row_indices) +
- MemoryConsumption::memory_consumption (column_indices));
+ MemoryConsumption::memory_consumption (columns) +
+ MemoryConsumption::memory_consumption (sub_objects) +
+ MemoryConsumption::memory_consumption (row_indices) +
+ MemoryConsumption::memory_consumption (column_indices));
for (unsigned int r=0; r<rows; ++r)
for (unsigned int c=0; c<columns; ++c)
mem += MemoryConsumption::memory_consumption (*sub_objects[r][c]);
void
BlockSparsityPattern::copy_from (const BlockCompressedSparsityPattern &csp)
{
- // delete old content, set block
- // sizes anew
+ // delete old content, set block
+ // sizes anew
reinit (csp.n_block_rows(), csp.n_block_cols());
- // copy over blocks
+ // copy over blocks
for (unsigned int i=0; i<n_block_rows(); ++i)
for (unsigned int j=0; j<n_block_cols(); ++j)
block(i,j).copy_from (csp.block(i,j));
- // and finally enquire their new
- // sizes
+ // and finally enquire their new
+ // sizes
collect_sizes();
}
void
BlockSparsityPattern::copy_from (const BlockCompressedSimpleSparsityPattern &csp)
{
- // delete old content, set block
- // sizes anew
+ // delete old content, set block
+ // sizes anew
reinit (csp.n_block_rows(), csp.n_block_cols());
- // copy over blocks
+ // copy over blocks
for (unsigned int i=0; i<rows; ++i)
for (unsigned int j=0; j<rows; ++j)
block(i,j).copy_from (csp.block(i,j));
- // and finally enquire their new
- // sizes
+ // and finally enquire their new
+ // sizes
collect_sizes();
}
void
BlockSparsityPattern::copy_from (const BlockCompressedSetSparsityPattern &csp)
{
- // delete old content, set block
- // sizes anew
+ // delete old content, set block
+ // sizes anew
reinit (csp.n_block_rows(), csp.n_block_cols());
- // copy over blocks
+ // copy over blocks
for (unsigned int i=0; i<rows; ++i)
for (unsigned int j=0; j<rows; ++j)
block(i,j).copy_from (csp.block(i,j));
- // and finally enquire their new
- // sizes
+ // and finally enquire their new
+ // sizes
collect_sizes();
}
BlockCompressedSparsityPattern (
const unsigned int n_rows,
const unsigned int n_columns)
- :
- BlockSparsityPatternBase<CompressedSparsityPattern>(n_rows,
- n_columns)
+ :
+ BlockSparsityPatternBase<CompressedSparsityPattern>(n_rows,
+ n_columns)
{}
const BlockIndices& col_indices)
{
BlockSparsityPatternBase<CompressedSparsityPattern>::reinit(row_indices.size(),
- col_indices.size());
+ col_indices.size());
for (unsigned int i=0;i<row_indices.size();++i)
for (unsigned int j=0;j<col_indices.size();++j)
this->block(i,j).reinit(row_indices.block_size(i),
- col_indices.block_size(j));
+ col_indices.block_size(j));
this->collect_sizes();
}
BlockCompressedSetSparsityPattern (
const unsigned int n_rows,
const unsigned int n_columns)
- :
- BlockSparsityPatternBase<CompressedSetSparsityPattern>(n_rows,
- n_columns)
+ :
+ BlockSparsityPatternBase<CompressedSetSparsityPattern>(n_rows,
+ n_columns)
{}
const BlockIndices& col_indices)
{
BlockSparsityPatternBase<CompressedSetSparsityPattern>::reinit(row_indices.size(),
- col_indices.size());
+ col_indices.size());
for (unsigned int i=0;i<row_indices.size();++i)
for (unsigned int j=0;j<col_indices.size();++j)
this->block(i,j).reinit(row_indices.block_size(i),
- col_indices.block_size(j));
+ col_indices.block_size(j));
this->collect_sizes();
}
BlockCompressedSimpleSparsityPattern::
BlockCompressedSimpleSparsityPattern (const unsigned int n_rows,
- const unsigned int n_columns)
- :
- BlockSparsityPatternBase<CompressedSimpleSparsityPattern>(n_rows,
- n_columns)
+ const unsigned int n_columns)
+ :
+ BlockSparsityPatternBase<CompressedSimpleSparsityPattern>(n_rows,
+ n_columns)
{}
BlockCompressedSimpleSparsityPattern::
BlockCompressedSimpleSparsityPattern (const std::vector<unsigned int>& row_indices,
- const std::vector<unsigned int>& col_indices)
- :
- BlockSparsityPatternBase<CompressedSimpleSparsityPattern>(row_indices.size(),
- col_indices.size())
+ const std::vector<unsigned int>& col_indices)
+ :
+ BlockSparsityPatternBase<CompressedSimpleSparsityPattern>(row_indices.size(),
+ col_indices.size())
{
for (unsigned int i=0;i<row_indices.size();++i)
for (unsigned int j=0;j<col_indices.size();++j)
BlockCompressedSimpleSparsityPattern::
BlockCompressedSimpleSparsityPattern (const std::vector<IndexSet> & partitioning)
- :
- BlockSparsityPatternBase<CompressedSimpleSparsityPattern>(partitioning.size(),
- partitioning.size())
+ :
+ BlockSparsityPatternBase<CompressedSimpleSparsityPattern>(partitioning.size(),
+ partitioning.size())
{
for (unsigned int i=0;i<partitioning.size();++i)
for (unsigned int j=0;j<partitioning.size();++j)
this->block(i,j).reinit(partitioning[i].size(),
- partitioning[j].size(),
- partitioning[i]);
+ partitioning[j].size(),
+ partitioning[i]);
this->collect_sizes();
}
for (unsigned int i=0;i<partitioning.size();++i)
for (unsigned int j=0;j<partitioning.size();++j)
this->block(i,j).reinit(partitioning[i].size(),
- partitioning[j].size(),
- partitioning[i]);
+ partitioning[j].size(),
+ partitioning[i]);
this->collect_sizes();
}
BlockSparsityPattern::
BlockSparsityPattern (const unsigned int n_rows,
- const unsigned int n_columns)
+ const unsigned int n_columns)
:
dealii::BlockSparsityPatternBase<SparsityPattern>(n_rows,
- n_columns)
+ n_columns)
{}
BlockSparsityPattern::
BlockSparsityPattern (const std::vector<unsigned int>& row_indices,
- const std::vector<unsigned int>& col_indices)
- :
- BlockSparsityPatternBase<SparsityPattern>(row_indices.size(),
- col_indices.size())
+ const std::vector<unsigned int>& col_indices)
+ :
+ BlockSparsityPatternBase<SparsityPattern>(row_indices.size(),
+ col_indices.size())
{
for (unsigned int i=0;i<row_indices.size();++i)
for (unsigned int j=0;j<col_indices.size();++j)
- this->block(i,j).reinit(row_indices[i],col_indices[j]);
+ this->block(i,j).reinit(row_indices[i],col_indices[j]);
this->collect_sizes();
}
BlockSparsityPattern::
BlockSparsityPattern (const std::vector<Epetra_Map>& parallel_partitioning)
- :
- BlockSparsityPatternBase<SparsityPattern>
- (parallel_partitioning.size(),
- parallel_partitioning.size())
+ :
+ BlockSparsityPatternBase<SparsityPattern>
+ (parallel_partitioning.size(),
+ parallel_partitioning.size())
{
for (unsigned int i=0;i<parallel_partitioning.size();++i)
for (unsigned int j=0;j<parallel_partitioning.size();++j)
- this->block(i,j).reinit(parallel_partitioning[i],
- parallel_partitioning[j]);
+ this->block(i,j).reinit(parallel_partitioning[i],
+ parallel_partitioning[j]);
this->collect_sizes();
}
BlockSparsityPattern::
BlockSparsityPattern (const std::vector<IndexSet>& parallel_partitioning,
- const MPI_Comm & communicator)
- :
- BlockSparsityPatternBase<SparsityPattern>
- (parallel_partitioning.size(),
- parallel_partitioning.size())
+ const MPI_Comm & communicator)
+ :
+ BlockSparsityPatternBase<SparsityPattern>
+ (parallel_partitioning.size(),
+ parallel_partitioning.size())
{
for (unsigned int i=0;i<parallel_partitioning.size();++i)
for (unsigned int j=0;j<parallel_partitioning.size();++j)
- this->block(i,j).reinit(parallel_partitioning[i],
- parallel_partitioning[j],
- communicator);
+ this->block(i,j).reinit(parallel_partitioning[i],
+ parallel_partitioning[j],
+ communicator);
this->collect_sizes();
}
void
BlockSparsityPattern::reinit (const std::vector<unsigned int> &row_block_sizes,
- const std::vector<unsigned int> &col_block_sizes)
+ const std::vector<unsigned int> &col_block_sizes)
{
dealii::BlockSparsityPatternBase<SparsityPattern>::
reinit(row_block_sizes.size(), col_block_sizes.size());
for (unsigned int i=0;i<row_block_sizes.size();++i)
for (unsigned int j=0;j<col_block_sizes.size();++j)
- this->block(i,j).reinit(row_block_sizes[i],col_block_sizes[j]);
+ this->block(i,j).reinit(row_block_sizes[i],col_block_sizes[j]);
this->collect_sizes();
}
{
dealii::BlockSparsityPatternBase<SparsityPattern>::
reinit(parallel_partitioning.size(),
- parallel_partitioning.size());
+ parallel_partitioning.size());
for (unsigned int i=0;i<parallel_partitioning.size();++i)
for (unsigned int j=0;j<parallel_partitioning.size();++j)
- this->block(i,j).reinit(parallel_partitioning[i],
- parallel_partitioning[j]);
+ this->block(i,j).reinit(parallel_partitioning[i],
+ parallel_partitioning[j]);
this->collect_sizes();
}
void
BlockSparsityPattern::reinit (const std::vector<IndexSet> ¶llel_partitioning,
- const MPI_Comm &communicator)
+ const MPI_Comm &communicator)
{
dealii::BlockSparsityPatternBase<SparsityPattern>::
reinit(parallel_partitioning.size(),
- parallel_partitioning.size());
+ parallel_partitioning.size());
for (unsigned int i=0;i<parallel_partitioning.size();++i)
for (unsigned int j=0;j<parallel_partitioning.size();++j)
- this->block(i,j).reinit(parallel_partitioning[i],
- parallel_partitioning[j],
- communicator);
+ this->block(i,j).reinit(parallel_partitioning[i],
+ parallel_partitioning[j],
+ communicator);
this->collect_sizes();
}
// $Id$
// Version: $Name$
//
-// Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 by the deal.II authors
+// Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
// these functions can't be generated by the preprocessor since
// the template arguments need to be different
-#ifndef DEAL_II_EXPLICIT_CONSTRUCTOR_BUG
+#ifndef DEAL_II_EXPLICIT_CONSTRUCTOR_BUG
template BlockVector<double>::BlockVector (const BlockVector<float> &);
template BlockVector<float>::BlockVector (const BlockVector<double> &);
// $Id$
// Version: $Name$
//
-// Copyright (C) 2008 by the deal.II authors
+// Copyright (C) 2008, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
// $Id$
// Version: $Name$
//
-// Copyright (C) 2008, 2011 by the deal.II authors
+// Copyright (C) 2008, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
ChunkSparsityPattern::ChunkSparsityPattern (const ChunkSparsityPattern &s)
:
- Subscriptor(),
- chunk_size (s.chunk_size),
- sparsity_pattern(s.sparsity_pattern)
+ Subscriptor(),
+ chunk_size (s.chunk_size),
+ sparsity_pattern(s.sparsity_pattern)
{
Assert (s.rows == 0, ExcInvalidConstructorCall());
Assert (s.cols == 0, ExcInvalidConstructorCall());
ChunkSparsityPattern::ChunkSparsityPattern (const unsigned int m,
- const unsigned int n,
- const unsigned int max_per_row,
- const unsigned int chunk_size,
- const bool optimize_diag)
+ const unsigned int n,
+ const unsigned int max_per_row,
+ const unsigned int chunk_size,
+ const bool optimize_diag)
{
Assert (chunk_size > 0, ExcInvalidNumber (chunk_size));
ChunkSparsityPattern::ChunkSparsityPattern (const unsigned int n,
- const unsigned int max_per_row,
- const unsigned int chunk_size)
+ const unsigned int max_per_row,
+ const unsigned int chunk_size)
{
reinit (n, n, max_per_row, chunk_size, true);
}
Assert (s.rows == 0, ExcInvalidConstructorCall());
Assert (s.cols == 0, ExcInvalidConstructorCall());
- // perform the checks in the underlying
- // object as well
+ // perform the checks in the underlying
+ // object as well
sparsity_pattern = s.sparsity_pattern;
return *this;
void
ChunkSparsityPattern::reinit (const unsigned int m,
- const unsigned int n,
- const unsigned int max_per_row,
- const unsigned int chunk_size,
- const bool optimize_diag)
+ const unsigned int n,
+ const unsigned int max_per_row,
+ const unsigned int chunk_size,
+ const bool optimize_diag)
{
Assert (chunk_size > 0, ExcInvalidNumber (chunk_size));
- // simply map this function to the
- // other @p{reinit} function
+ // simply map this function to the
+ // other @p{reinit} function
const std::vector<unsigned int> row_lengths (m, max_per_row);
reinit (m, n, row_lengths, chunk_size, optimize_diag);
}
this->chunk_size = chunk_size;
- // pass down to the necessary information
- // to the underlying object. we need to
- // calculate how many chunks we need: we
- // need to round up (m/chunk_size) and
- // (n/chunk_size). rounding up in integer
- // arithmetic equals
- // ((m+chunk_size-1)/chunk_size):
+ // pass down to the necessary information
+ // to the underlying object. we need to
+ // calculate how many chunks we need: we
+ // need to round up (m/chunk_size) and
+ // (n/chunk_size). rounding up in integer
+ // arithmetic equals
+ // ((m+chunk_size-1)/chunk_size):
const unsigned int m_chunks = (m+chunk_size-1) / chunk_size,
- n_chunks = (n+chunk_size-1) / chunk_size;
-
- // compute the maximum number of chunks in
- // each row. the passed array denotes the
- // number of entries in each row of the big
- // matrix -- in the worst case, these are
- // all in independent chunks, so we have to
- // calculate it as follows (as an example:
- // let chunk_size==2,
- // row_lengths={2,2,...}, and entries in
- // row zero at columns {0,2} and for row
- // one at {4,6} --> we'll need 4 chunks for
- // the first chunk row!) :
+ n_chunks = (n+chunk_size-1) / chunk_size;
+
+ // compute the maximum number of chunks in
+ // each row. the passed array denotes the
+ // number of entries in each row of the big
+ // matrix -- in the worst case, these are
+ // all in independent chunks, so we have to
+ // calculate it as follows (as an example:
+ // let chunk_size==2,
+ // row_lengths={2,2,...}, and entries in
+ // row zero at columns {0,2} and for row
+ // one at {4,6} --> we'll need 4 chunks for
+ // the first chunk row!) :
std::vector<unsigned int> chunk_row_lengths (m_chunks, 0);
for (unsigned int i=0; i<m; ++i)
chunk_row_lengths[i/chunk_size] += row_lengths[i];
sparsity_pattern.reinit (m_chunks,
- n_chunks,
- chunk_row_lengths,
- optimize_diag);
+ n_chunks,
+ chunk_row_lengths,
+ optimize_diag);
}
template <typename SparsityType>
void
ChunkSparsityPattern::copy_from (const SparsityType &csp,
- const unsigned int chunk_size,
- const bool optimize_diag)
+ const unsigned int chunk_size,
+ const bool optimize_diag)
{
Assert (chunk_size > 0, ExcInvalidNumber (chunk_size));
- // count number of entries per row, then
- // initialize the underlying sparsity
- // pattern
+ // count number of entries per row, then
+ // initialize the underlying sparsity
+ // pattern
std::vector<unsigned int> entries_per_row (csp.n_rows(), 0);
for (unsigned int row = 0; row<csp.n_rows(); ++row)
entries_per_row[row] = csp.row_length(row);
reinit (csp.n_rows(), csp.n_cols(),
- entries_per_row,
- chunk_size, optimize_diag);
+ entries_per_row,
+ chunk_size, optimize_diag);
- // then actually fill it
+ // then actually fill it
for (unsigned int row = 0; row<csp.n_rows(); ++row)
{
typename SparsityType::row_iterator col_num = csp.row_begin (row);
for (; col_num != csp.row_end (row); ++col_num)
- add (row, *col_num);
+ add (row, *col_num);
}
- // finally compress
+ // finally compress
compress ();
}
template <typename number>
void ChunkSparsityPattern::copy_from (const FullMatrix<number> &matrix,
- const unsigned int chunk_size,
- const bool optimize_diag)
+ const unsigned int chunk_size,
+ const bool optimize_diag)
{
Assert (chunk_size > 0, ExcInvalidNumber (chunk_size));
- // count number of entries per row, then
- // initialize the underlying sparsity
- // pattern
+ // count number of entries per row, then
+ // initialize the underlying sparsity
+ // pattern
std::vector<unsigned int> entries_per_row (matrix.m(), 0);
for (unsigned int row=0; row<matrix.m(); ++row)
for (unsigned int col=0; col<matrix.n(); ++col)
if (matrix(row,col) != 0)
- ++entries_per_row[row];
+ ++entries_per_row[row];
reinit (matrix.m(), matrix.n(),
- entries_per_row,
- chunk_size, optimize_diag);
+ entries_per_row,
+ chunk_size, optimize_diag);
- // then actually fill it
+ // then actually fill it
for (unsigned int row=0; row<matrix.m(); ++row)
for (unsigned int col=0; col<matrix.n(); ++col)
if (matrix(row,col) != 0)
- add (row,col);
+ add (row,col);
- // finally compress
+ // finally compress
compress ();
}
void
ChunkSparsityPattern::add (const unsigned int i,
- const unsigned int j)
+ const unsigned int j)
{
Assert (i<rows, ExcInvalidIndex(i,rows));
Assert (j<cols, ExcInvalidIndex(j,cols));
bool
ChunkSparsityPattern::exists (const unsigned int i,
- const unsigned int j) const
+ const unsigned int j) const
{
Assert (i<rows, ExcIndexRange(i,0,rows));
Assert (j<cols, ExcIndexRange(j,0,cols));
return sparsity_pattern.exists (i/chunk_size,
- j/chunk_size);
+ j/chunk_size);
}
void
ChunkSparsityPattern::symmetrize ()
{
- // matrix must be square. note that the for
- // some matrix sizes, the current sparsity
- // pattern may not be square even if the
- // underlying sparsity pattern is (e.g. a
- // 10x11 matrix with chunk_size 4)
+ // matrix must be square. note that the for
+ // some matrix sizes, the current sparsity
+ // pattern may not be square even if the
+ // underlying sparsity pattern is (e.g. a
+ // 10x11 matrix with chunk_size 4)
Assert (rows==cols, ExcNotQuadratic());
sparsity_pattern.symmetrize ();
&&
(n_cols() % chunk_size == 0))
return (sparsity_pattern.n_nonzero_elements() *
- chunk_size *
- chunk_size);
+ chunk_size *
+ chunk_size);
else
- // some of the chunks reach beyond the
- // extent of this matrix. this requires a
- // somewhat more complicated
- // computations, in particular if the
- // columns don't align
+ // some of the chunks reach beyond the
+ // extent of this matrix. this requires a
+ // somewhat more complicated
+ // computations, in particular if the
+ // columns don't align
{
if ((n_rows() % chunk_size != 0)
- &&
- (n_cols() % chunk_size == 0))
- {
- // columns align with chunks, but
- // not rows
- unsigned int n = sparsity_pattern.n_nonzero_elements() *
- chunk_size *
- chunk_size;
- n -= (sparsity_pattern.n_rows() * chunk_size - n_rows()) *
- sparsity_pattern.row_length(sparsity_pattern.n_rows()-1) *
- chunk_size;
- return n;
- }
+ &&
+ (n_cols() % chunk_size == 0))
+ {
+ // columns align with chunks, but
+ // not rows
+ unsigned int n = sparsity_pattern.n_nonzero_elements() *
+ chunk_size *
+ chunk_size;
+ n -= (sparsity_pattern.n_rows() * chunk_size - n_rows()) *
+ sparsity_pattern.row_length(sparsity_pattern.n_rows()-1) *
+ chunk_size;
+ return n;
+ }
else
- {
- // if columns don't align, then
- // just iterate over all chunks and
- // see what this leads to
- SparsityPattern::const_iterator p = sparsity_pattern.begin();
- unsigned int n = 0;
- for (; p!=sparsity_pattern.end(); ++p)
- if ((p->row() != sparsity_pattern.n_rows() - 1)
- &&
- (p->column() != sparsity_pattern.n_cols() - 1))
- n += chunk_size * chunk_size;
- else
- if ((p->row() == sparsity_pattern.n_rows() - 1)
- &&
- (p->column() != sparsity_pattern.n_cols() - 1))
- // last chunk row, but not
- // last chunk column. only a
- // smaller number (n_rows %
- // chunk_size) of rows
- // actually exist
- n += (n_rows() % chunk_size) * chunk_size;
- else
- if ((p->row() != sparsity_pattern.n_rows() - 1)
- &&
- (p->column() == sparsity_pattern.n_cols() - 1))
- // last chunk column, but
- // not row
- n += (n_cols() % chunk_size) * chunk_size;
- else
- // bottom right chunk
- n += (n_cols() % chunk_size) *
- (n_rows() % chunk_size);
-
- return n;
- }
+ {
+ // if columns don't align, then
+ // just iterate over all chunks and
+ // see what this leads to
+ SparsityPattern::const_iterator p = sparsity_pattern.begin();
+ unsigned int n = 0;
+ for (; p!=sparsity_pattern.end(); ++p)
+ if ((p->row() != sparsity_pattern.n_rows() - 1)
+ &&
+ (p->column() != sparsity_pattern.n_cols() - 1))
+ n += chunk_size * chunk_size;
+ else
+ if ((p->row() == sparsity_pattern.n_rows() - 1)
+ &&
+ (p->column() != sparsity_pattern.n_cols() - 1))
+ // last chunk row, but not
+ // last chunk column. only a
+ // smaller number (n_rows %
+ // chunk_size) of rows
+ // actually exist
+ n += (n_rows() % chunk_size) * chunk_size;
+ else
+ if ((p->row() != sparsity_pattern.n_rows() - 1)
+ &&
+ (p->column() == sparsity_pattern.n_cols() - 1))
+ // last chunk column, but
+ // not row
+ n += (n_cols() % chunk_size) * chunk_size;
+ else
+ // bottom right chunk
+ n += (n_cols() % chunk_size) *
+ (n_rows() % chunk_size);
+
+ return n;
+ }
}
}
ChunkSparsityPattern::print (std::ostream &out) const
{
Assert ((sparsity_pattern.rowstart!=0) && (sparsity_pattern.colnums!=0),
- ExcEmptyObject());
+ ExcEmptyObject());
AssertThrow (out, ExcIO());
for (unsigned int i=0; i<sparsity_pattern.rows; ++i)
for (unsigned int d=0;
- (d<chunk_size) && (i*chunk_size + d < n_rows());
- ++d)
+ (d<chunk_size) && (i*chunk_size + d < n_rows());
+ ++d)
{
- out << '[' << i*chunk_size+d;
- for (unsigned int j=sparsity_pattern.rowstart[i];
- j<sparsity_pattern.rowstart[i+1]; ++j)
- if (sparsity_pattern.colnums[j] != sparsity_pattern.invalid_entry)
- for (unsigned int e=0;
- ((e<chunk_size) &&
- (sparsity_pattern.colnums[j]*chunk_size + e < n_cols()));
- ++e)
- out << ',' << sparsity_pattern.colnums[j]*chunk_size+e;
- out << ']' << std::endl;
+ out << '[' << i*chunk_size+d;
+ for (unsigned int j=sparsity_pattern.rowstart[i];
+ j<sparsity_pattern.rowstart[i+1]; ++j)
+ if (sparsity_pattern.colnums[j] != sparsity_pattern.invalid_entry)
+ for (unsigned int e=0;
+ ((e<chunk_size) &&
+ (sparsity_pattern.colnums[j]*chunk_size + e < n_cols()));
+ ++e)
+ out << ',' << sparsity_pattern.colnums[j]*chunk_size+e;
+ out << ']' << std::endl;
}
AssertThrow (out, ExcIO());
ChunkSparsityPattern::print_gnuplot (std::ostream &out) const
{
Assert ((sparsity_pattern.rowstart!=0) &&
- (sparsity_pattern.colnums!=0), ExcEmptyObject());
+ (sparsity_pattern.colnums!=0), ExcEmptyObject());
AssertThrow (out, ExcIO());
- // for each entry in the underlying
- // sparsity pattern, repeat everything
- // chunk_size x chunk_size times
+ // for each entry in the underlying
+ // sparsity pattern, repeat everything
+ // chunk_size x chunk_size times
for (unsigned int i=0; i<sparsity_pattern.rows; ++i)
for (unsigned int j=sparsity_pattern.rowstart[i];
- j<sparsity_pattern.rowstart[i+1]; ++j)
+ j<sparsity_pattern.rowstart[i+1]; ++j)
if (sparsity_pattern.colnums[j] != sparsity_pattern.invalid_entry)
- for (unsigned int d=0;
- ((d<chunk_size) &&
- (sparsity_pattern.colnums[j]*chunk_size+d < n_cols()));
- ++d)
- for (unsigned int e=0;
- (e<chunk_size) && (i*chunk_size + e < n_rows());
- ++e)
- // while matrix entries are
- // usually written (i,j), with i
- // vertical and j horizontal,
- // gnuplot output is x-y, that is
- // we have to exchange the order
- // of output
- out << sparsity_pattern.colnums[j]*chunk_size+d << " "
- << -static_cast<signed int>(i*chunk_size+e)
- << std::endl;
+ for (unsigned int d=0;
+ ((d<chunk_size) &&
+ (sparsity_pattern.colnums[j]*chunk_size+d < n_cols()));
+ ++d)
+ for (unsigned int e=0;
+ (e<chunk_size) && (i*chunk_size + e < n_rows());
+ ++e)
+ // while matrix entries are
+ // usually written (i,j), with i
+ // vertical and j horizontal,
+ // gnuplot output is x-y, that is
+ // we have to exchange the order
+ // of output
+ out << sparsity_pattern.colnums[j]*chunk_size+d << " "
+ << -static_cast<signed int>(i*chunk_size+e)
+ << std::endl;
AssertThrow (out, ExcIO());
}
unsigned int
ChunkSparsityPattern::bandwidth () const
{
- // calculate the bandwidth from that of the
- // underlying sparsity pattern. note that
- // even if the bandwidth of that is zero,
- // then the bandwidth of the chunky pattern
- // is chunk_size-1, if it is 1 then the
- // chunky pattern has
- // chunk_size+(chunk_size-1), etc
- //
- // we'll cut it off at max(n(),m())
+ // calculate the bandwidth from that of the
+ // underlying sparsity pattern. note that
+ // even if the bandwidth of that is zero,
+ // then the bandwidth of the chunky pattern
+ // is chunk_size-1, if it is 1 then the
+ // chunky pattern has
+ // chunk_size+(chunk_size-1), etc
+ //
+ // we'll cut it off at max(n(),m())
return std::min (sparsity_pattern.bandwidth()*chunk_size
- + (chunk_size-1),
- std::max(n_rows(), n_cols()));
+ + (chunk_size-1),
+ std::max(n_rows(), n_cols()));
}
<< cols << ' '
<< chunk_size << ' '
<< "][";
- // then the underlying sparsity pattern
+ // then the underlying sparsity pattern
sparsity_pattern.block_write (out);
out << ']';
in >> c;
AssertThrow (c == '[', ExcIO());
- // then read the underlying sparsity
- // pattern
+ // then read the underlying sparsity
+ // pattern
sparsity_pattern.block_read (in);
in >> c;
ChunkSparsityPattern::memory_consumption () const
{
return (sizeof(*this) +
- sparsity_pattern.memory_consumption());
+ sparsity_pattern.memory_consumption());
}
// explicit instantiations
template
void ChunkSparsityPattern::copy_from<CompressedSparsityPattern> (const CompressedSparsityPattern &,
- const unsigned int,
- const bool);
+ const unsigned int,
+ const bool);
template
void ChunkSparsityPattern::copy_from<CompressedSetSparsityPattern> (const CompressedSetSparsityPattern &,
- const unsigned int,
- const bool);
+ const unsigned int,
+ const bool);
template
void ChunkSparsityPattern::copy_from<CompressedSimpleSparsityPattern> (const CompressedSimpleSparsityPattern &,
- const unsigned int,
- const bool);
+ const unsigned int,
+ const bool);
template
void ChunkSparsityPattern::copy_from<float> (const FullMatrix<float> &,
- const unsigned int,
- const bool);
+ const unsigned int,
+ const bool);
template
void ChunkSparsityPattern::copy_from<double> (const FullMatrix<double> &,
- const unsigned int,
- const bool);
+ const unsigned int,
+ const bool);
DEAL_II_NAMESPACE_CLOSE
// $Id$
// Version: $Name$
//
-// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2008 by the deal.II authors
+// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2008, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
CompressedSetSparsityPattern::CompressedSetSparsityPattern ()
:
- rows(0),
- cols(0)
+ rows(0),
+ cols(0)
{}
CompressedSetSparsityPattern::
CompressedSetSparsityPattern (const CompressedSetSparsityPattern &s)
:
- Subscriptor(),
- rows(0),
- cols(0)
+ Subscriptor(),
+ rows(0),
+ cols(0)
{
Assert (s.rows == 0, ExcInvalidConstructorCall());
Assert (s.cols == 0, ExcInvalidConstructorCall());
CompressedSetSparsityPattern::CompressedSetSparsityPattern (const unsigned int m,
- const unsigned int n)
- :
+ const unsigned int n)
+ :
rows(0),
cols(0)
{
CompressedSetSparsityPattern::CompressedSetSparsityPattern (const unsigned int n)
- :
+ :
rows(0),
cols(0)
{
void
CompressedSetSparsityPattern::reinit (const unsigned int m,
- const unsigned int n)
+ const unsigned int n)
{
rows = m;
cols = n;
{
m = std::max (m, static_cast<unsigned int>(lines[i].entries.size()));
}
-
+
return m;
}
-bool
+bool
CompressedSetSparsityPattern::exists (const unsigned int i,
- const unsigned int j) const
+ const unsigned int j) const
{
Assert (i<rows, ExcIndexRange(i, 0, rows));
Assert (j<cols, ExcIndexRange(j, 0, cols));
{
Assert (rows==cols, ExcNotQuadratic());
- // loop over all elements presently
- // in the sparsity pattern and add
- // the transpose element. note:
- //
- // 1. that the sparsity pattern
- // changes which we work on, but
- // not the present row
- //
- // 2. that the @p{add} function can
- // be called on elements that
- // already exist without any harm
+ // loop over all elements presently
+ // in the sparsity pattern and add
+ // the transpose element. note:
+ //
+ // 1. that the sparsity pattern
+ // changes which we work on, but
+ // not the present row
+ //
+ // 2. that the @p{add} function can
+ // be called on elements that
+ // already exist without any harm
for (unsigned int row=0; row<rows; ++row)
{
for (std::set<unsigned int>::const_iterator
j=lines[row].entries.begin();
j != lines[row].entries.end();
++j)
- // add the transpose entry if
- // this is not the diagonal
+ // add the transpose entry if
+ // this is not the diagonal
if (row != *j)
add (*j, row);
}
void
CompressedSetSparsityPattern::print (std::ostream &out) const
-{
+{
AssertThrow (out, ExcIO());
for (unsigned int row=0; row<rows; ++row)
{
out << '[' << row;
-
+
for (std::set<unsigned int>::const_iterator
j=lines[row].entries.begin();
j != lines[row].entries.end(); ++j)
void
CompressedSetSparsityPattern::print_gnuplot (std::ostream &out) const
-{
+{
AssertThrow (out, ExcIO());
for (unsigned int row=0; row<rows; ++row)
// the order of output
out << *j << " " << -static_cast<signed int>(row) << std::endl;
}
-
+
AssertThrow (out, ExcIO());
}
if (static_cast<unsigned int>(std::abs(static_cast<int>(row-*j))) > b)
b = std::abs(static_cast<signed int>(row-*j));
}
-
+
return b;
}
{
n += lines[i].entries.size();
}
-
+
return n;
}
// $Id$
// Version: $Name$
//
-// Copyright (C) 2008, 2009, 2011 by the deal.II authors
+// Copyright (C) 2008, 2009, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
template <typename ForwardIterator>
void
CompressedSimpleSparsityPattern::Line::add_entries (ForwardIterator begin,
- ForwardIterator end,
- const bool indices_are_sorted)
+ ForwardIterator end,
+ const bool indices_are_sorted)
{
const int n_elements = end - begin;
if (n_elements <= 0)
if (indices_are_sorted == true && n_elements > 3)
{
- // in debug mode, check whether the
- // indices really are sorted.
+ // in debug mode, check whether the
+ // indices really are sorted.
#ifdef DEBUG
{
- ForwardIterator test = begin, test1 = begin;
- ++test1;
- for ( ; test1 != end; ++test, ++test1)
- Assert (*test1 > *test, ExcInternalError());
+ ForwardIterator test = begin, test1 = begin;
+ ++test1;
+ for ( ; test1 != end; ++test, ++test1)
+ Assert (*test1 > *test, ExcInternalError());
}
#endif
if (entries.size() == 0 || entries.back() < *begin)
- {
- entries.insert(entries.end(), begin, end);
- return;
- }
-
- // find a possible insertion point for
- // the first entry. check whether the
- // first entry is a duplicate before
- // actually doing something.
+ {
+ entries.insert(entries.end(), begin, end);
+ return;
+ }
+
+ // find a possible insertion point for
+ // the first entry. check whether the
+ // first entry is a duplicate before
+ // actually doing something.
ForwardIterator my_it = begin;
unsigned int col = *my_it;
std::vector<unsigned int>::iterator it =
- Utilities::lower_bound(entries.begin(), entries.end(), col);
+ Utilities::lower_bound(entries.begin(), entries.end(), col);
while (*it == col)
- {
- ++my_it;
- if (my_it == end)
- break;
- col = *my_it;
- // check the very next entry in the
- // current array
- ++it;
- if (it == entries.end())
- break;
- if (*it > col)
- break;
- if (*it == col)
- continue;
- // ok, it wasn't the very next one, do a
- // binary search to find the insert point
- it = Utilities::lower_bound(it, entries.end(), col);
- if (it == entries.end())
- break;
- }
- // all input entries were duplicates.
+ {
+ ++my_it;
+ if (my_it == end)
+ break;
+ col = *my_it;
+ // check the very next entry in the
+ // current array
+ ++it;
+ if (it == entries.end())
+ break;
+ if (*it > col)
+ break;
+ if (*it == col)
+ continue;
+ // ok, it wasn't the very next one, do a
+ // binary search to find the insert point
+ it = Utilities::lower_bound(it, entries.end(), col);
+ if (it == entries.end())
+ break;
+ }
+ // all input entries were duplicates.
if (my_it == end)
- return;
+ return;
- // resize vector by just inserting the
- // list
+ // resize vector by just inserting the
+ // list
const unsigned int pos1 = it - entries.begin();
Assert (pos1 <= entries.size(), ExcInternalError());
entries.insert (it, my_it, end);
it = entries.begin() + pos1;
Assert (entries.size() >= (unsigned int)(it-entries.begin()), ExcInternalError());
- // now merge the two lists.
+ // now merge the two lists.
std::vector<unsigned int>::iterator it2 = it + (end-my_it);
- // as long as there are indices both in
- // the end of the entries list and in the
- // input list
+ // as long as there are indices both in
+ // the end of the entries list and in the
+ // input list
while (my_it != end && it2 != entries.end())
- {
- if (*my_it < *it2)
- *it++ = *my_it++;
- else if (*my_it == *it2)
- {
- *it++ = *it2++;
- ++my_it;
- }
- else
- *it++ = *it2++;
- }
- // in case there are indices left in the
- // input list
+ {
+ if (*my_it < *it2)
+ *it++ = *my_it++;
+ else if (*my_it == *it2)
+ {
+ *it++ = *it2++;
+ ++my_it;
+ }
+ else
+ *it++ = *it2++;
+ }
+ // in case there are indices left in the
+ // input list
while (my_it != end)
- *it++ = *my_it++;
+ *it++ = *my_it++;
- // in case there are indices left in the
- // end of entries
+ // in case there are indices left in the
+ // end of entries
while (it2 != entries.end())
- *it++ = *it2++;
+ *it++ = *it2++;
- // resize and return
+ // resize and return
const unsigned int new_size = it - entries.begin();
Assert (new_size <= stop_size, ExcInternalError());
entries.resize (new_size);
return;
}
- // unsorted case or case with too few
- // elements
+ // unsorted case or case with too few
+ // elements
ForwardIterator my_it = begin;
- // If necessary, increase the size of the
- // array.
+ // If necessary, increase the size of the
+ // array.
if (stop_size > entries.capacity())
entries.reserve (stop_size);
unsigned int col = *my_it;
std::vector<unsigned int>::iterator it, it2;
- // insert the first element as for one
- // entry only first check the last
- // element (or if line is still empty)
+ // insert the first element as for one
+ // entry only first check the last
+ // element (or if line is still empty)
if ( (entries.size()==0) || ( entries.back() < col) ) {
entries.push_back(col);
it = entries.end()-1;
}
else {
- // do a binary search to find the place
- // where to insert:
+ // do a binary search to find the place
+ // where to insert:
it2 = Utilities::lower_bound(entries.begin(), entries.end(), col);
- // If this entry is a duplicate, continue
- // immediately Insert at the right place
- // in the vector. Vector grows
- // automatically to fit elements. Always
- // doubles its size.
+ // If this entry is a duplicate, continue
+ // immediately Insert at the right place
+ // in the vector. Vector grows
+ // automatically to fit elements. Always
+ // doubles its size.
if (*it2 != col)
it = entries.insert(it2, col);
else
}
++my_it;
- // Now try to be smart and insert with
- // bias in the direction we are
- // walking. This has the advantage that
- // for sorted lists, we always search in
- // the right direction, what should
- // decrease the work needed in here.
+ // Now try to be smart and insert with
+ // bias in the direction we are
+ // walking. This has the advantage that
+ // for sorted lists, we always search in
+ // the right direction, what should
+ // decrease the work needed in here.
for ( ; my_it != end; ++my_it)
{
col = *my_it;
- // need a special insertion command when
- // we're at the end of the list
+ // need a special insertion command when
+ // we're at the end of the list
if (col > entries.back()) {
- entries.push_back(col);
- it = entries.end()-1;
+ entries.push_back(col);
+ it = entries.end()-1;
}
- // search to the right (preferred search
- // direction)
+ // search to the right (preferred search
+ // direction)
else if (col > *it) {
- it2 = Utilities::lower_bound(it++, entries.end(), col);
- if (*it2 != col)
- it = entries.insert(it2, col);
+ it2 = Utilities::lower_bound(it++, entries.end(), col);
+ if (*it2 != col)
+ it = entries.insert(it2, col);
}
- // search to the left
+ // search to the left
else if (col < *it) {
- it2 = Utilities::lower_bound(entries.begin(), it, col);
- if (*it2 != col)
- it = entries.insert(it2, col);
+ it2 = Utilities::lower_bound(entries.begin(), it, col);
+ if (*it2 != col)
+ it = entries.insert(it2, col);
}
- // if we're neither larger nor smaller,
- // then this was a duplicate and we can
- // just continue.
+ // if we're neither larger nor smaller,
+ // then this was a duplicate and we can
+ // just continue.
}
}
CompressedSimpleSparsityPattern::CompressedSimpleSparsityPattern ()
:
- rows(0),
- cols(0),
- rowset(0)
+ rows(0),
+ cols(0),
+ rowset(0)
{}
CompressedSimpleSparsityPattern::
CompressedSimpleSparsityPattern (const CompressedSimpleSparsityPattern &s)
:
- Subscriptor(),
- rows(0),
- cols(0),
- rowset(0)
+ Subscriptor(),
+ rows(0),
+ cols(0),
+ rowset(0)
{
Assert (s.rows == 0, ExcInvalidConstructorCall());
Assert (s.cols == 0, ExcInvalidConstructorCall());
CompressedSimpleSparsityPattern::CompressedSimpleSparsityPattern (const unsigned int m,
- const unsigned int n,
- const IndexSet & rowset_
+ const unsigned int n,
+ const IndexSet & rowset_
)
- :
+ :
rows(0),
cols(0),
- rowset(0)
+ rowset(0)
{
reinit (m,n, rowset_);
}
CompressedSimpleSparsityPattern::CompressedSimpleSparsityPattern (const unsigned int n)
- :
+ :
rows(0),
cols(0),
- rowset(0)
+ rowset(0)
{
reinit (n,n);
}
void
CompressedSimpleSparsityPattern::reinit (const unsigned int m,
- const unsigned int n,
- const IndexSet & rowset_)
+ const unsigned int n,
+ const IndexSet & rowset_)
{
rows = m;
cols = n;
rowset=rowset_;
Assert(rowset.size()==0 || rowset.size() == m, ExcInvalidConstructorCall());
-
+
std::vector<Line> new_lines (rowset.size()==0 ? rows : rowset.n_elements());
lines.swap (new_lines);
}
bool
CompressedSimpleSparsityPattern::exists (const unsigned int i,
- const unsigned int j) const
+ const unsigned int j) const
{
Assert (i<rows, ExcIndexRange(i, 0, rows));
Assert (j<cols, ExcIndexRange(j, 0, cols));
{
Assert (rows==cols, ExcNotQuadratic());
- // loop over all elements presently
- // in the sparsity pattern and add
- // the transpose element. note:
- //
- // 1. that the sparsity pattern
- // changes which we work on, but
- // not the present row
- //
- // 2. that the @p{add} function can
- // be called on elements that
- // already exist without any harm
+ // loop over all elements presently
+ // in the sparsity pattern and add
+ // the transpose element. note:
+ //
+ // 1. that the sparsity pattern
+ // changes which we work on, but
+ // not the present row
+ //
+ // 2. that the @p{add} function can
+ // be called on elements that
+ // already exist without any harm
for (unsigned int row=0; row<lines.size(); ++row)
{
const unsigned int rowindex =
- rowset.size()==0 ? row : rowset.nth_index_in_set(row);
+ rowset.size()==0 ? row : rowset.nth_index_in_set(row);
for (std::vector<unsigned int>::const_iterator
j=lines[row].entries.begin();
j != lines[row].entries.end();
++j)
- // add the transpose entry if
- // this is not the diagonal
+ // add the transpose entry if
+ // this is not the diagonal
if (rowindex != *j)
add (*j, rowindex);
}
for (unsigned int row=0; row<lines.size(); ++row)
{
const unsigned int rowindex =
- rowset.size()==0 ? row : rowset.nth_index_in_set(row);
+ rowset.size()==0 ? row : rowset.nth_index_in_set(row);
for (std::vector<unsigned int>::const_iterator
j=lines[row].entries.begin();
// x-y, that is we have to exchange
// the order of output
out << *j << " "
- << -static_cast<signed int>(rowindex)
- << std::endl;
+ << -static_cast<signed int>(rowindex)
+ << std::endl;
}
for (unsigned int row=0; row<lines.size(); ++row)
{
const unsigned int rowindex =
- rowset.size()==0 ? row : rowset.nth_index_in_set(row);
+ rowset.size()==0 ? row : rowset.nth_index_in_set(row);
for (std::vector<unsigned int>::const_iterator
j=lines[row].entries.begin();
j != lines[row].entries.end(); ++j)
- if (static_cast<unsigned int>(std::abs(static_cast<int>(rowindex-*j))) > b)
- b = std::abs(static_cast<signed int>(rowindex-*j));
+ if (static_cast<unsigned int>(std::abs(static_cast<int>(rowindex-*j))) > b)
+ b = std::abs(static_cast<signed int>(rowindex-*j));
}
return b;
std::size_t
CompressedSimpleSparsityPattern::memory_consumption () const
{
- //TODO: IndexSet...
+ //TODO: IndexSet...
std::size_t mem = sizeof(CompressedSimpleSparsityPattern);
for (unsigned int i=0; i<lines.size(); ++i)
mem += MemoryConsumption::memory_consumption (lines[i]);
// explicit instantiations
template void CompressedSimpleSparsityPattern::Line::add_entries(unsigned int *,
- unsigned int *,
- const bool);
+ unsigned int *,
+ const bool);
template void CompressedSimpleSparsityPattern::Line::add_entries(const unsigned int *,
- const unsigned int *,
- const bool);
+ const unsigned int *,
+ const bool);
#ifndef DEAL_II_VECTOR_ITERATOR_IS_POINTER
template void CompressedSimpleSparsityPattern::Line::
add_entries(std::vector<unsigned int>::iterator,
- std::vector<unsigned int>::iterator,
- const bool);
+ std::vector<unsigned int>::iterator,
+ const bool);
#endif
DEAL_II_NAMESPACE_CLOSE
// $Id$
// Version: $Name$
//
-// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2008, 2009 by the deal.II authors
+// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2008, 2009, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
// Make sure the caller checked
// necessity of this function.
Assert(cache_entries != 0, ExcInternalError());
-
+
// first sort the entries in the cache, so
// that it is easier to merge it with the
// main array. note that due to the way
}
}
- // TODO: could use the add_entries
+ // TODO: could use the add_entries
// function of the constraint line for
// doing this, but that one is
// non-const. Still need to figure out
// arrays, if there are any entries at
// all that need to be merged
Assert (n_new_entries >= entries.size(),
- ExcInternalError());
+ ExcInternalError());
if (n_new_entries > entries.size())
- {
- std::vector<unsigned int> new_entries;
- new_entries.reserve (n_new_entries);
- unsigned int cache_position = 0;
- unsigned int entry_position = 0;
- while ((entry_position<entries.size()) &&
- (cache_position<cache_entries))
- if (entries[entry_position] < cache[cache_position])
- {
- new_entries.push_back (entries[entry_position]);
- ++entry_position;
- }
- else if (entries[entry_position] == cache[cache_position])
- {
- new_entries.push_back (entries[entry_position]);
- ++entry_position;
- ++cache_position;
- }
- else
- {
- new_entries.push_back (cache[cache_position]);
- ++cache_position;
- }
-
- // copy remaining elements from the
- // array that we haven't
- // finished. note that at most one
- // of the following loops will run
- // at all
- for (; entry_position < entries.size(); ++entry_position)
- new_entries.push_back (entries[entry_position]);
- for (; cache_position < cache_entries; ++cache_position)
- new_entries.push_back (cache[cache_position]);
-
- Assert (new_entries.size() == n_new_entries,
- ExcInternalError());
-
- // finally swap old and new array,
- // and set cache size to zero
- new_entries.swap (entries);
- }
+ {
+ std::vector<unsigned int> new_entries;
+ new_entries.reserve (n_new_entries);
+ unsigned int cache_position = 0;
+ unsigned int entry_position = 0;
+ while ((entry_position<entries.size()) &&
+ (cache_position<cache_entries))
+ if (entries[entry_position] < cache[cache_position])
+ {
+ new_entries.push_back (entries[entry_position]);
+ ++entry_position;
+ }
+ else if (entries[entry_position] == cache[cache_position])
+ {
+ new_entries.push_back (entries[entry_position]);
+ ++entry_position;
+ ++cache_position;
+ }
+ else
+ {
+ new_entries.push_back (cache[cache_position]);
+ ++cache_position;
+ }
+
+ // copy remaining elements from the
+ // array that we haven't
+ // finished. note that at most one
+ // of the following loops will run
+ // at all
+ for (; entry_position < entries.size(); ++entry_position)
+ new_entries.push_back (entries[entry_position]);
+ for (; cache_position < cache_entries; ++cache_position)
+ new_entries.push_back (cache[cache_position]);
+
+ Assert (new_entries.size() == n_new_entries,
+ ExcInternalError());
+
+ // finally swap old and new array,
+ // and set cache size to zero
+ new_entries.swap (entries);
+ }
}
-
+
cache_entries = 0;
}
template <typename ForwardIterator>
void
CompressedSparsityPattern::Line::add_entries (ForwardIterator begin,
- ForwardIterator end,
- const bool indices_are_sorted)
+ ForwardIterator end,
+ const bool indices_are_sorted)
{
- // use the same code as when flushing the
- // cache in case we have many (more than
- // three) entries in a sorted
- // list. Otherwise, go on to the single
- // add() function.
+ // use the same code as when flushing the
+ // cache in case we have many (more than
+ // three) entries in a sorted
+ // list. Otherwise, go on to the single
+ // add() function.
const int n_elements = end - begin;
if (n_elements <= 0)
return;
// arrays. special case the case that the
// original array is empty.
if (entries.size() == 0)
- {
- entries.resize (n_cols);
- ForwardIterator my_it = begin;
- for (unsigned int i=0; i<n_cols; ++i)
- entries[i] = *my_it++;
- }
+ {
+ entries.resize (n_cols);
+ ForwardIterator my_it = begin;
+ for (unsigned int i=0; i<n_cols; ++i)
+ entries[i] = *my_it++;
+ }
else
- {
+ {
// first count how many of the cache
// entries are already in the main
// array, so that we can efficiently
// allocate memory
- unsigned int n_new_entries = 0;
- {
- unsigned int entry_position = 0;
- ForwardIterator my_it = begin;
- while ((entry_position<entries.size()) &&
- (my_it != end))
- {
- ++n_new_entries;
- if (entries[entry_position] < *my_it)
- ++entry_position;
- else if (entries[entry_position] == *my_it)
- {
- ++entry_position;
- ++my_it;
- }
- else
- ++my_it;
- }
+ unsigned int n_new_entries = 0;
+ {
+ unsigned int entry_position = 0;
+ ForwardIterator my_it = begin;
+ while ((entry_position<entries.size()) &&
+ (my_it != end))
+ {
+ ++n_new_entries;
+ if (entries[entry_position] < *my_it)
+ ++entry_position;
+ else if (entries[entry_position] == *my_it)
+ {
+ ++entry_position;
+ ++my_it;
+ }
+ else
+ ++my_it;
+ }
// scoop up leftovers in arrays
- n_new_entries += (entries.size() - entry_position) +
- (end - my_it);
- }
+ n_new_entries += (entries.size() - entry_position) +
+ (end - my_it);
+ }
// then allocate new memory and merge
// arrays, if there are any entries at
// all that need to be merged
- Assert (n_new_entries >= entries.size(),
- ExcInternalError());
- if (n_new_entries > entries.size())
- {
- std::vector<unsigned int> new_entries;
- new_entries.reserve (n_new_entries);
- ForwardIterator my_it = begin;
- unsigned int entry_position = 0;
- while ((entry_position<entries.size()) &&
- (my_it != end))
- if (entries[entry_position] < *my_it)
- {
- new_entries.push_back (entries[entry_position]);
- ++entry_position;
- }
- else if (entries[entry_position] == *my_it)
- {
- new_entries.push_back (entries[entry_position]);
- ++entry_position;
- ++my_it;
- }
- else
- {
- new_entries.push_back (*my_it);
- ++my_it;
- }
-
- // copy remaining elements from the
- // array that we haven't
- // finished. note that at most one
- // of the following loops will run
- // at all
- for (; entry_position < entries.size(); ++entry_position)
- new_entries.push_back (entries[entry_position]);
- for (; my_it != end; ++my_it)
- new_entries.push_back (*my_it);
-
- Assert (new_entries.size() == n_new_entries,
- ExcInternalError());
-
- // finally swap old and new array,
- // and set cache size to zero
- new_entries.swap (entries);
- }
- }
+ Assert (n_new_entries >= entries.size(),
+ ExcInternalError());
+ if (n_new_entries > entries.size())
+ {
+ std::vector<unsigned int> new_entries;
+ new_entries.reserve (n_new_entries);
+ ForwardIterator my_it = begin;
+ unsigned int entry_position = 0;
+ while ((entry_position<entries.size()) &&
+ (my_it != end))
+ if (entries[entry_position] < *my_it)
+ {
+ new_entries.push_back (entries[entry_position]);
+ ++entry_position;
+ }
+ else if (entries[entry_position] == *my_it)
+ {
+ new_entries.push_back (entries[entry_position]);
+ ++entry_position;
+ ++my_it;
+ }
+ else
+ {
+ new_entries.push_back (*my_it);
+ ++my_it;
+ }
+
+ // copy remaining elements from the
+ // array that we haven't
+ // finished. note that at most one
+ // of the following loops will run
+ // at all
+ for (; entry_position < entries.size(); ++entry_position)
+ new_entries.push_back (entries[entry_position]);
+ for (; my_it != end; ++my_it)
+ new_entries.push_back (*my_it);
+
+ Assert (new_entries.size() == n_new_entries,
+ ExcInternalError());
+
+ // finally swap old and new array,
+ // and set cache size to zero
+ new_entries.swap (entries);
+ }
+ }
return;
}
- // otherwise, insert the indices one
- // after each other
+ // otherwise, insert the indices one
+ // after each other
for (ForwardIterator it = begin; it != end; ++it)
add (*it);
}
CompressedSparsityPattern::CompressedSparsityPattern ()
:
- rows(0),
- cols(0)
+ rows(0),
+ cols(0)
{}
CompressedSparsityPattern::
CompressedSparsityPattern (const CompressedSparsityPattern &s)
:
- Subscriptor(),
- rows(0),
- cols(0)
+ Subscriptor(),
+ rows(0),
+ cols(0)
{
Assert (s.rows == 0, ExcInvalidConstructorCall());
Assert (s.cols == 0, ExcInvalidConstructorCall());
CompressedSparsityPattern::CompressedSparsityPattern (const unsigned int m,
- const unsigned int n)
- :
+ const unsigned int n)
+ :
rows(0),
cols(0)
{
CompressedSparsityPattern::CompressedSparsityPattern (const unsigned int n)
- :
+ :
rows(0),
cols(0)
{
void
CompressedSparsityPattern::reinit (const unsigned int m,
- const unsigned int n)
+ const unsigned int n)
{
rows = m;
cols = n;
for (unsigned int i=0; i<rows; ++i)
{
if (lines[i].cache_entries != 0)
- lines[i].flush_cache ();
+ lines[i].flush_cache ();
m = std::max (m, static_cast<unsigned int>(lines[i].entries.size()));
}
-
+
return m;
}
-bool
+bool
CompressedSparsityPattern::exists (const unsigned int i,
- const unsigned int j) const
+ const unsigned int j) const
{
Assert (i<rows, ExcIndexRange(i, 0, rows));
Assert (j<cols, ExcIndexRange(j, 0, cols));
{
Assert (rows==cols, ExcNotQuadratic());
- // loop over all elements presently
- // in the sparsity pattern and add
- // the transpose element. note:
- //
- // 1. that the sparsity pattern
- // changes which we work on, but
- // not the present row
- //
- // 2. that the @p{add} function can
- // be called on elements that
- // already exist without any harm
+ // loop over all elements presently
+ // in the sparsity pattern and add
+ // the transpose element. note:
+ //
+ // 1. that the sparsity pattern
+ // changes which we work on, but
+ // not the present row
+ //
+ // 2. that the @p{add} function can
+ // be called on elements that
+ // already exist without any harm
for (unsigned int row=0; row<rows; ++row)
{
if (lines[row].cache_entries != 0)
- lines[row].flush_cache ();
+ lines[row].flush_cache ();
for (std::vector<unsigned int>::const_iterator
j=lines[row].entries.begin();
j != lines[row].entries.end();
++j)
- // add the transpose entry if
- // this is not the diagonal
+ // add the transpose entry if
+ // this is not the diagonal
if (row != *j)
add (*j, row);
}
void
CompressedSparsityPattern::print (std::ostream &out) const
-{
+{
for (unsigned int row=0; row<rows; ++row)
{
if (lines[row].cache_entries != 0)
- lines[row].flush_cache ();
+ lines[row].flush_cache ();
out << '[' << row;
-
+
for (std::vector<unsigned int>::const_iterator
j=lines[row].entries.begin();
j != lines[row].entries.end(); ++j)
void
CompressedSparsityPattern::print_gnuplot (std::ostream &out) const
-{
+{
for (unsigned int row=0; row<rows; ++row)
{
if (lines[row].cache_entries != 0)
- lines[row].flush_cache ();
+ lines[row].flush_cache ();
for (std::vector<unsigned int>::const_iterator
j=lines[row].entries.begin();
j != lines[row].entries.end(); ++j)
// x-y, that is we have to exchange
// the order of output
out << *j << " " << -static_cast<signed int>(row) << std::endl;
- }
+ }
AssertThrow (out, ExcIO());
}
for (unsigned int row=0; row<rows; ++row)
{
if (lines[row].cache_entries != 0)
- lines[row].flush_cache ();
+ lines[row].flush_cache ();
for (std::vector<unsigned int>::const_iterator
j=lines[row].entries.begin();
if (static_cast<unsigned int>(std::abs(static_cast<int>(row-*j))) > b)
b = std::abs(static_cast<signed int>(row-*j));
}
-
+
return b;
}
for (unsigned int i=0; i<rows; ++i)
{
if (lines[i].cache_entries != 0)
- lines[i].flush_cache ();
+ lines[i].flush_cache ();
n += lines[i].entries.size();
}
-
+
return n;
}
// explicit instantiations
template void CompressedSparsityPattern::Line::add_entries(unsigned int *,
- unsigned int *,
- const bool);
+ unsigned int *,
+ const bool);
template void CompressedSparsityPattern::Line::add_entries(const unsigned int *,
- const unsigned int *,
- const bool);
+ const unsigned int *,
+ const bool);
#ifndef DEAL_II_VECTOR_ITERATOR_IS_POINTER
template void CompressedSparsityPattern::Line::
add_entries(std::vector<unsigned int>::iterator,
- std::vector<unsigned int>::iterator,
- const bool);
+ std::vector<unsigned int>::iterator,
+ const bool);
#endif
DEAL_II_NAMESPACE_CLOSE
//---------------------------------------------------------------------------
// $Id$
//
-// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 by the deal.II authors
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
- // Static member variable
+ // Static member variable
const Table<2,bool> ConstraintMatrix::default_empty_table = Table<2,bool>();
ConstraintMatrix::ConstraintLine::memory_consumption () const
{
return (MemoryConsumption::memory_consumption (line) +
- MemoryConsumption::memory_consumption (entries) +
- MemoryConsumption::memory_consumption (inhomogeneity));
+ MemoryConsumption::memory_consumption (entries) +
+ MemoryConsumption::memory_consumption (inhomogeneity));
}
ConstraintMatrix::add_lines (const std::set<unsigned int> &lines)
{
for (std::set<unsigned int>::const_iterator
- i = lines.begin(); i != lines.end(); ++i)
+ i = lines.begin(); i != lines.end(); ++i)
add_line (*i);
}
ConstraintLine * line_ptr = &lines[lines_cache[calculate_line_index(line)]];
Assert (line_ptr->line == line, ExcInternalError());
- // if in debug mode, check whether an
- // entry for this column already
- // exists and if its the same as
- // the one entered at present
- //
- // in any case: skip this entry if
- // an entry for this column already
- // exists, since we don't want to
- // enter it twice
+ // if in debug mode, check whether an
+ // entry for this column already
+ // exists and if its the same as
+ // the one entered at present
+ //
+ // in any case: skip this entry if
+ // an entry for this column already
+ // exists, since we don't want to
+ // enter it twice
for (std::vector<std::pair<unsigned int,double> >::const_iterator
col_val_pair = col_val_pairs.begin();
col_val_pair!=col_val_pairs.end(); ++col_val_pair)
{
Assert (line != col_val_pair->first,
- ExcMessage ("Can't constrain a degree of freedom to itself"));
+ ExcMessage ("Can't constrain a degree of freedom to itself"));
for (ConstraintLine::Entries::const_iterator
p=line_ptr->entries.begin();
- p != line_ptr->entries.end(); ++p)
- if (p->first == col_val_pair->first)
- {
- // entry exists, break
- // innermost loop
- Assert (p->second == col_val_pair->second,
- ExcEntryAlreadyExists(line, col_val_pair->first,
- p->second, col_val_pair->second));
- break;
- }
+ p != line_ptr->entries.end(); ++p)
+ if (p->first == col_val_pair->first)
+ {
+ // entry exists, break
+ // innermost loop
+ Assert (p->second == col_val_pair->second,
+ ExcEntryAlreadyExists(line, col_val_pair->first,
+ p->second, col_val_pair->second));
+ break;
+ }
line_ptr->entries.push_back (*col_val_pair);
}
return;
Assert (filter.size() > constraints.lines.back().line,
- ExcMessage ("Filter needs to be larger than constraint matrix size."));
+ ExcMessage ("Filter needs to be larger than constraint matrix size."));
for (std::vector<ConstraintLine>::const_iterator line=constraints.lines.begin();
line!=constraints.lines.end(); ++line)
if (filter.is_element(line->line))
{
- const unsigned int row = filter.index_within_set (line->line);
- add_line (row);
- set_inhomogeneity (row, line->inhomogeneity);
- for (unsigned int i=0; i<line->entries.size(); ++i)
- if (filter.is_element(line->entries[i].first))
- add_entry (row, filter.index_within_set (line->entries[i].first),
- line->entries[i].second);
+ const unsigned int row = filter.index_within_set (line->line);
+ add_line (row);
+ set_inhomogeneity (row, line->inhomogeneity);
+ for (unsigned int i=0; i<line->entries.size(); ++i)
+ if (filter.is_element(line->entries[i].first))
+ add_entry (row, filter.index_within_set (line->entries[i].first),
+ line->entries[i].second);
}
}
if (sorted == true)
return;
- // sort the lines
+ // sort the lines
std::sort (lines.begin(), lines.end());
- // update list of pointers and give the
- // vector a sharp size since we won't
- // modify the size any more after this
- // point.
+ // update list of pointers and give the
+ // vector a sharp size since we won't
+ // modify the size any more after this
+ // point.
{
std::vector<unsigned int> new_lines (lines_cache.size(),
- numbers::invalid_unsigned_int);
+ numbers::invalid_unsigned_int);
unsigned int counter = 0;
for (std::vector<ConstraintLine>::const_iterator line=lines.begin();
- line!=lines.end(); ++line, ++counter)
+ line!=lines.end(); ++line, ++counter)
new_lines[calculate_line_index(line->line)] = counter;
std::swap (lines_cache, new_lines);
}
- // in debug mode: check whether we really
- // set the pointers correctly.
+ // in debug mode: check whether we really
+ // set the pointers correctly.
for (unsigned int i=0; i<lines_cache.size(); ++i)
if (lines_cache[i] != numbers::invalid_unsigned_int)
Assert (i == calculate_line_index(lines[lines_cache[i]].line),
- ExcInternalError());
+ ExcInternalError());
- // first, strip zero entries, as we
- // have to do that only once
+ // first, strip zero entries, as we
+ // have to do that only once
for (std::vector<ConstraintLine>::iterator line = lines.begin();
line!=lines.end(); ++line)
- // first remove zero
- // entries. that would mean that
- // in the linear constraint for a
- // node, x_i = ax_1 + bx_2 + ...,
- // another node times 0
- // appears. obviously,
- // 0*something can be omitted
+ // first remove zero
+ // entries. that would mean that
+ // in the linear constraint for a
+ // node, x_i = ax_1 + bx_2 + ...,
+ // another node times 0
+ // appears. obviously,
+ // 0*something can be omitted
line->entries.erase (std::remove_if (line->entries.begin(),
- line->entries.end(),
- &check_zero_weight),
- line->entries.end());
-
- // replace references to dofs that
- // are themselves constrained. note
- // that because we may replace
- // references to other dofs that
- // may themselves be constrained to
- // third ones, we have to iterate
- // over all this until we replace
- // no chains of constraints any
- // more
+ line->entries.end(),
+ &check_zero_weight),
+ line->entries.end());
+
+ // replace references to dofs that
+ // are themselves constrained. note
+ // that because we may replace
+ // references to other dofs that
+ // may themselves be constrained to
+ // third ones, we have to iterate
+ // over all this until we replace
+ // no chains of constraints any
+ // more
//
// the iteration replaces
// references to constrained
bool chained_constraint_replaced = false;
for (std::vector<ConstraintLine>::iterator line = lines.begin();
- line!=lines.end(); ++line)
- {
- // loop over all entries of
- // this line (including
- // ones that we have
- // appended in this go
- // around) and see whether
- // they are further
- // constrained. ignore
- // elements that we don't
- // store on the current
- // processor
- unsigned int entry = 0;
- while (entry < line->entries.size())
- if (((local_lines.size() == 0)
- ||
- (local_lines.is_element(line->entries[entry].first)))
- &&
- is_constrained (line->entries[entry].first))
- {
- // ok, this entry is
- // further
- // constrained:
- chained_constraint_replaced = true;
-
- // look up the chain
- // of constraints for
- // this entry
- const unsigned int dof_index = line->entries[entry].first;
- const double weight = line->entries[entry].second;
-
- Assert (dof_index != line->line,
- ExcMessage ("Cycle in constraints detected!"));
-
- const ConstraintLine * constrained_line =
- &lines[lines_cache[calculate_line_index(dof_index)]];
- Assert (constrained_line->line == dof_index,
- ExcInternalError());
-
- // now we have to
- // replace an entry
- // by its
- // expansion. we do
- // that by
- // overwriting the
- // entry by the first
- // entry of the
- // expansion and
- // adding the
- // remaining ones to
- // the end, where we
- // will later process
- // them once more
- //
- // we can of course
- // only do that if
- // the DoF that we
- // are currently
- // handle is
- // constrained by a
- // linear combination
- // of other dofs:
- if (constrained_line->entries.size() > 0)
- {
- for (unsigned int i=0; i<constrained_line->entries.size(); ++i)
- Assert (dof_index != constrained_line->entries[i].first,
- ExcMessage ("Cycle in constraints detected!"));
-
- // replace first
- // entry, then tack
- // the rest to the
- // end of the list
- line->entries[entry] =
- std::make_pair (constrained_line->entries[0].first,
- constrained_line->entries[0].second *
- weight);
-
- for (unsigned int i=1; i<constrained_line->entries.size(); ++i)
- line->entries
- .push_back (std::make_pair (constrained_line->entries[i].first,
- constrained_line->entries[i].second *
- weight));
- }
- else
- // the DoF that we
- // encountered is not
- // constrained by a linear
- // combination of other
- // dofs but is equal to
- // just the inhomogeneity
- // (i.e. its chain of
- // entries is empty). in
- // that case, we can't just
- // overwrite the current
- // entry, but we have to
- // actually eliminate it
- {
- line->entries.erase (line->entries.begin()+entry);
- }
-
- line->inhomogeneity += constrained_line->inhomogeneity *
- weight;
-
- // now that we're here, do
- // not increase index by
- // one but rather make
- // another pass for the
- // present entry because we
- // have replaced the
- // present entry by another
- // one, or because we have
- // deleted it and shifted
- // all following ones one
- // forward
- }
- else
- // entry not further
- // constrained. just move
- // ahead by one
- ++entry;
- }
-
- // if we didn't do anything in
- // this round, then quit the
- // loop
+ line!=lines.end(); ++line)
+ {
+ // loop over all entries of
+ // this line (including
+ // ones that we have
+ // appended in this go
+ // around) and see whether
+ // they are further
+ // constrained. ignore
+ // elements that we don't
+ // store on the current
+ // processor
+ unsigned int entry = 0;
+ while (entry < line->entries.size())
+ if (((local_lines.size() == 0)
+ ||
+ (local_lines.is_element(line->entries[entry].first)))
+ &&
+ is_constrained (line->entries[entry].first))
+ {
+ // ok, this entry is
+ // further
+ // constrained:
+ chained_constraint_replaced = true;
+
+ // look up the chain
+ // of constraints for
+ // this entry
+ const unsigned int dof_index = line->entries[entry].first;
+ const double weight = line->entries[entry].second;
+
+ Assert (dof_index != line->line,
+ ExcMessage ("Cycle in constraints detected!"));
+
+ const ConstraintLine * constrained_line =
+ &lines[lines_cache[calculate_line_index(dof_index)]];
+ Assert (constrained_line->line == dof_index,
+ ExcInternalError());
+
+ // now we have to
+ // replace an entry
+ // by its
+ // expansion. we do
+ // that by
+ // overwriting the
+ // entry by the first
+ // entry of the
+ // expansion and
+ // adding the
+ // remaining ones to
+ // the end, where we
+ // will later process
+ // them once more
+ //
+ // we can of course
+ // only do that if
+ // the DoF that we
+ // are currently
+ // handle is
+ // constrained by a
+ // linear combination
+ // of other dofs:
+ if (constrained_line->entries.size() > 0)
+ {
+ for (unsigned int i=0; i<constrained_line->entries.size(); ++i)
+ Assert (dof_index != constrained_line->entries[i].first,
+ ExcMessage ("Cycle in constraints detected!"));
+
+ // replace first
+ // entry, then tack
+ // the rest to the
+ // end of the list
+ line->entries[entry] =
+ std::make_pair (constrained_line->entries[0].first,
+ constrained_line->entries[0].second *
+ weight);
+
+ for (unsigned int i=1; i<constrained_line->entries.size(); ++i)
+ line->entries
+ .push_back (std::make_pair (constrained_line->entries[i].first,
+ constrained_line->entries[i].second *
+ weight));
+ }
+ else
+ // the DoF that we
+ // encountered is not
+ // constrained by a linear
+ // combination of other
+ // dofs but is equal to
+ // just the inhomogeneity
+ // (i.e. its chain of
+ // entries is empty). in
+ // that case, we can't just
+ // overwrite the current
+ // entry, but we have to
+ // actually eliminate it
+ {
+ line->entries.erase (line->entries.begin()+entry);
+ }
+
+ line->inhomogeneity += constrained_line->inhomogeneity *
+ weight;
+
+ // now that we're here, do
+ // not increase index by
+ // one but rather make
+ // another pass for the
+ // present entry because we
+ // have replaced the
+ // present entry by another
+ // one, or because we have
+ // deleted it and shifted
+ // all following ones one
+ // forward
+ }
+ else
+ // entry not further
+ // constrained. just move
+ // ahead by one
+ ++entry;
+ }
+
+ // if we didn't do anything in
+ // this round, then quit the
+ // loop
if (chained_constraint_replaced == false)
- break;
-
- // increase iteration count. note
- // that we should not iterate more
- // times than there are constraints,
- // since this puts a natural upper
- // bound on the length of constraint
- // chains
+ break;
+
+ // increase iteration count. note
+ // that we should not iterate more
+ // times than there are constraints,
+ // since this puts a natural upper
+ // bound on the length of constraint
+ // chains
++iteration;
Assert (iteration <= lines.size(), ExcInternalError());
}
- // finally sort the entries and re-scale
- // them if necessary. in this step, we also
- // throw out duplicates as mentioned
- // above. moreover, as some entries might
- // have had zero weights, we replace them
- // by a vector with sharp sizes.
+ // finally sort the entries and re-scale
+ // them if necessary. in this step, we also
+ // throw out duplicates as mentioned
+ // above. moreover, as some entries might
+ // have had zero weights, we replace them
+ // by a vector with sharp sizes.
for (std::vector<ConstraintLine>::iterator line = lines.begin();
line!=lines.end(); ++line)
{
// entries.
unsigned int duplicates = 0;
for (unsigned int i=1; i<line->entries.size(); ++i)
- if (line->entries[i].first == line->entries[i-1].first)
- duplicates++;
+ if (line->entries[i].first == line->entries[i-1].first)
+ duplicates++;
if (duplicates > 0 || line->entries.size() < line->entries.capacity())
- {
- ConstraintLine::Entries new_entries;
+ {
+ ConstraintLine::Entries new_entries;
// if we have no duplicates, copy
// verbatim the entries. this
// way, the final size is of the
// vector is correct.
- if (duplicates == 0)
- new_entries = line->entries;
- else
- {
+ if (duplicates == 0)
+ new_entries = line->entries;
+ else
+ {
// otherwise, we need to go
// through the list by and and
// resolve the duplicates
- new_entries.reserve (line->entries.size() - duplicates);
- new_entries.push_back(line->entries[0]);
- for (unsigned int j=1; j<line->entries.size(); ++j)
- if (line->entries[j].first == line->entries[j-1].first)
- {
- Assert (new_entries.back().first == line->entries[j].first,
- ExcInternalError());
- new_entries.back().second += line->entries[j].second;
- }
- else
- new_entries.push_back (line->entries[j]);
-
- Assert (new_entries.size() == line->entries.size() - duplicates,
- ExcInternalError());
+ new_entries.reserve (line->entries.size() - duplicates);
+ new_entries.push_back(line->entries[0]);
+ for (unsigned int j=1; j<line->entries.size(); ++j)
+ if (line->entries[j].first == line->entries[j-1].first)
+ {
+ Assert (new_entries.back().first == line->entries[j].first,
+ ExcInternalError());
+ new_entries.back().second += line->entries[j].second;
+ }
+ else
+ new_entries.push_back (line->entries[j]);
+
+ Assert (new_entries.size() == line->entries.size() - duplicates,
+ ExcInternalError());
// make sure there are
// really no duplicates
// left and that the list
// is still sorted
- for (unsigned int j=1; j<new_entries.size(); ++j)
- {
- Assert (new_entries[j].first != new_entries[j-1].first,
- ExcInternalError());
- Assert (new_entries[j].first > new_entries[j-1].first,
- ExcInternalError());
- }
- }
+ for (unsigned int j=1; j<new_entries.size(); ++j)
+ {
+ Assert (new_entries[j].first != new_entries[j-1].first,
+ ExcInternalError());
+ Assert (new_entries[j].first > new_entries[j-1].first,
+ ExcInternalError());
+ }
+ }
// replace old list of
// constraints for this dof by
// the new one
- line->entries.swap (new_entries);
- }
-
- // finally do the following
- // check: if the sum of
- // weights for the
- // constraints is close to
- // one, but not exactly
- // one, then rescale all
- // the weights so that they
- // sum up to 1. this adds a
- // little numerical
- // stability and avoids all
- // sorts of problems where
- // the actual value is
- // close to, but not quite
- // what we expected
- //
- // the case where the
- // weights don't quite sum
- // up happens when we
- // compute the
- // interpolation weights
- // "on the fly", i.e. not
- // from precomputed
- // tables. in this case,
- // the interpolation
- // weights are also subject
- // to round-off
+ line->entries.swap (new_entries);
+ }
+
+ // finally do the following
+ // check: if the sum of
+ // weights for the
+ // constraints is close to
+ // one, but not exactly
+ // one, then rescale all
+ // the weights so that they
+ // sum up to 1. this adds a
+ // little numerical
+ // stability and avoids all
+ // sorts of problems where
+ // the actual value is
+ // close to, but not quite
+ // what we expected
+ //
+ // the case where the
+ // weights don't quite sum
+ // up happens when we
+ // compute the
+ // interpolation weights
+ // "on the fly", i.e. not
+ // from precomputed
+ // tables. in this case,
+ // the interpolation
+ // weights are also subject
+ // to round-off
double sum = 0;
for (unsigned int i=0; i<line->entries.size(); ++i)
- sum += line->entries[i].second;
+ sum += line->entries[i].second;
if ((sum != 1.0) && (std::fabs (sum-1.) < 1.e-13))
- {
- for (unsigned int i=0; i<line->entries.size(); ++i)
- line->entries[i].second /= sum;
- line->inhomogeneity /= sum;
- }
+ {
+ for (unsigned int i=0; i<line->entries.size(); ++i)
+ line->entries[i].second /= sum;
+ line->inhomogeneity /= sum;
+ }
} // end of loop over all constraint lines
#ifdef DEBUG
- // if in debug mode: check that no dof is
- // constrained to another dof that is also
- // constrained. exclude dofs from this
- // check whose constraint lines are not
- // stored on the local processor
+ // if in debug mode: check that no dof is
+ // constrained to another dof that is also
+ // constrained. exclude dofs from this
+ // check whose constraint lines are not
+ // stored on the local processor
for (std::vector<ConstraintLine>::const_iterator line=lines.begin();
line!=lines.end(); ++line)
for (ConstraintLine::Entries::const_iterator
- entry=line->entries.begin();
- entry!=line->entries.end(); ++entry)
+ entry=line->entries.begin();
+ entry!=line->entries.end(); ++entry)
if ((local_lines.size() == 0)
- ||
- (local_lines.is_element(entry->first)))
- {
- // make sure that entry->first is
- // not the index of a line itself
- const bool is_circle = is_constrained(entry->first);
- Assert (is_circle == false,
- ExcDoFConstrainedToConstrainedDoF(line->line, entry->first));
- }
+ ||
+ (local_lines.is_element(entry->first)))
+ {
+ // make sure that entry->first is
+ // not the index of a line itself
+ const bool is_circle = is_constrained(entry->first);
+ Assert (is_circle == false,
+ ExcDoFConstrainedToConstrainedDoF(line->line, entry->first));
+ }
#endif
sorted = true;
void
ConstraintMatrix::merge (const ConstraintMatrix &other_constraints,
- const MergeConflictBehavior merge_conflict_behavior)
+ const MergeConflictBehavior merge_conflict_behavior)
{
AssertThrow(local_lines == other_constraints.local_lines,
- ExcNotImplemented());
+ ExcNotImplemented());
- // store the previous state with
- // respect to sorting
+ // store the previous state with
+ // respect to sorting
const bool object_was_sorted = sorted;
sorted = false;
if (other_constraints.lines_cache.size() > lines_cache.size())
lines_cache.resize(other_constraints.lines_cache.size(),
- numbers::invalid_unsigned_int);
-
- // first action is to fold into the present
- // object possible constraints in the
- // second object. we don't strictly need to
- // do this any more since the
- // ConstraintMatrix has learned to deal
- // with chains of constraints in the
- // close() function, but we have
- // traditionally done this and it's not
- // overly hard to do.
- //
- // for this, loop over all
- // constraints and replace the
- // constraint lines with a new one
- // where constraints are replaced
- // if necessary.
+ numbers::invalid_unsigned_int);
+
+ // first action is to fold into the present
+ // object possible constraints in the
+ // second object. we don't strictly need to
+ // do this any more since the
+ // ConstraintMatrix has learned to deal
+ // with chains of constraints in the
+ // close() function, but we have
+ // traditionally done this and it's not
+ // overly hard to do.
+ //
+ // for this, loop over all
+ // constraints and replace the
+ // constraint lines with a new one
+ // where constraints are replaced
+ // if necessary.
ConstraintLine::Entries tmp;
for (std::vector<ConstraintLine>::iterator line=lines.begin();
line!=lines.end(); ++line)
{
tmp.clear ();
for (unsigned int i=0; i<line->entries.size(); ++i)
- {
- // if the present dof is not
- // constrained, or if we won't take
- // the constraint from the other
- // object, then simply copy it over
- if (other_constraints.is_constrained(line->entries[i].first) == false
- ||
- ((merge_conflict_behavior != right_object_wins)
- &&
- other_constraints.is_constrained(line->entries[i].first)
- &&
- this->is_constrained(line->entries[i].first)))
- tmp.push_back(line->entries[i]);
- else
- // otherwise resolve
- // further constraints by
- // replacing the old
- // entry by a sequence of
- // new entries taken from
- // the other object, but
- // with multiplied
- // weights
- {
- const ConstraintLine::Entries* other_line
- = other_constraints.get_constraint_entries (line->entries[i].first);
- Assert (other_line != 0,
- ExcInternalError());
-
- const double weight = line->entries[i].second;
-
- for (ConstraintLine::Entries::const_iterator j=other_line->begin();
- j!=other_line->end(); ++j)
- tmp.push_back (std::pair<unsigned int,double>(j->first,
- j->second*weight));
-
- line->inhomogeneity += other_constraints.get_inhomogeneity(line->entries[i].first) *
- weight;
- }
- }
- // finally exchange old and
- // newly resolved line
+ {
+ // if the present dof is not
+ // constrained, or if we won't take
+ // the constraint from the other
+ // object, then simply copy it over
+ if (other_constraints.is_constrained(line->entries[i].first) == false
+ ||
+ ((merge_conflict_behavior != right_object_wins)
+ &&
+ other_constraints.is_constrained(line->entries[i].first)
+ &&
+ this->is_constrained(line->entries[i].first)))
+ tmp.push_back(line->entries[i]);
+ else
+ // otherwise resolve
+ // further constraints by
+ // replacing the old
+ // entry by a sequence of
+ // new entries taken from
+ // the other object, but
+ // with multiplied
+ // weights
+ {
+ const ConstraintLine::Entries* other_line
+ = other_constraints.get_constraint_entries (line->entries[i].first);
+ Assert (other_line != 0,
+ ExcInternalError());
+
+ const double weight = line->entries[i].second;
+
+ for (ConstraintLine::Entries::const_iterator j=other_line->begin();
+ j!=other_line->end(); ++j)
+ tmp.push_back (std::pair<unsigned int,double>(j->first,
+ j->second*weight));
+
+ line->inhomogeneity += other_constraints.get_inhomogeneity(line->entries[i].first) *
+ weight;
+ }
+ }
+ // finally exchange old and
+ // newly resolved line
line->entries.swap (tmp);
}
- // next action: append those lines at the
- // end that we want to add
+ // next action: append those lines at the
+ // end that we want to add
for (std::vector<ConstraintLine>::const_iterator
- line=other_constraints.lines.begin();
+ line=other_constraints.lines.begin();
line!=other_constraints.lines.end(); ++line)
if (is_constrained(line->line) == false)
lines.push_back (*line);
else
{
- // the constrained dof we want to
- // copy from the other object is also
- // constrained here. let's see what
- // we should do with that
- switch (merge_conflict_behavior)
- {
- case no_conflicts_allowed:
- AssertThrow (false,
- ExcDoFIsConstrainedFromBothObjects (line->line));
- break;
-
- case left_object_wins:
- // ignore this constraint
- break;
-
- case right_object_wins:
- // we need to replace the
- // existing constraint by
- // the one from the other
- // object
- lines[lines_cache[calculate_line_index(line->line)]].entries
- = line->entries;
- lines[lines_cache[calculate_line_index(line->line)]].inhomogeneity
- = line->inhomogeneity;
- break;
-
- default:
- Assert (false, ExcNotImplemented());
- }
+ // the constrained dof we want to
+ // copy from the other object is also
+ // constrained here. let's see what
+ // we should do with that
+ switch (merge_conflict_behavior)
+ {
+ case no_conflicts_allowed:
+ AssertThrow (false,
+ ExcDoFIsConstrainedFromBothObjects (line->line));
+ break;
+
+ case left_object_wins:
+ // ignore this constraint
+ break;
+
+ case right_object_wins:
+ // we need to replace the
+ // existing constraint by
+ // the one from the other
+ // object
+ lines[lines_cache[calculate_line_index(line->line)]].entries
+ = line->entries;
+ lines[lines_cache[calculate_line_index(line->line)]].inhomogeneity
+ = line->inhomogeneity;
+ break;
+
+ default:
+ Assert (false, ExcNotImplemented());
+ }
}
- // update the lines cache
+ // update the lines cache
unsigned int counter = 0;
for (std::vector<ConstraintLine>::const_iterator line=lines.begin();
line!=lines.end(); ++line, ++counter)
lines_cache[calculate_line_index(line->line)] = counter;
- // if the object was sorted before,
- // then make sure it is so
- // afterward as well. otherwise
- // leave everything in the unsorted
- // state
+ // if the object was sorted before,
+ // then make sure it is so
+ // afterward as well. otherwise
+ // leave everything in the unsorted
+ // state
if (object_was_sorted == true)
close ();
}
void ConstraintMatrix::shift (const unsigned int offset)
{
- //TODO: this doesn't work with IndexSets yet. [TH]
+ //TODO: this doesn't work with IndexSets yet. [TH]
AssertThrow(local_lines.size()==0, ExcNotImplemented());
lines_cache.insert (lines_cache.begin(), offset,
- numbers::invalid_unsigned_int);
+ numbers::invalid_unsigned_int);
for (std::vector<ConstraintLine>::iterator i = lines.begin();
i != lines.end(); ++i)
{
i->line += offset;
for (ConstraintLine::Entries::iterator
- j = i->entries.begin();
- j != i->entries.end(); ++j)
- j->first += offset;
+ j = i->entries.begin();
+ j != i->entries.end(); ++j)
+ j->first += offset;
}
}
void ConstraintMatrix::condense (const SparsityPattern &uncondensed,
- SparsityPattern &condensed) const
+ SparsityPattern &condensed) const
{
Assert (sorted == true, ExcMatrixNotClosed());
Assert (uncondensed.is_compressed() == true, ExcMatrixNotClosed());
Assert (uncondensed.n_rows() == uncondensed.n_cols(),
- ExcNotQuadratic());
+ ExcNotQuadratic());
- // store for each line of the matrix
- // its new line number
- // after compression. If the shift is
- // -1, this line will be condensed away
+ // store for each line of the matrix
+ // its new line number
+ // after compression. If the shift is
+ // -1, this line will be condensed away
std::vector<int> new_line;
new_line.reserve (uncondensed.n_rows());
unsigned int n_rows = uncondensed.n_rows();
if (next_constraint == lines.end())
- // if no constraint is to be handled
+ // if no constraint is to be handled
for (unsigned int row=0; row!=n_rows; ++row)
new_line.push_back (row);
else
for (unsigned int row=0; row!=n_rows; ++row)
if (row == next_constraint->line)
- {
- // this line is constrained
- new_line.push_back (-1);
- // note that @p{lines} is ordered
- ++shift;
- ++next_constraint;
- if (next_constraint == lines.end())
- // nothing more to do; finish rest
- // of loop
- {
- for (unsigned int i=row+1; i<n_rows; ++i)
- new_line.push_back (i-shift);
- break;
- };
- }
+ {
+ // this line is constrained
+ new_line.push_back (-1);
+ // note that @p{lines} is ordered
+ ++shift;
+ ++next_constraint;
+ if (next_constraint == lines.end())
+ // nothing more to do; finish rest
+ // of loop
+ {
+ for (unsigned int i=row+1; i<n_rows; ++i)
+ new_line.push_back (i-shift);
+ break;
+ };
+ }
else
- new_line.push_back (row-shift);
+ new_line.push_back (row-shift);
next_constraint = lines.begin();
- // note: in this loop we need not check
- // whether @p{next_constraint} is a valid
- // iterator, since @p{next_constraint} is
- // only evaluated so often as there are
- // entries in new_line[*] which tells us
- // which constraints exist
+ // note: in this loop we need not check
+ // whether @p{next_constraint} is a valid
+ // iterator, since @p{next_constraint} is
+ // only evaluated so often as there are
+ // entries in new_line[*] which tells us
+ // which constraints exist
for (unsigned int row=0; row<uncondensed.n_rows(); ++row)
if (new_line[row] != -1)
- // line not constrained
- // copy entries if column will not
- // be condensed away, distribute
- // otherwise
+ // line not constrained
+ // copy entries if column will not
+ // be condensed away, distribute
+ // otherwise
for (unsigned int j=uncondensed.get_rowstart_indices()[row];
- j<uncondensed.get_rowstart_indices()[row+1]; ++j)
- if (new_line[uncondensed.get_column_numbers()[j]] != -1)
- condensed.add (new_line[row], new_line[uncondensed.get_column_numbers()[j]]);
- else
- {
- // let c point to the constraint
- // of this column
- std::vector<ConstraintLine>::const_iterator c = lines.begin();
- while (c->line != uncondensed.get_column_numbers()[j])
- ++c;
-
- for (unsigned int q=0; q!=c->entries.size(); ++q)
- condensed.add (new_line[row], new_line[c->entries[q].first]);
- }
+ j<uncondensed.get_rowstart_indices()[row+1]; ++j)
+ if (new_line[uncondensed.get_column_numbers()[j]] != -1)
+ condensed.add (new_line[row], new_line[uncondensed.get_column_numbers()[j]]);
+ else
+ {
+ // let c point to the constraint
+ // of this column
+ std::vector<ConstraintLine>::const_iterator c = lines.begin();
+ while (c->line != uncondensed.get_column_numbers()[j])
+ ++c;
+
+ for (unsigned int q=0; q!=c->entries.size(); ++q)
+ condensed.add (new_line[row], new_line[c->entries[q].first]);
+ }
else
- // line must be distributed
+ // line must be distributed
{
- for (unsigned int j=uncondensed.get_rowstart_indices()[row];
- j<uncondensed.get_rowstart_indices()[row+1]; ++j)
- // for each entry: distribute
- if (new_line[uncondensed.get_column_numbers()[j]] != -1)
- // column is not constrained
- for (unsigned int q=0; q!=next_constraint->entries.size(); ++q)
- condensed.add (new_line[next_constraint->entries[q].first],
- new_line[uncondensed.get_column_numbers()[j]]);
-
- else
- // not only this line but
- // also this col is constrained
- {
- // let c point to the constraint
- // of this column
- std::vector<ConstraintLine>::const_iterator c = lines.begin();
- while (c->line != uncondensed.get_column_numbers()[j]) ++c;
-
- for (unsigned int p=0; p!=c->entries.size(); ++p)
- for (unsigned int q=0; q!=next_constraint->entries.size(); ++q)
- condensed.add (new_line[next_constraint->entries[q].first],
- new_line[c->entries[p].first]);
- };
-
- ++next_constraint;
+ for (unsigned int j=uncondensed.get_rowstart_indices()[row];
+ j<uncondensed.get_rowstart_indices()[row+1]; ++j)
+ // for each entry: distribute
+ if (new_line[uncondensed.get_column_numbers()[j]] != -1)
+ // column is not constrained
+ for (unsigned int q=0; q!=next_constraint->entries.size(); ++q)
+ condensed.add (new_line[next_constraint->entries[q].first],
+ new_line[uncondensed.get_column_numbers()[j]]);
+
+ else
+ // not only this line but
+ // also this col is constrained
+ {
+ // let c point to the constraint
+ // of this column
+ std::vector<ConstraintLine>::const_iterator c = lines.begin();
+ while (c->line != uncondensed.get_column_numbers()[j]) ++c;
+
+ for (unsigned int p=0; p!=c->entries.size(); ++p)
+ for (unsigned int q=0; q!=next_constraint->entries.size(); ++q)
+ condensed.add (new_line[next_constraint->entries[q].first],
+ new_line[c->entries[p].first]);
+ };
+
+ ++next_constraint;
};
condensed.compress();
Assert (sorted == true, ExcMatrixNotClosed());
Assert (sparsity.is_compressed() == false, ExcMatrixIsClosed());
Assert (sparsity.n_rows() == sparsity.n_cols(),
- ExcNotQuadratic());
-
- // store for each index whether it must be
- // distributed or not. If entry is
- // numbers::invalid_unsigned_int,
- // no distribution is necessary.
- // otherwise, the number states which line
- // in the constraint matrix handles this
- // index
+ ExcNotQuadratic());
+
+ // store for each index whether it must be
+ // distributed or not. If entry is
+ // numbers::invalid_unsigned_int,
+ // no distribution is necessary.
+ // otherwise, the number states which line
+ // in the constraint matrix handles this
+ // index
std::vector<unsigned int> distribute(sparsity.n_rows(),
numbers::invalid_unsigned_int);
for (unsigned int row=0; row<n_rows; ++row)
{
if (distribute[row] == numbers::invalid_unsigned_int)
- {
- // regular line. loop over cols all
- // valid cols. note that this
- // changes the line we are
- // presently working on: we add
- // additional entries. these are
- // put to the end of the
- // row. however, as constrained
- // nodes cannot be constrained to
- // other constrained nodes, nothing
- // will happen if we run into these
- // added nodes, as they can't be
- // distributed further. we might
- // store the position of the last
- // old entry and stop work there,
- // but since operating on the newly
- // added ones only takes two
- // comparisons (column index valid,
- // distribute[column] necessarily
- // ==numbers::invalid_unsigned_int),
- // it is cheaper to not do so and
- // run right until the end of the
- // line
+ {
+ // regular line. loop over cols all
+ // valid cols. note that this
+ // changes the line we are
+ // presently working on: we add
+ // additional entries. these are
+ // put to the end of the
+ // row. however, as constrained
+ // nodes cannot be constrained to
+ // other constrained nodes, nothing
+ // will happen if we run into these
+ // added nodes, as they can't be
+ // distributed further. we might
+ // store the position of the last
+ // old entry and stop work there,
+ // but since operating on the newly
+ // added ones only takes two
+ // comparisons (column index valid,
+ // distribute[column] necessarily
+ // ==numbers::invalid_unsigned_int),
+ // it is cheaper to not do so and
+ // run right until the end of the
+ // line
for (SparsityPattern::iterator entry = sparsity.begin(row);
((entry != sparsity.end(row)) &&
entry->is_valid_entry());
++entry)
- {
- const unsigned int column = entry->column();
+ {
+ const unsigned int column = entry->column();
if (distribute[column] != numbers::invalid_unsigned_int)
{
sparsity.add (row,
lines[distribute[column]].entries[q].first);
}
- }
- }
+ }
+ }
else
- // row must be
- // distributed. note that
- // here the present row is
- // not touched (unlike above)
- {
+ // row must be
+ // distributed. note that
+ // here the present row is
+ // not touched (unlike above)
+ {
for (SparsityPattern::iterator entry = sparsity.begin(row);
(entry != sparsity.end(row)) && entry->is_valid_entry(); ++entry)
{
sparsity.add (lines[distribute[row]].entries[p].first,
lines[distribute[column]].entries[q].first);
}
- }
+ }
}
sparsity.compress();
{
Assert (sorted == true, ExcMatrixNotClosed());
Assert (sparsity.n_rows() == sparsity.n_cols(),
- ExcNotQuadratic());
-
- // store for each index whether it must be
- // distributed or not. If entry is
- // numbers::invalid_unsigned_int,
- // no distribution is necessary.
- // otherwise, the number states which line
- // in the constraint matrix handles this
- // index
+ ExcNotQuadratic());
+
+ // store for each index whether it must be
+ // distributed or not. If entry is
+ // numbers::invalid_unsigned_int,
+ // no distribution is necessary.
+ // otherwise, the number states which line
+ // in the constraint matrix handles this
+ // index
std::vector<unsigned int> distribute(sparsity.n_rows(),
numbers::invalid_unsigned_int);
for (unsigned int row=0; row<n_rows; ++row)
{
if (distribute[row] == numbers::invalid_unsigned_int)
- // regular line. loop over
- // cols. note that as we
- // proceed to distribute
- // cols, the loop may get
- // longer
- for (unsigned int j=0; j<sparsity.row_length(row); ++j)
- {
- const unsigned int column = sparsity.column_number(row,j);
-
- if (distribute[column] != numbers::invalid_unsigned_int)
- {
- // distribute entry
- // at regular row
- // @p{row} and
- // irregular column
- // column. note that
- // this changes the
- // line we are
- // presently working
- // on: we add
- // additional
- // entries. if we add
- // another entry at a
- // column behind the
- // present one, we
- // will encounter it
- // later on (but
- // since it can't be
- // further
- // constrained, won't
- // have to do
- // anything about
- // it). if we add it
- // up front of the
- // present column, we
- // will find the
- // present column
- // later on again as
- // it was shifted
- // back (again
- // nothing happens,
- // in particular no
- // endless loop, as
- // when we encounter
- // it the second time
- // we won't be able
- // to add more
- // entries as they
- // all already exist,
- // but we do the same
- // work more often
- // than necessary,
- // and the loop gets
- // longer), so move
- // the cursor one to
- // the right in the
- // case that we add
- // an entry up front
- // that did not exist
- // before. check
- // whether it existed
- // before by tracking
- // the length of this
- // row
- unsigned int old_rowlength = sparsity.row_length(row);
- for (unsigned int q=0;
- q!=lines[distribute[column]].entries.size();
- ++q)
- {
- const unsigned int
- new_col = lines[distribute[column]].entries[q].first;
-
- sparsity.add (row, new_col);
-
- const unsigned int new_rowlength = sparsity.row_length(row);
- if ((new_col < column) && (old_rowlength != new_rowlength))
- ++j;
- old_rowlength = new_rowlength;
- };
- };
- }
+ // regular line. loop over
+ // cols. note that as we
+ // proceed to distribute
+ // cols, the loop may get
+ // longer
+ for (unsigned int j=0; j<sparsity.row_length(row); ++j)
+ {
+ const unsigned int column = sparsity.column_number(row,j);
+
+ if (distribute[column] != numbers::invalid_unsigned_int)
+ {
+ // distribute entry
+ // at regular row
+ // @p{row} and
+ // irregular column
+ // column. note that
+ // this changes the
+ // line we are
+ // presently working
+ // on: we add
+ // additional
+ // entries. if we add
+ // another entry at a
+ // column behind the
+ // present one, we
+ // will encounter it
+ // later on (but
+ // since it can't be
+ // further
+ // constrained, won't
+ // have to do
+ // anything about
+ // it). if we add it
+ // up front of the
+ // present column, we
+ // will find the
+ // present column
+ // later on again as
+ // it was shifted
+ // back (again
+ // nothing happens,
+ // in particular no
+ // endless loop, as
+ // when we encounter
+ // it the second time
+ // we won't be able
+ // to add more
+ // entries as they
+ // all already exist,
+ // but we do the same
+ // work more often
+ // than necessary,
+ // and the loop gets
+ // longer), so move
+ // the cursor one to
+ // the right in the
+ // case that we add
+ // an entry up front
+ // that did not exist
+ // before. check
+ // whether it existed
+ // before by tracking
+ // the length of this
+ // row
+ unsigned int old_rowlength = sparsity.row_length(row);
+ for (unsigned int q=0;
+ q!=lines[distribute[column]].entries.size();
+ ++q)
+ {
+ const unsigned int
+ new_col = lines[distribute[column]].entries[q].first;
+
+ sparsity.add (row, new_col);
+
+ const unsigned int new_rowlength = sparsity.row_length(row);
+ if ((new_col < column) && (old_rowlength != new_rowlength))
+ ++j;
+ old_rowlength = new_rowlength;
+ };
+ };
+ }
else
- // row must be distributed
- for (unsigned int j=0; j<sparsity.row_length(row); ++j)
- {
- const unsigned int column = sparsity.column_number(row,j);
-
- if (distribute[column] == numbers::invalid_unsigned_int)
- // distribute entry at irregular
- // row @p{row} and regular column
- // sparsity.colnums[j]
- for (unsigned int q=0;
- q!=lines[distribute[row]].entries.size(); ++q)
- sparsity.add (lines[distribute[row]].entries[q].first,
- column);
- else
- // distribute entry at irregular
- // row @p{row} and irregular column
- // sparsity.get_column_numbers()[j]
- for (unsigned int p=0; p!=lines[distribute[row]].entries.size(); ++p)
- for (unsigned int q=0;
- q!=lines[distribute[sparsity.column_number(row,j)]]
- .entries.size(); ++q)
- sparsity.add (lines[distribute[row]].entries[p].first,
- lines[distribute[sparsity.column_number(row,j)]]
- .entries[q].first);
- };
+ // row must be distributed
+ for (unsigned int j=0; j<sparsity.row_length(row); ++j)
+ {
+ const unsigned int column = sparsity.column_number(row,j);
+
+ if (distribute[column] == numbers::invalid_unsigned_int)
+ // distribute entry at irregular
+ // row @p{row} and regular column
+ // sparsity.colnums[j]
+ for (unsigned int q=0;
+ q!=lines[distribute[row]].entries.size(); ++q)
+ sparsity.add (lines[distribute[row]].entries[q].first,
+ column);
+ else
+ // distribute entry at irregular
+ // row @p{row} and irregular column
+ // sparsity.get_column_numbers()[j]
+ for (unsigned int p=0; p!=lines[distribute[row]].entries.size(); ++p)
+ for (unsigned int q=0;
+ q!=lines[distribute[sparsity.column_number(row,j)]]
+ .entries.size(); ++q)
+ sparsity.add (lines[distribute[row]].entries[p].first,
+ lines[distribute[sparsity.column_number(row,j)]]
+ .entries[q].first);
+ };
};
}
{
Assert (sorted == true, ExcMatrixNotClosed());
Assert (sparsity.n_rows() == sparsity.n_cols(),
- ExcNotQuadratic());
-
- // store for each index whether it must be
- // distributed or not. If entry is
- // numbers::invalid_unsigned_int,
- // no distribution is necessary.
- // otherwise, the number states which line
- // in the constraint matrix handles this
- // index
+ ExcNotQuadratic());
+
+ // store for each index whether it must be
+ // distributed or not. If entry is
+ // numbers::invalid_unsigned_int,
+ // no distribution is necessary.
+ // otherwise, the number states which line
+ // in the constraint matrix handles this
+ // index
std::vector<unsigned int> distribute(sparsity.n_rows(),
numbers::invalid_unsigned_int);
for (unsigned int row=0; row<n_rows; ++row)
{
if (distribute[row] == numbers::invalid_unsigned_int)
- {
- // regular line. loop over
- // cols. note that as we proceed to
- // distribute cols, the loop may
- // get longer
- CompressedSetSparsityPattern::row_iterator col_num = sparsity.row_begin (row);
-
- for (; col_num != sparsity.row_end (row); ++col_num)
- {
- const unsigned int column = *col_num;
-
- if (distribute[column] != numbers::invalid_unsigned_int)
- {
- // row
- for (unsigned int q=0;
- q!=lines[distribute[column]].entries.size();
- ++q)
- {
- const unsigned int
- new_col = lines[distribute[column]].entries[q].first;
-
- sparsity.add (row, new_col);
- }
- }
- }
- }
+ {
+ // regular line. loop over
+ // cols. note that as we proceed to
+ // distribute cols, the loop may
+ // get longer
+ CompressedSetSparsityPattern::row_iterator col_num = sparsity.row_begin (row);
+
+ for (; col_num != sparsity.row_end (row); ++col_num)
+ {
+ const unsigned int column = *col_num;
+
+ if (distribute[column] != numbers::invalid_unsigned_int)
+ {
+ // row
+ for (unsigned int q=0;
+ q!=lines[distribute[column]].entries.size();
+ ++q)
+ {
+ const unsigned int
+ new_col = lines[distribute[column]].entries[q].first;
+
+ sparsity.add (row, new_col);
+ }
+ }
+ }
+ }
else
- // row must be distributed
- {
- CompressedSetSparsityPattern::row_iterator col_num = sparsity.row_begin (row);
-
- for (; col_num != sparsity.row_end (row); ++col_num)
- {
- const unsigned int column = *col_num;
-
- if (distribute[column] == numbers::invalid_unsigned_int)
- // distribute entry at irregular
- // row @p{row} and regular column
- // sparsity.colnums[j]
- for (unsigned int q=0;
- q!=lines[distribute[row]].entries.size(); ++q)
- sparsity.add (lines[distribute[row]].entries[q].first,
- column);
- else
- // distribute entry at irregular
- // row @p{row} and irregular column
- // sparsity.get_column_numbers()[j]
- for (unsigned int p=0; p!=lines[distribute[row]].entries.size(); ++p)
- for (unsigned int q=0;
- q!=lines[distribute[column]]
- .entries.size(); ++q)
- sparsity.add (lines[distribute[row]].entries[p].first,
- lines[distribute[column]]
- .entries[q].first);
- };
- }
+ // row must be distributed
+ {
+ CompressedSetSparsityPattern::row_iterator col_num = sparsity.row_begin (row);
+
+ for (; col_num != sparsity.row_end (row); ++col_num)
+ {
+ const unsigned int column = *col_num;
+
+ if (distribute[column] == numbers::invalid_unsigned_int)
+ // distribute entry at irregular
+ // row @p{row} and regular column
+ // sparsity.colnums[j]
+ for (unsigned int q=0;
+ q!=lines[distribute[row]].entries.size(); ++q)
+ sparsity.add (lines[distribute[row]].entries[q].first,
+ column);
+ else
+ // distribute entry at irregular
+ // row @p{row} and irregular column
+ // sparsity.get_column_numbers()[j]
+ for (unsigned int p=0; p!=lines[distribute[row]].entries.size(); ++p)
+ for (unsigned int q=0;
+ q!=lines[distribute[column]]
+ .entries.size(); ++q)
+ sparsity.add (lines[distribute[row]].entries[p].first,
+ lines[distribute[column]]
+ .entries[q].first);
+ };
+ }
};
}
{
Assert (sorted == true, ExcMatrixNotClosed());
Assert (sparsity.n_rows() == sparsity.n_cols(),
- ExcNotQuadratic());
-
- // store for each index whether it must be
- // distributed or not. If entry is
- // numbers::invalid_unsigned_int,
- // no distribution is necessary.
- // otherwise, the number states which line
- // in the constraint matrix handles this
- // index
+ ExcNotQuadratic());
+
+ // store for each index whether it must be
+ // distributed or not. If entry is
+ // numbers::invalid_unsigned_int,
+ // no distribution is necessary.
+ // otherwise, the number states which line
+ // in the constraint matrix handles this
+ // index
std::vector<unsigned int> distribute(sparsity.n_rows(),
numbers::invalid_unsigned_int);
for (unsigned int row=0; row<n_rows; ++row)
{
if (distribute[row] == numbers::invalid_unsigned_int)
- // regular line. loop over
- // cols. note that as we
- // proceed to distribute
- // cols, the loop may get
- // longer
- for (unsigned int j=0; j<sparsity.row_length(row); ++j)
- {
- const unsigned int column = sparsity.column_number(row,j);
-
- if (distribute[column] != numbers::invalid_unsigned_int)
- {
- // distribute entry
- // at regular row
- // @p{row} and
- // irregular column
- // column. note that
- // this changes the
- // line we are
- // presently working
- // on: we add
- // additional
- // entries. if we add
- // another entry at a
- // column behind the
- // present one, we
- // will encounter it
- // later on (but
- // since it can't be
- // further
- // constrained, won't
- // have to do
- // anything about
- // it). if we add it
- // up front of the
- // present column, we
- // will find the
- // present column
- // later on again as
- // it was shifted
- // back (again
- // nothing happens,
- // in particular no
- // endless loop, as
- // when we encounter
- // it the second time
- // we won't be able
- // to add more
- // entries as they
- // all already exist,
- // but we do the same
- // work more often
- // than necessary,
- // and the loop gets
- // longer), so move
- // the cursor one to
- // the right in the
- // case that we add
- // an entry up front
- // that did not exist
- // before. check
- // whether it existed
- // before by tracking
- // the length of this
- // row
- unsigned int old_rowlength = sparsity.row_length(row);
- for (unsigned int q=0;
- q!=lines[distribute[column]].entries.size();
- ++q)
- {
- const unsigned int
- new_col = lines[distribute[column]].entries[q].first;
-
- sparsity.add (row, new_col);
-
- const unsigned int new_rowlength = sparsity.row_length(row);
- if ((new_col < column) && (old_rowlength != new_rowlength))
- ++j;
- old_rowlength = new_rowlength;
- };
- };
- }
+ // regular line. loop over
+ // cols. note that as we
+ // proceed to distribute
+ // cols, the loop may get
+ // longer
+ for (unsigned int j=0; j<sparsity.row_length(row); ++j)
+ {
+ const unsigned int column = sparsity.column_number(row,j);
+
+ if (distribute[column] != numbers::invalid_unsigned_int)
+ {
+ // distribute entry
+ // at regular row
+ // @p{row} and
+ // irregular column
+ // column. note that
+ // this changes the
+ // line we are
+ // presently working
+ // on: we add
+ // additional
+ // entries. if we add
+ // another entry at a
+ // column behind the
+ // present one, we
+ // will encounter it
+ // later on (but
+ // since it can't be
+ // further
+ // constrained, won't
+ // have to do
+ // anything about
+ // it). if we add it
+ // up front of the
+ // present column, we
+ // will find the
+ // present column
+ // later on again as
+ // it was shifted
+ // back (again
+ // nothing happens,
+ // in particular no
+ // endless loop, as
+ // when we encounter
+ // it the second time
+ // we won't be able
+ // to add more
+ // entries as they
+ // all already exist,
+ // but we do the same
+ // work more often
+ // than necessary,
+ // and the loop gets
+ // longer), so move
+ // the cursor one to
+ // the right in the
+ // case that we add
+ // an entry up front
+ // that did not exist
+ // before. check
+ // whether it existed
+ // before by tracking
+ // the length of this
+ // row
+ unsigned int old_rowlength = sparsity.row_length(row);
+ for (unsigned int q=0;
+ q!=lines[distribute[column]].entries.size();
+ ++q)
+ {
+ const unsigned int
+ new_col = lines[distribute[column]].entries[q].first;
+
+ sparsity.add (row, new_col);
+
+ const unsigned int new_rowlength = sparsity.row_length(row);
+ if ((new_col < column) && (old_rowlength != new_rowlength))
+ ++j;
+ old_rowlength = new_rowlength;
+ };
+ };
+ }
else
- // row must be distributed
- for (unsigned int j=0; j<sparsity.row_length(row); ++j)
- {
- const unsigned int column = sparsity.column_number(row,j);
-
- if (distribute[column] == numbers::invalid_unsigned_int)
- // distribute entry at irregular
- // row @p{row} and regular column
- // sparsity.colnums[j]
- for (unsigned int q=0;
- q!=lines[distribute[row]].entries.size(); ++q)
- sparsity.add (lines[distribute[row]].entries[q].first,
- column);
- else
- // distribute entry at irregular
- // row @p{row} and irregular column
- // sparsity.get_column_numbers()[j]
- for (unsigned int p=0; p!=lines[distribute[row]].entries.size(); ++p)
- for (unsigned int q=0;
- q!=lines[distribute[sparsity.column_number(row,j)]]
- .entries.size(); ++q)
- sparsity.add (lines[distribute[row]].entries[p].first,
- lines[distribute[sparsity.column_number(row,j)]]
- .entries[q].first);
- };
+ // row must be distributed
+ for (unsigned int j=0; j<sparsity.row_length(row); ++j)
+ {
+ const unsigned int column = sparsity.column_number(row,j);
+
+ if (distribute[column] == numbers::invalid_unsigned_int)
+ // distribute entry at irregular
+ // row @p{row} and regular column
+ // sparsity.colnums[j]
+ for (unsigned int q=0;
+ q!=lines[distribute[row]].entries.size(); ++q)
+ sparsity.add (lines[distribute[row]].entries[q].first,
+ column);
+ else
+ // distribute entry at irregular
+ // row @p{row} and irregular column
+ // sparsity.get_column_numbers()[j]
+ for (unsigned int p=0; p!=lines[distribute[row]].entries.size(); ++p)
+ for (unsigned int q=0;
+ q!=lines[distribute[sparsity.column_number(row,j)]]
+ .entries.size(); ++q)
+ sparsity.add (lines[distribute[row]].entries[p].first,
+ lines[distribute[sparsity.column_number(row,j)]]
+ .entries[q].first);
+ };
};
}
Assert (sorted == true, ExcMatrixNotClosed());
Assert (sparsity.is_compressed() == false, ExcMatrixIsClosed());
Assert (sparsity.n_rows() == sparsity.n_cols(),
- ExcNotQuadratic());
+ ExcNotQuadratic());
Assert (sparsity.n_block_rows() == sparsity.n_block_cols(),
- ExcNotQuadratic());
+ ExcNotQuadratic());
Assert (sparsity.get_column_indices() == sparsity.get_row_indices(),
- ExcNotQuadratic());
+ ExcNotQuadratic());
const BlockIndices &
index_mapping = sparsity.get_column_indices();
const unsigned int n_blocks = sparsity.n_block_rows();
- // store for each index whether it must be
- // distributed or not. If entry is
- // numbers::invalid_unsigned_int,
- // no distribution is necessary.
- // otherwise, the number states which line
- // in the constraint matrix handles this
- // index
+ // store for each index whether it must be
+ // distributed or not. If entry is
+ // numbers::invalid_unsigned_int,
+ // no distribution is necessary.
+ // otherwise, the number states which line
+ // in the constraint matrix handles this
+ // index
std::vector<unsigned int> distribute (sparsity.n_rows(),
numbers::invalid_unsigned_int);
const unsigned int n_rows = sparsity.n_rows();
for (unsigned int row=0; row<n_rows; ++row)
{
- // get index of this row
- // within the blocks
+ // get index of this row
+ // within the blocks
const std::pair<unsigned int,unsigned int>
- block_index = index_mapping.global_to_local(row);
+ block_index = index_mapping.global_to_local(row);
const unsigned int block_row = block_index.first;
if (distribute[row] == numbers::invalid_unsigned_int)
- // regular line. loop over
- // all columns and see
- // whether this column must
- // be distributed
- {
-
- // to loop over all entries
- // in this row, we have to
- // loop over all blocks in
- // this blockrow and the
- // corresponding row
- // therein
- for (unsigned int block_col=0; block_col<n_blocks; ++block_col)
- {
- const SparsityPattern &
- block_sparsity = sparsity.block(block_row, block_col);
+ // regular line. loop over
+ // all columns and see
+ // whether this column must
+ // be distributed
+ {
+
+ // to loop over all entries
+ // in this row, we have to
+ // loop over all blocks in
+ // this blockrow and the
+ // corresponding row
+ // therein
+ for (unsigned int block_col=0; block_col<n_blocks; ++block_col)
+ {
+ const SparsityPattern &
+ block_sparsity = sparsity.block(block_row, block_col);
for (SparsityPattern::const_iterator
entry = block_sparsity.begin(block_index.second);
lines[distribute[global_col]].entries[q].first);
}
}
- }
- }
+ }
+ }
else
- {
- // row must be
- // distributed. split the
- // whole row into the
- // chunks defined by the
- // blocks
- for (unsigned int block_col=0; block_col<n_blocks; ++block_col)
- {
- const SparsityPattern &
- block_sparsity = sparsity.block(block_row,block_col);
+ {
+ // row must be
+ // distributed. split the
+ // whole row into the
+ // chunks defined by the
+ // blocks
+ for (unsigned int block_col=0; block_col<n_blocks; ++block_col)
+ {
+ const SparsityPattern &
+ block_sparsity = sparsity.block(block_row,block_col);
for (SparsityPattern::const_iterator
entry = block_sparsity.begin(block_index.second);
lines[distribute[global_col]].entries[q].first);
}
}
- }
- }
+ }
+ }
}
sparsity.compress();
{
Assert (sorted == true, ExcMatrixNotClosed());
Assert (sparsity.n_rows() == sparsity.n_cols(),
- ExcNotQuadratic());
+ ExcNotQuadratic());
Assert (sparsity.n_block_rows() == sparsity.n_block_cols(),
- ExcNotQuadratic());
+ ExcNotQuadratic());
Assert (sparsity.get_column_indices() == sparsity.get_row_indices(),
- ExcNotQuadratic());
+ ExcNotQuadratic());
const BlockIndices &
index_mapping = sparsity.get_column_indices();
const unsigned int n_blocks = sparsity.n_block_rows();
- // store for each index whether it must be
- // distributed or not. If entry is
- // numbers::invalid_unsigned_int,
- // no distribution is necessary.
- // otherwise, the number states which line
- // in the constraint matrix handles this
- // index
+ // store for each index whether it must be
+ // distributed or not. If entry is
+ // numbers::invalid_unsigned_int,
+ // no distribution is necessary.
+ // otherwise, the number states which line
+ // in the constraint matrix handles this
+ // index
std::vector<unsigned int> distribute (sparsity.n_rows(),
numbers::invalid_unsigned_int);
const unsigned int n_rows = sparsity.n_rows();
for (unsigned int row=0; row<n_rows; ++row)
{
- // get index of this row
- // within the blocks
+ // get index of this row
+ // within the blocks
const std::pair<unsigned int,unsigned int>
- block_index = index_mapping.global_to_local(row);
+ block_index = index_mapping.global_to_local(row);
const unsigned int block_row = block_index.first;
const unsigned int local_row = block_index.second;
if (distribute[row] == numbers::invalid_unsigned_int)
- // regular line. loop over
- // all columns and see
- // whether this column must
- // be distributed. note that
- // as we proceed to
- // distribute cols, the loop
- // over cols may get longer.
- //
- // don't try to be clever
- // here as in the algorithm
- // for the
- // CompressedSparsityPattern,
- // as that would be much more
- // complicated here. after
- // all, we know that
- // compressed patterns are
- // inefficient...
- {
-
- // to loop over all entries
- // in this row, we have to
- // loop over all blocks in
- // this blockrow and the
- // corresponding row
- // therein
- for (unsigned int block_col=0; block_col<n_blocks; ++block_col)
- {
- const CompressedSparsityPattern &
- block_sparsity = sparsity.block(block_row, block_col);
-
- for (unsigned int j=0; j<block_sparsity.row_length(local_row); ++j)
- {
- const unsigned int global_col
- = index_mapping.local_to_global(block_col,
- block_sparsity.column_number(local_row,j));
-
- if (distribute[global_col] != numbers::invalid_unsigned_int)
- // distribute entry at regular
- // row @p{row} and irregular column
- // global_col
- {
- for (unsigned int q=0;
- q!=lines[distribute[global_col]]
- .entries.size(); ++q)
- sparsity.add (row,
- lines[distribute[global_col]].entries[q].first);
- };
- };
- };
- }
+ // regular line. loop over
+ // all columns and see
+ // whether this column must
+ // be distributed. note that
+ // as we proceed to
+ // distribute cols, the loop
+ // over cols may get longer.
+ //
+ // don't try to be clever
+ // here as in the algorithm
+ // for the
+ // CompressedSparsityPattern,
+ // as that would be much more
+ // complicated here. after
+ // all, we know that
+ // compressed patterns are
+ // inefficient...
+ {
+
+ // to loop over all entries
+ // in this row, we have to
+ // loop over all blocks in
+ // this blockrow and the
+ // corresponding row
+ // therein
+ for (unsigned int block_col=0; block_col<n_blocks; ++block_col)
+ {
+ const CompressedSparsityPattern &
+ block_sparsity = sparsity.block(block_row, block_col);
+
+ for (unsigned int j=0; j<block_sparsity.row_length(local_row); ++j)
+ {
+ const unsigned int global_col
+ = index_mapping.local_to_global(block_col,
+ block_sparsity.column_number(local_row,j));
+
+ if (distribute[global_col] != numbers::invalid_unsigned_int)
+ // distribute entry at regular
+ // row @p{row} and irregular column
+ // global_col
+ {
+ for (unsigned int q=0;
+ q!=lines[distribute[global_col]]
+ .entries.size(); ++q)
+ sparsity.add (row,
+ lines[distribute[global_col]].entries[q].first);
+ };
+ };
+ };
+ }
else
- {
- // row must be
- // distributed. split the
- // whole row into the
- // chunks defined by the
- // blocks
- for (unsigned int block_col=0; block_col<n_blocks; ++block_col)
- {
- const CompressedSparsityPattern &
- block_sparsity = sparsity.block(block_row,block_col);
-
- for (unsigned int j=0; j<block_sparsity.row_length(local_row); ++j)
- {
- const unsigned int global_col
- = index_mapping.local_to_global (block_col,
- block_sparsity.column_number(local_row,j));
-
- if (distribute[global_col] == numbers::invalid_unsigned_int)
- // distribute entry at irregular
- // row @p{row} and regular column
- // global_col.
- {
- for (unsigned int q=0; q!=lines[distribute[row]].entries.size(); ++q)
- sparsity.add (lines[distribute[row]].entries[q].first,
- global_col);
- }
- else
- // distribute entry at irregular
- // row @p{row} and irregular column
- // @p{global_col}
- {
- for (unsigned int p=0; p!=lines[distribute[row]].entries.size(); ++p)
- for (unsigned int q=0; q!=lines[distribute[global_col]].entries.size(); ++q)
- sparsity.add (lines[distribute[row]].entries[p].first,
- lines[distribute[global_col]].entries[q].first);
- };
- };
- };
- };
+ {
+ // row must be
+ // distributed. split the
+ // whole row into the
+ // chunks defined by the
+ // blocks
+ for (unsigned int block_col=0; block_col<n_blocks; ++block_col)
+ {
+ const CompressedSparsityPattern &
+ block_sparsity = sparsity.block(block_row,block_col);
+
+ for (unsigned int j=0; j<block_sparsity.row_length(local_row); ++j)
+ {
+ const unsigned int global_col
+ = index_mapping.local_to_global (block_col,
+ block_sparsity.column_number(local_row,j));
+
+ if (distribute[global_col] == numbers::invalid_unsigned_int)
+ // distribute entry at irregular
+ // row @p{row} and regular column
+ // global_col.
+ {
+ for (unsigned int q=0; q!=lines[distribute[row]].entries.size(); ++q)
+ sparsity.add (lines[distribute[row]].entries[q].first,
+ global_col);
+ }
+ else
+ // distribute entry at irregular
+ // row @p{row} and irregular column
+ // @p{global_col}
+ {
+ for (unsigned int p=0; p!=lines[distribute[row]].entries.size(); ++p)
+ for (unsigned int q=0; q!=lines[distribute[global_col]].entries.size(); ++q)
+ sparsity.add (lines[distribute[row]].entries[p].first,
+ lines[distribute[global_col]].entries[q].first);
+ };
+ };
+ };
+ };
};
}
{
Assert (sorted == true, ExcMatrixNotClosed());
Assert (sparsity.n_rows() == sparsity.n_cols(),
- ExcNotQuadratic());
+ ExcNotQuadratic());
Assert (sparsity.n_block_rows() == sparsity.n_block_cols(),
- ExcNotQuadratic());
+ ExcNotQuadratic());
Assert (sparsity.get_column_indices() == sparsity.get_row_indices(),
- ExcNotQuadratic());
+ ExcNotQuadratic());
const BlockIndices &
index_mapping = sparsity.get_column_indices();
const unsigned int n_blocks = sparsity.n_block_rows();
- // store for each index whether it must be
- // distributed or not. If entry is
- // numbers::invalid_unsigned_int,
- // no distribution is necessary.
- // otherwise, the number states which line
- // in the constraint matrix handles this
- // index
+ // store for each index whether it must be
+ // distributed or not. If entry is
+ // numbers::invalid_unsigned_int,
+ // no distribution is necessary.
+ // otherwise, the number states which line
+ // in the constraint matrix handles this
+ // index
std::vector<unsigned int> distribute (sparsity.n_rows(),
numbers::invalid_unsigned_int);
const unsigned int n_rows = sparsity.n_rows();
for (unsigned int row=0; row<n_rows; ++row)
{
- // get index of this row
- // within the blocks
+ // get index of this row
+ // within the blocks
const std::pair<unsigned int,unsigned int>
- block_index = index_mapping.global_to_local(row);
+ block_index = index_mapping.global_to_local(row);
const unsigned int block_row = block_index.first;
const unsigned int local_row = block_index.second;
if (distribute[row] == numbers::invalid_unsigned_int)
- // regular line. loop over
- // all columns and see
- // whether this column must
- // be distributed. note that
- // as we proceed to
- // distribute cols, the loop
- // over cols may get longer.
- //
- // don't try to be clever
- // here as in the algorithm
- // for the
- // CompressedSparsityPattern,
- // as that would be much more
- // complicated here. after
- // all, we know that
- // compressed patterns are
- // inefficient...
- {
-
- // to loop over all entries
- // in this row, we have to
- // loop over all blocks in
- // this blockrow and the
- // corresponding row
- // therein
- for (unsigned int block_col=0; block_col<n_blocks; ++block_col)
- {
- const CompressedSetSparsityPattern &
- block_sparsity = sparsity.block(block_row, block_col);
-
- for (CompressedSetSparsityPattern::row_iterator
- j = block_sparsity.row_begin(local_row);
- j != block_sparsity.row_end(local_row); ++j)
- {
- const unsigned int global_col
- = index_mapping.local_to_global(block_col, *j);
-
- if (distribute[global_col] != numbers::invalid_unsigned_int)
- // distribute entry at regular
- // row @p{row} and irregular column
- // global_col
- {
- for (unsigned int q=0;
- q!=lines[distribute[global_col]]
- .entries.size(); ++q)
- sparsity.add (row,
- lines[distribute[global_col]].entries[q].first);
- };
- };
- };
- }
+ // regular line. loop over
+ // all columns and see
+ // whether this column must
+ // be distributed. note that
+ // as we proceed to
+ // distribute cols, the loop
+ // over cols may get longer.
+ //
+ // don't try to be clever
+ // here as in the algorithm
+ // for the
+ // CompressedSparsityPattern,
+ // as that would be much more
+ // complicated here. after
+ // all, we know that
+ // compressed patterns are
+ // inefficient...
+ {
+
+ // to loop over all entries
+ // in this row, we have to
+ // loop over all blocks in
+ // this blockrow and the
+ // corresponding row
+ // therein
+ for (unsigned int block_col=0; block_col<n_blocks; ++block_col)
+ {
+ const CompressedSetSparsityPattern &
+ block_sparsity = sparsity.block(block_row, block_col);
+
+ for (CompressedSetSparsityPattern::row_iterator
+ j = block_sparsity.row_begin(local_row);
+ j != block_sparsity.row_end(local_row); ++j)
+ {
+ const unsigned int global_col
+ = index_mapping.local_to_global(block_col, *j);
+
+ if (distribute[global_col] != numbers::invalid_unsigned_int)
+ // distribute entry at regular
+ // row @p{row} and irregular column
+ // global_col
+ {
+ for (unsigned int q=0;
+ q!=lines[distribute[global_col]]
+ .entries.size(); ++q)
+ sparsity.add (row,
+ lines[distribute[global_col]].entries[q].first);
+ };
+ };
+ };
+ }
else
- {
- // row must be
- // distributed. split the
- // whole row into the
- // chunks defined by the
- // blocks
- for (unsigned int block_col=0; block_col<n_blocks; ++block_col)
- {
- const CompressedSetSparsityPattern &
- block_sparsity = sparsity.block(block_row,block_col);
-
- for (CompressedSetSparsityPattern::row_iterator
- j = block_sparsity.row_begin(local_row);
- j != block_sparsity.row_end(local_row); ++j)
- {
- const unsigned int global_col
- = index_mapping.local_to_global (block_col, *j);
-
- if (distribute[global_col] == numbers::invalid_unsigned_int)
- // distribute entry at irregular
- // row @p{row} and regular column
- // global_col.
- {
- for (unsigned int q=0; q!=lines[distribute[row]].entries.size(); ++q)
- sparsity.add (lines[distribute[row]].entries[q].first,
- global_col);
- }
- else
- // distribute entry at irregular
- // row @p{row} and irregular column
- // @p{global_col}
- {
- for (unsigned int p=0; p!=lines[distribute[row]].entries.size(); ++p)
- for (unsigned int q=0; q!=lines[distribute[global_col]].entries.size(); ++q)
- sparsity.add (lines[distribute[row]].entries[p].first,
- lines[distribute[global_col]].entries[q].first);
- };
- };
- };
- };
+ {
+ // row must be
+ // distributed. split the
+ // whole row into the
+ // chunks defined by the
+ // blocks
+ for (unsigned int block_col=0; block_col<n_blocks; ++block_col)
+ {
+ const CompressedSetSparsityPattern &
+ block_sparsity = sparsity.block(block_row,block_col);
+
+ for (CompressedSetSparsityPattern::row_iterator
+ j = block_sparsity.row_begin(local_row);
+ j != block_sparsity.row_end(local_row); ++j)
+ {
+ const unsigned int global_col
+ = index_mapping.local_to_global (block_col, *j);
+
+ if (distribute[global_col] == numbers::invalid_unsigned_int)
+ // distribute entry at irregular
+ // row @p{row} and regular column
+ // global_col.
+ {
+ for (unsigned int q=0; q!=lines[distribute[row]].entries.size(); ++q)
+ sparsity.add (lines[distribute[row]].entries[q].first,
+ global_col);
+ }
+ else
+ // distribute entry at irregular
+ // row @p{row} and irregular column
+ // @p{global_col}
+ {
+ for (unsigned int p=0; p!=lines[distribute[row]].entries.size(); ++p)
+ for (unsigned int q=0; q!=lines[distribute[global_col]].entries.size(); ++q)
+ sparsity.add (lines[distribute[row]].entries[p].first,
+ lines[distribute[global_col]].entries[q].first);
+ };
+ };
+ };
+ };
};
}
{
Assert (sorted == true, ExcMatrixNotClosed());
Assert (sparsity.n_rows() == sparsity.n_cols(),
- ExcNotQuadratic());
+ ExcNotQuadratic());
Assert (sparsity.n_block_rows() == sparsity.n_block_cols(),
- ExcNotQuadratic());
+ ExcNotQuadratic());
Assert (sparsity.get_column_indices() == sparsity.get_row_indices(),
- ExcNotQuadratic());
+ ExcNotQuadratic());
const BlockIndices &
index_mapping = sparsity.get_column_indices();
const unsigned int n_blocks = sparsity.n_block_rows();
- // store for each index whether it must be
- // distributed or not. If entry is
- // numbers::invalid_unsigned_int,
- // no distribution is necessary.
- // otherwise, the number states which line
- // in the constraint matrix handles this
- // index
+ // store for each index whether it must be
+ // distributed or not. If entry is
+ // numbers::invalid_unsigned_int,
+ // no distribution is necessary.
+ // otherwise, the number states which line
+ // in the constraint matrix handles this
+ // index
std::vector<unsigned int> distribute (sparsity.n_rows(),
numbers::invalid_unsigned_int);
const unsigned int n_rows = sparsity.n_rows();
for (unsigned int row=0; row<n_rows; ++row)
{
- // get index of this row
- // within the blocks
+ // get index of this row
+ // within the blocks
const std::pair<unsigned int,unsigned int>
- block_index = index_mapping.global_to_local(row);
+ block_index = index_mapping.global_to_local(row);
const unsigned int block_row = block_index.first;
const unsigned int local_row = block_index.second;
if (distribute[row] == numbers::invalid_unsigned_int)
- // regular line. loop over
- // all columns and see
- // whether this column must
- // be distributed. note that
- // as we proceed to
- // distribute cols, the loop
- // over cols may get longer.
- //
- // don't try to be clever
- // here as in the algorithm
- // for the
- // CompressedSparsityPattern,
- // as that would be much more
- // complicated here. after
- // all, we know that
- // compressed patterns are
- // inefficient...
- {
-
- // to loop over all entries
- // in this row, we have to
- // loop over all blocks in
- // this blockrow and the
- // corresponding row
- // therein
- for (unsigned int block_col=0; block_col<n_blocks; ++block_col)
- {
- const CompressedSimpleSparsityPattern &
- block_sparsity = sparsity.block(block_row, block_col);
-
- for (unsigned int j=0; j<block_sparsity.row_length(local_row); ++j)
- {
- const unsigned int global_col
- = index_mapping.local_to_global(block_col,
- block_sparsity.column_number(local_row,j));
-
- if (distribute[global_col] != numbers::invalid_unsigned_int)
- // distribute entry at regular
- // row @p{row} and irregular column
- // global_col
- {
- for (unsigned int q=0;
- q!=lines[distribute[global_col]]
- .entries.size(); ++q)
- sparsity.add (row,
- lines[distribute[global_col]].entries[q].first);
- };
- };
- };
- }
+ // regular line. loop over
+ // all columns and see
+ // whether this column must
+ // be distributed. note that
+ // as we proceed to
+ // distribute cols, the loop
+ // over cols may get longer.
+ //
+ // don't try to be clever
+ // here as in the algorithm
+ // for the
+ // CompressedSparsityPattern,
+ // as that would be much more
+ // complicated here. after
+ // all, we know that
+ // compressed patterns are
+ // inefficient...
+ {
+
+ // to loop over all entries
+ // in this row, we have to
+ // loop over all blocks in
+ // this blockrow and the
+ // corresponding row
+ // therein
+ for (unsigned int block_col=0; block_col<n_blocks; ++block_col)
+ {
+ const CompressedSimpleSparsityPattern &
+ block_sparsity = sparsity.block(block_row, block_col);
+
+ for (unsigned int j=0; j<block_sparsity.row_length(local_row); ++j)
+ {
+ const unsigned int global_col
+ = index_mapping.local_to_global(block_col,
+ block_sparsity.column_number(local_row,j));
+
+ if (distribute[global_col] != numbers::invalid_unsigned_int)
+ // distribute entry at regular
+ // row @p{row} and irregular column
+ // global_col
+ {
+ for (unsigned int q=0;
+ q!=lines[distribute[global_col]]
+ .entries.size(); ++q)
+ sparsity.add (row,
+ lines[distribute[global_col]].entries[q].first);
+ };
+ };
+ };
+ }
else
- {
- // row must be
- // distributed. split the
- // whole row into the
- // chunks defined by the
- // blocks
- for (unsigned int block_col=0; block_col<n_blocks; ++block_col)
- {
- const CompressedSimpleSparsityPattern &
- block_sparsity = sparsity.block(block_row,block_col);
-
- for (unsigned int j=0; j<block_sparsity.row_length(local_row); ++j)
- {
- const unsigned int global_col
- = index_mapping.local_to_global (block_col,
- block_sparsity.column_number(local_row,j));
-
- if (distribute[global_col] == numbers::invalid_unsigned_int)
- // distribute entry at irregular
- // row @p{row} and regular column
- // global_col.
- {
- for (unsigned int q=0; q!=lines[distribute[row]].entries.size(); ++q)
- sparsity.add (lines[distribute[row]].entries[q].first,
- global_col);
- }
- else
- // distribute entry at irregular
- // row @p{row} and irregular column
- // @p{global_col}
- {
- for (unsigned int p=0; p!=lines[distribute[row]].entries.size(); ++p)
- for (unsigned int q=0; q!=lines[distribute[global_col]].entries.size(); ++q)
- sparsity.add (lines[distribute[row]].entries[p].first,
- lines[distribute[global_col]].entries[q].first);
- };
- };
- };
- };
+ {
+ // row must be
+ // distributed. split the
+ // whole row into the
+ // chunks defined by the
+ // blocks
+ for (unsigned int block_col=0; block_col<n_blocks; ++block_col)
+ {
+ const CompressedSimpleSparsityPattern &
+ block_sparsity = sparsity.block(block_row,block_col);
+
+ for (unsigned int j=0; j<block_sparsity.row_length(local_row); ++j)
+ {
+ const unsigned int global_col
+ = index_mapping.local_to_global (block_col,
+ block_sparsity.column_number(local_row,j));
+
+ if (distribute[global_col] == numbers::invalid_unsigned_int)
+ // distribute entry at irregular
+ // row @p{row} and regular column
+ // global_col.
+ {
+ for (unsigned int q=0; q!=lines[distribute[row]].entries.size(); ++q)
+ sparsity.add (lines[distribute[row]].entries[q].first,
+ global_col);
+ }
+ else
+ // distribute entry at irregular
+ // row @p{row} and irregular column
+ // @p{global_col}
+ {
+ for (unsigned int p=0; p!=lines[distribute[row]].entries.size(); ++p)
+ for (unsigned int q=0; q!=lines[distribute[global_col]].entries.size(); ++q)
+ sparsity.add (lines[distribute[row]].entries[p].first,
+ lines[distribute[global_col]].entries[q].first);
+ };
+ };
+ };
+ };
};
}
#ifdef DEAL_II_USE_TRILINOS
- // this is a specialization for a
- // parallel (non-block) Trilinos
- // vector. The basic idea is to just work
- // on the local range of the vector. But
- // we need access to values that the
- // local nodes are constrained to.
+ // this is a specialization for a
+ // parallel (non-block) Trilinos
+ // vector. The basic idea is to just work
+ // on the local range of the vector. But
+ // we need access to values that the
+ // local nodes are constrained to.
template<>
void
{
Assert (sorted==true, ExcMatrixIsClosed());
- //TODO: not implemented yet, we need to fix
- //LocalRange() first to only include
- //"owned" indices. For this we need to keep
- //track of the owned indices, because
- //Trilinos doesn't. Use same constructor
- //interface as in PETSc with two IndexSets!
+ //TODO: not implemented yet, we need to fix
+ //LocalRange() first to only include
+ //"owned" indices. For this we need to keep
+ //track of the owned indices, because
+ //Trilinos doesn't. Use same constructor
+ //interface as in PETSc with two IndexSets!
AssertThrow (vec.vector_partitioner().IsOneToOne(),
- ExcMessage ("Distribute does not work on vectors with overlapping parallel partitioning."));
+ ExcMessage ("Distribute does not work on vectors with overlapping parallel partitioning."));
typedef std::vector<ConstraintLine>::const_iterator constraint_iterator;
ConstraintLine index_comparison;
const constraint_iterator end_my_constraints
= Utilities::lower_bound(lines.begin(),lines.end(),index_comparison);
- // Here we search all the indices that we
- // need to have read-access to - the
- // local nodes and all the nodes that the
- // constraints indicate.
+ // Here we search all the indices that we
+ // need to have read-access to - the
+ // local nodes and all the nodes that the
+ // constraints indicate.
IndexSet my_indices (vec.size());
{
const std::pair<unsigned int, unsigned int>
std::set<unsigned int> individual_indices;
for (constraint_iterator it = begin_my_constraints;
- it != end_my_constraints; ++it)
+ it != end_my_constraints; ++it)
for (unsigned int i=0; i<it->entries.size(); ++i)
- if ((it->entries[i].first < local_range.first)
- ||
- (it->entries[i].first >= local_range.second))
- individual_indices.insert (it->entries[i].first);
+ if ((it->entries[i].first < local_range.first)
+ ||
+ (it->entries[i].first >= local_range.second))
+ individual_indices.insert (it->entries[i].first);
my_indices.add_indices (individual_indices.begin(),
- individual_indices.end());
+ individual_indices.end());
}
#ifdef DEAL_II_COMPILER_SUPPORTS_MPI
(my_indices.make_trilinos_map (MPI_COMM_WORLD, true));
#endif
- // here we import the data
+ // here we import the data
vec_distribute.reinit(vec,false,true);
for (constraint_iterator it = begin_my_constraints;
it != end_my_constraints; ++it)
{
- // fill entry in line
- // next_constraint.line by adding the
- // different contributions
+ // fill entry in line
+ // next_constraint.line by adding the
+ // different contributions
double new_value = it->inhomogeneity;
for (unsigned int i=0; i<it->entries.size(); ++i)
- new_value += (vec_distribute(it->entries[i].first) *
+ new_value += (vec_distribute(it->entries[i].first) *
it->entries[i].second);
vec(it->line) = new_value;
}
- // some processes might not apply
- // constraints, so we need to explicitly
- // state, that the others are doing an
- // insert here:
+ // some processes might not apply
+ // constraints, so we need to explicitly
+ // state, that the others are doing an
+ // insert here:
vec.compress (Insert);
}
typedef std::vector<ConstraintLine>::const_iterator constraint_iterator;
ConstraintLine index_comparison;
index_comparison.line = vec.block(block).local_range().first
- +vec.get_block_indices().block_start(block);
+ +vec.get_block_indices().block_start(block);
const constraint_iterator begin_my_constraints =
- Utilities::lower_bound (lines.begin(),lines.end(),index_comparison);
+ Utilities::lower_bound (lines.begin(),lines.end(),index_comparison);
index_comparison.line = vec.block(block).local_range().second
- +vec.get_block_indices().block_start(block);
+ +vec.get_block_indices().block_start(block);
const constraint_iterator end_my_constraints
- = Utilities::lower_bound(lines.begin(),lines.end(),index_comparison);
-
- // Here we search all the indices that we
- // need to have read-access to - the local
- // nodes and all the nodes that the
- // constraints indicate. No caching done
- // yet. would need some more clever data
- // structures for doing that.
+ = Utilities::lower_bound(lines.begin(),lines.end(),index_comparison);
+
+ // Here we search all the indices that we
+ // need to have read-access to - the local
+ // nodes and all the nodes that the
+ // constraints indicate. No caching done
+ // yet. would need some more clever data
+ // structures for doing that.
const std::pair<unsigned int, unsigned int>
- local_range = vec.block(block).local_range();
+ local_range = vec.block(block).local_range();
my_indices.add_range (local_range.first, local_range.second);
std::set<unsigned int> individual_indices;
for (constraint_iterator it = begin_my_constraints;
- it != end_my_constraints; ++it)
- for (unsigned int i=0; i<it->entries.size(); ++i)
- if ((it->entries[i].first < local_range.first)
- ||
- (it->entries[i].first >= local_range.second))
- individual_indices.insert (it->entries[i].first);
+ it != end_my_constraints; ++it)
+ for (unsigned int i=0; i<it->entries.size(); ++i)
+ if ((it->entries[i].first < local_range.first)
+ ||
+ (it->entries[i].first >= local_range.second))
+ individual_indices.insert (it->entries[i].first);
my_indices.add_indices (individual_indices.begin(),
- individual_indices.end());
+ individual_indices.end());
}
#ifdef DEAL_II_COMPILER_SUPPORTS_MPI
(my_indices.make_trilinos_map (MPI_COMM_WORLD, true));
#endif
- // here we import the data
+ // here we import the data
vec_distribute.reinit(vec,true);
for (unsigned int block=0; block<vec.n_blocks(); ++block)
typedef std::vector<ConstraintLine>::const_iterator constraint_iterator;
ConstraintLine index_comparison;
index_comparison.line = vec.block(block).local_range().first
- +vec.get_block_indices().block_start(block);
+ +vec.get_block_indices().block_start(block);
const constraint_iterator begin_my_constraints =
- Utilities::lower_bound (lines.begin(),lines.end(),index_comparison);
+ Utilities::lower_bound (lines.begin(),lines.end(),index_comparison);
index_comparison.line = vec.block(block).local_range().second
- +vec.get_block_indices().block_start(block);
+ +vec.get_block_indices().block_start(block);
const constraint_iterator end_my_constraints
- = Utilities::lower_bound(lines.begin(),lines.end(),index_comparison);
+ = Utilities::lower_bound(lines.begin(),lines.end(),index_comparison);
for (constraint_iterator it = begin_my_constraints;
- it != end_my_constraints; ++it)
- {
- // fill entry in line
- // next_constraint.line by adding the
- // different contributions
- double new_value = it->inhomogeneity;
- for (unsigned int i=0; i<it->entries.size(); ++i)
- new_value += (vec_distribute(it->entries[i].first) *
- it->entries[i].second);
- vec(it->line) = new_value;
- }
+ it != end_my_constraints; ++it)
+ {
+ // fill entry in line
+ // next_constraint.line by adding the
+ // different contributions
+ double new_value = it->inhomogeneity;
+ for (unsigned int i=0; i<it->entries.size(); ++i)
+ new_value += (vec_distribute(it->entries[i].first) *
+ it->entries[i].second);
+ vec(it->line) = new_value;
+ }
vec.block(block).compress(Insert);
}
}
#ifdef DEAL_II_USE_PETSC
- // this is a specialization for a
- // parallel (non-block) PETSc
- // vector. The basic idea is to just work
- // on the local range of the vector. But
- // we need access to values that the
- // local nodes are constrained to.
+ // this is a specialization for a
+ // parallel (non-block) PETSc
+ // vector. The basic idea is to just work
+ // on the local range of the vector. But
+ // we need access to values that the
+ // local nodes are constrained to.
template<>
void
const constraint_iterator end_my_constraints
= Utilities::lower_bound(lines.begin(),lines.end(),index_comparison);
- // all indices we need to read from
+ // all indices we need to read from
IndexSet my_indices (vec.size());
const std::pair<unsigned int, unsigned int>
it != end_my_constraints; ++it)
for (unsigned int i=0; i<it->entries.size(); ++i)
if ((it->entries[i].first < local_range.first)
- ||
- (it->entries[i].first >= local_range.second))
- individual_indices.insert (it->entries[i].first);
+ ||
+ (it->entries[i].first >= local_range.second))
+ individual_indices.insert (it->entries[i].first);
my_indices.add_indices (individual_indices.begin(),
- individual_indices.end());
+ individual_indices.end());
IndexSet local_range_is (vec.size());
local_range_is.add_range(local_range.first, local_range.second);
- // create a vector and import those indices
+ // create a vector and import those indices
PETScWrappers::MPI::Vector ghost_vec (vec.get_mpi_communicator(),
- local_range_is,
- my_indices);
+ local_range_is,
+ my_indices);
ghost_vec = vec;
ghost_vec.update_ghost_values();
- // finally do the distribution on own
- // constraints
+ // finally do the distribution on own
+ // constraints
for (constraint_iterator it = begin_my_constraints;
it != end_my_constraints; ++it)
{
- // fill entry in line
- // next_constraint.line by adding the
- // different contributions
+ // fill entry in line
+ // next_constraint.line by adding the
+ // different contributions
PetscScalar new_value = it->inhomogeneity;
for (unsigned int i=0; i<it->entries.size(); ++i)
- new_value += (PetscScalar(ghost_vec(it->entries[i].first)) *
+ new_value += (PetscScalar(ghost_vec(it->entries[i].first)) *
it->entries[i].second);
vec(it->line) = new_value;
}
const ConstraintLine & p = lines[lines_cache[calculate_line_index(index)]];
Assert (p.line == index, ExcInternalError());
- // return if an entry for this
- // line was found and if it has
- // only one entry equal to 1.0
+ // return if an entry for this
+ // line was found and if it has
+ // only one entry equal to 1.0
return ((p.entries.size() == 1) &&
- (p.entries[0].second == 1.0));
+ (p.entries[0].second == 1.0));
}
unsigned int return_value = 0;
for (std::vector<ConstraintLine>::const_iterator i=lines.begin();
i!=lines.end(); ++i)
- // use static cast, since
- // typeof(size)==std::size_t, which is !=
- // unsigned int on AIX
+ // use static cast, since
+ // typeof(size)==std::size_t, which is !=
+ // unsigned int on AIX
return_value = std::max(return_value,
- static_cast<unsigned int>(i->entries.size()));
+ static_cast<unsigned int>(i->entries.size()));
return return_value;
}
{
for (unsigned int i=0; i!=lines.size(); ++i)
{
- // output the list of
- // constraints as pairs of dofs
- // and their weights
+ // output the list of
+ // constraints as pairs of dofs
+ // and their weights
if (lines[i].entries.size() > 0)
- {
- for (unsigned int j=0; j<lines[i].entries.size(); ++j)
- out << " " << lines[i].line
- << " " << lines[i].entries[j].first
- << ": " << lines[i].entries[j].second << "\n";
-
- // print out inhomogeneity.
- if (lines[i].inhomogeneity != 0)
- out << " " << lines[i].line
- << ": " << lines[i].inhomogeneity << "\n";
- }
+ {
+ for (unsigned int j=0; j<lines[i].entries.size(); ++j)
+ out << " " << lines[i].line
+ << " " << lines[i].entries[j].first
+ << ": " << lines[i].entries[j].second << "\n";
+
+ // print out inhomogeneity.
+ if (lines[i].inhomogeneity != 0)
+ out << " " << lines[i].line
+ << ": " << lines[i].inhomogeneity << "\n";
+ }
else
- // but also output something
- // if the constraint simply
- // reads x[13]=0, i.e. where
- // the right hand side is not
- // a linear combination of
- // other dofs
- {
- if (lines[i].inhomogeneity != 0)
- out << " " << lines[i].line
- << " = " << lines[i].inhomogeneity
- << "\n";
- else
- out << " " << lines[i].line << " = 0\n";
- }
+ // but also output something
+ // if the constraint simply
+ // reads x[13]=0, i.e. where
+ // the right hand side is not
+ // a linear combination of
+ // other dofs
+ {
+ if (lines[i].inhomogeneity != 0)
+ out << " " << lines[i].line
+ << " = " << lines[i].inhomogeneity
+ << "\n";
+ else
+ out << " " << lines[i].line << " = 0\n";
+ }
}
AssertThrow (out, ExcIO());
<< std::endl;
for (unsigned int i=0; i!=lines.size(); ++i)
{
- // same concept as in the
- // previous function
+ // same concept as in the
+ // previous function
if (lines[i].entries.size() > 0)
- for (unsigned int j=0; j<lines[i].entries.size(); ++j)
- out << " " << lines[i].line << "->" << lines[i].entries[j].first
- << "; // weight: "
- << lines[i].entries[j].second
- << "\n";
+ for (unsigned int j=0; j<lines[i].entries.size(); ++j)
+ out << " " << lines[i].line << "->" << lines[i].entries[j].first
+ << "; // weight: "
+ << lines[i].entries[j].second
+ << "\n";
else
- out << " " << lines[i].line << "\n";
+ out << " " << lines[i].line << "\n";
}
out << "}" << std::endl;
}
ConstraintMatrix::memory_consumption () const
{
return (MemoryConsumption::memory_consumption (lines) +
- MemoryConsumption::memory_consumption (lines_cache) +
- MemoryConsumption::memory_consumption (sorted) +
- MemoryConsumption::memory_consumption (local_lines));
+ MemoryConsumption::memory_consumption (lines_cache) +
+ MemoryConsumption::memory_consumption (sorted) +
+ MemoryConsumption::memory_consumption (local_lines));
}
#define VECTOR_FUNCTIONS(VectorType) \
template void ConstraintMatrix::condense<VectorType >(const VectorType &uncondensed,\
- VectorType &condensed) const;\
+ VectorType &condensed) const;\
template void ConstraintMatrix::condense<VectorType >(VectorType &vec) const;\
template void ConstraintMatrix::condense<float,VectorType >(const SparseMatrix<float> &uncondensed, \
- const VectorType &uncondensed_vector, \
- SparseMatrix<float> &condensed, \
- VectorType &condensed_vector) const; \
+ const VectorType &uncondensed_vector, \
+ SparseMatrix<float> &condensed, \
+ VectorType &condensed_vector) const; \
template void ConstraintMatrix::condense<double,VectorType >(const SparseMatrix<double> &uncondensed, \
- const VectorType &uncondensed_vector, \
- SparseMatrix<double> &condensed, \
- VectorType &condensed_vector) const; \
+ const VectorType &uncondensed_vector, \
+ SparseMatrix<double> &condensed, \
+ VectorType &condensed_vector) const; \
template void ConstraintMatrix::set_zero<VectorType >(VectorType &vec) const;\
template void ConstraintMatrix:: \
distribute_local_to_global<VectorType > (const Vector<double> &, \
const std::vector<unsigned int> &, \
VectorType &, \
- const FullMatrix<double> &) const; \
+ const FullMatrix<double> &) const; \
template void ConstraintMatrix::distribute<VectorType >(const VectorType &condensed,\
- VectorType &uncondensed) const;\
+ VectorType &uncondensed) const;\
template void ConstraintMatrix::distribute<VectorType >(VectorType &vec) const
#define PARALLEL_VECTOR_FUNCTIONS(VectorType) \
distribute_local_to_global<VectorType > (const Vector<double> &, \
const std::vector<unsigned int> &, \
VectorType &, \
- const FullMatrix<double> &) const
+ const FullMatrix<double> &) const
// TODO: Can PETSc really do all the operations required by the above
const std::vector<unsigned int> &, \
MatrixType &, \
VectorType &, \
- bool , \
+ bool , \
internal::bool2type<false>) const
#define MATRIX_FUNCTIONS(MatrixType) \
template void ConstraintMatrix:: \
const std::vector<unsigned int> &, \
MatrixType &, \
Vector<double> &, \
- bool , \
+ bool , \
internal::bool2type<false>) const
#define BLOCK_MATRIX_VECTOR_FUNCTIONS(MatrixType, VectorType) \
template void ConstraintMatrix:: \
const std::vector<unsigned int> &, \
MatrixType &, \
VectorType &, \
- bool , \
+ bool , \
internal::bool2type<true>) const
#define BLOCK_MATRIX_FUNCTIONS(MatrixType) \
template void ConstraintMatrix:: \
const std::vector<unsigned int> &, \
MatrixType &, \
Vector<double> &, \
- bool , \
+ bool , \
internal::bool2type<true>) const
MATRIX_FUNCTIONS(SparseMatrix<double>);
// $Id$
// Version: $Name$
//
-// Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2010 by the deal.II authors
+// Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2010, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
// arguments is covered by the default copy constructor and copy operator that
// is declared separately)
-#define TEMPL_OP_EQ(S1,S2) \
+#define TEMPL_OP_EQ(S1,S2) \
template FullMatrix<S1>& FullMatrix<S1>::operator = \
(const FullMatrix<S2>&)
// $Id$
// Version: $Name$
//
-// Copyright (C) 2005, 2006, 2008, 2010, 2011 by the deal.II authors
+// Copyright (C) 2005, 2006, 2008, 2010, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
template <typename number>
LAPACKFullMatrix<number>::LAPACKFullMatrix(const unsigned int n)
- :
- TransposeTable<number> (n,n),
- state(matrix)
+ :
+ TransposeTable<number> (n,n),
+ state(matrix)
{}
LAPACKFullMatrix<number>::LAPACKFullMatrix(
const unsigned int m,
const unsigned int n)
- :
- TransposeTable<number> (m,n),
- state(matrix)
+ :
+ TransposeTable<number> (m,n),
+ state(matrix)
{}
template <typename number>
LAPACKFullMatrix<number>::LAPACKFullMatrix(const LAPACKFullMatrix &M)
- :
- TransposeTable<number> (M),
- state(matrix)
+ :
+ TransposeTable<number> (M),
+ state(matrix)
{}
Vector<number> &w,
const Vector<number> &v,
const bool adding) const
-{
+{
const int mm = this->n_rows();
const int nn = this->n_cols();
const number alpha = 1.;
const number beta = (adding ? 1. : 0.);
const number null = 0.;
-
+
switch (state)
{
case matrix:
case inverse_matrix:
- {
- AssertDimension(v.size(), this->n_cols());
- AssertDimension(w.size(), this->n_rows());
-
- gemv("N", &mm, &nn, &alpha, this->data(), &mm, v.val, &one, &beta, w.val, &one);
- break;
+ {
+ AssertDimension(v.size(), this->n_cols());
+ AssertDimension(w.size(), this->n_rows());
+
+ gemv("N", &mm, &nn, &alpha, this->data(), &mm, v.val, &one, &beta, w.val, &one);
+ break;
}
case svd:
{
- AssertDimension(v.size(), this->n_cols());
- AssertDimension(w.size(), this->n_rows());
- // Compute V^T v
- work.resize(std::max(mm,nn));
- gemv("N", &nn, &nn, &alpha, svd_vt->data(), &nn, v.val, &one, &null, &work[0], &one);
- // Multiply by singular values
- for (unsigned int i=0;i<wr.size();++i)
- work[i] *= wr[i];
- // Multiply with U
- gemv("N", &mm, &mm, &alpha, svd_u->data(), &mm, &work[0], &one, &beta, w.val, &one);
- break;
+ AssertDimension(v.size(), this->n_cols());
+ AssertDimension(w.size(), this->n_rows());
+ // Compute V^T v
+ work.resize(std::max(mm,nn));
+ gemv("N", &nn, &nn, &alpha, svd_vt->data(), &nn, v.val, &one, &null, &work[0], &one);
+ // Multiply by singular values
+ for (unsigned int i=0;i<wr.size();++i)
+ work[i] *= wr[i];
+ // Multiply with U
+ gemv("N", &mm, &mm, &alpha, svd_u->data(), &mm, &work[0], &one, &beta, w.val, &one);
+ break;
}
case inverse_svd:
{
- AssertDimension(w.size(), this->n_cols());
- AssertDimension(v.size(), this->n_rows());
- // Compute U^T v
- work.resize(std::max(mm,nn));
- gemv("T", &mm, &mm, &alpha, svd_u->data(), &mm, v.val, &one, &null, &work[0], &one);
- // Multiply by singular values
- for (unsigned int i=0;i<wr.size();++i)
- work[i] *= wr[i];
- // Multiply with V
- gemv("T", &nn, &nn, &alpha, svd_vt->data(), &nn, &work[0], &one, &beta, w.val, &one);
- break;
+ AssertDimension(w.size(), this->n_cols());
+ AssertDimension(v.size(), this->n_rows());
+ // Compute U^T v
+ work.resize(std::max(mm,nn));
+ gemv("T", &mm, &mm, &alpha, svd_u->data(), &mm, v.val, &one, &null, &work[0], &one);
+ // Multiply by singular values
+ for (unsigned int i=0;i<wr.size();++i)
+ work[i] *= wr[i];
+ // Multiply with V
+ gemv("T", &nn, &nn, &alpha, svd_vt->data(), &nn, &work[0], &one, &beta, w.val, &one);
+ break;
}
default:
- Assert (false, ExcState(state));
+ Assert (false, ExcState(state));
}
}
const number alpha = 1.;
const number beta = (adding ? 1. : 0.);
const number null = 0.;
-
+
switch (state)
{
case matrix:
case inverse_matrix:
- {
- AssertDimension(w.size(), this->n_cols());
- AssertDimension(v.size(), this->n_rows());
-
- gemv("T", &mm, &nn, &alpha, this->data(), &mm, v.val, &one, &beta, w.val, &one);
- break;
+ {
+ AssertDimension(w.size(), this->n_cols());
+ AssertDimension(v.size(), this->n_rows());
+
+ gemv("T", &mm, &nn, &alpha, this->data(), &mm, v.val, &one, &beta, w.val, &one);
+ break;
}
case svd:
{
- AssertDimension(w.size(), this->n_cols());
- AssertDimension(v.size(), this->n_rows());
-
- // Compute U^T v
- work.resize(std::max(mm,nn));
- gemv("T", &mm, &mm, &alpha, svd_u->data(), &mm, v.val, &one, &null, &work[0], &one);
- // Multiply by singular values
- for (unsigned int i=0;i<wr.size();++i)
- work[i] *= wr[i];
- // Multiply with V
- gemv("T", &nn, &nn, &alpha, svd_vt->data(), &nn, &work[0], &one, &beta, w.val, &one);
- break;
+ AssertDimension(w.size(), this->n_cols());
+ AssertDimension(v.size(), this->n_rows());
+
+ // Compute U^T v
+ work.resize(std::max(mm,nn));
+ gemv("T", &mm, &mm, &alpha, svd_u->data(), &mm, v.val, &one, &null, &work[0], &one);
+ // Multiply by singular values
+ for (unsigned int i=0;i<wr.size();++i)
+ work[i] *= wr[i];
+ // Multiply with V
+ gemv("T", &nn, &nn, &alpha, svd_vt->data(), &nn, &work[0], &one, &beta, w.val, &one);
+ break;
case inverse_svd:
{
- AssertDimension(v.size(), this->n_cols());
- AssertDimension(w.size(), this->n_rows());
-
- // Compute V^T v
- work.resize(std::max(mm,nn));
- gemv("N", &nn, &nn, &alpha, svd_vt->data(), &nn, v.val, &one, &null, &work[0], &one);
- // Multiply by singular values
- for (unsigned int i=0;i<wr.size();++i)
- work[i] *= wr[i];
- // Multiply with U
- gemv("N", &mm, &mm, &alpha, svd_u->data(), &mm, &work[0], &one, &beta, w.val, &one);
- break;
+ AssertDimension(v.size(), this->n_cols());
+ AssertDimension(w.size(), this->n_rows());
+
+ // Compute V^T v
+ work.resize(std::max(mm,nn));
+ gemv("N", &nn, &nn, &alpha, svd_vt->data(), &nn, v.val, &one, &null, &work[0], &one);
+ // Multiply by singular values
+ for (unsigned int i=0;i<wr.size();++i)
+ work[i] *= wr[i];
+ // Multiply with U
+ gemv("N", &mm, &mm, &alpha, svd_u->data(), &mm, &work[0], &one, &beta, w.val, &one);
+ break;
}
}
default:
- Assert (false, ExcState(state));
+ Assert (false, ExcState(state));
}
}
{
Assert(state == matrix, ExcState(state));
state = LAPACKSupport::unusable;
-
+
const int mm = this->n_rows();
const int nn = this->n_cols();
number* values = const_cast<number*> (this->data());
wr.resize(std::max(mm,nn));
std::fill(wr.begin(), wr.end(), 0.);
ipiv.resize(8*mm);
-
+
svd_u.reset (new LAPACKFullMatrix<number>(mm,mm));
svd_vt.reset (new LAPACKFullMatrix<number>(nn,nn));
number* mu = const_cast<number*> (svd_u->data());
number* mvt = const_cast<number*> (svd_vt->data());
int info = 0;
- // see comment on this #if
- // below. Another reason to love Petsc
+ // see comment on this #if
+ // below. Another reason to love Petsc
#ifndef DEAL_II_LIBLAPACK_NOQUERYMODE
- // First determine optimal
- // workspace size
+ // First determine optimal
+ // workspace size
work.resize(1);
int lwork = -1;
gesdd(&LAPACKSupport::A, &mm, &nn, values, &mm,
- &wr[0], mu, &mm, mvt, &nn,
- &work[0], &lwork, &ipiv[0], &info);
+ &wr[0], mu, &mm, mvt, &nn,
+ &work[0], &lwork, &ipiv[0], &info);
AssertThrow (info==0, LAPACKSupport::ExcErrorCode("gesdd", info));
- // Now resize work array and
+ // Now resize work array and
lwork = static_cast<int>(work[0] + .5);
#else
int lwork = 3*std::min(mm,nn) +
- std::max(std::max(mm,nn),4*std::min(mm,nn)*std::min(mm,nn)+4*std::min(mm,nn));
+ std::max(std::max(mm,nn),4*std::min(mm,nn)*std::min(mm,nn)+4*std::min(mm,nn));
#endif
work.resize(lwork);
- // Do the actual SVD.
+ // Do the actual SVD.
gesdd(&LAPACKSupport::A, &mm, &nn, values, &mm,
- &wr[0], mu, &mm, mvt, &nn,
- &work[0], &lwork, &ipiv[0], &info);
+ &wr[0], mu, &mm, mvt, &nn,
+ &work[0], &lwork, &ipiv[0], &info);
AssertThrow (info==0, LAPACKSupport::ExcErrorCode("gesdd", info));
work.resize(0);
ipiv.resize(0);
-
+
state = LAPACKSupport::svd;
}
{
if (state == LAPACKSupport::matrix)
compute_svd();
-
+
Assert (state==LAPACKSupport::svd, ExcState(state));
-
+
const double lim = wr[0]*threshold;
for (unsigned int i=0;i<wr.size();++i)
{
if (wr[i] > lim)
- wr[i] = 1./wr[i];
+ wr[i] = 1./wr[i];
else
- wr[i] = 0.;
+ wr[i] = 0.;
}
state = LAPACKSupport::inverse_svd;
}
LAPACKFullMatrix<number>::invert()
{
Assert(state == matrix || state == lu,
- ExcState(state));
+ ExcState(state));
const int mm = this->n_rows();
const int nn = this->n_cols();
Assert (nn == mm, ExcNotQuadratic());
template <typename number>
void
LAPACKFullMatrix<number>::apply_lu_factorization(Vector<number>& v,
- const bool transposed) const
+ const bool transposed) const
{
Assert(state == lu, ExcState(state));
Assert(this->n_rows() == this->n_cols(),
- LACExceptions::ExcNotQuadratic());
+ LACExceptions::ExcNotQuadratic());
const char* trans = transposed ? &T : &N;
const int nn = this->n_cols();
int info = 0;
getrs(trans, &nn, &one, values, &nn, &ipiv[0],
- v.begin(), &nn, &info);
+ v.begin(), &nn, &info);
AssertThrow(info == 0, ExcInternalError());
}
const char * const jobvr = (right) ? (&V) : (&N);
const char * const jobvl = (left) ? (&V) : (&N);
- // Optimal workspace query:
-
- // The LAPACK routine DGEEV requires
- // a sufficient large workspace variable,
- // minimum requirement is
- // work.size>=4*nn.
- // However, to improve performance, a
- // somewhat larger workspace may be needed.
-
- // SOME implementations of the LAPACK routine
- // provide a workspace query call,
- // info:=0, lwork:=-1
- // which returns an optimal value for the
- // size of the workspace array
- // (the PETSc 2.3.0 implementation does NOT
- // provide this functionality!).
-
- // define the DEAL_II_LIBLAPACK_NOQUERYMODE flag to
- // disable the workspace query.
+ // Optimal workspace query:
+
+ // The LAPACK routine DGEEV requires
+ // a sufficient large workspace variable,
+ // minimum requirement is
+ // work.size>=4*nn.
+ // However, to improve performance, a
+ // somewhat larger workspace may be needed.
+
+ // SOME implementations of the LAPACK routine
+ // provide a workspace query call,
+ // info:=0, lwork:=-1
+ // which returns an optimal value for the
+ // size of the workspace array
+ // (the PETSc 2.3.0 implementation does NOT
+ // provide this functionality!).
+
+ // define the DEAL_II_LIBLAPACK_NOQUERYMODE flag to
+ // disable the workspace query.
#ifndef DEAL_II_LIBLAPACK_NOQUERYMODE
lwork = -1;
work.resize(1);
&wr[0], &wi[0],
&vl[0], &nn, &vr[0], &nn,
&work[0], &lwork, &info);
- // geev returns info=0 on
- // success. Since we only queried
- // the optimal size for work,
- // everything else would not be
- // acceptable.
+ // geev returns info=0 on
+ // success. Since we only queried
+ // the optimal size for work,
+ // everything else would not be
+ // acceptable.
Assert (info == 0, ExcInternalError());
- // Allocate working array according
- // to suggestion.
+ // Allocate working array according
+ // to suggestion.
lwork = (int) (work[0]+.1);
#else
lwork = 4*nn; // no query mode
#endif
- // resize workspace array
+ // resize workspace array
work.resize((unsigned int) lwork);
- // Finally compute the eigenvalues.
+ // Finally compute the eigenvalues.
geev(jobvl, jobvr, &nn, values, &nn,
&wr[0], &wi[0],
&vl[0], &nn, &vr[0], &nn,
&work[0], &lwork, &info);
- // Negative return value implies a
- // wrong argument. This should be
- // internal.
+ // Negative return value implies a
+ // wrong argument. This should be
+ // internal.
Assert (info >=0, ExcInternalError());
//TODO:[GK] What if the QR method fails?
number* values_A = const_cast<number*> (this->data());
number* values_eigenvectors = const_cast<number*> (matrix_eigenvectors.data());
-
+
int info(0),
lwork(1),
n_eigenpairs(0);
const int * const dummy(&one);
std::vector<int> iwork(static_cast<unsigned int> (5*nn));
std::vector<int> ifail(static_cast<unsigned int> (nn));
-
-
- // Optimal workspace query:
-
- // The LAPACK routine ?SYEVX requires
- // a sufficient large workspace variable,
- // minimum requirement is
- // work.size>=3*nn-1.
- // However, to improve performance, a
- // somewhat larger workspace may be needed.
-
- // SOME implementations of the LAPACK routine
- // provide a workspace query call,
- // info:=0, lwork:=-1
- // which returns an optimal value for the
- // size of the workspace array
- // (the PETSc 2.3.0 implementation does NOT
- // provide this functionality!).
-
- // define the DEAL_II_LIBLAPACK_NOQUERYMODE flag to
- // disable the workspace query.
+
+
+ // Optimal workspace query:
+
+ // The LAPACK routine ?SYEVX requires
+ // a sufficient large workspace variable,
+ // minimum requirement is
+ // work.size>=3*nn-1.
+ // However, to improve performance, a
+ // somewhat larger workspace may be needed.
+
+ // SOME implementations of the LAPACK routine
+ // provide a workspace query call,
+ // info:=0, lwork:=-1
+ // which returns an optimal value for the
+ // size of the workspace array
+ // (the PETSc 2.3.0 implementation does NOT
+ // provide this functionality!).
+
+ // define the DEAL_II_LIBLAPACK_NOQUERYMODE flag to
+ // disable the workspace query.
#ifndef DEAL_II_LIBLAPACK_NOQUERYMODE
lwork = -1;
work.resize(1);
-
+
syevx (jobz, range,
- uplo, &nn, values_A, &nn,
- &lower_bound, &upper_bound,
+ uplo, &nn, values_A, &nn,
+ &lower_bound, &upper_bound,
dummy, dummy, &abs_accuracy,
- &n_eigenpairs, &wr[0], values_eigenvectors,
- &nn, &work[0], &lwork, &iwork[0],
- &ifail[0], &info);
- // syevx returns info=0 on
- // success. Since we only queried
- // the optimal size for work,
- // everything else would not be
- // acceptable.
+ &n_eigenpairs, &wr[0], values_eigenvectors,
+ &nn, &work[0], &lwork, &iwork[0],
+ &ifail[0], &info);
+ // syevx returns info=0 on
+ // success. Since we only queried
+ // the optimal size for work,
+ // everything else would not be
+ // acceptable.
Assert (info == 0, ExcInternalError());
- // Allocate working array according
- // to suggestion.
+ // Allocate working array according
+ // to suggestion.
lwork = (int) (work[0]+.1);
#else
lwork = 8*nn > 1 ? 8*nn : 1; // no query mode
#endif
- // resize workspace arrays
+ // resize workspace arrays
work.resize(static_cast<unsigned int> (lwork));
- // Finally compute the eigenvalues.
+ // Finally compute the eigenvalues.
syevx (jobz, range,
- uplo, &nn, values_A, &nn,
- &lower_bound, &upper_bound,
+ uplo, &nn, values_A, &nn,
+ &lower_bound, &upper_bound,
dummy, dummy, &abs_accuracy,
- &n_eigenpairs, &wr[0], values_eigenvectors,
- &nn, &work[0], &lwork, &iwork[0],
- &ifail[0], &info);
+ &n_eigenpairs, &wr[0], values_eigenvectors,
+ &nn, &work[0], &lwork, &iwork[0],
+ &ifail[0], &info);
- // Negative return value implies a
- // wrong argument. This should be
- // internal.
+ // Negative return value implies a
+ // wrong argument. This should be
+ // internal.
Assert (info >=0, ExcInternalError());
if (info != 0)
std::cerr << "LAPACK error in syevx" << std::endl;
const int nn = (this->n_cols() > 0 ? this->n_cols() : 1);
Assert(static_cast<unsigned int>(nn) == this->n_rows(), ExcNotQuadratic());
Assert(B.n_rows() == B.n_cols(), ExcNotQuadratic());
- Assert(static_cast<unsigned int>(nn) == B.n_cols(),
- ExcDimensionMismatch (nn, B.n_cols()));
+ Assert(static_cast<unsigned int>(nn) == B.n_cols(),
+ ExcDimensionMismatch (nn, B.n_cols()));
wr.resize(nn);
LAPACKFullMatrix<number> matrix_eigenvectors(nn, nn);
number* values_A = const_cast<number*> (this->data());
number* values_B = const_cast<number*> (B.data());
number* values_eigenvectors = const_cast<number*> (matrix_eigenvectors.data());
-
+
int info(0),
lwork(1),
n_eigenpairs(0);
const int * const dummy(&one);
std::vector<int> iwork(static_cast<unsigned int> (5*nn));
std::vector<int> ifail(static_cast<unsigned int> (nn));
-
-
- // Optimal workspace query:
-
- // The LAPACK routine ?SYGVX requires
- // a sufficient large workspace variable,
- // minimum requirement is
- // work.size>=3*nn-1.
- // However, to improve performance, a
- // somewhat larger workspace may be needed.
-
- // SOME implementations of the LAPACK routine
- // provide a workspace query call,
- // info:=0, lwork:=-1
- // which returns an optimal value for the
- // size of the workspace array
- // (the PETSc 2.3.0 implementation does NOT
- // provide this functionality!).
-
- // define the DEAL_II_LIBLAPACK_NOQUERYMODE flag to
- // disable the workspace query.
+
+
+ // Optimal workspace query:
+
+ // The LAPACK routine ?SYGVX requires
+ // a sufficient large workspace variable,
+ // minimum requirement is
+ // work.size>=3*nn-1.
+ // However, to improve performance, a
+ // somewhat larger workspace may be needed.
+
+ // SOME implementations of the LAPACK routine
+ // provide a workspace query call,
+ // info:=0, lwork:=-1
+ // which returns an optimal value for the
+ // size of the workspace array
+ // (the PETSc 2.3.0 implementation does NOT
+ // provide this functionality!).
+
+ // define the DEAL_II_LIBLAPACK_NOQUERYMODE flag to
+ // disable the workspace query.
#ifndef DEAL_II_LIBLAPACK_NOQUERYMODE
lwork = -1;
work.resize(1);
-
+
sygvx (&itype, jobz, range, uplo, &nn, values_A, &nn,
values_B, &nn, &lower_bound, &upper_bound,
dummy, dummy, &abs_accuracy, &n_eigenpairs,
&wr[0], values_eigenvectors, &nn, &work[0],
&lwork, &iwork[0], &ifail[0], &info);
- // sygvx returns info=0 on
- // success. Since we only queried
- // the optimal size for work,
- // everything else would not be
- // acceptable.
+ // sygvx returns info=0 on
+ // success. Since we only queried
+ // the optimal size for work,
+ // everything else would not be
+ // acceptable.
Assert (info == 0, ExcInternalError());
- // Allocate working array according
- // to suggestion.
+ // Allocate working array according
+ // to suggestion.
lwork = (int) (work[0]+.1);
#else
lwork = 8*nn > 1 ? 8*nn : 1; // no query mode
#endif
- // resize workspace arrays
+ // resize workspace arrays
work.resize(static_cast<unsigned int> (lwork));
- // Finally compute the generalized
- // eigenvalues.
+ // Finally compute the generalized
+ // eigenvalues.
sygvx (&itype, jobz, range, uplo, &nn, values_A, &nn,
values_B, &nn, &lower_bound, &upper_bound,
dummy, dummy, &abs_accuracy, &n_eigenpairs,
&wr[0], values_eigenvectors, &nn, &work[0],
&lwork, &iwork[0], &ifail[0], &info);
- // Negative return value implies a
- // wrong argument. This should be
- // internal.
+ // Negative return value implies a
+ // wrong argument. This should be
+ // internal.
Assert (info >=0, ExcInternalError());
if (info != 0)
std::cerr << "LAPACK error in sygvx" << std::endl;
Assert(static_cast<unsigned int>(nn) == this->n_rows(), ExcNotQuadratic());
Assert(B.n_rows() == B.n_cols(), ExcNotQuadratic());
Assert(static_cast<unsigned int>(nn) == B.n_cols(),
- ExcDimensionMismatch (nn, B.n_cols()));
+ ExcDimensionMismatch (nn, B.n_cols()));
Assert(eigenvectors.size() <= static_cast<unsigned int>(nn),
- ExcMessage ("eigenvectors.size() > matrix.n_cols()"));
+ ExcMessage ("eigenvectors.size() > matrix.n_cols()"));
wr.resize(nn);
wi.resize(nn); //This is set purley for consistency reasons with the
const char * const jobz = (eigenvectors.size() > 0) ? (&V) : (&N);
const char * const uplo = (&U);
- // Optimal workspace query:
-
- // The LAPACK routine DSYGV requires
- // a sufficient large workspace variable,
- // minimum requirement is
- // work.size>=3*nn-1.
- // However, to improve performance, a
- // somewhat larger workspace may be needed.
-
- // SOME implementations of the LAPACK routine
- // provide a workspace query call,
- // info:=0, lwork:=-1
- // which returns an optimal value for the
- // size of the workspace array
- // (the PETSc 2.3.0 implementation does NOT
- // provide this functionality!).
-
- // define the DEAL_II_LIBLAPACK_NOQUERYMODE flag to
- // disable the workspace query.
+ // Optimal workspace query:
+
+ // The LAPACK routine DSYGV requires
+ // a sufficient large workspace variable,
+ // minimum requirement is
+ // work.size>=3*nn-1.
+ // However, to improve performance, a
+ // somewhat larger workspace may be needed.
+
+ // SOME implementations of the LAPACK routine
+ // provide a workspace query call,
+ // info:=0, lwork:=-1
+ // which returns an optimal value for the
+ // size of the workspace array
+ // (the PETSc 2.3.0 implementation does NOT
+ // provide this functionality!).
+
+ // define the DEAL_II_LIBLAPACK_NOQUERYMODE flag to
+ // disable the workspace query.
#ifndef DEAL_II_LIBLAPACK_NOQUERYMODE
lwork = -1;
work.resize(1);
sygv (&itype, jobz, uplo, &nn, values_A, &nn,
values_B, &nn,
&wr[0], &work[0], &lwork, &info);
- // sygv returns info=0 on
- // success. Since we only queried
- // the optimal size for work,
- // everything else would not be
- // acceptable.
+ // sygv returns info=0 on
+ // success. Since we only queried
+ // the optimal size for work,
+ // everything else would not be
+ // acceptable.
Assert (info == 0, ExcInternalError());
- // Allocate working array according
- // to suggestion.
+ // Allocate working array according
+ // to suggestion.
lwork = (int) (work[0]+.1);
#else
lwork = 3*nn-1 > 1 ? 3*nn-1 : 1; // no query mode
#endif
- // resize workspace array
+ // resize workspace array
work.resize((unsigned int) lwork);
- // Finally compute the generalized
- // eigenvalues.
+ // Finally compute the generalized
+ // eigenvalues.
sygv (&itype, jobz, uplo, &nn, values_A, &nn,
values_B, &nn,
&wr[0], &work[0], &lwork, &info);
- // Negative return value implies a
- // wrong argument. This should be
- // internal.
+ // Negative return value implies a
+ // wrong argument. This should be
+ // internal.
Assert (info >=0, ExcInternalError());
if (info != 0)
unsigned int width = width_;
Assert ((!this->empty()) || (this->n_cols()+this->n_rows()==0),
- ExcInternalError());
+ ExcInternalError());
- // set output format, but store old
- // state
+ // set output format, but store old
+ // state
std::ios::fmtflags old_flags = out.flags();
unsigned int old_precision = out.precision (precision);
{
out.setf (std::ios::scientific, std::ios::floatfield);
if (!width)
- width = precision+7;
+ width = precision+7;
} else {
out.setf (std::ios::fixed, std::ios::floatfield);
if (!width)
- width = precision+2;
+ width = precision+2;
}
for (unsigned int i=0; i<this->n_rows(); ++i)
{
for (unsigned int j=0; j<this->n_cols(); ++j)
- if (std::fabs(this->el(i,j)) > threshold)
- out << std::setw(width)
- << this->el(i,j) * denominator << ' ';
- else
- out << std::setw(width) << zero_string << ' ';
+ if (std::fabs(this->el(i,j)) > threshold)
+ out << std::setw(width)
+ << this->el(i,j) * denominator << ' ';
+ else
+ out << std::setw(width) << zero_string << ' ';
out << std::endl;
};
AssertThrow (out, ExcIO());
- // reset output format
+ // reset output format
out.flags (old_flags);
out.precision(old_precision);
}
template <typename number>
void
PreconditionLU<number>::initialize(const LAPACKFullMatrix<number>& M,
- VectorMemory<Vector<number> >& V)
+ VectorMemory<Vector<number> >& V)
{
matrix = &M;
mem = &V;
template <typename number>
void
PreconditionLU<number>::vmult(Vector<number>& dst,
- const Vector<number>& src) const
+ const Vector<number>& src) const
{
dst = src;
matrix->apply_lu_factorization(dst, false);
template <typename number>
void
PreconditionLU<number>::Tvmult(Vector<number>& dst,
- const Vector<number>& src) const
+ const Vector<number>& src) const
{
dst = src;
matrix->apply_lu_factorization(dst, true);
template <typename number>
void
PreconditionLU<number>::vmult(BlockVector<number>& dst,
- const BlockVector<number>& src) const
+ const BlockVector<number>& src) const
{
Assert(mem != 0, ExcNotInitialized());
Vector<number>* aux = mem->alloc();
template <typename number>
void
PreconditionLU<number>::Tvmult(BlockVector<number>& dst,
- const BlockVector<number>& src) const
+ const BlockVector<number>& src) const
{
Assert(mem != 0, ExcNotInitialized());
Vector<number>* aux = mem->alloc();
// $Id$
// Version: $Name$
//
-// Copyright (C) 2002, 2003, 2005, 2006 by the deal.II authors
+// Copyright (C) 2002, 2003, 2005, 2006, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
DEAL_II_NAMESPACE_OPEN
MeanValueFilter::MeanValueFilter(unsigned int component)
- :
- component(component)
+ :
+ component(component)
{}
const MatrixType& mat1,
const MatrixType& mat2,
VectorMemory<VectorType>& mem)
- :
- m1(&mat1, typeid(*this).name()),
- m2(&mat2, typeid(*this).name()),
- mem(&mem, typeid(*this).name())
+ :
+ m1(&mat1, typeid(*this).name()),
+ m2(&mat2, typeid(*this).name()),
+ mem(&mem, typeid(*this).name())
{
Assert(mat1.n() == mat2.m(), ExcDimensionMismatch(mat1.n(),mat2.m()));
}
template<typename number, typename vnumber>
ProductSparseMatrix<number, vnumber>::ProductSparseMatrix()
- :
- m1(0, typeid(*this).name()),
- m2(0, typeid(*this).name()),
- mem(0, typeid(*this).name())
+ :
+ m1(0, typeid(*this).name()),
+ m2(0, typeid(*this).name()),
+ mem(0, typeid(*this).name())
{}
Assert(mem != 0, ExcNotInitialized());
Assert(m1 != 0, ExcNotInitialized());
Assert(m2 != 0, ExcNotInitialized());
-
+
VectorType* v = mem->alloc();
v->reinit(m1->n());
m2->vmult (*v, src);
Assert(mem != 0, ExcNotInitialized());
Assert(m1 != 0, ExcNotInitialized());
Assert(m2 != 0, ExcNotInitialized());
-
+
VectorType* v = mem->alloc();
v->reinit(m1->n());
m2->vmult (*v, src);
Assert(mem != 0, ExcNotInitialized());
Assert(m1 != 0, ExcNotInitialized());
Assert(m2 != 0, ExcNotInitialized());
-
+
VectorType* v = mem->alloc();
v->reinit(m1->n());
m1->Tvmult (*v, src);
Assert(mem != 0, ExcNotInitialized());
Assert(m1 != 0, ExcNotInitialized());
Assert(m2 != 0, ExcNotInitialized());
-
+
VectorType* v = mem->alloc();
v->reinit(m1->n());
m1->Tvmult (*v, src);
template void MeanValueFilter::filter(BlockVector<float>&) const;
template void MeanValueFilter::filter(BlockVector<double>&) const;
template void MeanValueFilter::vmult(Vector<float>&,
- const Vector<float>&) const;
+ const Vector<float>&) const;
template void MeanValueFilter::vmult(Vector<double>&,
- const Vector<double>&) const;
+ const Vector<double>&) const;
template void MeanValueFilter::vmult(BlockVector<float>&,
- const BlockVector<float>&) const;
+ const BlockVector<float>&) const;
template void MeanValueFilter::vmult(BlockVector<double>&,
- const BlockVector<double>&) const;
+ const BlockVector<double>&) const;
template void MeanValueFilter::vmult_add(Vector<float>&,
- const Vector<float>&) const;
+ const Vector<float>&) const;
template void MeanValueFilter::vmult_add(Vector<double>&,
- const Vector<double>&) const;
+ const Vector<double>&) const;
template void MeanValueFilter::vmult_add(BlockVector<float>&,
- const BlockVector<float>&) const;
+ const BlockVector<float>&) const;
template void MeanValueFilter::vmult_add(BlockVector<double>&,
- const BlockVector<double>&) const;
+ const BlockVector<double>&) const;
template class InverseMatrixRichardson<Vector<float> >;
template class InverseMatrixRichardson<Vector<double> >;
// $Id$
// Version: $Name$
//
-// Copyright (C) 2001, 2002, 2003, 2005, 2006 by the deal.II authors
+// Copyright (C) 2001, 2002, 2003, 2005, 2006, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
MatrixOut::Options::Options (const bool show_absolute_values,
- const unsigned int block_size,
- const bool discontinuous)
- :
- show_absolute_values (show_absolute_values),
- block_size (block_size),
- discontinuous (discontinuous)
+ const unsigned int block_size,
+ const bool discontinuous)
+ :
+ show_absolute_values (show_absolute_values),
+ block_size (block_size),
+ discontinuous (discontinuous)
{}
-MatrixOut::~MatrixOut ()
+MatrixOut::~MatrixOut ()
{}
-std::vector<std::string>
+std::vector<std::string>
MatrixOut::get_dataset_names () const
{
return std::vector<std::string>(1,name);
// $Id$
// Version: $Name$
//
-// Copyright (C) 2010 by the deal.II authors
+// Copyright (C) 2010, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
// $Id$
// Version: $Name$
//
-// Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by the deal.II authors
+// Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
// $Id$
// Version: $Name$
//
-// Copyright (C) 2004, 2005, 2006, 2008 by the deal.II authors
+// Copyright (C) 2004, 2005, 2006, 2008, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
{
BlockSparseMatrix::BlockSparseMatrix ()
{}
-
-
+
+
BlockSparseMatrix::~BlockSparseMatrix ()
{}
{
BaseClass::collect_sizes ();
}
-
+
}
-
+
DEAL_II_NAMESPACE_CLOSE
#endif
// $Id$
// Version: $Name$
//
-// Copyright (C) 2004, 2005, 2006, 2008 by the deal.II authors
+// Copyright (C) 2004, 2005, 2006, 2008, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
// $Id$
// Version: $Name$
//
-// Copyright (C) 2004, 2005, 2006, 2008, 2009, 2010, 2011 by the deal.II authors
+// Copyright (C) 2004, 2005, 2006, 2008, 2009, 2010, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
ierr = MatAssemblyEnd (matrix,MAT_FINAL_ASSEMBLY);
AssertThrow (ierr == 0, ExcPETScError(ierr));
-
+
last_action = LastAction::none;
}
#endif
begin, end;
const int ierr = MatGetOwnershipRange (static_cast<const Mat &>(matrix),
- &begin, &end);
+ &begin, &end);
AssertThrow (ierr == 0, ExcPETScError(ierr));
return std::make_pair (begin, end);
MatrixBase::is_symmetric (const double tolerance)
{
#if DEAL_II_PETSC_VERSION_LT(3,2,0)
- PetscTruth
+ PetscTruth
#else
PetscBool
#endif
MatrixBase::is_hermitian (const double tolerance)
{
#if DEAL_II_PETSC_VERSION_LT(3,2,0)
- PetscTruth
+ PetscTruth
#else
PetscBool
#endif
truth;
- // First flush PETSc caches
+ // First flush PETSc caches
compress ();
#if DEAL_II_PETSC_VERSION_LT(3,0,0)
- // avoid warning about unused variables
+ // avoid warning about unused variables
(void) tolerance;
MatIsHermitian (matrix, &truth);
// Set options
#if DEAL_II_PETSC_VERSION_LT(3,0,0)
PetscViewerSetFormat (PETSC_VIEWER_STDOUT_WORLD,
- PETSC_VIEWER_ASCII_DEFAULT);
+ PETSC_VIEWER_ASCII_DEFAULT);
#else
PetscViewerSetFormat (PETSC_VIEWER_STDOUT_WORLD,
- PETSC_VIEWER_DEFAULT);
+ PETSC_VIEWER_DEFAULT);
#endif
// Write to screen
MatView (matrix,PETSC_VIEWER_STDOUT_WORLD);
// $Id$
// Version: $Name$
//
-// Copyright (C) 2004, 2005, 2006, 2008 by the deal.II authors
+// Copyright (C) 2004, 2005, 2006, 2008, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
{
namespace MPI
{
-
+
BlockSparseMatrix::BlockSparseMatrix ()
{}
-
-
+
+
BlockSparseMatrix::~BlockSparseMatrix ()
{}
}
}
-
+
DEAL_II_NAMESPACE_CLOSE
// $Id$
// Version: $Name$
//
-// Copyright (C) 2004, 2005, 2006, 2008 by the deal.II authors
+// Copyright (C) 2004, 2005, 2006, 2008, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
#include <deal.II/lac/petsc_parallel_block_vector.h>
-
+
#ifdef DEAL_II_USE_PETSC
# include <deal.II/lac/petsc_block_vector.h>
for (unsigned int i=0; i<this->n_blocks(); ++i)
this->block(i) = v.block(i);
-
+
return *this;
}
}
// $Id$
// Version: $Name$
//
-// Copyright (C) 2004, 2005, 2006, 2008, 2009, 2010 by the deal.II authors
+// Copyright (C) 2004, 2005, 2006, 2008, 2009, 2010, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
#ifdef DEAL_II_USE_PETSC_DEV
ierr
= MatCreateAIJ (communicator,
- local_rows, local_columns,
- m, n,
- n_nonzero_per_row, 0, 0, 0,
- &matrix);
+ local_rows, local_columns,
+ m, n,
+ n_nonzero_per_row, 0, 0, 0,
+ &matrix);
AssertThrow (ierr == 0, ExcPETScError(ierr));
ierr = MatSetOption (matrix, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_FALSE);
#else
ierr
= MatCreateMPIAIJ (communicator,
- local_rows, local_columns,
- m, n,
- n_nonzero_per_row, 0, 0, 0,
- &matrix);
+ local_rows, local_columns,
+ m, n,
+ n_nonzero_per_row, 0, 0, 0,
+ &matrix);
#endif
AssertThrow (ierr == 0, ExcPETScError(ierr));
const int ierr
= MatSetOption (matrix, MAT_SYMMETRIC);
#else
- const int ierr
- = MatSetOption (matrix, MAT_SYMMETRIC, PETSC_TRUE);
+ const int ierr
+ = MatSetOption (matrix, MAT_SYMMETRIC, PETSC_TRUE);
#endif
AssertThrow (ierr == 0, ExcPETScError(ierr));
Assert (row_lengths.size() == m,
ExcDimensionMismatch (row_lengths.size(), m));
- // For the case that
- // local_columns is smaller
- // than one of the row lengths
- // MatCreateMPIAIJ throws an
- // error. In this case use a
- // PETScWrappers::SparseMatrix
+ // For the case that
+ // local_columns is smaller
+ // than one of the row lengths
+ // MatCreateMPIAIJ throws an
+ // error. In this case use a
+ // PETScWrappers::SparseMatrix
for (unsigned int i=0; i<row_lengths.size(); ++i)
- Assert(row_lengths[i]<=local_columns,
- ExcIndexRange(row_lengths[i], 1, local_columns+1));
+ Assert(row_lengths[i]<=local_columns,
+ ExcIndexRange(row_lengths[i], 1, local_columns+1));
// use the call sequence indicating a
// maximal number of elements for each
// tricks with conversions of pointers
#ifdef PETSC_USE_64BIT_INDICES
const std::vector<PetscInt> int_row_lengths (row_lengths.begin(),
- row_lengths.end());
+ row_lengths.end());
#else
const std::vector<signed int> int_row_lengths (row_lengths.begin(),
row_lengths.end());
#ifdef DEAL_II_USE_PETSC_DEV
ierr
= MatCreateAIJ (communicator,
- local_rows, local_columns,
- m, n,
- 0, &int_row_lengths[0], 0, 0,
- &matrix);
+ local_rows, local_columns,
+ m, n,
+ 0, &int_row_lengths[0], 0, 0,
+ &matrix);
AssertThrow (ierr == 0, ExcPETScError(ierr));
//TODO: Sometimes the actual number of nonzero entries allocated is greater than the number of nonzero entries, which petsc will complain about unless explicitly disabled with MatSetOption. There is probably a way to prevent a different number nonzero elements being allocated in the first place. (See also previous TODO).
#else
ierr
= MatCreateMPIAIJ (communicator,
- local_rows, local_columns,
- m, n,
- 0, &int_row_lengths[0], 0, 0,
- &matrix);
+ local_rows, local_columns,
+ m, n,
+ 0, &int_row_lengths[0], 0, 0,
+ &matrix);
#endif
AssertThrow (ierr == 0, ExcPETScError(ierr));
const int ierr
= MatSetOption (matrix, MAT_SYMMETRIC);
#else
- const int ierr
- = MatSetOption (matrix, MAT_SYMMETRIC, PETSC_TRUE);
+ const int ierr
+ = MatSetOption (matrix, MAT_SYMMETRIC, PETSC_TRUE);
#endif
AssertThrow (ierr == 0, ExcPETScError(ierr));
local_row_end = local_row_start + local_rows_per_process[this_process];
#if DEAL_II_PETSC_VERSION_LT(2,3,3)
- //old version to create the matrix, we
- //can skip calculating the row length
- //at least starting from 2.3.3 (tested,
- //see below)
+ //old version to create the matrix, we
+ //can skip calculating the row length
+ //at least starting from 2.3.3 (tested,
+ //see below)
const unsigned int
- local_col_end = local_col_start + local_columns_per_process[this_process];
-
+ local_col_end = local_col_start + local_columns_per_process[this_process];
+
// then count the elements in- and
// out-of-window for the rows we own
#ifdef PETSC_USE_64BIT_INDICES
#else
std::vector<int>
#endif
- row_lengths_in_window (local_row_end - local_row_start),
- row_lengths_out_of_window (local_row_end - local_row_start);
+ row_lengths_in_window (local_row_end - local_row_start),
+ row_lengths_out_of_window (local_row_end - local_row_start);
for (unsigned int row = local_row_start; row<local_row_end; ++row)
for (unsigned int c=0; c<sparsity_pattern.row_length(row); ++c)
{
// _all_ rows.
const int ierr
= MatCreateMPIAIJ(communicator,
- local_rows_per_process[this_process],
+ local_rows_per_process[this_process],
local_columns_per_process[this_process],
- sparsity_pattern.n_rows(),
+ sparsity_pattern.n_rows(),
sparsity_pattern.n_cols(),
0, &row_lengths_in_window[0],
0, &row_lengths_out_of_window[0],
&matrix);
AssertThrow (ierr == 0, ExcPETScError(ierr));
-
+
#else //PETSC_VERSION>=2.3.3
- // new version to create the matrix. We
- // do not set row length but set the
- // correct SparsityPattern later.
+ // new version to create the matrix. We
+ // do not set row length but set the
+ // correct SparsityPattern later.
int ierr;
-
+
ierr = MatCreate(communicator,&matrix);
AssertThrow (ierr == 0, ExcPETScError(ierr));
-
+
ierr = MatSetSizes(matrix,
- local_rows_per_process[this_process],
- local_columns_per_process[this_process],
- sparsity_pattern.n_rows(),
- sparsity_pattern.n_cols());
+ local_rows_per_process[this_process],
+ local_columns_per_process[this_process],
+ sparsity_pattern.n_rows(),
+ sparsity_pattern.n_cols());
AssertThrow (ierr == 0, ExcPETScError(ierr));
-
+
ierr = MatSetType(matrix,MATMPIAIJ);
AssertThrow (ierr == 0, ExcPETScError(ierr));
#endif
-
-
+
+
// next preset the exact given matrix
// entries with zeros, if the user
// requested so. this doesn't avoid any
#else
std::vector<int>
#endif
- rowstart_in_window (local_row_end - local_row_start + 1, 0),
- colnums_in_window;
+ rowstart_in_window (local_row_end - local_row_start + 1, 0),
+ colnums_in_window;
{
unsigned int n_cols = 0;
for (unsigned int i=local_row_start; i<local_row_end; ++i)
// now copy over the information
// from the sparsity pattern.
- {
+ {
#ifdef PETSC_USE_64BIT_INDICES
- PetscInt
+ PetscInt
#else
- int
+ int
#endif
- * ptr = & colnums_in_window[0];
-
+ * ptr = & colnums_in_window[0];
+
for (unsigned int i=local_row_start; i<local_row_end; ++i)
- {
- typename SparsityType::row_iterator
- row_start = sparsity_pattern.row_begin(i),
- row_end = sparsity_pattern.row_end(i);
+ {
+ typename SparsityType::row_iterator
+ row_start = sparsity_pattern.row_begin(i),
+ row_end = sparsity_pattern.row_end(i);
+
+ std::copy(row_start, row_end, ptr);
+ ptr += row_end - row_start;
+ }
+ }
- std::copy(row_start, row_end, ptr);
- ptr += row_end - row_start;
- }
- }
-
// then call the petsc function
// that summarily allocates these
0);
#if DEAL_II_PETSC_VERSION_LT(2,3,3)
- // this is only needed for old
- // PETSc versions:
-
- // for some reason, it does not
+ // this is only needed for old
+ // PETSc versions:
+
+ // for some reason, it does not
// seem to be possible to force
// actual allocation of actual
// entries by using the last
for (unsigned int i=local_row_start; i<local_row_end; ++i)
{
#ifdef PETSC_USE_64BIT_INDICES
- PetscInt
+ PetscInt
#else
- int
+ int
#endif
- petsc_i = i;
+ petsc_i = i;
MatSetValues (matrix, 1, &petsc_i,
sparsity_pattern.row_length(i),
&colnums_in_window[rowstart_in_window[i-local_row_start]],
#endif
- // Tell PETSc that we are not
- // planning on adding new entries
- // to the matrix. Generate errors
- // in debug mode.
+ // Tell PETSc that we are not
+ // planning on adding new entries
+ // to the matrix. Generate errors
+ // in debug mode.
int ierr;
#if DEAL_II_PETSC_VERSION_LT(3,0,0)
#ifdef DEBUG
- ierr = MatSetOption (matrix, MAT_NEW_NONZERO_LOCATION_ERR);
- AssertThrow (ierr == 0, ExcPETScError(ierr));
+ ierr = MatSetOption (matrix, MAT_NEW_NONZERO_LOCATION_ERR);
+ AssertThrow (ierr == 0, ExcPETScError(ierr));
#else
- ierr = MatSetOption (matrix, MAT_NO_NEW_NONZERO_LOCATIONS);
- AssertThrow (ierr == 0, ExcPETScError(ierr));
-#endif
+ ierr = MatSetOption (matrix, MAT_NO_NEW_NONZERO_LOCATIONS);
+ AssertThrow (ierr == 0, ExcPETScError(ierr));
+#endif
#else
#ifdef DEBUG
- ierr = MatSetOption (matrix, MAT_NEW_NONZERO_LOCATION_ERR, PETSC_TRUE);
- AssertThrow (ierr == 0, ExcPETScError(ierr));
+ ierr = MatSetOption (matrix, MAT_NEW_NONZERO_LOCATION_ERR, PETSC_TRUE);
+ AssertThrow (ierr == 0, ExcPETScError(ierr));
#else
- ierr = MatSetOption (matrix, MAT_NEW_NONZERO_LOCATIONS, PETSC_FALSE);
- AssertThrow (ierr == 0, ExcPETScError(ierr));
+ ierr = MatSetOption (matrix, MAT_NEW_NONZERO_LOCATIONS, PETSC_FALSE);
+ AssertThrow (ierr == 0, ExcPETScError(ierr));
#endif
#endif
- // Tell PETSc to keep the
- // SparsityPattern entries even if
- // we delete a row with
- // clear_rows() which calls
- // MatZeroRows(). Otherwise one can
- // not write into that row
- // afterwards.
+ // Tell PETSc to keep the
+ // SparsityPattern entries even if
+ // we delete a row with
+ // clear_rows() which calls
+ // MatZeroRows(). Otherwise one can
+ // not write into that row
+ // afterwards.
#if DEAL_II_PETSC_VERSION_LT(3,0,0)
- ierr = MatSetOption (matrix, MAT_KEEP_ZEROED_ROWS);
- AssertThrow (ierr == 0, ExcPETScError(ierr));
+ ierr = MatSetOption (matrix, MAT_KEEP_ZEROED_ROWS);
+ AssertThrow (ierr == 0, ExcPETScError(ierr));
#elif DEAL_II_PETSC_VERSION_LT(3,1,0)
- ierr = MatSetOption (matrix, MAT_KEEP_ZEROED_ROWS, PETSC_TRUE);
- AssertThrow (ierr == 0, ExcPETScError(ierr));
+ ierr = MatSetOption (matrix, MAT_KEEP_ZEROED_ROWS, PETSC_TRUE);
+ AssertThrow (ierr == 0, ExcPETScError(ierr));
#else
- ierr = MatSetOption (matrix, MAT_KEEP_NONZERO_PATTERN, PETSC_TRUE);
- AssertThrow (ierr == 0, ExcPETScError(ierr));
+ ierr = MatSetOption (matrix, MAT_KEEP_NONZERO_PATTERN, PETSC_TRUE);
+ AssertThrow (ierr == 0, ExcPETScError(ierr));
#endif
-
+
}
}
//
template
SparseMatrix::SparseMatrix (const MPI_Comm &,
- const SparsityPattern &,
- const std::vector<unsigned int> &,
- const std::vector<unsigned int> &,
- const unsigned int,
- const bool);
+ const SparsityPattern &,
+ const std::vector<unsigned int> &,
+ const std::vector<unsigned int> &,
+ const unsigned int,
+ const bool);
template
SparseMatrix::SparseMatrix (const MPI_Comm &,
- const CompressedSparsityPattern &,
- const std::vector<unsigned int> &,
- const std::vector<unsigned int> &,
- const unsigned int,
- const bool);
+ const CompressedSparsityPattern &,
+ const std::vector<unsigned int> &,
+ const std::vector<unsigned int> &,
+ const unsigned int,
+ const bool);
template
SparseMatrix::SparseMatrix (const MPI_Comm &,
- const CompressedSimpleSparsityPattern &,
- const std::vector<unsigned int> &,
- const std::vector<unsigned int> &,
- const unsigned int,
- const bool);
+ const CompressedSimpleSparsityPattern &,
+ const std::vector<unsigned int> &,
+ const std::vector<unsigned int> &,
+ const unsigned int,
+ const bool);
template void
SparseMatrix::reinit (const MPI_Comm &,
- const SparsityPattern &,
- const std::vector<unsigned int> &,
- const std::vector<unsigned int> &,
- const unsigned int,
- const bool);
+ const SparsityPattern &,
+ const std::vector<unsigned int> &,
+ const std::vector<unsigned int> &,
+ const unsigned int,
+ const bool);
template void
SparseMatrix::reinit (const MPI_Comm &,
- const CompressedSparsityPattern &,
- const std::vector<unsigned int> &,
- const std::vector<unsigned int> &,
- const unsigned int,
- const bool);
+ const CompressedSparsityPattern &,
+ const std::vector<unsigned int> &,
+ const std::vector<unsigned int> &,
+ const unsigned int,
+ const bool);
template void
SparseMatrix::reinit (const MPI_Comm &,
- const CompressedSimpleSparsityPattern &,
- const std::vector<unsigned int> &,
- const std::vector<unsigned int> &,
- const unsigned int,
- const bool);
+ const CompressedSimpleSparsityPattern &,
+ const std::vector<unsigned int> &,
+ const std::vector<unsigned int> &,
+ const unsigned int,
+ const bool);
template void
SparseMatrix::do_reinit (const SparsityPattern &,
- const std::vector<unsigned int> &,
- const std::vector<unsigned int> &,
- const unsigned int ,
- const bool);
+ const std::vector<unsigned int> &,
+ const std::vector<unsigned int> &,
+ const unsigned int ,
+ const bool);
template void
SparseMatrix::do_reinit (const CompressedSparsityPattern &,
- const std::vector<unsigned int> &,
- const std::vector<unsigned int> &,
- const unsigned int ,
- const bool);
+ const std::vector<unsigned int> &,
+ const std::vector<unsigned int> &,
+ const unsigned int ,
+ const bool);
template void
SparseMatrix::do_reinit (const CompressedSimpleSparsityPattern &,
- const std::vector<unsigned int> &,
- const std::vector<unsigned int> &,
- const unsigned int ,
- const bool);
+ const std::vector<unsigned int> &,
+ const std::vector<unsigned int> &,
+ const unsigned int ,
+ const bool);
}
}
// $Id$
// Version: $Name$
//
-// Copyright (C) 2004, 2006, 2008, 2009, 2010, 2011 by the deal.II authors
+// Copyright (C) 2004, 2006, 2008, 2009, 2010, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
Vector::create_vector (n, local_size);
}
-
+
Vector::Vector (const MPI_Comm &communicator,
const VectorBase &v,
Vector::Vector (const MPI_Comm &communicator,
- const IndexSet & local,
- const IndexSet & ghost)
+ const IndexSet & local,
+ const IndexSet & ghost)
:
communicator (communicator)
{
Assert(local.is_contiguous(), ExcNotImplemented());
-
+
IndexSet ghost_set = ghost;
ghost_set.subtract_set(local);
-
- //possible optmization: figure out if
- //there are ghost indices (collective
- //operation!) and then create a
- //non-ghosted vector.
+
+ //possible optmization: figure out if
+ //there are ghost indices (collective
+ //operation!) and then create a
+ //non-ghosted vector.
// Vector::create_vector (local.size(), local.n_elements());
-
- Vector::create_vector(local.size(), local.n_elements(), ghost_set);
+
+ Vector::create_vector(local.size(), local.n_elements(), ghost_set);
}
-
+
void
const bool fast)
{
communicator = comm;
-
+
// only do something if the sizes
// mismatch (may not be true for every proc)
-
+
int k_global, k = ((size() != n) || (local_size() != local_sz));
MPI_Allreduce (&k, &k_global, 1,
- MPI_INT, MPI_LOR, communicator);
+ MPI_INT, MPI_LOR, communicator);
if (k_global)
{
const bool fast)
{
communicator = v.communicator;
-
+
reinit (communicator, v.size(), v.local_size(), fast);
}
-
+
void
Vector::reinit (const MPI_Comm &comm,
- const IndexSet & local,
- const IndexSet & ghost)
+ const IndexSet & local,
+ const IndexSet & ghost)
{
communicator = comm;
Assert(local.is_contiguous(), ExcNotImplemented());
-
+
IndexSet ghost_set = ghost;
ghost_set.subtract_set(local);
- create_vector(local.size(), local.n_elements(), ghost_set);
+ create_vector(local.size(), local.n_elements(), ghost_set);
}
-
+
Vector &
Vector::operator = (const PETScWrappers::Vector &v)
local_elements = local_range ();
std::copy (src_array + local_elements.first,
src_array + local_elements.second,
- dest_array);
+ dest_array);
// finally restore the arrays
ierr = VecRestoreArray (vector, &dest_array);
AssertThrow (ierr == 0, ExcPETScError(ierr));
Assert (size() == n,
- ExcDimensionMismatch (size(), n));
+ ExcDimensionMismatch (size(), n));
}
-
+
void
Vector::create_vector (const unsigned int n,
const unsigned int local_size,
- const IndexSet & ghostnodes)
+ const IndexSet & ghostnodes)
{
Assert (local_size <= n, ExcIndexRange (local_size, 0, n));
ghosted = true;
ghost_indices = ghostnodes;
-
- //64bit indices won't work yet:
+
+ //64bit indices won't work yet:
Assert (sizeof(unsigned int)==sizeof(PetscInt), ExcInternalError());
-
+
std::vector<unsigned int> ghostindices;
ghostnodes.fill_index_vector(ghostindices);
-
+
const PetscInt * ptr
- = (ghostindices.size() > 0
- ?
- (const PetscInt*)(&(ghostindices[0]))
- :
- 0);
+ = (ghostindices.size() > 0
+ ?
+ (const PetscInt*)(&(ghostindices[0]))
+ :
+ 0);
int ierr
- = VecCreateGhost(communicator,
- local_size,
- PETSC_DETERMINE,
- ghostindices.size(),
- ptr,
- &vector);
-
+ = VecCreateGhost(communicator,
+ local_size,
+ PETSC_DETERMINE,
+ ghostindices.size(),
+ ptr,
+ &vector);
+
AssertThrow (ierr == 0, ExcPETScError(ierr));
Assert (size() == n,
- ExcDimensionMismatch (size(), n));
+ ExcDimensionMismatch (size(), n));
#if DEBUG
- // test ghost allocation in debug mode
+ // test ghost allocation in debug mode
#ifdef PETSC_USE_64BIT_INDICES
PetscInt
#else
- int
+ int
#endif
- begin, end;
+ begin, end;
ierr = VecGetOwnershipRange (vector, &begin, &end);
PetscInt lsize;
ierr = VecGetSize(l, &lsize);
AssertThrow (ierr == 0, ExcPETScError(ierr));
-
+
ierr = VecGhostRestoreLocalForm(vector, &l);
AssertThrow (ierr == 0, ExcPETScError(ierr));
-
+
Assert( lsize==end-begin+(PetscInt)ghost_indices.n_elements() ,ExcInternalError());
#endif
-
+
}
-
+
}
// $Id$
// Version: $Name$
//
-// Copyright (C) 2004, 2006, 2008, 2009, 2010 by the deal.II authors
+// Copyright (C) 2004, 2006, 2008, 2009, 2010, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
namespace PETScWrappers
{
PreconditionerBase::PreconditionerBase ()
- :
- pc(NULL), matrix(NULL)
+ :
+ pc(NULL), matrix(NULL)
{}
if (pc!=NULL)
{
#if DEAL_II_PETSC_VERSION_LT(3,2,0)
- int ierr = PCDestroy(pc);
+ int ierr = PCDestroy(pc);
#else
- int ierr = PCDestroy(&pc);
+ int ierr = PCDestroy(&pc);
#endif
- AssertThrow (ierr == 0, ExcPETScError(ierr));
+ AssertThrow (ierr == 0, ExcPETScError(ierr));
}
}
-
-
+
+
void
PreconditionerBase::vmult (VectorBase &dst,
- const VectorBase &src) const
+ const VectorBase &src) const
{
AssertThrow (pc != NULL, StandardExceptions::ExcInvalidState ());
int ierr;
ierr = PCApply(pc, src, dst);
AssertThrow (ierr == 0, ExcPETScError(ierr));
- }
+ }
+
-
void
PreconditionerBase::create_pc ()
{
- // only allow the creation of the
- // preconditioner once
+ // only allow the creation of the
+ // preconditioner once
AssertThrow (pc == NULL, StandardExceptions::ExcInvalidState ());
-
+
MPI_Comm comm;
int ierr;
- // this ugly cast is necessay because the
- // type Mat and PETScObject are
- // unrelated.
+ // this ugly cast is necessay because the
+ // type Mat and PETScObject are
+ // unrelated.
ierr = PetscObjectGetComm(reinterpret_cast<PetscObject>(matrix), &comm);
AssertThrow (ierr == 0, ExcPETScError(ierr));
-
+
ierr = PCCreate(comm, &pc);
AssertThrow (ierr == 0, ExcPETScError(ierr));
return pc;
}
-
+
PreconditionerBase::operator Mat () const
{
return matrix;
PreconditionJacobi::PreconditionJacobi ()
{}
-
-
+
+
PreconditionJacobi::PreconditionJacobi (const MatrixBase &matrix,
const AdditionalData &additional_data)
{
- initialize(matrix, additional_data);
+ initialize(matrix, additional_data);
}
void
PreconditionJacobi::initialize (const MatrixBase &matrix_,
- const AdditionalData &additional_data_)
+ const AdditionalData &additional_data_)
{
matrix = static_cast<Mat>(matrix_);
additional_data = additional_data_;
-
+
create_pc();
-
+
int ierr;
ierr = PCSetType (pc, const_cast<char *>(PCJACOBI));
AssertThrow (ierr == 0, ExcPETScError(ierr));
PreconditionBlockJacobi::PreconditionBlockJacobi ()
{}
-
-
+
+
PreconditionBlockJacobi::
PreconditionBlockJacobi (const MatrixBase &matrix,
const AdditionalData &additional_data)
{
- initialize(matrix, additional_data);
+ initialize(matrix, additional_data);
}
void
PreconditionBlockJacobi::initialize (const MatrixBase &matrix_,
- const AdditionalData &additional_data_)
+ const AdditionalData &additional_data_)
{
matrix = static_cast<Mat>(matrix_);
additional_data = additional_data_;
-
+
create_pc();
int ierr;
PreconditionSOR::PreconditionSOR ()
{}
-
+
PreconditionSOR::PreconditionSOR (const MatrixBase &matrix,
const AdditionalData &additional_data)
{
- initialize(matrix, additional_data);
+ initialize(matrix, additional_data);
}
void
PreconditionSOR::initialize (const MatrixBase &matrix_,
- const AdditionalData &additional_data_)
+ const AdditionalData &additional_data_)
{
matrix = static_cast<Mat>(matrix_);
additional_data = additional_data_;
-
+
create_pc();
int ierr;
omega (omega)
{}
-
+
PreconditionSSOR::PreconditionSSOR ()
{}
PreconditionSSOR::PreconditionSSOR (const MatrixBase &matrix,
const AdditionalData &additional_data)
{
- initialize(matrix, additional_data);
+ initialize(matrix, additional_data);
}
void
PreconditionSSOR::initialize (const MatrixBase &matrix_,
- const AdditionalData &additional_data_)
+ const AdditionalData &additional_data_)
{
matrix = static_cast<Mat>(matrix_);
additional_data = additional_data_;
-
+
create_pc();
int ierr;
PreconditionEisenstat::PreconditionEisenstat ()
{}
-
+
PreconditionEisenstat::PreconditionEisenstat (const MatrixBase &matrix,
const AdditionalData &additional_data)
{
- initialize(matrix, additional_data);
+ initialize(matrix, additional_data);
}
void
PreconditionEisenstat::initialize (const MatrixBase &matrix_,
- const AdditionalData &additional_data_)
+ const AdditionalData &additional_data_)
{
matrix = static_cast<Mat>(matrix_);
additional_data = additional_data_;
-
+
create_pc();
int ierr;
PreconditionICC::PreconditionICC ()
{}
-
+
PreconditionICC::PreconditionICC (const MatrixBase &matrix,
const AdditionalData &additional_data)
{
- initialize(matrix, additional_data);
+ initialize(matrix, additional_data);
}
void
PreconditionICC::initialize (const MatrixBase &matrix_,
- const AdditionalData &additional_data_)
+ const AdditionalData &additional_data_)
{
matrix = static_cast<Mat>(matrix_);
additional_data = additional_data_;
-
+
create_pc();
int ierr;
PreconditionILU::PreconditionILU ()
{}
-
+
PreconditionILU::PreconditionILU (const MatrixBase &matrix,
const AdditionalData &additional_data)
{
- initialize(matrix, additional_data);
+ initialize(matrix, additional_data);
}
void
PreconditionILU::initialize (const MatrixBase &matrix_,
- const AdditionalData &additional_data_)
+ const AdditionalData &additional_data_)
{
matrix = static_cast<Mat>(matrix_);
additional_data = additional_data_;
-
+
create_pc();
int ierr;
PreconditionBoomerAMG::AdditionalData::
AdditionalData(const bool symmetric_operator,
- const double strong_threshold,
- const double max_row_sum,
- const unsigned int aggressive_coarsening_num_levels,
- const bool output_details
+ const double strong_threshold,
+ const double max_row_sum,
+ const unsigned int aggressive_coarsening_num_levels,
+ const bool output_details
)
- :
- symmetric_operator(symmetric_operator),
- strong_threshold(strong_threshold),
- max_row_sum(max_row_sum),
- aggressive_coarsening_num_levels(aggressive_coarsening_num_levels),
- output_details(output_details)
+ :
+ symmetric_operator(symmetric_operator),
+ strong_threshold(strong_threshold),
+ max_row_sum(max_row_sum),
+ aggressive_coarsening_num_levels(aggressive_coarsening_num_levels),
+ output_details(output_details)
{}
PreconditionBoomerAMG::PreconditionBoomerAMG ()
{}
-
+
PreconditionBoomerAMG::PreconditionBoomerAMG (const MatrixBase &matrix,
- const AdditionalData &additional_data)
+ const AdditionalData &additional_data)
{
- initialize(matrix, additional_data);
+ initialize(matrix, additional_data);
}
void
PreconditionBoomerAMG::initialize (const MatrixBase &matrix_,
- const AdditionalData &additional_data_)
+ const AdditionalData &additional_data_)
{
matrix = static_cast<Mat>(matrix_);
additional_data = additional_data_;
PetscOptionsSetValue("-pc_hypre_boomeramg_print_statistics","1");
PetscOptionsSetValue("-pc_hypre_boomeramg_agg_nl",
- Utilities::int_to_string(
- additional_data.aggressive_coarsening_num_levels
- ).c_str());
+ Utilities::int_to_string(
+ additional_data.aggressive_coarsening_num_levels
+ ).c_str());
std::stringstream ssStream;
ssStream << additional_data.max_row_sum;
if (additional_data.symmetric_operator)
{
- PetscOptionsSetValue("-pc_hypre_boomeramg_relax_type_up", "symmetric-SOR/Jacobi");
- PetscOptionsSetValue("-pc_hypre_boomeramg_relax_type_down", "symmetric-SOR/Jacobi");
- PetscOptionsSetValue("-pc_hypre_boomeramg_relax_type_coarse", "Gaussian-elimination");
+ PetscOptionsSetValue("-pc_hypre_boomeramg_relax_type_up", "symmetric-SOR/Jacobi");
+ PetscOptionsSetValue("-pc_hypre_boomeramg_relax_type_down", "symmetric-SOR/Jacobi");
+ PetscOptionsSetValue("-pc_hypre_boomeramg_relax_type_coarse", "Gaussian-elimination");
}
else
{
- PetscOptionsSetValue("-pc_hypre_boomeramg_relax_type_up", "SOR/Jacobi");
- PetscOptionsSetValue("-pc_hypre_boomeramg_relax_type_down", "SOR/Jacobi");
- PetscOptionsSetValue("-pc_hypre_boomeramg_relax_type_coarse", "Gaussian-elimination");
+ PetscOptionsSetValue("-pc_hypre_boomeramg_relax_type_up", "SOR/Jacobi");
+ PetscOptionsSetValue("-pc_hypre_boomeramg_relax_type_down", "SOR/Jacobi");
+ PetscOptionsSetValue("-pc_hypre_boomeramg_relax_type_coarse", "Gaussian-elimination");
}
ierr = PCSetFromOptions (pc);
#else // PETSC_HAVE_HYPRE
(void)pc;
Assert (false,
- ExcMessage ("Your PETSc installation does not include a copy of "
- "the hypre package necessary for this preconditioner."));
+ ExcMessage ("Your PETSc installation does not include a copy of "
+ "the hypre package necessary for this preconditioner."));
#endif
}
PreconditionLU::AdditionalData::
AdditionalData (const double pivoting,
- const double zero_pivot,
- const double damping)
+ const double zero_pivot,
+ const double damping)
:
pivoting (pivoting),
zero_pivot (zero_pivot),
- damping (damping)
+ damping (damping)
{}
PreconditionLU::PreconditionLU ()
{}
-
+
PreconditionLU::PreconditionLU (const MatrixBase &matrix,
- const AdditionalData &additional_data)
+ const AdditionalData &additional_data)
{
- initialize(matrix, additional_data);
+ initialize(matrix, additional_data);
}
void
PreconditionLU::initialize (const MatrixBase &matrix_,
- const AdditionalData &additional_data_)
+ const AdditionalData &additional_data_)
{
matrix = static_cast<Mat>(matrix_);
additional_data = additional_data_;
-
+
create_pc();
int ierr;
// $Id$
// Version: $Name$
//
-// Copyright (C) 2004, 2006, 2008, 2009, 2010 by the deal.II authors
+// Copyright (C) 2004, 2006, 2008, 2009, 2010, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
#else
int ierr = KSPDestroy (&ksp);
#endif
-
+
AssertThrow (ierr == 0, ExcPETScError(ierr));
// and destroy the solver object if we
// preconditioner
set_solver_type (solver_data->ksp);
- ierr = KSPSetPC (solver_data->ksp, preconditioner.get_pc());
- AssertThrow (ierr == 0, ExcPETScError(ierr));
+ ierr = KSPSetPC (solver_data->ksp, preconditioner.get_pc());
+ AssertThrow (ierr == 0, ExcPETScError(ierr));
// then a convergence monitor
// function. that function simply
#else
KSPSetConvergenceTest (solver_data->ksp, &convergence_test,
reinterpret_cast<void *>(&solver_control),
- PETSC_NULL);
+ PETSC_NULL);
#endif
}
// set the command line option prefix name
ierr = KSPSetOptionsPrefix(solver_data->ksp, prefix_name.c_str());
AssertThrow (ierr == 0, ExcPETScError(ierr));
-
+
// set the command line options provided
// by the user to override the defaults
ierr = KSPSetFromOptions (solver_data->ksp);
AssertThrow (ierr == 0, ExcPETScError(ierr));
-
+
// then do the real work: set up solver
// internal data and solve the
- // system.
+ // system.
ierr = KSPSetUp (solver_data->ksp);
AssertThrow (ierr == 0, ExcPETScError(ierr));
int
SolverBase::convergence_test (KSP /*ksp*/,
#ifdef PETSC_USE_64BIT_INDICES
- const PetscInt iteration,
+ const PetscInt iteration,
#else
- const int iteration,
+ const int iteration,
#endif
const PetscReal residual_norm,
KSPConvergedReason *reason,
// solution vector. do so here as well:
KSPSetInitialGuessNonzero (ksp, PETSC_TRUE);
- // Hand over the absolute
- // tolerance and the maximum
- // iteration number to the PETSc
- // convergence criterion. The
- // custom deal.II SolverControl
- // object is ignored by the PETSc
- // Richardson method (when no
- // PETSc monitoring is present),
- // since in this case PETSc
- // uses a faster version of
- // the Richardson iteration,
- // where no residual is
- // available.
+ // Hand over the absolute
+ // tolerance and the maximum
+ // iteration number to the PETSc
+ // convergence criterion. The
+ // custom deal.II SolverControl
+ // object is ignored by the PETSc
+ // Richardson method (when no
+ // PETSc monitoring is present),
+ // since in this case PETSc
+ // uses a faster version of
+ // the Richardson iteration,
+ // where no residual is
+ // available.
KSPSetTolerances(ksp, PETSC_DEFAULT, this->solver_control.tolerance(),
- PETSC_DEFAULT, this->solver_control.max_steps()+1);
+ PETSC_DEFAULT, this->solver_control.max_steps()+1);
}
SolverGMRES::AdditionalData::
AdditionalData (const unsigned int restart_parameter,
- const bool right_preconditioning)
+ const bool right_preconditioning)
:
restart_parameter (restart_parameter),
- right_preconditioning (right_preconditioning)
+ right_preconditioning (right_preconditioning)
{}
ierr = (*fun_ptr)(ksp,additional_data.restart_parameter);
AssertThrow (ierr == 0, ExcPETScError(ierr));
- // Set preconditioning side to
- // right
+ // Set preconditioning side to
+ // right
if (additional_data.right_preconditioning)
{
#if DEAL_II_PETSC_VERSION_LT(3,2,0)
- ierr = KSPSetPreconditionerSide(ksp, PC_RIGHT);
+ ierr = KSPSetPreconditionerSide(ksp, PC_RIGHT);
#else
- ierr = KSPSetPCSide(ksp, PC_RIGHT);
+ ierr = KSPSetPCSide(ksp, PC_RIGHT);
#endif
- AssertThrow (ierr == 0, ExcPETScError(ierr));
+ AssertThrow (ierr == 0, ExcPETScError(ierr));
}
// in the deal.II solvers, we always
/* ---------------------- SolverPreOnly ------------------------ */
SolverPreOnly::SolverPreOnly (SolverControl &cn,
- const MPI_Comm &mpi_communicator,
- const AdditionalData &data)
+ const MPI_Comm &mpi_communicator,
+ const AdditionalData &data)
:
SolverBase (cn, mpi_communicator),
additional_data (data)
// $Id$
// Version: $Name$
//
-// Copyright (C) 2004, 2005, 2006, 2008 by the deal.II authors
+// Copyright (C) 2004, 2005, 2006, 2008, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
}
-
+
void
SparseMatrix::reinit (const unsigned int m,
const unsigned int n,
if (preset_nonzero_locations == true)
{
#ifdef PETSC_USE_64BIT_INDICES
- std::vector<PetscInt>
+ std::vector<PetscInt>
#else
- std::vector<int>
+ std::vector<int>
#endif
- row_entries;
+ row_entries;
std::vector<PetscScalar> row_values;
for (unsigned int i=0; i<sparsity_pattern.n_rows(); ++i)
{
row_entries[j] = sparsity_pattern.column_number (i,j);
#ifdef PETSC_USE_64BIT_INDICES
- const PetscInt
+ const PetscInt
#else
- const int
+ const int
#endif
- int_row = i;
+ int_row = i;
MatSetValues (matrix, 1, &int_row,
row_lengths[i], &row_entries[0],
&row_values[0], INSERT_VALUES);
compress ();
- // Tell PETSc that we are not
- // planning on adding new entries
- // to the matrix. Generate errors
- // in debug mode.
+ // Tell PETSc that we are not
+ // planning on adding new entries
+ // to the matrix. Generate errors
+ // in debug mode.
int ierr;
#if DEAL_II_PETSC_VERSION_LT(3,0,0)
#ifdef DEBUG
- ierr = MatSetOption (matrix, MAT_NEW_NONZERO_LOCATION_ERR);
- AssertThrow (ierr == 0, ExcPETScError(ierr));
+ ierr = MatSetOption (matrix, MAT_NEW_NONZERO_LOCATION_ERR);
+ AssertThrow (ierr == 0, ExcPETScError(ierr));
#else
- ierr = MatSetOption (matrix, MAT_NO_NEW_NONZERO_LOCATIONS);
- AssertThrow (ierr == 0, ExcPETScError(ierr));
-#endif
+ ierr = MatSetOption (matrix, MAT_NO_NEW_NONZERO_LOCATIONS);
+ AssertThrow (ierr == 0, ExcPETScError(ierr));
+#endif
#else
#ifdef DEBUG
- ierr = MatSetOption (matrix, MAT_NEW_NONZERO_LOCATION_ERR, PETSC_TRUE);
- AssertThrow (ierr == 0, ExcPETScError(ierr));
+ ierr = MatSetOption (matrix, MAT_NEW_NONZERO_LOCATION_ERR, PETSC_TRUE);
+ AssertThrow (ierr == 0, ExcPETScError(ierr));
#else
- ierr = MatSetOption (matrix, MAT_NEW_NONZERO_LOCATIONS, PETSC_FALSE);
- AssertThrow (ierr == 0, ExcPETScError(ierr));
+ ierr = MatSetOption (matrix, MAT_NEW_NONZERO_LOCATIONS, PETSC_FALSE);
+ AssertThrow (ierr == 0, ExcPETScError(ierr));
#endif
#endif
- // Tell PETSc to keep the
- // SparsityPattern entries even if
- // we delete a row with
- // clear_rows() which calls
- // MatZeroRows(). Otherwise one can
- // not write into that row
- // afterwards.
+ // Tell PETSc to keep the
+ // SparsityPattern entries even if
+ // we delete a row with
+ // clear_rows() which calls
+ // MatZeroRows(). Otherwise one can
+ // not write into that row
+ // afterwards.
#if DEAL_II_PETSC_VERSION_LT(3,0,0)
- ierr = MatSetOption (matrix, MAT_KEEP_ZEROED_ROWS);
- AssertThrow (ierr == 0, ExcPETScError(ierr));
+ ierr = MatSetOption (matrix, MAT_KEEP_ZEROED_ROWS);
+ AssertThrow (ierr == 0, ExcPETScError(ierr));
#elif DEAL_II_PETSC_VERSION_LT(3,1,0)
- ierr = MatSetOption (matrix, MAT_KEEP_ZEROED_ROWS, PETSC_TRUE);
- AssertThrow (ierr == 0, ExcPETScError(ierr));
+ ierr = MatSetOption (matrix, MAT_KEEP_ZEROED_ROWS, PETSC_TRUE);
+ AssertThrow (ierr == 0, ExcPETScError(ierr));
#else
- ierr = MatSetOption (matrix, MAT_KEEP_NONZERO_PATTERN, PETSC_TRUE);
- AssertThrow (ierr == 0, ExcPETScError(ierr));
+ ierr = MatSetOption (matrix, MAT_KEEP_NONZERO_PATTERN, PETSC_TRUE);
+ AssertThrow (ierr == 0, ExcPETScError(ierr));
#endif
}
//
template
SparseMatrix::SparseMatrix (const SparsityPattern &,
- const bool);
+ const bool);
template
SparseMatrix::SparseMatrix (const CompressedSparsityPattern &,
- const bool);
+ const bool);
template
SparseMatrix::SparseMatrix (const CompressedSimpleSparsityPattern &,
- const bool);
+ const bool);
template void
SparseMatrix::reinit (const SparsityPattern &,
- const bool);
+ const bool);
template void
SparseMatrix::reinit (const CompressedSparsityPattern &,
- const bool);
+ const bool);
template void
SparseMatrix::reinit (const CompressedSimpleSparsityPattern &,
- const bool);
+ const bool);
template void
SparseMatrix::do_reinit (const SparsityPattern &,
// $Id$
// Version: $Name$
//
-// Copyright (C) 2004, 2006, 2008 by the deal.II authors
+// Copyright (C) 2004, 2006, 2008, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
Vector::create_vector (n);
}
-
+
Vector::Vector (const Vector &v)
:
// AssertThrow (ierr == 0, ExcPETScError(ierr));
// so let's go the slow way:
- if (attained_ownership)
- {
+ if (attained_ownership)
+ {
#if DEAL_II_PETSC_VERSION_LT(3,2,0)
- int ierr = VecDestroy (vector);
+ int ierr = VecDestroy (vector);
#else
- int ierr = VecDestroy (&vector);
+ int ierr = VecDestroy (&vector);
#endif
- AssertThrow (ierr == 0, ExcPETScError(ierr));
- }
+ AssertThrow (ierr == 0, ExcPETScError(ierr));
+ }
create_vector (n);
}
{
reinit (v.size(), fast);
}
-
-
+
+
void
Vector::create_vector (const unsigned int n)
{
// $Id$
// Version: $Name$
//
-// Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 by the deal.II authors
+// Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
Assert (index < vector.size(),
ExcIndexRange (index, 0, vector.size()));
- // old versions of PETSc appear to be
+ // old versions of PETSc appear to be
// missing the function VecGetValues(),
// so the workaround consists of
// obtaining a pointer to a contiguous
AssertThrow (ierr == 0, ExcPETScError(ierr));
return value;
#else
- PetscInt idx = index;
- PetscScalar value;
- int ierr = VecGetValues(vector.vector, 1, &idx, &value);
- AssertThrow (ierr == 0, ExcPETScError(ierr));
- return value;
+ PetscInt idx = index;
+ PetscScalar value;
+ int ierr = VecGetValues(vector.vector, 1, &idx, &value);
+ AssertThrow (ierr == 0, ExcPETScError(ierr));
+ return value;
#endif
}
else if (dynamic_cast<const PETScWrappers::MPI::Vector *>(&vector) != 0)
{
- int ierr;
+ int ierr;
- if (vector.ghosted)
- {
+ if (vector.ghosted)
+ {
#ifdef PETSC_USE_64BIT_INDICES
- PetscInt
+ PetscInt
#else
- int
+ int
#endif
- begin, end;
- ierr = VecGetOwnershipRange (vector.vector, &begin, &end);
- AssertThrow (ierr == 0, ExcPETScError(ierr));
-
- Vec l;
- ierr = VecGhostGetLocalForm(vector.vector, &l);
- AssertThrow (ierr == 0, ExcPETScError(ierr));
-
- PetscInt lsize;
- ierr = VecGetSize(l, &lsize);
- AssertThrow (ierr == 0, ExcPETScError(ierr));
-
- PetscScalar *ptr;
- ierr = VecGetArray(l, &ptr);
- AssertThrow (ierr == 0, ExcPETScError(ierr));
-
- PetscScalar value;
-
- if ( index>=static_cast<unsigned int>(begin)
- && index<static_cast<unsigned int>(end) )
- {
- //local entry
- value=*(ptr+index-begin);
- }
- else
- {
- //ghost entry
- unsigned ghostidx
- = vector.ghost_indices.index_within_set(index);
-
- Assert(ghostidx+end-begin<(unsigned int)lsize, ExcInternalError());
- value=*(ptr+ghostidx+end-begin);
-
-
- }
-
-
- ierr = VecRestoreArray(l, &ptr);
- AssertThrow (ierr == 0, ExcPETScError(ierr));
-
- ierr = VecGhostRestoreLocalForm(vector.vector, &l);
- AssertThrow (ierr == 0, ExcPETScError(ierr));
-
- return value;
- }
+ begin, end;
+ ierr = VecGetOwnershipRange (vector.vector, &begin, &end);
+ AssertThrow (ierr == 0, ExcPETScError(ierr));
+
+ Vec l;
+ ierr = VecGhostGetLocalForm(vector.vector, &l);
+ AssertThrow (ierr == 0, ExcPETScError(ierr));
+
+ PetscInt lsize;
+ ierr = VecGetSize(l, &lsize);
+ AssertThrow (ierr == 0, ExcPETScError(ierr));
+
+ PetscScalar *ptr;
+ ierr = VecGetArray(l, &ptr);
+ AssertThrow (ierr == 0, ExcPETScError(ierr));
+
+ PetscScalar value;
+
+ if ( index>=static_cast<unsigned int>(begin)
+ && index<static_cast<unsigned int>(end) )
+ {
+ //local entry
+ value=*(ptr+index-begin);
+ }
+ else
+ {
+ //ghost entry
+ unsigned ghostidx
+ = vector.ghost_indices.index_within_set(index);
+
+ Assert(ghostidx+end-begin<(unsigned int)lsize, ExcInternalError());
+ value=*(ptr+ghostidx+end-begin);
+
+
+ }
+
+
+ ierr = VecRestoreArray(l, &ptr);
+ AssertThrow (ierr == 0, ExcPETScError(ierr));
+
+ ierr = VecGhostRestoreLocalForm(vector.vector, &l);
+ AssertThrow (ierr == 0, ExcPETScError(ierr));
+
+ return value;
+ }
// first verify that the requested
// element is actually locally
// available
-
+
#ifdef PETSC_USE_64BIT_INDICES
- PetscInt
+ PetscInt
#else
- int
+ int
#endif
- begin, end;
+ begin, end;
ierr = VecGetOwnershipRange (vector.vector, &begin, &end);
AssertThrow (ierr == 0, ExcPETScError(ierr));
-
+
AssertThrow ((index >= static_cast<unsigned int>(begin)) &&
(index < static_cast<unsigned int>(end)),
ExcAccessToNonlocalElement (index, begin, end-1));
- // old version which only work with
- // VecGetArray()...
+ // old version which only work with
+ // VecGetArray()...
#if (PETSC_VERSION_MAJOR <= 2) && (PETSC_VERSION_MINOR < 3)
-
+
// then access it
PetscScalar *ptr;
ierr = VecGetArray (vector.vector, &ptr);
AssertThrow (ierr == 0, ExcPETScError(ierr));
return value;
-
+
#else
- //new version with VecGetValues()
- PetscInt idx = index;
- PetscScalar value;
- ierr = VecGetValues(vector.vector, 1, &idx, &value);
- AssertThrow (ierr == 0, ExcPETScError(ierr));
-
- return value;
+ //new version with VecGetValues()
+ PetscInt idx = index;
+ PetscScalar value;
+ ierr = VecGetValues(vector.vector, 1, &idx, &value);
+ AssertThrow (ierr == 0, ExcPETScError(ierr));
+
+ return value;
#endif
-
+
}
else
// what? what other kind of vector
VectorBase::VectorBase ()
:
- ghosted(false),
+ ghosted(false),
last_action (LastAction::none),
- attained_ownership(true)
+ attained_ownership(true)
{}
VectorBase::VectorBase (const VectorBase &v)
:
- Subscriptor (),
- ghosted(v.ghosted),
- ghost_indices(v.ghost_indices),
+ Subscriptor (),
+ ghosted(v.ghosted),
+ ghost_indices(v.ghost_indices),
last_action (LastAction::none),
- attained_ownership(true)
+ attained_ownership(true)
{
int ierr = VecDuplicate (v.vector, &vector);
AssertThrow (ierr == 0, ExcPETScError(ierr));
}
-
+
VectorBase::VectorBase (const Vec & v)
- :
- Subscriptor (),
- vector(v),
- ghosted(false),
+ :
+ Subscriptor (),
+ vector(v),
+ ghosted(false),
last_action (LastAction::none),
- attained_ownership(false)
+ attained_ownership(false)
{}
-
+
VectorBase::~VectorBase ()
{
if (attained_ownership)
- {
+ {
#if DEAL_II_PETSC_VERSION_LT(3,2,0)
- const int ierr = VecDestroy (vector);
+ const int ierr = VecDestroy (vector);
#else
- const int ierr = VecDestroy (&vector);
+ const int ierr = VecDestroy (&vector);
#endif
- AssertThrow (ierr == 0, ExcPETScError(ierr));
+ AssertThrow (ierr == 0, ExcPETScError(ierr));
}
}
ExcDimensionMismatch(size(), v.size()));
#if DEAL_II_PETSC_VERSION_LT(3,2,0)
- PetscTruth
+ PetscTruth
#else
- PetscBool
+ PetscBool
#endif
flag;
ExcDimensionMismatch(size(), v.size()));
#if DEAL_II_PETSC_VERSION_LT(3,2,0)
- PetscTruth
+ PetscTruth
#else
- PetscBool
+ PetscBool
#endif
flag;
#endif
begin, end;
const int ierr = VecGetOwnershipRange (static_cast<const Vec &>(vector),
- &begin, &end);
+ &begin, &end);
AssertThrow (ierr == 0, ExcPETScError(ierr));
return std::make_pair (begin, end);
void
VectorBase::add (const unsigned int n_elements,
- const unsigned int *indices,
- const PetscScalar *values)
+ const unsigned int *indices,
+ const PetscScalar *values)
{
do_set_add_operation(n_elements, indices, values, true);
}
// if in fact the state is anything but LastAction::none. but
// that's not true: one frequently gets into situations where
// only one processor (or a subset of processors) actually writes
- // something into a vector, but we still need to call
+ // something into a vector, but we still need to call
// VecAssemblyBegin/End on all processors, even those that are
// still in LastAction::none state
int ierr;
AssertThrow (ierr == 0, ExcPETScError(ierr));
ierr = VecAssemblyEnd(vector);
AssertThrow (ierr == 0, ExcPETScError(ierr));
-
+
// reset the last action field to indicate that we're back to
// a pristine state
last_action = VectorBase::LastAction::none;
VectorBase::mean_value () const
{
int ierr;
- // We can only use our more efficient
- // routine in the serial case.
+ // We can only use our more efficient
+ // routine in the serial case.
if (dynamic_cast<const PETScWrappers::MPI::Vector *>(this) != 0)
{
- PetscScalar sum;
- ierr = VecSum( vector, &sum);
- AssertThrow (ierr == 0, ExcPETScError(ierr));
- return sum/size();
+ PetscScalar sum;
+ ierr = VecSum( vector, &sum);
+ AssertThrow (ierr == 0, ExcPETScError(ierr));
+ return sum/size();
}
-
+
// get a representation of the vector and
// loop over all the elements
PetscScalar *start_ptr;
real_type norm = 0;
{
real_type sum0 = 0,
- sum1 = 0,
- sum2 = 0,
- sum3 = 0;
+ sum1 = 0,
+ sum2 = 0,
+ sum3 = 0;
// use modern processors better by
// allowing pipelined commands to be
bool is_non_negative (const std::complex<T> &)
{
Assert (false,
- ExcMessage ("You can't ask a complex value "
- "whether it is non-negative."))
+ ExcMessage ("You can't ask a complex value "
+ "whether it is non-negative."))
return true;
}
}
std::size_t
VectorBase::memory_consumption () const
- {
+ {
std::size_t mem = sizeof(Vec)+sizeof(LastAction::Values)
+MemoryConsumption::memory_consumption(ghosted)
+MemoryConsumption::memory_consumption(ghost_indices);
- // TH: I am relatively sure that PETSc is
- // storing the local data in a contiguous
- // block without indices:
+ // TH: I am relatively sure that PETSc is
+ // storing the local data in a contiguous
+ // block without indices:
mem += local_size()*sizeof(PetscScalar);
- // assume that PETSc is storing one index
- // and one double per ghost element
+ // assume that PETSc is storing one index
+ // and one double per ghost element
if (ghosted)
mem += ghost_indices.n_elements()*(sizeof(PetscScalar)+sizeof(int));
- //TODO[TH]: size of constant memory for PETSc?
+ //TODO[TH]: size of constant memory for PETSc?
return mem;
}
void
VectorBase::do_set_add_operation (const unsigned int n_elements,
- const unsigned int *indices,
- const PetscScalar *values,
- const bool add_values)
+ const unsigned int *indices,
+ const PetscScalar *values,
+ const bool add_values)
{
- Assert ((last_action == (add_values ?
+ Assert ((last_action == (add_values ?
LastAction::add :
LastAction::insert))
||
(last_action == LastAction::none),
- internal::VectorReference::ExcWrongMode ((add_values ?
- LastAction::add :
- LastAction::insert),
- last_action));
-
- // VecSetValues complains if we
- // come with an empty
- // vector. however, it is not a
- // collective operation, so we
- // can skip the call if necessary
- // (unlike the above calls)
+ internal::VectorReference::ExcWrongMode ((add_values ?
+ LastAction::add :
+ LastAction::insert),
+ last_action));
+
+ // VecSetValues complains if we
+ // come with an empty
+ // vector. however, it is not a
+ // collective operation, so we
+ // can skip the call if necessary
+ // (unlike the above calls)
if (n_elements != 0)
{
#ifdef PETSC_USE_64BIT_INDICES
- std::vector<PetscInt> petsc_ind (n_elements);
- for (unsigned int i=0; i<n_elements; ++i)
- petsc_ind[i] = indices[i];
- const PetscInt *petsc_indices = &petsc_ind[0];
+ std::vector<PetscInt> petsc_ind (n_elements);
+ for (unsigned int i=0; i<n_elements; ++i)
+ petsc_ind[i] = indices[i];
+ const PetscInt *petsc_indices = &petsc_ind[0];
#else
- const int * petsc_indices = (const int*)indices;
+ const int * petsc_indices = (const int*)indices;
#endif
- const InsertMode mode = (add_values ? ADD_VALUES : INSERT_VALUES);
- const int ierr
- = VecSetValues (vector, n_elements, petsc_indices, values,
- mode);
- AssertThrow (ierr == 0, ExcPETScError(ierr));
+ const InsertMode mode = (add_values ? ADD_VALUES : INSERT_VALUES);
+ const int ierr
+ = VecSetValues (vector, n_elements, petsc_indices, values,
+ mode);
+ AssertThrow (ierr == 0, ExcPETScError(ierr));
}
// set the mode here, independent of whether we have actually
// written elements or whether the list was empty
- last_action = (add_values ?
+ last_action = (add_values ?
VectorBase::LastAction::add :
VectorBase::LastAction::insert);
}
- void
+ void
VectorBase::update_ghost_values() const
{
- // generate an error for not ghosted
- // vectors
+ // generate an error for not ghosted
+ // vectors
if (!ghosted)
AssertThrow (false, ExcInternalError());
ierr = VecGhostUpdateEnd(vector, INSERT_VALUES, SCATTER_FORWARD);
AssertThrow (ierr == 0, ExcPETScError(ierr));
}
-
-
+
+
}
DEAL_II_NAMESPACE_CLOSE
// $Id$
// Version: $Name$
//
-// Copyright (C) 1999, 2000, 2001, 2002, 2003, 2005, 2006, 2007 by the deal.II authors
+// Copyright (C) 1999, 2000, 2001, 2002, 2003, 2005, 2006, 2007, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
// $Id$
// Version: $Name$
//
-// Copyright (C) 2003, 2005, 2006 by the deal.II authors
+// Copyright (C) 2003, 2005, 2006, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
// $Id$
// Version: $Name$
//
-// Copyright (C) 2010 by the deal.II authors
+// Copyright (C) 2010, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
// Version: $Name$
// Author: Toby D. Young, Polish Academy of Sciences, 2008, 2009
//
-// Copyright (C) 2009 by the deal.II authors
+// Copyright (C) 2009, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
void
SolverBase::set_matrices (const PETScWrappers::MatrixBase &A,
- const PETScWrappers::MatrixBase &B)
+ const PETScWrappers::MatrixBase &B)
{
// generalized eigenspectrum problem
opA = &A;
{
#if DEAL_II_PETSC_VERSION_LT(3,1,0)
- ierr = EPSSetInitialVector (solver_data->eps, *initial_vector);
+ ierr = EPSSetInitialVector (solver_data->eps, *initial_vector);
#else
- Vec this_vector = *initial_vector;
- ierr = EPSSetInitialSpace (solver_data->eps, 1, &this_vector);
+ Vec this_vector = *initial_vector;
+ ierr = EPSSetInitialSpace (solver_data->eps, 1, &this_vector);
#endif
- AssertThrow (ierr == 0, ExcSLEPcError(ierr));
+ AssertThrow (ierr == 0, ExcSLEPcError(ierr));
}
// set transformation type if any
// set number of eigenvectors to
// compute
ierr = EPSSetDimensions (solver_data->eps, n_eigenvectors,
- PETSC_DECIDE, PETSC_DECIDE);
+ PETSC_DECIDE, PETSC_DECIDE);
AssertThrow (ierr == 0, ExcSLEPcError(ierr));
// set the solve options to the
// eigenstates
ierr = EPSGetConverged (solver_data->eps,
#ifdef PETSC_USE_64BIT_INDICES
- reinterpret_cast<PetscInt *>(n_converged));
+ reinterpret_cast<PetscInt *>(n_converged));
#else
- reinterpret_cast<int *>(n_converged));
+ reinterpret_cast<int *>(n_converged));
#endif
AssertThrow (ierr == 0, ExcSLEPcError(ierr));
}
void
SolverBase::get_eigenpair (const unsigned int index,
#ifndef DEAL_II_USE_PETSC_COMPLEX
- double &kr,
+ double &kr,
#else
- std::complex<double> &kr,
+ std::complex<double> &kr,
#endif
- PETScWrappers::VectorBase &vr)
+ PETScWrappers::VectorBase &vr)
{
AssertThrow (solver_data.get() != 0, ExcSLEPcWrappersUsageError());
// get converged eigenpair
int ierr = EPSGetEigenpair (solver_data->eps, index,
- &kr, PETSC_NULL, vr, PETSC_NULL);
+ &kr, PETSC_NULL, vr, PETSC_NULL);
AssertThrow (ierr == 0, ExcSLEPcError(ierr));
}
int
SolverBase::convergence_test (EPS /*eps*/,
#ifdef PETSC_USE_64BIT_INDICES
- const PetscInt iteration,
+ const PetscInt iteration,
#else
- const int iteration,
+ const int iteration,
#endif
- const PetscReal residual_norm,
- EPSConvergedReason *reason,
- void *solver_control_x)
+ const PetscReal residual_norm,
+ EPSConvergedReason *reason,
+ void *solver_control_x)
{
SolverControl &solver_control
= *reinterpret_cast<SolverControl*>(solver_control_x);
switch (state)
{
case ::dealii::SolverControl::iterate:
- *reason = EPS_CONVERGED_ITERATING;
- break;
+ *reason = EPS_CONVERGED_ITERATING;
+ break;
case ::dealii::SolverControl::success:
- *reason = static_cast<EPSConvergedReason>(1);
- break;
+ *reason = static_cast<EPSConvergedReason>(1);
+ break;
case ::dealii::SolverControl::failure:
- if (solver_control.last_step() > solver_control.max_steps())
- *reason = EPS_DIVERGED_ITS;
- else
- *reason = EPS_DIVERGED_BREAKDOWN;
- break;
+ if (solver_control.last_step() > solver_control.max_steps())
+ *reason = EPS_DIVERGED_ITS;
+ else
+ *reason = EPS_DIVERGED_BREAKDOWN;
+ break;
default:
- Assert (false, ExcNotImplemented());
+ Assert (false, ExcNotImplemented());
}
// return without failure.
/* ---------------------- SolverKrylovSchur ------------------------ */
SolverKrylovSchur::SolverKrylovSchur (SolverControl &cn,
- const MPI_Comm &mpi_communicator,
- const AdditionalData &data)
+ const MPI_Comm &mpi_communicator,
+ const AdditionalData &data)
:
SolverBase (cn, mpi_communicator),
additional_data (data)
// the SLEPc convergence
// criterion.
ierr = EPSSetTolerances(eps, this->solver_control.tolerance(),
- this->solver_control.max_steps());
+ this->solver_control.max_steps());
AssertThrow (ierr == 0, ExcSLEPcError(ierr));
}
/* ---------------------- SolverArnoldi ------------------------ */
SolverArnoldi::AdditionalData::
- AdditionalData (const bool delayed_reorthogonalization)
+ AdditionalData (const bool delayed_reorthogonalization)
:
delayed_reorthogonalization (delayed_reorthogonalization)
{}
SolverArnoldi::SolverArnoldi (SolverControl &cn,
- const MPI_Comm &mpi_communicator,
- const AdditionalData &data)
+ const MPI_Comm &mpi_communicator,
+ const AdditionalData &data)
:
SolverBase (cn, mpi_communicator),
additional_data (data)
// the SLEPc convergence
// criterion.
ierr = EPSSetTolerances(eps, this->solver_control.tolerance(),
- this->solver_control.max_steps());
+ this->solver_control.max_steps());
AssertThrow (ierr == 0, ExcSLEPcError(ierr));
// if requested, set delayed
// Arnoldi iteration.
if (additional_data.delayed_reorthogonalization)
{
- ierr = EPSArnoldiSetDelayed (eps, PETSC_TRUE);
- AssertThrow (ierr == 0, ExcSLEPcError(ierr));
+ ierr = EPSArnoldiSetDelayed (eps, PETSC_TRUE);
+ AssertThrow (ierr == 0, ExcSLEPcError(ierr));
}
}
/* ---------------------- Lanczos ------------------------ */
SolverLanczos::SolverLanczos (SolverControl &cn,
- const MPI_Comm &mpi_communicator,
- const AdditionalData &data)
+ const MPI_Comm &mpi_communicator,
+ const AdditionalData &data)
:
SolverBase (cn, mpi_communicator),
additional_data (data)
// the SLEPc convergence
// criterion.
ierr = EPSSetTolerances (eps, this->solver_control.tolerance(),
- this->solver_control.max_steps());
+ this->solver_control.max_steps());
AssertThrow (ierr == 0, ExcSLEPcError(ierr));
}
/* ----------------------- Power ------------------------- */
SolverPower::SolverPower (SolverControl &cn,
- const MPI_Comm &mpi_communicator,
- const AdditionalData &data)
+ const MPI_Comm &mpi_communicator,
+ const AdditionalData &data)
:
SolverBase (cn, mpi_communicator),
additional_data (data)
// the SLEPc convergence
// criterion.
ierr = EPSSetTolerances (eps, this->solver_control.tolerance(),
- this->solver_control.max_steps());
+ this->solver_control.max_steps());
AssertThrow (ierr == 0, ExcSLEPcError(ierr));
}
/* ---------------------- Davidson ----------------------- */
SolverDavidson::SolverDavidson (SolverControl &cn,
- const MPI_Comm &mpi_communicator,
- const AdditionalData &data)
+ const MPI_Comm &mpi_communicator,
+ const AdditionalData &data)
:
SolverBase (cn, mpi_communicator),
additional_data (data)
// the SLEPc convergence
// criterion.
ierr = EPSSetTolerances (eps, this->solver_control.tolerance(),
- this->solver_control.max_steps());
+ this->solver_control.max_steps());
AssertThrow (ierr == 0, ExcSLEPcError(ierr));
}
#endif
// Version: $Name$
// Author: Toby D. Young, Polish Academy of Sciences, 2009
//
-// Copyright (C) 2009 by the deal.II authors
+// Copyright (C) 2009, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
void TransformationBase::set_context (EPS &eps)
{
AssertThrow (transformation_data.get() == 0,
- SolverBase::ExcSLEPcWrappersUsageError());
+ SolverBase::ExcSLEPcWrappersUsageError());
transformation_data.reset (new TransformationData());
int ierr = EPSGetST(eps, &transformation_data->st);
TransformationCayley::AdditionalData::
AdditionalData (const double shift_parameter,
- const double antishift_parameter)
+ const double antishift_parameter)
:
shift_parameter (shift_parameter),
- antishift_parameter (antishift_parameter)
+ antishift_parameter (antishift_parameter)
{
}
TransformationCayley::TransformationCayley (const double shift,
- const double antishift)
+ const double antishift)
:
additional_data (shift, antishift)
{}
// $Id$
// Version: $Name$
//
-// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2006, 2007 by the deal.II authors
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2006, 2007, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
// $Id$
// Version: $Name$
//
-// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2006, 2010 by the deal.II authors
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2006, 2010, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
SolverControl::NoConvergence::NoConvergence (const unsigned int last_step,
- const double last_residual)
- :
- last_step (last_step),
- last_residual (last_residual)
+ const double last_residual)
+ :
+ last_step (last_step),
+ last_residual (last_residual)
{}
const char *
SolverControl::NoConvergence::what () const throw ()
{
- // have a place where to store the
- // description of the exception as a char *
- //
- // this thing obviously is not multi-threading
- // safe, but we don't care about that for now
- //
- // we need to make this object static, since
- // we want to return the data stored in it
- // and therefore need a liftime which is
- // longer than the execution time of this
- // function
+ // have a place where to store the
+ // description of the exception as a char *
+ //
+ // this thing obviously is not multi-threading
+ // safe, but we don't care about that for now
+ //
+ // we need to make this object static, since
+ // we want to return the data stored in it
+ // and therefore need a liftime which is
+ // longer than the execution time of this
+ // function
static std::string description;
- // convert the messages printed by the
- // exceptions into a std::string
+ // convert the messages printed by the
+ // exceptions into a std::string
std::ostringstream out;
out << "Iterative method reported convergence failure in step "
<< last_step << " with residual " << last_residual;
SolverControl::SolverControl (const unsigned int maxiter,
- const double tolerance,
- const bool m_log_history,
- const bool m_log_result)
- :
- maxsteps(maxiter),
- tol(tolerance),
- lvalue(1.e300),
- lstep(0),
- check_failure(false),
- relative_failure_residual(0),
- failure_residual(0),
- m_log_history(m_log_history),
- m_log_frequency(1),
- m_log_result(m_log_result),
- history_data_enabled(false)
+ const double tolerance,
+ const bool m_log_history,
+ const bool m_log_result)
+ :
+ maxsteps(maxiter),
+ tol(tolerance),
+ lvalue(1.e300),
+ lstep(0),
+ check_failure(false),
+ relative_failure_residual(0),
+ failure_residual(0),
+ m_log_history(m_log_history),
+ m_log_frequency(1),
+ m_log_result(m_log_result),
+ history_data_enabled(false)
{}
-SolverControl::~SolverControl()
+SolverControl::~SolverControl()
{}
SolverControl::State
SolverControl::check (const unsigned int step,
- const double check_value)
+ const double check_value)
{
- // if this is the first time we
- // come here, then store the
- // residual for later comparisons
+ // if this is the first time we
+ // come here, then store the
+ // residual for later comparisons
if (step==0)
{
initial_val = check_value;
if (history_data_enabled)
- history_data.resize(maxsteps);
+ history_data.resize(maxsteps);
}
-
+
if (m_log_history && ((step % m_log_frequency) == 0))
deallog << "Check " << step << "\t" << check_value << std::endl;
-
+
lstep = step;
lvalue = check_value;
if (step==0)
{
if (check_failure)
- failure_residual=relative_failure_residual*check_value;
-
+ failure_residual=relative_failure_residual*check_value;
+
if (m_log_result)
- deallog << "Starting value " << check_value << std::endl;
+ deallog << "Starting value " << check_value << std::endl;
}
if (history_data_enabled)
history_data[step] = check_value;
-
+
if (check_value <= tol)
{
if (m_log_result)
- deallog << "Convergence step " << step
- << " value " << check_value << std::endl;
+ deallog << "Convergence step " << step
+ << " value " << check_value << std::endl;
lcheck = success;
return success;
}
-
+
if ((step >= maxsteps) ||
#ifdef HAVE_ISNAN
isnan(check_value) ||
#else
# if HAVE_UNDERSCORE_ISNAN
- // on Microsoft Windows, the
- // function is called _isnan
+ // on Microsoft Windows, the
+ // function is called _isnan
_isnan(check_value) ||
# endif
#endif
)
{
if (m_log_result)
- deallog << "Failure step " << step
- << " value " << check_value << std::endl;
+ deallog << "Failure step " << step
+ << " value " << check_value << std::endl;
lcheck = failure;
return failure;
}
{
if (lstep == 0)
return 0.;
-
+
Assert (history_data_enabled, ExcHistoryDataRequired());
Assert (history_data.size() > lstep, ExcInternalError());
Assert (history_data[0] > 0., ExcInternalError());
Assert (history_data[lstep] > 0., ExcInternalError());
-
+
return std::pow(history_data[lstep]/history_data[0], 1./lstep);
}
Assert (history_data.size() > lstep, ExcInternalError());
Assert (step <=lstep, ExcIndexRange(step,1,lstep+1));
Assert (step>0, ExcIndexRange(step,1,lstep+1));
-
+
return history_data[step]/history_data[step-1];
}
return step_reduction(lstep);
}
-
+
void
SolverControl::declare_parameters (ParameterHandler& param)
{
ReductionControl::ReductionControl(const unsigned int n,
- const double tol,
- const double red,
- const bool m_log_history,
- const bool m_log_result)
- :
- SolverControl (n, tol, m_log_history, m_log_result),
- reduce(red)
+ const double tol,
+ const double red,
+ const bool m_log_history,
+ const bool m_log_result)
+ :
+ SolverControl (n, tol, m_log_history, m_log_result),
+ reduce(red)
{}
ReductionControl::ReductionControl (const SolverControl& c)
- :
- SolverControl(c)
+ :
+ SolverControl(c)
{
set_reduction(0.);
}
SolverControl::State
ReductionControl::check (const unsigned int step,
- const double check_value)
+ const double check_value)
{
- // if this is the first time we
- // come here, then store the
- // residual for later comparisons
+ // if this is the first time we
+ // come here, then store the
+ // residual for later comparisons
if (step==0)
{
initial_val = check_value;
reduced_tol = check_value * reduce;
};
- // check whether desired reduction
- // has been achieved. also check
- // for equality in case initial
- // residual already was zero
+ // check whether desired reduction
+ // has been achieved. also check
+ // for equality in case initial
+ // residual already was zero
if (check_value <= reduced_tol)
{
if (m_log_result)
- deallog << "Convergence step " << step
- << " value " << check_value << std::endl;
+ deallog << "Convergence step " << step
+ << " value " << check_value << std::endl;
lstep = step;
lvalue = check_value;
-
+
lcheck = success;
return success;
}
//---------------------------------------------------------------------------
-// Copyright (C) 2002, 2003, 2005, 2006 by the deal.II authors
+// Copyright (C) 2002, 2003, 2005, 2006, 2012 by the deal.II authors
// by the deal.II authors and Stephen "Cheffo" Kolaroff
//
// This file is subject to QPL and may not be distributed
template class SparseLUDecomposition<double>;
template void SparseLUDecomposition<double>::initialize<double> (const SparseMatrix<double> &,
- const AdditionalData data);
+ const AdditionalData data);
template void SparseLUDecomposition<double>::initialize<float> (const SparseMatrix<float> &,
- const AdditionalData data);
+ const AdditionalData data);
template void SparseLUDecomposition<double>::decompose<double> (const SparseMatrix<double> &,
const double);
template void SparseLUDecomposition<double>::decompose<float> (const SparseMatrix<float> &,
template class SparseLUDecomposition<float>;
template void SparseLUDecomposition<float>::initialize<double> (const SparseMatrix<double> &,
- const AdditionalData data);
+ const AdditionalData data);
template void SparseLUDecomposition<float>::initialize<float> (const SparseMatrix<float> &,
- const AdditionalData data);
+ const AdditionalData data);
template void SparseLUDecomposition<float>::decompose<double> (const SparseMatrix<double> &,
const double);
template void SparseLUDecomposition<float>::decompose<float> (const SparseMatrix<float> &,
{
extern "C"
void ma27ad_ (const unsigned int *,
- const unsigned int *,
- const unsigned int *,
- const unsigned int *,
- unsigned int *,
- const unsigned int *,
- unsigned int *,
- unsigned int *,
- unsigned int *,
- int *)
+ const unsigned int *,
+ const unsigned int *,
+ const unsigned int *,
+ unsigned int *,
+ const unsigned int *,
+ unsigned int *,
+ unsigned int *,
+ unsigned int *,
+ int *)
{
AssertThrow (false,
ExcMessage("You can only use the HSL functions after putting "
extern "C"
void ma27bd_ (const unsigned int *,
- const unsigned int *,
- const unsigned int *,
- const unsigned int *,
- double *,
- const unsigned int *,
- unsigned int *,
- const unsigned int *,
- const unsigned int *,
- const unsigned int *,
- unsigned int *,
- unsigned int *,
- int *)
+ const unsigned int *,
+ const unsigned int *,
+ const unsigned int *,
+ double *,
+ const unsigned int *,
+ unsigned int *,
+ const unsigned int *,
+ const unsigned int *,
+ const unsigned int *,
+ unsigned int *,
+ unsigned int *,
+ int *)
{
AssertThrow (false,
ExcMessage("You can only use the HSL functions after putting "
extern "C"
void ma27cd_ (const unsigned int *,
- const double *,
- const unsigned int *,
- const unsigned int *,
- const unsigned int *,
- double *,
- const unsigned int *,
- double *,
- const unsigned int *,
- const unsigned int *)
+ const double *,
+ const unsigned int *,
+ const unsigned int *,
+ const unsigned int *,
+ double *,
+ const unsigned int *,
+ double *,
+ const unsigned int *,
+ const unsigned int *)
{
AssertThrow (false,
ExcMessage("You can only use the HSL functions after putting "
{
extern "C"
void ma47id_ (double *,
- unsigned int *)
+ unsigned int *)
{
AssertThrow (false,
ExcMessage("You can only use the HSL functions after putting "
extern "C"
void ma47ad_ (const unsigned int *,
- const unsigned int *,
- unsigned int *,
- unsigned int *,
- unsigned int *,
- const unsigned int *,
- unsigned int *,
- const unsigned int *,
- double *,
- int *)
+ const unsigned int *,
+ unsigned int *,
+ unsigned int *,
+ unsigned int *,
+ const unsigned int *,
+ unsigned int *,
+ const unsigned int *,
+ double *,
+ int *)
{
AssertThrow (false,
ExcMessage("You can only use the HSL functions after putting "
extern "C"
void ma47bd_ (const unsigned int *,
- const unsigned int *,
- const unsigned int *,
- double *,
- const unsigned int *,
- unsigned int *,
- const unsigned int *,
- const unsigned int *,
- const double *,
- const unsigned int *,
- unsigned int *,
- double *,
- int *)
+ const unsigned int *,
+ const unsigned int *,
+ double *,
+ const unsigned int *,
+ unsigned int *,
+ const unsigned int *,
+ const unsigned int *,
+ const double *,
+ const unsigned int *,
+ unsigned int *,
+ double *,
+ int *)
{
AssertThrow (false,
ExcMessage("You can only use the HSL functions after putting "
extern "C"
void ma47cd_ (const unsigned int *,
- const double *,
- const unsigned int *,
- const unsigned int *,
- const unsigned int *,
- double *,
- double *,
- unsigned int *,
- const unsigned int *)
+ const double *,
+ const unsigned int *,
+ const unsigned int *,
+ const unsigned int *,
+ double *,
+ double *,
+ unsigned int *,
+ const unsigned int *)
{
AssertThrow (false,
ExcMessage("You can only use the HSL functions after putting "
*/
Threads::ThreadMutex mutex;
- /**
- * File handles for the pipe
- * between server (computing
- * process) and client (display
- * process).
- */
+ /**
+ * File handles for the pipe
+ * between server (computing
+ * process) and client (display
+ * process).
+ */
int server_client_pipe[2];
int client_server_pipe[2];
- /**
- * PID of the forked child
- * process.
- */
+ /**
+ * PID of the forked child
+ * process.
+ */
pid_t child_pid;
/**
template <typename T>
void put (const T *t,
const std::size_t N,
- const char * /*debug_info*/) const
+ const char * /*debug_info*/) const
{
unsigned int count = 0;
while (count < sizeof(T)*N)
*/
template <typename T>
void get (T *t,
- const std::size_t N,
- const char * /*debug_info*/) const
+ const std::size_t N,
+ const char * /*debug_info*/) const
{
unsigned int count = 0;
while (count < sizeof(T)*N)
SparseDirectMA27::SparseDirectMA27 (const double LIW_factor_1,
- const double LIW_factor_2,
- const double LA_factor,
- const double LIW_increase_factor_1,
- const double LIW_increase_factor_2,
- const double LA_increase_factor,
- const bool suppress_output)
+ const double LIW_factor_2,
+ const double LA_factor,
+ const double LIW_increase_factor_1,
+ const double LIW_increase_factor_2,
+ const double LA_increase_factor,
+ const bool suppress_output)
:
suppress_output (suppress_output),
detached_mode (false),
detached_mode_data (0),
- LIW_factor_1 (LIW_factor_1),
- LIW_factor_2 (LIW_factor_2),
- LA_factor (LA_factor),
- LIW_increase_factor_1 (LIW_increase_factor_1),
- LIW_increase_factor_2 (LIW_increase_factor_2),
- LA_increase_factor (LA_increase_factor),
- initialize_called (false),
- factorize_called (false),
- sparsity_pattern (0, typeid(*this).name())
+ LIW_factor_1 (LIW_factor_1),
+ LIW_factor_2 (LIW_factor_2),
+ LA_factor (LA_factor),
+ LIW_increase_factor_1 (LIW_increase_factor_1),
+ LIW_increase_factor_2 (LIW_increase_factor_2),
+ LA_increase_factor (LA_increase_factor),
+ initialize_called (false),
+ factorize_called (false),
+ sparsity_pattern (0, typeid(*this).name())
{}
{
// close down client
Threads::ThreadMutex::ScopedLock lock (detached_mode_data->mutex);
- // Assign the result of write
- // and reset the variable to
- // avoid compiler warnings
+ // Assign the result of write
+ // and reset the variable to
+ // avoid compiler warnings
//TODO:[WB] Should t be used to trace errors?
ssize_t t = write (detached_mode_data->server_client_pipe[1], "7", 1);
- (void)t;
+ (void)t;
// then also delete data
delete detached_mode_data;
detached_mode_data = 0;
// slave process will read its
// stdin
- // Assign the return value to a
- // variable to avoid compiler
- // warnings
+ // Assign the return value to a
+ // variable to avoid compiler
+ // warnings
//TODO:[WB] Use t to trace errors?
int t = pipe(detached_mode_data->server_client_pipe);
(void)t;
};
- // suppress error output if
- // requested
+ // suppress error output if
+ // requested
if (suppress_output)
{
const unsigned int LP = 0;
const unsigned int * const
col_nums = sparsity_pattern->get_column_numbers();
- // first count number of nonzero
- // elements in the upper right
- // part. the matrix is symmetric,
- // so this suffices
+ // first count number of nonzero
+ // elements in the upper right
+ // part. the matrix is symmetric,
+ // so this suffices
n_nonzero_elements = 0;
for (unsigned int row=0; row<n_rows; ++row)
for (const unsigned int *col=&col_nums[rowstart_indices[row]];
- col != &col_nums[rowstart_indices[row+1]];
- ++col)
+ col != &col_nums[rowstart_indices[row+1]];
+ ++col)
if (row <= *col)
- ++n_nonzero_elements;
+ ++n_nonzero_elements;
- // fill the row numbers and column
- // numbers arrays from the sparsity
- // pattern. note that we have
- // Fortran convention, i.e. indices
- // need to be 1-base, as opposed to
- // C's 0-based convention!
+ // fill the row numbers and column
+ // numbers arrays from the sparsity
+ // pattern. note that we have
+ // Fortran convention, i.e. indices
+ // need to be 1-base, as opposed to
+ // C's 0-based convention!
row_numbers.resize (n_nonzero_elements);
column_numbers.resize (n_nonzero_elements);
unsigned int global_index = 0;
for (unsigned int row=0; row<n_rows; ++row)
for (const unsigned int *col=&col_nums[rowstart_indices[row]];
- col != &col_nums[rowstart_indices[row+1]];
- ++col)
- // note that the matrix must be
- // symmetric, so only treat the
- // upper right part
+ col != &col_nums[rowstart_indices[row+1]];
+ ++col)
+ // note that the matrix must be
+ // symmetric, so only treat the
+ // upper right part
if (row <= *col)
- {
- Assert (global_index < n_nonzero_elements, ExcInternalError());
+ {
+ Assert (global_index < n_nonzero_elements, ExcInternalError());
- row_numbers[global_index] = row+1;
- column_numbers[global_index] = *col+1;
- ++global_index;
- };
+ row_numbers[global_index] = row+1;
+ column_numbers[global_index] = *col+1;
+ ++global_index;
+ };
Assert (global_index == n_nonzero_elements, ExcInternalError());
- // initialize scratch arrays and
- // variables
+ // initialize scratch arrays and
+ // variables
LIW = static_cast<unsigned int>((2*n_nonzero_elements + 3*n_rows + 1) *
- LIW_factor_1);
+ LIW_factor_1);
IW.resize (detached_mode_set() ? 0 : LIW);
IKEEP.resize (detached_mode_set() ? 0 : 3*n_rows);
IW1.resize (detached_mode_set() ? 0 : 2*n_rows);
- // no output please
+ // no output please
IFLAG = 0;
- // loop until memory requirements
- // are satisfied or we are not
- // allowed to allocate more memory
- // no more
+ // loop until memory requirements
+ // are satisfied or we are not
+ // allowed to allocate more memory
+ // no more
bool call_succeeded = true;
do
{
&IW1[0], &NSTEPS, &IFLAG);
call_succeeded = (IFLAG==0);
- // if enough memory or no
- // increase allowed: exit loop
+ // if enough memory or no
+ // increase allowed: exit loop
if (call_succeeded || (LIW_increase_factor_1 <= 1))
- break;
+ break;
- // otherwise: increase LIW and retry
+ // otherwise: increase LIW and retry
LIW = static_cast<unsigned int>(LIW * LIW_increase_factor_1);
IW.resize (LIW);
}
while (true);
- // if we were not allowed to
- // allocate more memory, then throw
- // an exception
+ // if we were not allowed to
+ // allocate more memory, then throw
+ // an exception
AssertThrow (call_succeeded, ExcMA27AFailed(IFLAG));
- // catch returned values from the
- // COMMON block. we need these
- // values in order to set array
- // sizes in the next function
+ // catch returned values from the
+ // COMMON block. we need these
+ // values in order to set array
+ // sizes in the next function
call_ma27x1 (&NRLNEC);
call_ma27x2 (&NIRNEC);
- // note that we have already been
- // in this function
+ // note that we have already been
+ // in this function
initialize_called = true;
}
void
SparseDirectMA27::factorize (const SparseMatrix<number> &matrix)
{
- // if necessary, initialize process
+ // if necessary, initialize process
if (initialize_called == false)
initialize (matrix.get_sparsity_pattern());
- // make sure the sparsity patterns
- // are the same
+ // make sure the sparsity patterns
+ // are the same
Assert (sparsity_pattern == &matrix.get_sparsity_pattern(),
- ExcDifferentSparsityPatterns());
+ ExcDifferentSparsityPatterns());
- // set LA and fill the A array of
- // values
+ // set LA and fill the A array of
+ // values
LA = std::max (static_cast<int>(NRLNEC * LA_factor),
- static_cast<int>(n_nonzero_elements));
+ static_cast<int>(n_nonzero_elements));
A.resize (LA);
fill_A (matrix);
- // if necessary extend IW
+ // if necessary extend IW
if (LIW < NIRNEC * LIW_factor_2)
{
LIW = static_cast<unsigned int>(NIRNEC * LIW_factor_2);
const unsigned int n_rows = matrix.get_sparsity_pattern().n_rows();
- // loop until memory requirements
- // are satisfied or we are not
- // allowed to allocate more memory
- // no more
+ // loop until memory requirements
+ // are satisfied or we are not
+ // allowed to allocate more memory
+ // no more
bool call_succeeded = true;
do
{
&IW1[0], &IFLAG);
call_succeeded = (IFLAG==0);
- // if enough memory or no
- // increase allowed: exit
- // loop. delete data that is no
- // more used
+ // if enough memory or no
+ // increase allowed: exit
+ // loop. delete data that is no
+ // more used
if (call_succeeded)
{
std::vector<unsigned int> tmp1, tmp2, tmp3;
};
- // otherwise: increase LIW or
- // LA if that is allowed and
- // retry
+ // otherwise: increase LIW or
+ // LA if that is allowed and
+ // retry
switch (IFLAG)
- {
- case -3:
- {
- if (LIW_increase_factor_2 <= 1)
- goto exit_loop;
-
- LIW = static_cast<unsigned int>(LIW * LIW_increase_factor_2);
- IW.resize (LIW);
- break;
- };
-
- case -4:
- {
- if (LA_increase_factor <= 1)
- goto exit_loop;
- // increase A. note that
- // since the function has
- // already part of the
- // array @p{A}, we have
- // to re-fill it with the
- // original values. minor
- // clue: since the old
- // entries are no more
- // needed, we can discard
- // them; we use this to
- // first release all
- // memory (through the
- // call to @p{swap} and
- // the subsequent call to
- // the destructor of the
- // @p{tmp} object) and
- // only then re-allocate
- // it. If we called
- // @p{resize} directly,
- // this would first
- // allocate more memory,
- // then copy the old
- // contents, and only
- // then release the old
- // memory, but keeping
- // both memory regions at
- // the same time could
- // sometimes be more than
- // we can do, leading to
- // an exception on the
- // allocation.
- std::cout << "<*>" << std::flush;
-
- LA = static_cast<unsigned int>(LA * LA_increase_factor);
- if (true)
- {
- std::vector<double> tmp;
- A.swap (tmp);
- };
-
- A.resize (LA);
- fill_A (matrix);
-
- break;
- };
-
- // ups, other return
- // value, don't know
- // what to do here
- default:
- AssertThrow (false, ExcMA27BFailed(IFLAG));
- };
+ {
+ case -3:
+ {
+ if (LIW_increase_factor_2 <= 1)
+ goto exit_loop;
+
+ LIW = static_cast<unsigned int>(LIW * LIW_increase_factor_2);
+ IW.resize (LIW);
+ break;
+ };
+
+ case -4:
+ {
+ if (LA_increase_factor <= 1)
+ goto exit_loop;
+ // increase A. note that
+ // since the function has
+ // already part of the
+ // array @p{A}, we have
+ // to re-fill it with the
+ // original values. minor
+ // clue: since the old
+ // entries are no more
+ // needed, we can discard
+ // them; we use this to
+ // first release all
+ // memory (through the
+ // call to @p{swap} and
+ // the subsequent call to
+ // the destructor of the
+ // @p{tmp} object) and
+ // only then re-allocate
+ // it. If we called
+ // @p{resize} directly,
+ // this would first
+ // allocate more memory,
+ // then copy the old
+ // contents, and only
+ // then release the old
+ // memory, but keeping
+ // both memory regions at
+ // the same time could
+ // sometimes be more than
+ // we can do, leading to
+ // an exception on the
+ // allocation.
+ std::cout << "<*>" << std::flush;
+
+ LA = static_cast<unsigned int>(LA * LA_increase_factor);
+ if (true)
+ {
+ std::vector<double> tmp;
+ A.swap (tmp);
+ };
+
+ A.resize (LA);
+ fill_A (matrix);
+
+ break;
+ };
+
+ // ups, other return
+ // value, don't know
+ // what to do here
+ default:
+ AssertThrow (false, ExcMA27BFailed(IFLAG));
+ };
continue;
exit_loop:
AssertThrow (call_succeeded, ExcMA27BFailed(IFLAG));
- // note that we have been here
- // already and release the sparsity
- // pattern object, since we won't
- // need it any more
+ // note that we have been here
+ // already and release the sparsity
+ // pattern object, since we won't
+ // need it any more
factorize_called = true;
sparsity_pattern = 0;
}
template <typename number>
void
SparseDirectMA27::solve (const SparseMatrix<number> &matrix,
- Vector<double> &rhs_and_solution)
+ Vector<double> &rhs_and_solution)
{
initialize (matrix.get_sparsity_pattern());
factorize (matrix);
SparseDirectMA27::memory_consumption () const
{
return (sizeof(*this) +
- MemoryConsumption::memory_consumption (row_numbers) +
- MemoryConsumption::memory_consumption (column_numbers) +
- MemoryConsumption::memory_consumption (A) +
- MemoryConsumption::memory_consumption (IW) +
- MemoryConsumption::memory_consumption (IKEEP) +
- MemoryConsumption::memory_consumption (IW1));
+ MemoryConsumption::memory_consumption (row_numbers) +
+ MemoryConsumption::memory_consumption (column_numbers) +
+ MemoryConsumption::memory_consumption (A) +
+ MemoryConsumption::memory_consumption (IW) +
+ MemoryConsumption::memory_consumption (IKEEP) +
+ MemoryConsumption::memory_consumption (IW1));
}
unsigned int global_index = 0;
for (unsigned int row=0; row<n_rows; ++row)
for (const unsigned int *col=&col_nums[rowstart_indices[row]];
- col != &col_nums[rowstart_indices[row+1]];
- ++col)
- // note that the matrix must be
- // symmetric, so only treat the
- // upper right part
+ col != &col_nums[rowstart_indices[row+1]];
+ ++col)
+ // note that the matrix must be
+ // symmetric, so only treat the
+ // upper right part
if (row <= *col)
- {
- Assert (global_index < n_nonzero_elements, ExcInternalError());
+ {
+ Assert (global_index < n_nonzero_elements, ExcInternalError());
- A[global_index] = matrix(row,*col);
- ++global_index;
+ A[global_index] = matrix(row,*col);
+ ++global_index;
// make sure that the symmetric
// entry exists and has the same
Assert ((matrix(row,*col) == 0)
||
(std::fabs(matrix(row,*col) - matrix(*col,row))
- <= 1e-15 * std::fabs (matrix(row,*col))),
+ <= 1e-15 * std::fabs (matrix(row,*col))),
ExcMatrixNotSymmetric());
- }
+ }
else
// lower left part. just check
// symmetry
Assert ((matrix(row,*col) == 0)
||
(std::fabs(matrix(row,*col) - matrix(*col,row))
- <= 1e-15 * std::fabs (matrix(row,*col))),
+ <= 1e-15 * std::fabs (matrix(row,*col))),
ExcMatrixNotSymmetric());
Assert (global_index == n_nonzero_elements, ExcInternalError());
SparseDirectMA47::SparseDirectMA47 (const double LIW_factor_1,
- const double LIW_factor_2,
- const double LA_factor,
- const double LIW_increase_factor_1,
- const double LIW_increase_factor_2,
- const double LA_increase_factor,
- const bool suppress_output)
+ const double LIW_factor_2,
+ const double LA_factor,
+ const double LIW_increase_factor_1,
+ const double LIW_increase_factor_2,
+ const double LA_increase_factor,
+ const bool suppress_output)
:
suppress_output (suppress_output),
- LIW_factor_1 (LIW_factor_1),
- LIW_factor_2 (LIW_factor_2),
- LA_factor (LA_factor),
- LIW_increase_factor_1 (LIW_increase_factor_1),
- LIW_increase_factor_2 (LIW_increase_factor_2),
- LA_increase_factor (LA_increase_factor),
- initialize_called (false),
- factorize_called (false),
- matrix (0, typeid(*this).name())
+ LIW_factor_1 (LIW_factor_1),
+ LIW_factor_2 (LIW_factor_2),
+ LA_factor (LA_factor),
+ LIW_increase_factor_1 (LIW_increase_factor_1),
+ LIW_increase_factor_2 (LIW_increase_factor_2),
+ LA_increase_factor (LA_increase_factor),
+ initialize_called (false),
+ factorize_called (false),
+ matrix (0, typeid(*this).name())
{}
const unsigned int * const
col_nums = sparsity_pattern.get_column_numbers();
- // first count number of nonzero
- // elements in the upper right
- // part. the matrix is symmetric,
- // so this suffices
+ // first count number of nonzero
+ // elements in the upper right
+ // part. the matrix is symmetric,
+ // so this suffices
n_nonzero_elements = 0;
for (unsigned int row=0; row<n_rows; ++row)
for (const unsigned int *col=&col_nums[rowstart_indices[row]];
- col != &col_nums[rowstart_indices[row+1]];
- ++col)
- // skip zero elements, as
- // required by the docs of MA47
+ col != &col_nums[rowstart_indices[row+1]];
+ ++col)
+ // skip zero elements, as
+ // required by the docs of MA47
if ((row <= *col) && (m(row,*col) != 0))
- ++n_nonzero_elements;
+ ++n_nonzero_elements;
- // fill the row numbers and column
- // numbers arrays from the sparsity
- // pattern. note that we have
- // Fortran convention, i.e. indices
- // need to be 1-base, as opposed to
- // C's 0-based convention!
+ // fill the row numbers and column
+ // numbers arrays from the sparsity
+ // pattern. note that we have
+ // Fortran convention, i.e. indices
+ // need to be 1-base, as opposed to
+ // C's 0-based convention!
row_numbers.resize (n_nonzero_elements);
column_numbers.resize (n_nonzero_elements);
unsigned int global_index = 0;
for (unsigned int row=0; row<n_rows; ++row)
for (const unsigned int *col=&col_nums[rowstart_indices[row]];
- col != &col_nums[rowstart_indices[row+1]];
- ++col)
- // note that the matrix must be
- // symmetric, so only treat the
- // upper right part
+ col != &col_nums[rowstart_indices[row+1]];
+ ++col)
+ // note that the matrix must be
+ // symmetric, so only treat the
+ // upper right part
if ((row <= *col) && (m(row,*col) != 0))
- {
- Assert (global_index < n_nonzero_elements, ExcInternalError());
+ {
+ Assert (global_index < n_nonzero_elements, ExcInternalError());
- row_numbers[global_index] = row+1;
- column_numbers[global_index] = *col+1;
- ++global_index;
- };
+ row_numbers[global_index] = row+1;
+ column_numbers[global_index] = *col+1;
+ ++global_index;
+ };
Assert (global_index == n_nonzero_elements, ExcInternalError());
- // initialize scratch arrays and
- // variables
+ // initialize scratch arrays and
+ // variables
LIW = static_cast<unsigned int>((2*n_nonzero_elements + 5*n_rows + 4) *
- LIW_factor_1);
+ LIW_factor_1);
IW.resize (LIW);
KEEP.resize (n_nonzero_elements + 5*n_rows + 2);
- // declare output info fields
+ // declare output info fields
bool call_succeeded;
do
{
&ICNTL[0], &INFO[0]);
call_succeeded = (INFO[0] == 0);
- // if enough memory or no
- // increase allowed: exit loop
+ // if enough memory or no
+ // increase allowed: exit loop
if (call_succeeded || (LIW_increase_factor_1 <= 1))
- break;
+ break;
- // otherwise: increase LIW and retry
+ // otherwise: increase LIW and retry
LIW = static_cast<unsigned int>(LIW * LIW_increase_factor_1);
IW.resize (LIW);
}
AssertThrow (call_succeeded, ExcMA47AFailed(INFO[0]));
- // note that we have already been
- // in this function
+ // note that we have already been
+ // in this function
initialize_called = true;
}
Assert (factorize_called == false,
ExcCantFactorizeAgain());
- // if necessary, initialize process
+ // if necessary, initialize process
if (initialize_called == false)
initialize (m);
- // make sure the matrices
- // are the same
+ // make sure the matrices
+ // are the same
Assert (matrix == &m, ExcDifferentMatrices());
- // set LA and fill the A array of
- // values
+ // set LA and fill the A array of
+ // values
LA = std::max (static_cast<int>(INFO[5] * LA_factor),
- static_cast<int>(n_nonzero_elements));
+ static_cast<int>(n_nonzero_elements));
A.resize (LA);
fill_A (m);
- // if necessary extend IW
+ // if necessary extend IW
if (LIW < INFO[6] * LIW_factor_2)
{
LIW = static_cast<unsigned int>(INFO[6] * LIW_factor_2);
const unsigned int n_rows = m.get_sparsity_pattern().n_rows();
IW1.resize (2*n_rows+2);
- // output info flags
+ // output info flags
bool call_succeeded;
do
{
&IW1[0], &INFO[0]);
call_succeeded = (INFO[0] == 0);
- // if enough memory or no
- // increase allowed: exit loop
+ // if enough memory or no
+ // increase allowed: exit loop
if (call_succeeded)
- break;
+ break;
- // otherwise: increase LIW or
- // LA if that is allowed and
- // retry
+ // otherwise: increase LIW or
+ // LA if that is allowed and
+ // retry
switch (INFO[0])
- {
- case -3:
- {
- if (LIW_increase_factor_2 <= 1)
- goto exit_loop;
-
- LIW = static_cast<unsigned int>(LIW * LIW_increase_factor_2);
- IW.resize (LIW);
- break;
- };
-
- case -4:
- {
- if (LA_increase_factor <= 1)
- goto exit_loop;
- // increase A. note that
- // since the function has
- // already part of the
- // array @p{A}, we have
- // to re-fill it with the
- // original values. minor
- // clue: since the old
- // entries are no more
- // needed, we can discard
- // them; we use this to
- // first release all
- // memory (through the
- // call to @p{swap} and
- // the subsequent call to
- // the destructor of the
- // @p{tmp} object) and
- // only then re-allocate
- // it. If we called
- // @p{resize} directly,
- // this would first
- // allocate more memory,
- // then copy the old
- // contents, and only
- // then release the old
- // memory, but keeping
- // both memory regions at
- // the same time could
- // sometimes be more than
- // we can do, leading to
- // an exception on the
- // allocation.
- std::cout << "<*>" << std::flush;
-
- LA = static_cast<unsigned int>(LA * LA_increase_factor);
- if (true)
- {
- std::vector<double> tmp;
- A.swap (tmp);
- };
-
- A.resize (LA);
- fill_A (m);
-
- break;
- };
-
- // ups, other return
- // value, don't know
- // what to do here
- default:
- AssertThrow (false, ExcMA47BFailed(INFO[0]));
- };
+ {
+ case -3:
+ {
+ if (LIW_increase_factor_2 <= 1)
+ goto exit_loop;
+
+ LIW = static_cast<unsigned int>(LIW * LIW_increase_factor_2);
+ IW.resize (LIW);
+ break;
+ };
+
+ case -4:
+ {
+ if (LA_increase_factor <= 1)
+ goto exit_loop;
+ // increase A. note that
+ // since the function has
+ // already part of the
+ // array @p{A}, we have
+ // to re-fill it with the
+ // original values. minor
+ // clue: since the old
+ // entries are no more
+ // needed, we can discard
+ // them; we use this to
+ // first release all
+ // memory (through the
+ // call to @p{swap} and
+ // the subsequent call to
+ // the destructor of the
+ // @p{tmp} object) and
+ // only then re-allocate
+ // it. If we called
+ // @p{resize} directly,
+ // this would first
+ // allocate more memory,
+ // then copy the old
+ // contents, and only
+ // then release the old
+ // memory, but keeping
+ // both memory regions at
+ // the same time could
+ // sometimes be more than
+ // we can do, leading to
+ // an exception on the
+ // allocation.
+ std::cout << "<*>" << std::flush;
+
+ LA = static_cast<unsigned int>(LA * LA_increase_factor);
+ if (true)
+ {
+ std::vector<double> tmp;
+ A.swap (tmp);
+ };
+
+ A.resize (LA);
+ fill_A (m);
+
+ break;
+ };
+
+ // ups, other return
+ // value, don't know
+ // what to do here
+ default:
+ AssertThrow (false, ExcMA47BFailed(INFO[0]));
+ };
continue;
exit_loop:
AssertThrow (call_succeeded, ExcMA47BFailed(INFO[0]));
- // note that we have been here
- // already
+ // note that we have been here
+ // already
factorize_called = true;
}
void
SparseDirectMA47::solve (const SparseMatrix<double> &matrix,
- Vector<double> &rhs_and_solution)
+ Vector<double> &rhs_and_solution)
{
initialize (matrix);
factorize (matrix);
SparseDirectMA47::memory_consumption () const
{
return (sizeof(*this) +
- MemoryConsumption::memory_consumption (row_numbers) +
- MemoryConsumption::memory_consumption (column_numbers) +
- MemoryConsumption::memory_consumption (A) +
- MemoryConsumption::memory_consumption (IW) +
- MemoryConsumption::memory_consumption (KEEP) +
- MemoryConsumption::memory_consumption (IW1));
+ MemoryConsumption::memory_consumption (row_numbers) +
+ MemoryConsumption::memory_consumption (column_numbers) +
+ MemoryConsumption::memory_consumption (A) +
+ MemoryConsumption::memory_consumption (IW) +
+ MemoryConsumption::memory_consumption (KEEP) +
+ MemoryConsumption::memory_consumption (IW1));
}
unsigned int global_index = 0;
for (unsigned int row=0; row<n_rows; ++row)
for (const unsigned int *col=&col_nums[rowstart_indices[row]];
- col != &col_nums[rowstart_indices[row+1]];
- ++col)
- // note that the matrix must be
- // symmetric, so only treat the
- // upper right part
+ col != &col_nums[rowstart_indices[row+1]];
+ ++col)
+ // note that the matrix must be
+ // symmetric, so only treat the
+ // upper right part
if ((row <= *col) && (matrix(row,*col) != 0))
- {
- Assert (global_index < n_nonzero_elements, ExcInternalError());
+ {
+ Assert (global_index < n_nonzero_elements, ExcInternalError());
- A[global_index] = matrix(row,*col);
- ++global_index;
+ A[global_index] = matrix(row,*col);
+ ++global_index;
// make sure that the symmetric
// entry exists and has the same
||
(matrix(row,*col) == matrix(*col,row)),
ExcMatrixNotSymmetric());
- }
+ }
else
// lower left part. just check
// symmetry
{
std::vector<double> W(*n_rows);
HSL::MA47::ma47cd_(n_rows, A, LA,
- IW, LIW, &W[0],
- rhs_and_solution, IW1, ICNTL);
+ IW, LIW, &W[0],
+ rhs_and_solution, IW1, ICNTL);
}
// matrices, so we have to do a bit
// of book keeping
{
- // have an array that for each
- // row points to the first entry
- // not yet written to
+ // have an array that for each
+ // row points to the first entry
+ // not yet written to
std::vector<long int> row_pointers = Ap;
for (typename Matrix::const_iterator p=matrix.begin();
p!=matrix.end(); ++p)
{
- // write entry into the first
- // free one for this row
+ // write entry into the first
+ // free one for this row
Ai[row_pointers[p->row()]] = p->column();
Ax[row_pointers[p->row()]] = p->value();
- // then move pointer ahead
- ++row_pointers[p->row()];
+ // then move pointer ahead
+ ++row_pointers[p->row()];
}
- // at the end, we should have
- // written all rows completely
+ // at the end, we should have
+ // written all rows completely
for (unsigned int i=0; i<Ap.size()-1; ++i)
Assert (row_pointers[i] == Ap[i+1], ExcInternalError());
}
template <class Matrix>
void
SparseDirectUMFPACK::initialize (const Matrix &M,
- const AdditionalData)
+ const AdditionalData)
{
this->factorize(M);
}
template <class Matrix>
void SparseDirectMUMPS::initialize (const Matrix& matrix,
- const Vector<double> & vector)
+ const Vector<double> & vector)
{
// Check we haven't been here before:
Assert (initialize_called == false, ExcInitializeAlreadyCalled());
unsigned int index = 0;
for (SparseMatrix<double>::const_iterator ptr = matrix.begin ();
- ptr != matrix.end (); ++ptr)
- if (std::abs (ptr->value ()) > 0.0)
- {
- a[index] = ptr->value ();
- irn[index] = ptr->row () + 1;
- jcn[index] = ptr->column () + 1;
- ++index;
- }
+ ptr != matrix.end (); ++ptr)
+ if (std::abs (ptr->value ()) > 0.0)
+ {
+ a[index] = ptr->value ();
+ irn[index] = ptr->row () + 1;
+ jcn[index] = ptr->column () + 1;
+ ++index;
+ }
rhs = new double[n];
for (unsigned int i = 0; i < n; ++i)
- rhs[i] = vector (i);
+ rhs[i] = vector (i);
id.n = n;
id.nz = nz;
if (Utilities::MPI::this_mpi_process (MPI_COMM_WORLD) == 0)
{
for (unsigned int i=0; i<n; ++i)
- vector(i) = rhs[i];
+ vector(i) = rhs[i];
delete[] a;
delete[] irn;
template
void SparseDirectMA27::solve (const SparseMatrix<double> &matrix,
- Vector<double> &rhs_and_solution);
+ Vector<double> &rhs_and_solution);
template
void SparseDirectMA27::solve (const SparseMatrix<float> &matrix,
- Vector<double> &rhs_and_solution);
+ Vector<double> &rhs_and_solution);
// explicit instantiations for SparseMatrixUMFPACK
void SparseDirectUMFPACK::factorize (const MATRIX &); \
template \
void SparseDirectUMFPACK::solve (const MATRIX &, \
- Vector<double> &); \
+ Vector<double> &); \
template \
void SparseDirectUMFPACK::initialize (const MATRIX &, \
- const AdditionalData)
+ const AdditionalData)
InstantiateUMFPACK(SparseMatrix<double>);
InstantiateUMFPACK(SparseMatrix<float>);
#ifdef DEAL_II_USE_MUMPS
template <class Matrix>
void SparseDirectMUMPS::initialize (const Matrix& matrix,
- const Vector<double> & vector);
+ const Vector<double> & vector);
void SparseDirectMUMPS::solve (Vector<double>& vector);
#endif
//---------------------------------------------------------------------------
-// Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 by the deal.II authors
+// Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
// explicit instantiations
template class SparseILU<double>;
template void SparseILU<double>::initialize<double> (const SparseMatrix<double> &,
- const AdditionalData data);
+ const AdditionalData data);
template void SparseILU<double>::decompose<double> (const SparseMatrix<double> &,
- const double);
+ const double);
template void SparseILU<double>::vmult <double> (Vector<double> &,
const Vector<double> &) const;
template void SparseILU<double>::Tvmult <double> (Vector<double> &,
- const Vector<double> &) const;
+ const Vector<double> &) const;
template void SparseILU<double>::initialize<float> (const SparseMatrix<float> &,
- const AdditionalData data);
+ const AdditionalData data);
template void SparseILU<double>::decompose<float> (const SparseMatrix<float> &,
- const double);
+ const double);
template void SparseILU<double>::vmult<float> (Vector<float> &,
const Vector<float> &) const;
template void SparseILU<double>::Tvmult<float> (Vector<float> &,
- const Vector<float> &) const;
+ const Vector<float> &) const;
template class SparseILU<float>;
template void SparseILU<float>::initialize<double> (const SparseMatrix<double> &,
- const AdditionalData data);
+ const AdditionalData data);
template void SparseILU<float>::decompose<double> (const SparseMatrix<double> &,
- const double);
+ const double);
template void SparseILU<float>::vmult<double> (Vector<double> &,
const Vector<double> &) const;
template void SparseILU<float>::Tvmult<double> (Vector<double> &,
- const Vector<double> &) const;
+ const Vector<double> &) const;
template void SparseILU<float>::initialize<float> (const SparseMatrix<float> &,
- const AdditionalData data);
+ const AdditionalData data);
template void SparseILU<float>::decompose<float> (const SparseMatrix<float> &,
- const double);
+ const double);
template void SparseILU<float>::vmult<float> (Vector<float> &,
const Vector<float> &) const;
template void SparseILU<float>::Tvmult<float> (Vector<float> &,
- const Vector<float> &) const;
+ const Vector<float> &) const;
DEAL_II_NAMESPACE_CLOSE
// $Id$
// Version: $Name$
//
-// Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009 by the deal.II authors
+// Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
// $Id$
// Version: $Name$
//
-// Copyright (C) 2007 by the deal.II authors
+// Copyright (C) 2007, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
//---------------------------------------------------------------------------
-// Copyright (C) 2002, 2003, 2005, 2006 by the deal.II authors
+// Copyright (C) 2002, 2003, 2005, 2006, 2012 by the deal.II authors
// by the deal.II authors and Stephen "Cheffo" Kolaroff
//
// This file is subject to QPL and may not be distributed
// explicit instantiations for double and float matrices
template class SparseMIC<double>;
template void SparseMIC<double>::initialize<double> (const SparseMatrix<double> &,
- const AdditionalData data);
+ const AdditionalData data);
template void SparseMIC<double>::decompose<double> (const SparseMatrix<double> &,
const double);
template void SparseMIC<double>::vmult<double> (Vector<double> &,
const Vector<double> &) const;
template void SparseMIC<double>::initialize<float> (const SparseMatrix<float> &,
- const AdditionalData data);
+ const AdditionalData data);
template void SparseMIC<double>::decompose<float> (const SparseMatrix<float> &,
const double);
template void SparseMIC<double>::vmult<float> (Vector<float> &,
template class SparseMIC<float>;
template void SparseMIC<float>::initialize<double> (const SparseMatrix<double> &,
- const AdditionalData data);
+ const AdditionalData data);
template void SparseMIC<float>::decompose<double> (const SparseMatrix<double> &,
const double);
template void SparseMIC<float>::vmult<double> (Vector<double> &,
const Vector<double> &) const;
template void SparseMIC<float>::initialize<float> (const SparseMatrix<float> &,
- const AdditionalData data);
+ const AdditionalData data);
template void SparseMIC<float>::decompose<float> (const SparseMatrix<float> &,
const double);
template void SparseMIC<float>::vmult<float> (Vector<float> &,
// $Id$
// Version: $Name$
//
-// Copyright (C) 1999, 2000, 2001, 2002, 2003, 2005, 2006 by the deal.II authors
+// Copyright (C) 1999, 2000, 2001, 2002, 2003, 2005, 2006, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
template class SparseVanka<double>;
template void SparseVanka<double>::vmult<float> (Vector<float> &dst,
- const Vector<float> &src) const;
+ const Vector<float> &src) const;
template void SparseVanka<double>::vmult<double> (Vector<double> &dst,
- const Vector<double> &src) const;
+ const Vector<double> &src) const;
template class SparseBlockVanka<float>;
template class SparseBlockVanka<double>;
template void SparseBlockVanka<double>::vmult<float> (Vector<float> &dst,
- const Vector<float> &src) const;
+ const Vector<float> &src) const;
template void SparseBlockVanka<double>::vmult<double> (Vector<double> &dst,
- const Vector<double> &src) const;
+ const Vector<double> &src) const;
DEAL_II_NAMESPACE_CLOSE
// $Id$
// Version: $Name$
//
-// Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 by the deal.II authors
+// Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
SparsityPattern::SparsityPattern ()
:
- max_dim(0),
- max_vec_len(0),
- rowstart(0),
- colnums(0),
- compressed(false),
- diagonal_optimized(false)
+ max_dim(0),
+ max_vec_len(0),
+ rowstart(0),
+ colnums(0),
+ compressed(false),
+ diagonal_optimized(false)
{
reinit (0,0,0);
}
SparsityPattern::SparsityPattern (const SparsityPattern &s)
:
- Subscriptor(),
- max_dim(0),
- max_vec_len(0),
- rowstart(0),
- colnums(0),
- compressed(false),
- diagonal_optimized(false)
+ Subscriptor(),
+ max_dim(0),
+ max_vec_len(0),
+ rowstart(0),
+ colnums(0),
+ compressed(false),
+ diagonal_optimized(false)
{
Assert (s.rowstart == 0, ExcInvalidConstructorCall());
Assert (s.colnums == 0, ExcInvalidConstructorCall());
SparsityPattern::SparsityPattern (const unsigned int m,
- const unsigned int n,
- const unsigned int max_per_row,
- const bool optimize_diag)
- :
+ const unsigned int n,
+ const unsigned int max_per_row,
+ const bool optimize_diag)
+ :
max_dim(0),
max_vec_len(0),
rowstart(0),
const unsigned int n,
const std::vector<unsigned int>& row_lengths,
const bool optimize_diag)
- :
+ :
max_dim(0),
max_vec_len(0),
rowstart(0),
SparsityPattern::SparsityPattern (const unsigned int n,
- const unsigned int max_per_row)
- :
+ const unsigned int max_per_row)
+ :
max_dim(0),
max_vec_len(0),
rowstart(0),
const unsigned int m,
const std::vector<unsigned int>& row_lengths,
const bool optimize_diag)
- :
+ :
max_dim(0),
max_vec_len(0),
rowstart(0),
SparsityPattern::SparsityPattern (const SparsityPattern &original,
- const unsigned int max_per_row,
- const unsigned int extra_off_diagonals)
- :
+ const unsigned int max_per_row,
+ const unsigned int extra_off_diagonals)
+ :
max_dim(0),
max_vec_len(0),
rowstart(0),
Assert (original.is_compressed(), ExcNotCompressed());
reinit (original.rows, original.cols, max_per_row,
- original.optimize_diagonal());
+ original.optimize_diagonal());
- // now copy the entries from
- // the other object
+ // now copy the entries from
+ // the other object
for (unsigned int row=0; row<original.rows; ++row)
{
- // copy the elements of this row
- // of the other object
- //
- // note that the first object actually
- // is the main-diagonal element,
- // which we need not copy
- //
- // we do the copying in two steps:
- // first we note that the elements in
- // @p{original} are sorted, so we may
- // first copy all the elements up to
- // the first side-diagonal one which
- // is to be filled in. then we insert
- // the side-diagonals, finally copy
- // the rest from that element onwards
- // which is not a side-diagonal any
- // more.
+ // copy the elements of this row
+ // of the other object
+ //
+ // note that the first object actually
+ // is the main-diagonal element,
+ // which we need not copy
+ //
+ // we do the copying in two steps:
+ // first we note that the elements in
+ // @p{original} are sorted, so we may
+ // first copy all the elements up to
+ // the first side-diagonal one which
+ // is to be filled in. then we insert
+ // the side-diagonals, finally copy
+ // the rest from that element onwards
+ // which is not a side-diagonal any
+ // more.
const unsigned int * const
- original_row_start = &original.colnums[original.rowstart[row]] + 1;
- // the following requires that
- // @p{original} be compressed since
- // otherwise there might be invalid_entry's
+ original_row_start = &original.colnums[original.rowstart[row]] + 1;
+ // the following requires that
+ // @p{original} be compressed since
+ // otherwise there might be invalid_entry's
const unsigned int * const
- original_row_end = &original.colnums[original.rowstart[row+1]];
-
- // find pointers before and
- // after extra
- // off-diagonals. if at top or
- // bottom of matrix, then set
- // these pointers such that no
- // copying is necessary (see
- // the @p{copy} commands)
+ original_row_end = &original.colnums[original.rowstart[row+1]];
+
+ // find pointers before and
+ // after extra
+ // off-diagonals. if at top or
+ // bottom of matrix, then set
+ // these pointers such that no
+ // copying is necessary (see
+ // the @p{copy} commands)
const unsigned int * const
- original_last_before_side_diagonals
- = (row > extra_off_diagonals ?
- Utilities::lower_bound (original_row_start,
- original_row_end,
- row-extra_off_diagonals) :
- original_row_start);
+ original_last_before_side_diagonals
+ = (row > extra_off_diagonals ?
+ Utilities::lower_bound (original_row_start,
+ original_row_end,
+ row-extra_off_diagonals) :
+ original_row_start);
const unsigned int * const
- original_first_after_side_diagonals
- = (row < rows-extra_off_diagonals-1 ?
- std::upper_bound (original_row_start,
- original_row_end,
- row+extra_off_diagonals) :
- original_row_end);
-
- // find first free slot. the
- // first slot in each row is
- // the diagonal element
+ original_first_after_side_diagonals
+ = (row < rows-extra_off_diagonals-1 ?
+ std::upper_bound (original_row_start,
+ original_row_end,
+ row+extra_off_diagonals) :
+ original_row_end);
+
+ // find first free slot. the
+ // first slot in each row is
+ // the diagonal element
unsigned int * next_free_slot = &colnums[rowstart[row]] + 1;
- // copy elements before side-diagonals
+ // copy elements before side-diagonals
next_free_slot = std::copy (original_row_start,
- original_last_before_side_diagonals,
- next_free_slot);
+ original_last_before_side_diagonals,
+ next_free_slot);
- // insert left and right side-diagonals
+ // insert left and right side-diagonals
for (unsigned int i=1; i<=std::min(row,extra_off_diagonals);
- ++i, ++next_free_slot)
- *next_free_slot = row-i;
+ ++i, ++next_free_slot)
+ *next_free_slot = row-i;
for (unsigned int i=1; i<=std::min(extra_off_diagonals, rows-row-1);
- ++i, ++next_free_slot)
- *next_free_slot = row+i;
+ ++i, ++next_free_slot)
+ *next_free_slot = row+i;
- // copy rest
+ // copy rest
next_free_slot = std::copy (original_first_after_side_diagonals,
- original_row_end,
- next_free_slot);
-
- // this error may happen if the
- // sum of previous elements per row
- // and those of the new diagonals
- // exceeds the maximum number of
- // elements per row given to this
- // constructor
+ original_row_end,
+ next_free_slot);
+
+ // this error may happen if the
+ // sum of previous elements per row
+ // and those of the new diagonals
+ // exceeds the maximum number of
+ // elements per row given to this
+ // constructor
Assert (next_free_slot <= &colnums[rowstart[row+1]],
- ExcNotEnoughSpace (0,rowstart[row+1]-rowstart[row]));
+ ExcNotEnoughSpace (0,rowstart[row+1]-rowstart[row]));
};
}
void
SparsityPattern::reinit (const unsigned int m,
- const unsigned int n,
- const unsigned int max_per_row,
- const bool optimize_diag)
+ const unsigned int n,
+ const unsigned int max_per_row,
+ const bool optimize_diag)
{
- // simply map this function to the
- // other @p{reinit} function
+ // simply map this function to the
+ // other @p{reinit} function
const std::vector<unsigned int> row_lengths (m, max_per_row);
reinit (m, n, row_lengths, optimize_diag);
}
rows = m;
cols = n;
- // delete empty matrices
+ // delete empty matrices
if ((m==0) || (n==0))
{
if (rowstart) delete[] rowstart;
rowstart = 0;
colnums = 0;
max_vec_len = max_dim = rows = cols = 0;
- // if dimension is zero: ignore
- // max_per_row
+ // if dimension is zero: ignore
+ // max_per_row
max_row_length = 0;
compressed = false;
return;
}
- // first, if the matrix is
- // quadratic and special treatment
- // of diagonals is requested, we
- // will have to make sure that each
- // row has at least one entry for
- // the diagonal element. make this
- // more obvious by having a
- // variable which we can query
+ // first, if the matrix is
+ // quadratic and special treatment
+ // of diagonals is requested, we
+ // will have to make sure that each
+ // row has at least one entry for
+ // the diagonal element. make this
+ // more obvious by having a
+ // variable which we can query
diagonal_optimized = (m == n ? true : false) && optimize_diag;
- // find out how many entries we
- // need in the @p{colnums} array. if
- // this number is larger than
- // @p{max_vec_len}, then we will need
- // to reallocate memory
- //
- // note that the number of elements
- // per row is bounded by the number
- // of columns
+ // find out how many entries we
+ // need in the @p{colnums} array. if
+ // this number is larger than
+ // @p{max_vec_len}, then we will need
+ // to reallocate memory
+ //
+ // note that the number of elements
+ // per row is bounded by the number
+ // of columns
std::size_t vec_len = 0;
for (unsigned int i=0; i<m; ++i)
vec_len += std::min((diagonal_optimized ?
- std::max(row_lengths[i], 1U) :
- row_lengths[i]),
- n);
-
- // sometimes, no entries are
- // requested in the matrix (this
- // most often happens when blocks
- // in a block matrix are simply
- // zero). in that case, allocate
- // exactly one element, to have a
- // valid pointer to some memory
+ std::max(row_lengths[i], 1U) :
+ row_lengths[i]),
+ n);
+
+ // sometimes, no entries are
+ // requested in the matrix (this
+ // most often happens when blocks
+ // in a block matrix are simply
+ // zero). in that case, allocate
+ // exactly one element, to have a
+ // valid pointer to some memory
if (vec_len == 0)
{
vec_len = 1;
if (colnums)
- {
- delete[] colnums;
- colnums = 0;
- }
+ {
+ delete[] colnums;
+ colnums = 0;
+ }
max_vec_len = vec_len;
colnums = new unsigned int[max_vec_len];
}
max_row_length = (row_lengths.size() == 0 ?
- 0 :
- std::min (*std::max_element(row_lengths.begin(),
- row_lengths.end()),
- n));
+ 0 :
+ std::min (*std::max_element(row_lengths.begin(),
+ row_lengths.end()),
+ n));
if (diagonal_optimized && (max_row_length==0) && (m!=0))
max_row_length = 1;
- // allocate memory for the rowstart
- // values, if necessary. even
- // though we re-set the pointers
- // again immediately after deleting
- // their old content, set them to
- // zero in between because the
- // allocation might fail, in which
- // case we get an exception and the
- // destructor of this object will
- // be called -- where we look at
- // the non-nullness of the (now
- // invalid) pointer again and try
- // to delete the memory a second
- // time.
+ // allocate memory for the rowstart
+ // values, if necessary. even
+ // though we re-set the pointers
+ // again immediately after deleting
+ // their old content, set them to
+ // zero in between because the
+ // allocation might fail, in which
+ // case we get an exception and the
+ // destructor of this object will
+ // be called -- where we look at
+ // the non-nullness of the (now
+ // invalid) pointer again and try
+ // to delete the memory a second
+ // time.
if (rows > max_dim)
{
if (rowstart)
- {
- delete[] rowstart;
- rowstart = 0;
- }
+ {
+ delete[] rowstart;
+ rowstart = 0;
+ }
max_dim = rows;
rowstart = new std::size_t[max_dim+1];
}
- // allocate memory for the column
- // numbers if necessary
+ // allocate memory for the column
+ // numbers if necessary
if (vec_len > max_vec_len)
{
if (colnums)
- {
- delete[] colnums;
- colnums = 0;
- }
+ {
+ delete[] colnums;
+ colnums = 0;
+ }
max_vec_len = vec_len;
colnums = new unsigned int[max_vec_len];
}
- // set the rowstart array
+ // set the rowstart array
rowstart[0] = 0;
for (unsigned int i=1; i<=rows; ++i)
rowstart[i] = rowstart[i-1] +
- (diagonal_optimized ?
- std::max(std::min(row_lengths[i-1],n),1U) :
- std::min(row_lengths[i-1],n));
+ (diagonal_optimized ?
+ std::max(std::min(row_lengths[i-1],n),1U) :
+ std::min(row_lengths[i-1],n));
Assert ((rowstart[rows]==vec_len)
- ||
- ((vec_len == 1) && (rowstart[rows] == 0)),
- ExcInternalError());
+ ||
+ ((vec_len == 1) && (rowstart[rows] == 0)),
+ ExcInternalError());
- // preset the column numbers by a
- // value indicating it is not in
- // use
+ // preset the column numbers by a
+ // value indicating it is not in
+ // use
std::fill_n (&colnums[0], vec_len, invalid_entry);
- // if diagonal elements are
- // special: let the first entry in
- // each row be the diagonal value
+ // if diagonal elements are
+ // special: let the first entry in
+ // each row be the diagonal value
if (diagonal_optimized)
for (unsigned int i=0;i<rows;i++)
colnums[rowstart[i]] = i;
{
Assert ((rowstart!=0) && (colnums!=0), ExcEmptyObject());
- // do nothing if already compressed
+ // do nothing if already compressed
if (compressed)
return;
unsigned int next_free_entry = 0,
- next_row_start = 0,
- row_length = 0;
+ next_row_start = 0,
+ row_length = 0;
- // first find out how many non-zero
- // elements there are, in order to
- // allocate the right amount of
- // memory
+ // first find out how many non-zero
+ // elements there are, in order to
+ // allocate the right amount of
+ // memory
const std::size_t nonzero_elements
= std::count_if (&colnums[rowstart[0]],
- &colnums[rowstart[rows]],
- std::bind2nd(std::not_equal_to<unsigned int>(), invalid_entry));
- // now allocate the respective memory
+ &colnums[rowstart[rows]],
+ std::bind2nd(std::not_equal_to<unsigned int>(), invalid_entry));
+ // now allocate the respective memory
unsigned int *new_colnums = new unsigned int[nonzero_elements];
- // reserve temporary storage to
- // store the entries of one row
+ // reserve temporary storage to
+ // store the entries of one row
std::vector<unsigned int> tmp_entries (max_row_length);
- // Traverse all rows
+ // Traverse all rows
for (unsigned int line=0; line<rows; ++line)
{
- // copy used entries, break if
- // first unused entry is reached
+ // copy used entries, break if
+ // first unused entry is reached
row_length = 0;
for (unsigned int j=rowstart[line]; j<rowstart[line+1]; ++j,++row_length)
- if (colnums[j] != invalid_entry)
- tmp_entries[row_length] = colnums[j];
- else
- break;
- // now @p{rowstart} is
- // the number of entries in
- // this line
-
- // Sort only beginning at the
- // second entry, if optimized
- // storage of diagonal entries
- // is on.
-
- // if this line is empty or has
- // only one entry, don't sort
+ if (colnums[j] != invalid_entry)
+ tmp_entries[row_length] = colnums[j];
+ else
+ break;
+ // now @p{rowstart} is
+ // the number of entries in
+ // this line
+
+ // Sort only beginning at the
+ // second entry, if optimized
+ // storage of diagonal entries
+ // is on.
+
+ // if this line is empty or has
+ // only one entry, don't sort
if (row_length > 1)
- std::sort ((diagonal_optimized)
- ? tmp_entries.begin()+1
- : tmp_entries.begin(),
- tmp_entries.begin()+row_length);
+ std::sort ((diagonal_optimized)
+ ? tmp_entries.begin()+1
+ : tmp_entries.begin(),
+ tmp_entries.begin()+row_length);
- // insert column numbers
- // into the new field
+ // insert column numbers
+ // into the new field
for (unsigned int j=0; j<row_length; ++j)
- new_colnums[next_free_entry++] = tmp_entries[j];
+ new_colnums[next_free_entry++] = tmp_entries[j];
- // note new start of this and
- // the next row
+ // note new start of this and
+ // the next row
rowstart[line] = next_row_start;
next_row_start = next_free_entry;
- // some internal checks: either
- // the matrix is not quadratic,
- // or if it is, then the first
- // element of this row must be
- // the diagonal element
- // (i.e. with column
- // index==line number)
+ // some internal checks: either
+ // the matrix is not quadratic,
+ // or if it is, then the first
+ // element of this row must be
+ // the diagonal element
+ // (i.e. with column
+ // index==line number)
Assert ((!diagonal_optimized) ||
- (new_colnums[rowstart[line]] == line),
- ExcInternalError());
- // assert that the first entry
- // does not show up in
- // the remaining ones and that
- // the remaining ones are unique
- // among themselves (this handles
- // both cases, quadratic and
- // rectangular matrices)
- //
- // the only exception here is
- // if the row contains no
- // entries at all
+ (new_colnums[rowstart[line]] == line),
+ ExcInternalError());
+ // assert that the first entry
+ // does not show up in
+ // the remaining ones and that
+ // the remaining ones are unique
+ // among themselves (this handles
+ // both cases, quadratic and
+ // rectangular matrices)
+ //
+ // the only exception here is
+ // if the row contains no
+ // entries at all
Assert ((rowstart[line] == next_row_start)
- ||
- (std::find (&new_colnums[rowstart[line]+1],
- &new_colnums[next_row_start],
- new_colnums[rowstart[line]]) ==
- &new_colnums[next_row_start]),
- ExcInternalError());
+ ||
+ (std::find (&new_colnums[rowstart[line]+1],
+ &new_colnums[next_row_start],
+ new_colnums[rowstart[line]]) ==
+ &new_colnums[next_row_start]),
+ ExcInternalError());
Assert ((rowstart[line] == next_row_start)
- ||
- (std::adjacent_find(&new_colnums[rowstart[line]+1],
- &new_colnums[next_row_start]) ==
- &new_colnums[next_row_start]),
- ExcInternalError());
+ ||
+ (std::adjacent_find(&new_colnums[rowstart[line]+1],
+ &new_colnums[next_row_start]) ==
+ &new_colnums[next_row_start]),
+ ExcInternalError());
};
- // assert that we have used all
- // allocated space, no more and no
- // less
+ // assert that we have used all
+ // allocated space, no more and no
+ // less
Assert (next_free_entry == nonzero_elements,
- ExcInternalError());
+ ExcInternalError());
- // set iterator-past-the-end
+ // set iterator-past-the-end
rowstart[rows] = next_row_start;
- // set colnums to the newly
- // allocated array and delete the
- // old one
+ // set colnums to the newly
+ // allocated array and delete the
+ // old one
delete[] colnums;
colnums = new_colnums;
- // store the size
+ // store the size
max_vec_len = nonzero_elements;
compressed = true;
template <typename CSP>
void
SparsityPattern::copy_from (const CSP &csp,
- const bool optimize_diag)
+ const bool optimize_diag)
{
- // first determine row lengths for
- // each row. if the matrix is
- // quadratic, then we might have to
- // add an additional entry for the
- // diagonal, if that is not yet
- // present. as we have to call
- // compress anyway later on, don't
- // bother to check whether that
- // diagonal entry is in a certain
- // row or not
+ // first determine row lengths for
+ // each row. if the matrix is
+ // quadratic, then we might have to
+ // add an additional entry for the
+ // diagonal, if that is not yet
+ // present. as we have to call
+ // compress anyway later on, don't
+ // bother to check whether that
+ // diagonal entry is in a certain
+ // row or not
const bool do_diag_optimize = optimize_diag && (csp.n_rows() == csp.n_cols());
std::vector<unsigned int> row_lengths (csp.n_rows());
for (unsigned int i=0; i<csp.n_rows(); ++i)
{
row_lengths[i] = csp.row_length(i);
if (do_diag_optimize && !csp.exists(i,i))
- ++row_lengths[i];
+ ++row_lengths[i];
}
reinit (csp.n_rows(), csp.n_cols(), row_lengths, do_diag_optimize);
- // now enter all the elements into
- // the matrix, if there are
- // any. note that if the matrix is
- // quadratic, then we already have
- // the diagonal element
- // preallocated
+ // now enter all the elements into
+ // the matrix, if there are
+ // any. note that if the matrix is
+ // quadratic, then we already have
+ // the diagonal element
+ // preallocated
if (n_rows() != 0 && n_cols() != 0)
for (unsigned int row = 0; row<csp.n_rows(); ++row)
{
- unsigned int *cols = &colnums[rowstart[row]] + (do_diag_optimize ? 1 : 0);
- typename CSP::row_iterator col_num = csp.row_begin (row),
- end_row = csp.row_end (row);
-
- for (; col_num != end_row; ++col_num)
- {
- const unsigned int col = *col_num;
- if ((col!=row) || !do_diag_optimize)
- *cols++ = col;
- }
+ unsigned int *cols = &colnums[rowstart[row]] + (do_diag_optimize ? 1 : 0);
+ typename CSP::row_iterator col_num = csp.row_begin (row),
+ end_row = csp.row_end (row);
+
+ for (; col_num != end_row; ++col_num)
+ {
+ const unsigned int col = *col_num;
+ if ((col!=row) || !do_diag_optimize)
+ *cols++ = col;
+ }
}
- // do not need to compress the sparsity
- // pattern since we already have
- // allocated the right amount of data,
- // and the CSP data is sorted, too.
+ // do not need to compress the sparsity
+ // pattern since we already have
+ // allocated the right amount of data,
+ // and the CSP data is sorted, too.
compressed = true;
}
template <typename number>
void SparsityPattern::copy_from (const FullMatrix<number> &matrix,
- const bool optimize_diag)
+ const bool optimize_diag)
{
- // first init with the number of entries
- // per row. if optimize_diag is set then we
- // also have to allocate memory for the
- // diagonal entry, unless we have already
- // counted it or the matrix isn't square
+ // first init with the number of entries
+ // per row. if optimize_diag is set then we
+ // also have to allocate memory for the
+ // diagonal entry, unless we have already
+ // counted it or the matrix isn't square
std::vector<unsigned int> entries_per_row (matrix.m(), 0);
for (unsigned int row=0; row<matrix.m(); ++row)
{
for (unsigned int col=0; col<matrix.n(); ++col)
- if (matrix(row,col) != 0)
- ++entries_per_row[row];
+ if (matrix(row,col) != 0)
+ ++entries_per_row[row];
if ((optimize_diag == true)
- &&
- (matrix(row,row) == 0)
- &&
- (matrix.m() == matrix.n()))
- ++entries_per_row[row];
+ &&
+ (matrix(row,row) == 0)
+ &&
+ (matrix.m() == matrix.n()))
+ ++entries_per_row[row];
}
reinit (matrix.m(), matrix.n(), entries_per_row, optimize_diag);
- // now set entries
+ // now set entries
for (unsigned int row=0; row<matrix.m(); ++row)
for (unsigned int col=0; col<matrix.n(); ++col)
if (matrix(row,col) != 0)
- add (row,col);
+ add (row,col);
- // finally compress
+ // finally compress
compress ();
}
bool
SparsityPattern::empty () const
{
- // let's try to be on the safe side of
- // life by using multiple possibilities in
- // the check for emptiness... (sorry for
- // this kludge -- emptying matrices and
- // freeing memory was not present in the
- // original implementation and I don't
- // know at how many places I missed
- // something in adding it, so I try to
- // be cautious. wb)
+ // let's try to be on the safe side of
+ // life by using multiple possibilities in
+ // the check for emptiness... (sorry for
+ // this kludge -- emptying matrices and
+ // freeing memory was not present in the
+ // original implementation and I don't
+ // know at how many places I missed
+ // something in adding it, so I try to
+ // be cautious. wb)
if ((rowstart==0) || (rows==0) || (cols==0))
{
Assert (rowstart==0, ExcInternalError());
unsigned int
SparsityPattern::max_entries_per_row () const
{
- // if compress() has not yet been
- // called, we can get the maximum
- // number of elements per row using
- // the stored value
+ // if compress() has not yet been
+ // called, we can get the maximum
+ // number of elements per row using
+ // the stored value
if (!compressed)
return max_row_length;
- // if compress() was called, we
- // use a better algorithm which
- // gives us a sharp bound
+ // if compress() was called, we
+ // use a better algorithm which
+ // gives us a sharp bound
unsigned int m = 0;
for (unsigned int i=1; i<rows; ++i)
m = std::max (m, static_cast<unsigned int>(rowstart[i]-rowstart[i-1]));
unsigned int
SparsityPattern::operator () (const unsigned int i,
- const unsigned int j) const
+ const unsigned int j) const
{
Assert ((rowstart!=0) && (colnums!=0), ExcEmptyObject());
Assert (i<rows, ExcIndexRange(i,0,rows));
Assert (j<cols, ExcIndexRange(j,0,cols));
Assert (compressed, ExcNotCompressed());
- // let's see whether there is
- // something in this line
+ // let's see whether there is
+ // something in this line
if (rowstart[i] == rowstart[i+1])
return invalid_entry;
- // If special storage of diagonals
- // was requested, we can get the
- // diagonal element faster by this
- // query.
+ // If special storage of diagonals
+ // was requested, we can get the
+ // diagonal element faster by this
+ // query.
if (diagonal_optimized && (i==j))
return rowstart[i];
- // all other entries are sorted, so
- // we can use a binary search
- // algorithm
- //
- // note that the entries are only
- // sorted upon compression, so this
- // would fail for non-compressed
- // sparsity patterns; however, that
- // is why the Assertion is at the
- // top of this function, so it may
- // not be called for noncompressed
- // structures.
+ // all other entries are sorted, so
+ // we can use a binary search
+ // algorithm
+ //
+ // note that the entries are only
+ // sorted upon compression, so this
+ // would fail for non-compressed
+ // sparsity patterns; however, that
+ // is why the Assertion is at the
+ // top of this function, so it may
+ // not be called for noncompressed
+ // structures.
const unsigned int * sorted_region_start = (diagonal_optimized ?
- &colnums[rowstart[i]+1] :
- &colnums[rowstart[i]]);
+ &colnums[rowstart[i]+1] :
+ &colnums[rowstart[i]]);
const unsigned int * const p
= Utilities::lower_bound<const unsigned int *> (sorted_region_start,
- &colnums[rowstart[i+1]],
- j);
+ &colnums[rowstart[i+1]],
+ j);
if ((p != &colnums[rowstart[i+1]]) && (*p == j))
return (p - &colnums[0]);
else
void
SparsityPattern::add (const unsigned int i,
- const unsigned int j)
+ const unsigned int j)
{
Assert ((rowstart!=0) && (colnums!=0), ExcEmptyObject());
Assert (i<rows, ExcIndexRange(i,0,rows));
for (unsigned int k=rowstart[i]; k<rowstart[i+1]; k++)
{
- // entry already exists
+ // entry already exists
if (colnums[k] == j) return;
- // empty entry found, put new
- // entry here
+ // empty entry found, put new
+ // entry here
if (colnums[k] == invalid_entry)
- {
- colnums[k] = j;
- return;
- };
+ {
+ colnums[k] = j;
+ return;
+ };
};
- // if we came thus far, something went
- // wrong: there was not enough space
- // in this line
+ // if we came thus far, something went
+ // wrong: there was not enough space
+ // in this line
Assert (false, ExcNotEnoughSpace(i, rowstart[i+1]-rowstart[i]));
}
template <typename ForwardIterator>
void
SparsityPattern::add_entries (const unsigned int row,
- ForwardIterator begin,
- ForwardIterator end,
- const bool /*indices_are_sorted*/)
+ ForwardIterator begin,
+ ForwardIterator end,
+ const bool /*indices_are_sorted*/)
{
// right now, just forward to the other function.
for (ForwardIterator it = begin; it != end; ++it)
for (unsigned int k=rowstart[i]; k<rowstart[i+1]; k++)
{
- // entry already exists
+ // entry already exists
if (colnums[k] == j) return true;
}
return false;
for (unsigned int k=rowstart[i]; k<rowstart[i+1]; k++)
{
- // entry exists
+ // entry exists
if (colnums[k] == j) return k-rowstart[i];
}
return numbers::invalid_unsigned_int;
{
Assert (compressed == true, ExcNotCompressed());
Assert (global_index < n_nonzero_elements(),
- ExcIndexRange (global_index, 0, n_nonzero_elements()));
-
- // first find the row in which the
- // entry is located. for this note
- // that the rowstart array indexes
- // the global indices at which each
- // row starts. since it is sorted,
- // and since there is an element
- // for the one-past-last row, we
- // can simply use a bisection
- // search on it
+ ExcIndexRange (global_index, 0, n_nonzero_elements()));
+
+ // first find the row in which the
+ // entry is located. for this note
+ // that the rowstart array indexes
+ // the global indices at which each
+ // row starts. since it is sorted,
+ // and since there is an element
+ // for the one-past-last row, we
+ // can simply use a bisection
+ // search on it
const unsigned int row
= (std::upper_bound (&rowstart[0], &rowstart[rows], global_index)
- &rowstart[0] - 1);
- // now, the column index is simple
- // since that is what the colnums
- // array stores:
+ // now, the column index is simple
+ // since that is what the colnums
+ // array stores:
const unsigned int col = colnums[global_index];
- // so return the respective pair
+ // so return the respective pair
return std::make_pair (row,col);
}
{
Assert ((rowstart!=0) && (colnums!=0), ExcEmptyObject());
Assert (compressed==false, ExcMatrixIsCompressed());
- // Note that we only require a
- // quadratic matrix here, no
- // special treatment of diagonals
+ // Note that we only require a
+ // quadratic matrix here, no
+ // special treatment of diagonals
Assert (rows==cols, ExcNotQuadratic());
- // loop over all elements presently
- // in the sparsity pattern and add
- // the transpose element. note:
- //
- // 1. that the sparsity pattern
- // changes which we work on, but
- // not the present row
- //
- // 2. that the @p{add} function can
- // be called on elements that
- // already exist without any harm
+ // loop over all elements presently
+ // in the sparsity pattern and add
+ // the transpose element. note:
+ //
+ // 1. that the sparsity pattern
+ // changes which we work on, but
+ // not the present row
+ //
+ // 2. that the @p{add} function can
+ // be called on elements that
+ // already exist without any harm
for (unsigned int row=0; row<rows; ++row)
for (unsigned int k=rowstart[row]; k<rowstart[row+1]; k++)
{
- // check whether we are at
- // the end of the entries of
- // this row. if so, go to
- // next row
- if (colnums[k] == invalid_entry)
- break;
-
- // otherwise add the
- // transpose entry if this is
- // not the diagonal (that
- // would not harm, only take
- // time to check up)
- if (colnums[k] != row)
- add (colnums[k], row);
+ // check whether we are at
+ // the end of the entries of
+ // this row. if so, go to
+ // next row
+ if (colnums[k] == invalid_entry)
+ break;
+
+ // otherwise add the
+ // transpose entry if this is
+ // not the diagonal (that
+ // would not harm, only take
+ // time to check up)
+ if (colnums[k] != row)
+ add (colnums[k], row);
};
}
{
out << '[' << i;
for (unsigned int j=rowstart[i]; j<rowstart[i+1]; ++j)
- if (colnums[j] != invalid_entry)
- out << ',' << colnums[j];
+ if (colnums[j] != invalid_entry)
+ out << ',' << colnums[j];
out << ']' << std::endl;
}
for (unsigned int i=0; i<rows; ++i)
for (unsigned int j=rowstart[i]; j<rowstart[i+1]; ++j)
if (colnums[j] != invalid_entry)
- // while matrix entries are
- // usually written (i,j),
- // with i vertical and j
- // horizontal, gnuplot output
- // is x-y, that is we have to
- // exchange the order of
- // output
- out << colnums[j] << " " << -static_cast<signed int>(i) << std::endl;
+ // while matrix entries are
+ // usually written (i,j),
+ // with i vertical and j
+ // horizontal, gnuplot output
+ // is x-y, that is we have to
+ // exchange the order of
+ // output
+ out << colnums[j] << " " << -static_cast<signed int>(i) << std::endl;
AssertThrow (out, ExcIO());
}
for (unsigned int i=0; i<rows; ++i)
for (unsigned int j=rowstart[i]; j<rowstart[i+1]; ++j)
if (colnums[j] != invalid_entry)
- {
- if (static_cast<unsigned int>(std::abs(static_cast<int>(i-colnums[j]))) > b)
- b = std::abs(static_cast<signed int>(i-colnums[j]));
- }
+ {
+ if (static_cast<unsigned int>(std::abs(static_cast<int>(i-colnums[j]))) > b)
+ b = std::abs(static_cast<signed int>(i-colnums[j]));
+ }
else
- // leave if at the end of
- // the entries of this line
- break;
+ // leave if at the end of
+ // the entries of this line
+ break;
return b;
}
<< diagonal_optimized << "][";
// then write out real data
out.write (reinterpret_cast<const char*>(&rowstart[0]),
- reinterpret_cast<const char*>(&rowstart[max_dim+1])
- - reinterpret_cast<const char*>(&rowstart[0]));
+ reinterpret_cast<const char*>(&rowstart[max_dim+1])
+ - reinterpret_cast<const char*>(&rowstart[0]));
out << "][";
out.write (reinterpret_cast<const char*>(&colnums[0]),
- reinterpret_cast<const char*>(&colnums[max_vec_len])
- - reinterpret_cast<const char*>(&colnums[0]));
+ reinterpret_cast<const char*>(&colnums[max_vec_len])
+ - reinterpret_cast<const char*>(&colnums[0]));
out << ']';
AssertThrow (out, ExcIO());
SparsityPattern::memory_consumption () const
{
return (max_dim * sizeof(unsigned int) +
- sizeof(*this) +
- max_vec_len * sizeof(unsigned int));
+ sizeof(*this) +
+ max_vec_len * sizeof(unsigned int));
}
template void SparsityPattern::copy_from<double> (const FullMatrix<double> &, bool);
template void SparsityPattern::add_entries<const unsigned int*> (const unsigned int,
- const unsigned int*,
- const unsigned int*,
- const bool);
+ const unsigned int*,
+ const unsigned int*,
+ const bool);
#ifndef DEAL_II_VECTOR_ITERATOR_IS_POINTER
template void SparsityPattern::add_entries<std::vector<unsigned int>::const_iterator>
(const unsigned int,
// $Id$
// Version: $Name$
//
-// Copyright (C) 2008, 2009, 2010, 2011 by the deal.II authors
+// Copyright (C) 2008, 2009, 2010, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
// and this is from proto.h
void
METIS_PartGraphKway(int *, idxtype *, idxtype *,
- idxtype *, idxtype *, int *,
- int *, int *, int *, int *, idxtype *);
+ idxtype *, idxtype *, int *,
+ int *, int *, int *, int *, idxtype *);
void
METIS_PartGraphRecursive(int *, idxtype *, idxtype *,
- idxtype *, idxtype *, int *,
- int *, int *, int *, int *, idxtype *);
+ idxtype *, idxtype *, int *,
+ int *, int *, int *, int *, idxtype *);
}
#endif
{
void partition (const SparsityPattern &sparsity_pattern,
- const unsigned int n_partitions,
- std::vector<unsigned int> &partition_indices)
+ const unsigned int n_partitions,
+ std::vector<unsigned int> &partition_indices)
{
Assert (sparsity_pattern.n_rows()==sparsity_pattern.n_cols(),
- ExcNotQuadratic());
+ ExcNotQuadratic());
Assert (sparsity_pattern.is_compressed(),
- SparsityPattern::ExcNotCompressed());
+ SparsityPattern::ExcNotCompressed());
Assert (n_partitions > 0, ExcInvalidNumberOfPartitions(n_partitions));
Assert (partition_indices.size() == sparsity_pattern.n_rows(),
- ExcInvalidArraySize (partition_indices.size(),
- sparsity_pattern.n_rows()));
+ ExcInvalidArraySize (partition_indices.size(),
+ sparsity_pattern.n_rows()));
- // check for an easy return
+ // check for an easy return
if (n_partitions == 1)
{
- std::fill_n (partition_indices.begin(), partition_indices.size(), 0U);
- return;
+ std::fill_n (partition_indices.begin(), partition_indices.size(), 0U);
+ return;
}
- // Make sure that METIS is actually
- // installed and detected
+ // Make sure that METIS is actually
+ // installed and detected
#ifndef DEAL_II_USE_METIS
AssertThrow (false, ExcMETISNotInstalled());
#else
- // generate the data structures for
- // METIS. Note that this is particularly
- // simple, since METIS wants exactly our
- // compressed row storage format. we only
- // have to set up a few auxiliary arrays
+ // generate the data structures for
+ // METIS. Note that this is particularly
+ // simple, since METIS wants exactly our
+ // compressed row storage format. we only
+ // have to set up a few auxiliary arrays
int
n = static_cast<signed int>(sparsity_pattern.n_rows()),
wgtflag = 0, // no weights on nodes or edges
numflag = 0, // C-style 0-based numbering
nparts = static_cast<int>(n_partitions), // number of subdomains to create
dummy; // the numbers of edges cut by the
- // resulting partition
+ // resulting partition
- // use default options for METIS
+ // use default options for METIS
int options[5] = { 0,0,0,0,0 };
- // one more nuisance: we have to copy our
- // own data to arrays that store signed
- // integers :-(
+ // one more nuisance: we have to copy our
+ // own data to arrays that store signed
+ // integers :-(
std::vector<idxtype> int_rowstart (sparsity_pattern.get_rowstart_indices(),
- sparsity_pattern.get_rowstart_indices() +
- sparsity_pattern.n_rows()+1);
+ sparsity_pattern.get_rowstart_indices() +
+ sparsity_pattern.n_rows()+1);
std::vector<idxtype> int_colnums (sparsity_pattern.get_column_numbers(),
- sparsity_pattern.get_column_numbers()+
- int_rowstart[sparsity_pattern.n_rows()]);
+ sparsity_pattern.get_column_numbers()+
+ int_rowstart[sparsity_pattern.n_rows()]);
std::vector<idxtype> int_partition_indices (sparsity_pattern.n_rows());
- // Select which type of partitioning to
- // create
+ // Select which type of partitioning to
+ // create
- // Use recursive if the number of
- // partitions is less than or equal to 8
+ // Use recursive if the number of
+ // partitions is less than or equal to 8
if (n_partitions <= 8)
METIS_PartGraphRecursive(&n, &int_rowstart[0], &int_colnums[0],
- NULL, NULL,
- &wgtflag, &numflag, &nparts, &options[0],
- &dummy, &int_partition_indices[0]);
+ NULL, NULL,
+ &wgtflag, &numflag, &nparts, &options[0],
+ &dummy, &int_partition_indices[0]);
- // Otherwise use kway
+ // Otherwise use kway
else
METIS_PartGraphKway(&n, &int_rowstart[0], &int_colnums[0],
- NULL, NULL,
- &wgtflag, &numflag, &nparts, &options[0],
- &dummy, &int_partition_indices[0]);
+ NULL, NULL,
+ &wgtflag, &numflag, &nparts, &options[0],
+ &dummy, &int_partition_indices[0]);
- // now copy back generated indices into the
- // output array
+ // now copy back generated indices into the
+ // output array
std::copy (int_partition_indices.begin(),
- int_partition_indices.end(),
- partition_indices.begin());
+ int_partition_indices.end(),
+ partition_indices.begin());
#endif
}
namespace internal
{
- /**
- * Given a connectivity graph and
- * a list of indices (where
- * invalid_unsigned_int indicates
- * that a node has not been
- * numbered yet), pick a valid
- * starting index among the
- * as-yet unnumbered one.
- */
+ /**
+ * Given a connectivity graph and
+ * a list of indices (where
+ * invalid_unsigned_int indicates
+ * that a node has not been
+ * numbered yet), pick a valid
+ * starting index among the
+ * as-yet unnumbered one.
+ */
unsigned int
find_unnumbered_starting_index (const SparsityPattern &sparsity,
- const std::vector<unsigned int> &new_indices)
+ const std::vector<unsigned int> &new_indices)
{
{
- unsigned int starting_point = numbers::invalid_unsigned_int;
- unsigned int min_coordination = sparsity.n_rows();
- for (unsigned int row=0; row<sparsity.n_rows(); ++row)
- // look over all as-yet
- // unnumbered indices
- if (new_indices[row] == numbers::invalid_unsigned_int)
- {
- unsigned int j;
-
- // loop until we hit the end
- // of this row's entries
- for (j=sparsity.get_rowstart_indices()[row];
- j<sparsity.get_rowstart_indices()[row+1]; ++j)
- if (sparsity.get_column_numbers()[j] == SparsityPattern::invalid_entry)
- break;
- // post-condition after loop:
- // coordination, i.e. the number
- // of entries in this row is now
- // j-rowstart[row]
- if (j-sparsity.get_rowstart_indices()[row] < min_coordination)
- {
- min_coordination = j-sparsity.get_rowstart_indices()[row];
- starting_point = row;
- }
- }
-
- // now we still have to care
- // for the case that no
- // unnumbered dof has a
- // coordination number less
- // than
- // sparsity.n_rows(). this
- // rather exotic case only
- // happens if we only have
- // one cell, as far as I can
- // see, but there may be
- // others as well.
- //
- // if that should be the
- // case, we can chose an
- // arbitrary dof as starting
- // point, e.g. the first
- // unnumbered one
- if (starting_point == numbers::invalid_unsigned_int)
- {
- for (unsigned int i=0; i<new_indices.size(); ++i)
- if (new_indices[i] == numbers::invalid_unsigned_int)
- {
- starting_point = i;
- break;
- }
-
- Assert (starting_point != numbers::invalid_unsigned_int,
- ExcInternalError());
- }
-
- return starting_point;
+ unsigned int starting_point = numbers::invalid_unsigned_int;
+ unsigned int min_coordination = sparsity.n_rows();
+ for (unsigned int row=0; row<sparsity.n_rows(); ++row)
+ // look over all as-yet
+ // unnumbered indices
+ if (new_indices[row] == numbers::invalid_unsigned_int)
+ {
+ unsigned int j;
+
+ // loop until we hit the end
+ // of this row's entries
+ for (j=sparsity.get_rowstart_indices()[row];
+ j<sparsity.get_rowstart_indices()[row+1]; ++j)
+ if (sparsity.get_column_numbers()[j] == SparsityPattern::invalid_entry)
+ break;
+ // post-condition after loop:
+ // coordination, i.e. the number
+ // of entries in this row is now
+ // j-rowstart[row]
+ if (j-sparsity.get_rowstart_indices()[row] < min_coordination)
+ {
+ min_coordination = j-sparsity.get_rowstart_indices()[row];
+ starting_point = row;
+ }
+ }
+
+ // now we still have to care
+ // for the case that no
+ // unnumbered dof has a
+ // coordination number less
+ // than
+ // sparsity.n_rows(). this
+ // rather exotic case only
+ // happens if we only have
+ // one cell, as far as I can
+ // see, but there may be
+ // others as well.
+ //
+ // if that should be the
+ // case, we can chose an
+ // arbitrary dof as starting
+ // point, e.g. the first
+ // unnumbered one
+ if (starting_point == numbers::invalid_unsigned_int)
+ {
+ for (unsigned int i=0; i<new_indices.size(); ++i)
+ if (new_indices[i] == numbers::invalid_unsigned_int)
+ {
+ starting_point = i;
+ break;
+ }
+
+ Assert (starting_point != numbers::invalid_unsigned_int,
+ ExcInternalError());
+ }
+
+ return starting_point;
}
}
}
void
reorder_Cuthill_McKee (const SparsityPattern &sparsity,
- std::vector<unsigned int> &new_indices,
- const std::vector<unsigned int> &starting_indices)
+ std::vector<unsigned int> &new_indices,
+ const std::vector<unsigned int> &starting_indices)
{
Assert (sparsity.n_rows() == sparsity.n_cols(),
- ExcDimensionMismatch (sparsity.n_rows(), sparsity.n_cols()));
+ ExcDimensionMismatch (sparsity.n_rows(), sparsity.n_cols()));
Assert (sparsity.n_rows() == new_indices.size(),
- ExcDimensionMismatch (sparsity.n_rows(), new_indices.size()));
+ ExcDimensionMismatch (sparsity.n_rows(), new_indices.size()));
Assert (starting_indices.size() <= sparsity.n_rows(),
- ExcMessage ("You can't specify more starting indices than there are rows"));
+ ExcMessage ("You can't specify more starting indices than there are rows"));
for (unsigned int i=0; i<starting_indices.size(); ++i)
Assert (starting_indices[i] < sparsity.n_rows(),
- ExcMessage ("Invalid starting index"));
+ ExcMessage ("Invalid starting index"));
- // store the indices of the dofs renumbered
- // in the last round. Default to starting
- // points
+ // store the indices of the dofs renumbered
+ // in the last round. Default to starting
+ // points
std::vector<unsigned int> last_round_dofs (starting_indices);
- // initialize the new_indices array with
- // invalid values
+ // initialize the new_indices array with
+ // invalid values
std::fill (new_indices.begin(), new_indices.end(),
- numbers::invalid_unsigned_int);
+ numbers::invalid_unsigned_int);
- // delete disallowed elements
+ // delete disallowed elements
for (unsigned int i=0; i<last_round_dofs.size(); ++i)
if ((last_round_dofs[i]==numbers::invalid_unsigned_int) ||
- (last_round_dofs[i]>=sparsity.n_rows()))
- last_round_dofs[i] = numbers::invalid_unsigned_int;
+ (last_round_dofs[i]>=sparsity.n_rows()))
+ last_round_dofs[i] = numbers::invalid_unsigned_int;
std::remove_if (last_round_dofs.begin(), last_round_dofs.end(),
- std::bind2nd(std::equal_to<unsigned int>(),
- numbers::invalid_unsigned_int));
+ std::bind2nd(std::equal_to<unsigned int>(),
+ numbers::invalid_unsigned_int));
- // now if no valid points remain:
- // find dof with lowest coordination
- // number
+ // now if no valid points remain:
+ // find dof with lowest coordination
+ // number
if (last_round_dofs.empty())
last_round_dofs
- .push_back (internal::find_unnumbered_starting_index (sparsity,
- new_indices));
+ .push_back (internal::find_unnumbered_starting_index (sparsity,
+ new_indices));
- // store next free dof index
+ // store next free dof index
unsigned int next_free_number = 0;
- // enumerate the first round dofs
+ // enumerate the first round dofs
for (unsigned int i=0; i!=last_round_dofs.size(); ++i)
new_indices[last_round_dofs[i]] = next_free_number++;
- // now do as many steps as needed to
- // renumber all dofs
+ // now do as many steps as needed to
+ // renumber all dofs
while (true)
{
- // store the indices of the dofs to be
- // renumbered in the next round
- std::vector<unsigned int> next_round_dofs;
-
- // find all neighbors of the
- // dofs numbered in the last
- // round
- for (unsigned int i=0; i<last_round_dofs.size(); ++i)
- for (unsigned int j=sparsity.get_rowstart_indices()[last_round_dofs[i]];
- j<sparsity.get_rowstart_indices()[last_round_dofs[i]+1]; ++j)
- if (sparsity.get_column_numbers()[j] == SparsityPattern::invalid_entry)
- break;
- else
- next_round_dofs.push_back (sparsity.get_column_numbers()[j]);
-
- // sort dof numbers
- std::sort (next_round_dofs.begin(), next_round_dofs.end());
-
- // delete multiple entries
- std::vector<unsigned int>::iterator end_sorted;
- end_sorted = std::unique (next_round_dofs.begin(), next_round_dofs.end());
- next_round_dofs.erase (end_sorted, next_round_dofs.end());
-
- // eliminate dofs which are
- // already numbered
- for (int s=next_round_dofs.size()-1; s>=0; --s)
- if (new_indices[next_round_dofs[s]] != numbers::invalid_unsigned_int)
- next_round_dofs.erase (next_round_dofs.begin() + s);
-
- // check whether there are
- // any new dofs in the
- // list. if there are none,
- // then we have completely
- // numbered the current
- // component of the
- // graph. check if there are
- // as yet unnumbered
- // components of the graph
- // that we would then have to
- // do next
- if (next_round_dofs.empty())
- {
- if (std::find (new_indices.begin(), new_indices.end(),
- numbers::invalid_unsigned_int)
- ==
- new_indices.end())
- // no unnumbered
- // indices, so we can
- // leave now
- break;
-
- // otherwise find a valid
- // starting point for the
- // next component of the
- // graph and continue
- // with numbering that
- // one. we only do so if
- // no starting indices
- // were provided by the
- // user (see the
- // documentation of this
- // function) so produce
- // an error if we got
- // here and starting
- // indices were given
- Assert (starting_indices.empty(),
- ExcMessage ("The input graph appears to have more than one "
- "component, but as stated in the documentation "
- "we only want to reorder such graphs if no "
- "starting indices are given. The function was "
- "called with starting indices, however."))
-
- next_round_dofs
- .push_back (internal::find_unnumbered_starting_index (sparsity,
- new_indices));
- }
-
-
-
- // store for each coordination
- // number the dofs with these
- // coordination number
- std::multimap<unsigned int, int> dofs_by_coordination;
-
- // find coordination number for
- // each of these dofs
- for (std::vector<unsigned int>::iterator s=next_round_dofs.begin();
- s!=next_round_dofs.end(); ++s)
- {
- unsigned int coordination = 0;
- for (unsigned int j=sparsity.get_rowstart_indices()[*s];
- j<sparsity.get_rowstart_indices()[*s+1]; ++j)
- if (sparsity.get_column_numbers()[j] == SparsityPattern::invalid_entry)
- break;
- else
- ++coordination;
-
- // insert this dof at its
- // coordination number
- const std::pair<const unsigned int, int> new_entry (coordination, *s);
- dofs_by_coordination.insert (new_entry);
- }
-
- // assign new DoF numbers to
- // the elements of the present
- // front:
- std::multimap<unsigned int, int>::iterator i;
- for (i = dofs_by_coordination.begin(); i!=dofs_by_coordination.end(); ++i)
- new_indices[i->second] = next_free_number++;
-
- // after that: copy this round's
- // dofs for the next round
- last_round_dofs = next_round_dofs;
+ // store the indices of the dofs to be
+ // renumbered in the next round
+ std::vector<unsigned int> next_round_dofs;
+
+ // find all neighbors of the
+ // dofs numbered in the last
+ // round
+ for (unsigned int i=0; i<last_round_dofs.size(); ++i)
+ for (unsigned int j=sparsity.get_rowstart_indices()[last_round_dofs[i]];
+ j<sparsity.get_rowstart_indices()[last_round_dofs[i]+1]; ++j)
+ if (sparsity.get_column_numbers()[j] == SparsityPattern::invalid_entry)
+ break;
+ else
+ next_round_dofs.push_back (sparsity.get_column_numbers()[j]);
+
+ // sort dof numbers
+ std::sort (next_round_dofs.begin(), next_round_dofs.end());
+
+ // delete multiple entries
+ std::vector<unsigned int>::iterator end_sorted;
+ end_sorted = std::unique (next_round_dofs.begin(), next_round_dofs.end());
+ next_round_dofs.erase (end_sorted, next_round_dofs.end());
+
+ // eliminate dofs which are
+ // already numbered
+ for (int s=next_round_dofs.size()-1; s>=0; --s)
+ if (new_indices[next_round_dofs[s]] != numbers::invalid_unsigned_int)
+ next_round_dofs.erase (next_round_dofs.begin() + s);
+
+ // check whether there are
+ // any new dofs in the
+ // list. if there are none,
+ // then we have completely
+ // numbered the current
+ // component of the
+ // graph. check if there are
+ // as yet unnumbered
+ // components of the graph
+ // that we would then have to
+ // do next
+ if (next_round_dofs.empty())
+ {
+ if (std::find (new_indices.begin(), new_indices.end(),
+ numbers::invalid_unsigned_int)
+ ==
+ new_indices.end())
+ // no unnumbered
+ // indices, so we can
+ // leave now
+ break;
+
+ // otherwise find a valid
+ // starting point for the
+ // next component of the
+ // graph and continue
+ // with numbering that
+ // one. we only do so if
+ // no starting indices
+ // were provided by the
+ // user (see the
+ // documentation of this
+ // function) so produce
+ // an error if we got
+ // here and starting
+ // indices were given
+ Assert (starting_indices.empty(),
+ ExcMessage ("The input graph appears to have more than one "
+ "component, but as stated in the documentation "
+ "we only want to reorder such graphs if no "
+ "starting indices are given. The function was "
+ "called with starting indices, however."))
+
+ next_round_dofs
+ .push_back (internal::find_unnumbered_starting_index (sparsity,
+ new_indices));
+ }
+
+
+
+ // store for each coordination
+ // number the dofs with these
+ // coordination number
+ std::multimap<unsigned int, int> dofs_by_coordination;
+
+ // find coordination number for
+ // each of these dofs
+ for (std::vector<unsigned int>::iterator s=next_round_dofs.begin();
+ s!=next_round_dofs.end(); ++s)
+ {
+ unsigned int coordination = 0;
+ for (unsigned int j=sparsity.get_rowstart_indices()[*s];
+ j<sparsity.get_rowstart_indices()[*s+1]; ++j)
+ if (sparsity.get_column_numbers()[j] == SparsityPattern::invalid_entry)
+ break;
+ else
+ ++coordination;
+
+ // insert this dof at its
+ // coordination number
+ const std::pair<const unsigned int, int> new_entry (coordination, *s);
+ dofs_by_coordination.insert (new_entry);
+ }
+
+ // assign new DoF numbers to
+ // the elements of the present
+ // front:
+ std::multimap<unsigned int, int>::iterator i;
+ for (i = dofs_by_coordination.begin(); i!=dofs_by_coordination.end(); ++i)
+ new_indices[i->second] = next_free_number++;
+
+ // after that: copy this round's
+ // dofs for the next round
+ last_round_dofs = next_round_dofs;
}
- // test for all indices
- // numbered. this mostly tests
- // whether the
- // front-marching-algorithm (which
- // Cuthill-McKee actually is) has
- // reached all points.
+ // test for all indices
+ // numbered. this mostly tests
+ // whether the
+ // front-marching-algorithm (which
+ // Cuthill-McKee actually is) has
+ // reached all points.
Assert ((std::find (new_indices.begin(), new_indices.end(), numbers::invalid_unsigned_int)
- ==
- new_indices.end())
- &&
- (next_free_number == sparsity.n_rows()),
- ExcInternalError());
+ ==
+ new_indices.end())
+ &&
+ (next_free_number == sparsity.n_rows()),
+ ExcInternalError());
}
#ifdef DEAL_II_COMPILER_SUPPORTS_MPI
template <class CSP_t>
void distribute_sparsity_pattern(CSP_t & csp,
- const std::vector<unsigned int> & rows_per_cpu,
- const MPI_Comm & mpi_comm,
- const IndexSet & myrange)
+ const std::vector<unsigned int> & rows_per_cpu,
+ const MPI_Comm & mpi_comm,
+ const IndexSet & myrange)
{
unsigned int myid = Utilities::MPI::this_mpi_process(mpi_comm);
std::vector<unsigned int> start_index(rows_per_cpu.size()+1);
unsigned int n_local_rel_rows = myrange.n_elements();
for (unsigned int row_idx=0;row_idx<n_local_rel_rows;++row_idx)
- {
- unsigned int row=myrange.nth_index_in_set(row_idx);
-
- //calculate destination CPU
- while (row>=start_index[dest_cpu+1])
- ++dest_cpu;
-
- //skip myself
- if (dest_cpu==myid)
- {
- row_idx+=rows_per_cpu[myid]-1;
- continue;
- }
-
- unsigned int rlen = csp.row_length(row);
-
- //skip empty lines
- if (!rlen)
- continue;
-
- //save entries
- std::vector<unsigned int> & dst = send_data[dest_cpu];
-
- dst.push_back(rlen); // number of entries
- dst.push_back(row); // row index
- for (unsigned int c=0; c<rlen; ++c)
- {
- //columns
- unsigned int column = csp.column_number(row, c);
- dst.push_back(column);
- }
- }
+ {
+ unsigned int row=myrange.nth_index_in_set(row_idx);
+
+ //calculate destination CPU
+ while (row>=start_index[dest_cpu+1])
+ ++dest_cpu;
+
+ //skip myself
+ if (dest_cpu==myid)
+ {
+ row_idx+=rows_per_cpu[myid]-1;
+ continue;
+ }
+
+ unsigned int rlen = csp.row_length(row);
+
+ //skip empty lines
+ if (!rlen)
+ continue;
+
+ //save entries
+ std::vector<unsigned int> & dst = send_data[dest_cpu];
+
+ dst.push_back(rlen); // number of entries
+ dst.push_back(row); // row index
+ for (unsigned int c=0; c<rlen; ++c)
+ {
+ //columns
+ unsigned int column = csp.column_number(row, c);
+ dst.push_back(column);
+ }
+ }
}
std::vector<unsigned int> send_to;
send_to.reserve(send_data.size());
for (map_vec_t::iterator it=send_data.begin();it!=send_data.end();++it)
- send_to.push_back(it->first);
+ send_to.push_back(it->first);
num_receive =
- Utilities::MPI::
- compute_point_to_point_communication_pattern(mpi_comm, send_to).size();
+ Utilities::MPI::
+ compute_point_to_point_communication_pattern(mpi_comm, send_to).size();
}
std::vector<MPI_Request> requests(send_data.size());
- // send data
+ // send data
{
unsigned int idx=0;
for (map_vec_t::iterator it=send_data.begin();it!=send_data.end();++it, ++idx)
- MPI_Isend(&(it->second[0]),
- it->second.size(),
- MPI_INT,
- it->first,
- 124,
- mpi_comm,
- &requests[idx]);
+ MPI_Isend(&(it->second[0]),
+ it->second.size(),
+ MPI_INT,
+ it->first,
+ 124,
+ mpi_comm,
+ &requests[idx]);
}
{
- //receive
+ //receive
std::vector<unsigned int> recv_buf;
for (unsigned int index=0;index<num_receive;++index)
- {
- MPI_Status status;
- int len;
- MPI_Probe(MPI_ANY_SOURCE, MPI_ANY_TAG, mpi_comm, &status);
- Assert (status.MPI_TAG==124, ExcInternalError());
-
- MPI_Get_count(&status, MPI_BYTE, &len);
- Assert( len%sizeof(unsigned int)==0, ExcInternalError());
-
- recv_buf.resize(len/sizeof(unsigned int));
-
- MPI_Recv(&recv_buf[0], len, MPI_BYTE, status.MPI_SOURCE,
- status.MPI_TAG, mpi_comm, &status);
-
- unsigned int *ptr=&recv_buf[0];
- unsigned int *end=&*(--recv_buf.end());
- while (ptr<end)
- {
- unsigned int num=*(ptr++);
- unsigned int row=*(ptr++);
- for (unsigned int c=0;c<num;++c)
- {
- csp.add(row, *ptr);
- ptr++;
- }
- }
- Assert(ptr-1==end, ExcInternalError());
-
- }
+ {
+ MPI_Status status;
+ int len;
+ MPI_Probe(MPI_ANY_SOURCE, MPI_ANY_TAG, mpi_comm, &status);
+ Assert (status.MPI_TAG==124, ExcInternalError());
+
+ MPI_Get_count(&status, MPI_BYTE, &len);
+ Assert( len%sizeof(unsigned int)==0, ExcInternalError());
+
+ recv_buf.resize(len/sizeof(unsigned int));
+
+ MPI_Recv(&recv_buf[0], len, MPI_BYTE, status.MPI_SOURCE,
+ status.MPI_TAG, mpi_comm, &status);
+
+ unsigned int *ptr=&recv_buf[0];
+ unsigned int *end=&*(--recv_buf.end());
+ while (ptr<end)
+ {
+ unsigned int num=*(ptr++);
+ unsigned int row=*(ptr++);
+ for (unsigned int c=0;c<num;++c)
+ {
+ csp.add(row, *ptr);
+ ptr++;
+ }
+ }
+ Assert(ptr-1==end, ExcInternalError());
+
+ }
}
- // complete all sends, so that we can
- // safely destroy the buffers.
+ // complete all sends, so that we can
+ // safely destroy the buffers.
MPI_Waitall(requests.size(), &requests[0], MPI_STATUSES_IGNORE);
}
// $Id$
// Version: $Name$
//
-// Copyright (C) 2000, 2001, 2002, 2005, 2006 by the deal.II authors
+// Copyright (C) 2000, 2001, 2002, 2005, 2006, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
//---------------------------------------------------------------------------
// $Id$
//
-// Copyright (C) 2006, 2007, 2010 by Guido Kanschat
+// Copyright (C) 2006, 2007, 2010, 2012 by Guido Kanschat
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
using namespace Algorithms;
TimestepControl::TimestepControl (double start,
- double final,
- double tolerance,
- double start_step,
- double print_step,
- double max_step)
+ double final,
+ double tolerance,
+ double start_step,
+ double print_step,
+ double max_step)
: start_val(start),
final_val(final),
tolerance_val(tolerance),
param.declare_entry ("Tolerance", "1.e-2", Patterns::Double());
param.declare_entry ("Print step", "-1.", Patterns::Double());
param.declare_entry ("Strategy", "uniform",
- Patterns::Selection("uniform|doubling"));
+ Patterns::Selection("uniform|doubling"));
}
bool changed = false;
double s = step_val;
- // Do time step control, but not in
- // first step.
+ // Do time step control, but not in
+ // first step.
if (now_val != start())
{
if (strategy_val == doubling && 2*s <= tolerance_val)
- s *= 2;
+ s *= 2;
if (s > max_step_val)
- s = max_step_val;
+ s = max_step_val;
}
- // Try incrementing time by s
+ // Try incrementing time by s
double h = now_val + s;
changed = s != step_val;
-
+
step_val = s;
current_step_val = s;
- // If we just missed the final
- // time, increase the step size a
- // bit. This way, we avoid a very
- // small final step. If the step
- // shot over the final time, adjust
- // it so we hit the final time
- // exactly.
+ // If we just missed the final
+ // time, increase the step size a
+ // bit. This way, we avoid a very
+ // small final step. If the step
+ // shot over the final time, adjust
+ // it so we hit the final time
+ // exactly.
double s1 = .01*s;
if (h > final_val-s1)
{
h = final_val;
changed = true;
}
-
+
now_val = h;
return changed;
}
return false;
if (print_step < 0.)
return true;
-
+
bool result = (now_val >= next_print_val);
if (result)
{
next_print_val += print_step;
if (next_print_val > final_val)
- next_print_val = final_val;
+ next_print_val = final_val;
}
return result;
}
// $Id$
// Version: $Name$
//
-// Copyright (C) 2005, 2006 by the deal.II authors
+// Copyright (C) 2005, 2006, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
TridiagonalMatrix<number>::TridiagonalMatrix(
unsigned int size,
bool symmetric)
- :
- diagonal(size, 0.),
- left((symmetric ? 0 : size), 0.),
- right(size, 0.),
- is_symmetric(symmetric),
- state(matrix)
+ :
+ diagonal(size, 0.),
+ left((symmetric ? 0 : size), 0.),
+ right(size, 0.),
+ is_symmetric(symmetric),
+ state(matrix)
{}
void
TridiagonalMatrix<number>::reinit(
unsigned int size,
- bool symmetric)
+ bool symmetric)
{
is_symmetric = symmetric;
diagonal.resize(size);
TridiagonalMatrix<number>::all_zero() const
{
Assert(state == matrix, ExcState(state));
-
+
typename std::vector<number>::const_iterator i;
typename std::vector<number>::const_iterator e;
e = diagonal.end();
for (i=diagonal.begin() ; i != e ; ++i)
if (*i != 0.) return false;
-
+
e = left.end();
for (i=left.begin() ; i != e ; ++i)
if (*i != 0.) return false;
-
+
e = right.end();
for (i=right.begin() ; i != e ; ++i)
if (*i != 0.) return false;
const bool adding) const
{
Assert(state == matrix, ExcState(state));
-
+
Assert(w.size() == n(), ExcDimensionMismatch(w.size(), n()));
Assert(v.size() == n(), ExcDimensionMismatch(v.size(), n()));
if (n()==0) return;
- // The actual loop skips the first
- // and last row
+ // The actual loop skips the first
+ // and last row
const unsigned int e=n()-1;
- // Let iterators point to the first
- // entry of each diagonal
+ // Let iterators point to the first
+ // entry of each diagonal
typename std::vector<number>::const_iterator d = diagonal.begin();
typename std::vector<number>::const_iterator r = right.begin();
- // The left diagonal starts one
- // later or is equal to the right
- // one for symmetric storage
+ // The left diagonal starts one
+ // later or is equal to the right
+ // one for symmetric storage
typename std::vector<number>::const_iterator l = left.begin();
if (is_symmetric)
l = r;
else
++l;
-
+
if (adding)
{
- // Treat first row separately
+ // Treat first row separately
w(0) += (*d) * v(0) + (*r) * v(1);
++d; ++r;
- // All rows with three entries
+ // All rows with three entries
for (unsigned int i=1;i<e;++i,++d,++r,++l)
- w(i) += (*l) * v(i-1) + (*d) * v(i) + (*r) * v(i+1);
- // Last row is special again
+ w(i) += (*l) * v(i-1) + (*d) * v(i) + (*r) * v(i+1);
+ // Last row is special again
w(e) += (*l) * v(e-1) + (*d) * v(e);
}
else
w(0) = (*d) * v(0) + (*r) * v(1);
++d; ++r;
for (unsigned int i=1;i<e;++i,++d,++r,++l)
- w(i) = (*l) * v(i-1) + (*d) * v(i) + (*r) * v(i+1);
+ w(i) = (*l) * v(i-1) + (*d) * v(i) + (*r) * v(i+1);
w(e) = (*l) * v(e-1) + (*d) * v(e);
}
}
const bool adding) const
{
Assert(state == matrix, ExcState(state));
-
+
Assert(w.size() == n(), ExcDimensionMismatch(w.size(), n()));
Assert(v.size() == n(), ExcDimensionMismatch(v.size(), n()));
if (n()==0) return;
-
+
const unsigned int e=n()-1;
typename std::vector<number>::const_iterator d = diagonal.begin();
typename std::vector<number>::const_iterator r = right.begin();
l = r;
else
++l;
-
+
if (adding)
{
w(0) += (*d) * v(0) + (*l) * v(1);
++d; ++l;
for (unsigned int i=1;i<e;++i,++d,++r,++l)
- w(i) += (*l) * v(i+1) + (*d) * v(i) + (*r) * v(i-1);
+ w(i) += (*l) * v(i+1) + (*d) * v(i) + (*r) * v(i-1);
w(e) += (*d) * v(e) + (*r) * v(e-1);
}
else
w(0) = (*d) * v(0) + (*l) * v(1);
++d; ++l;
for (unsigned int i=1;i<e;++i,++d,++r,++l)
- w(i) = (*l) * v(i+1) + (*d) * v(i) + (*r) * v(i-1);
+ w(i) = (*l) * v(i+1) + (*d) * v(i) + (*r) * v(i-1);
w(e) = (*d) * v(e) + (*r) * v(e-1);
}
}
const Vector<number>& v) const
{
Assert(state == matrix, ExcState(state));
-
+
const unsigned int e=n()-1;
typename std::vector<number>::const_iterator d = diagonal.begin();
typename std::vector<number>::const_iterator r = right.begin();
l = r;
else
++l;
-
+
number result = w(0) * ((*d) * v(0) + (*r) * v(1));
++d; ++r;
for (unsigned int i=1;i<e;++i,++d,++r,++l)
#ifdef HAVE_LIBLAPACK
Assert(state == matrix, ExcState(state));
Assert(is_symmetric, ExcNotImplemented());
-
+
const int nn = n();
int info;
stev (&N, &nn, &*diagonal.begin(), &*right.begin(), 0, &one, 0, &info);
Assert(info == 0, ExcInternalError());
-
+
state = eigenvalues;
#else
Assert(false, ExcNeedsLAPACK());
// $Id$
// Version: $Name$
//
-// Copyright (C) 2008, 2009 by the deal.II authors
+// Copyright (C) 2008, 2009, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
BlockSparseMatrix::~BlockSparseMatrix ()
{
- // delete previous content of
- // the subobjects array
+ // delete previous content of
+ // the subobjects array
clear ();
}
{
BlockType *p = new BlockType();
- Assert (this->sub_objects[r][c] == 0,
- ExcInternalError());
+ Assert (this->sub_objects[r][c] == 0,
+ ExcInternalError());
this->sub_objects[r][c] = p;
}
}
void
BlockSparseMatrix::
reinit (const std::vector<Epetra_Map> ¶llel_partitioning,
- const BlockSparsityType &block_sparsity_pattern)
+ const BlockSparsityType &block_sparsity_pattern)
{
Assert (parallel_partitioning.size() == block_sparsity_pattern.n_block_rows(),
- ExcDimensionMismatch (parallel_partitioning.size(),
- block_sparsity_pattern.n_block_rows()));
+ ExcDimensionMismatch (parallel_partitioning.size(),
+ block_sparsity_pattern.n_block_rows()));
Assert (parallel_partitioning.size() == block_sparsity_pattern.n_block_cols(),
- ExcDimensionMismatch (parallel_partitioning.size(),
- block_sparsity_pattern.n_block_cols()));
+ ExcDimensionMismatch (parallel_partitioning.size(),
+ block_sparsity_pattern.n_block_cols()));
const unsigned int n_block_rows = parallel_partitioning.size();
Assert (n_block_rows == block_sparsity_pattern.n_block_rows(),
- ExcDimensionMismatch (n_block_rows,
- block_sparsity_pattern.n_block_rows()));
+ ExcDimensionMismatch (n_block_rows,
+ block_sparsity_pattern.n_block_rows()));
Assert (n_block_rows == block_sparsity_pattern.n_block_cols(),
- ExcDimensionMismatch (n_block_rows,
- block_sparsity_pattern.n_block_cols()));
+ ExcDimensionMismatch (n_block_rows,
+ block_sparsity_pattern.n_block_cols()));
- // Call the other basic reinit function, ...
+ // Call the other basic reinit function, ...
reinit (block_sparsity_pattern.n_block_rows(),
- block_sparsity_pattern.n_block_cols());
+ block_sparsity_pattern.n_block_cols());
- // ... set the correct sizes, ...
+ // ... set the correct sizes, ...
this->row_block_indices = block_sparsity_pattern.get_row_indices();
this->column_block_indices = block_sparsity_pattern.get_column_indices();
- // ... and then assign the correct
- // data to the blocks.
+ // ... and then assign the correct
+ // data to the blocks.
for (unsigned int r=0; r<this->n_block_rows(); ++r)
for (unsigned int c=0; c<this->n_block_cols(); ++c)
{
- this->sub_objects[r][c]->reinit (parallel_partitioning[r],
- parallel_partitioning[c],
- block_sparsity_pattern.block(r,c));
+ this->sub_objects[r][c]->reinit (parallel_partitioning[r],
+ parallel_partitioning[c],
+ block_sparsity_pattern.block(r,c));
}
}
void
BlockSparseMatrix::
reinit (const std::vector<IndexSet> ¶llel_partitioning,
- const BlockSparsityType &block_sparsity_pattern,
- const MPI_Comm &communicator)
+ const BlockSparsityType &block_sparsity_pattern,
+ const MPI_Comm &communicator)
{
std::vector<Epetra_Map> epetra_maps;
for (unsigned int i=0; i<block_sparsity_pattern.n_block_rows(); ++i)
epetra_maps.push_back
- (parallel_partitioning[i].make_trilinos_map(communicator, false));
+ (parallel_partitioning[i].make_trilinos_map(communicator, false));
reinit (epetra_maps, block_sparsity_pattern);
std::vector<Epetra_Map> parallel_partitioning;
for (unsigned int i=0; i<block_sparsity_pattern.n_block_rows(); ++i)
parallel_partitioning.push_back
- (Epetra_Map(block_sparsity_pattern.block(i,0).n_rows(),
- 0,
- Utilities::Trilinos::comm_self()));
+ (Epetra_Map(block_sparsity_pattern.block(i,0).n_rows(),
+ 0,
+ Utilities::Trilinos::comm_self()));
reinit (parallel_partitioning, block_sparsity_pattern);
}
reinit (const BlockSparsityPattern &block_sparsity_pattern)
{
- // Call the other basic reinit function, ...
+ // Call the other basic reinit function, ...
reinit (block_sparsity_pattern.n_block_rows(),
- block_sparsity_pattern.n_block_cols());
+ block_sparsity_pattern.n_block_cols());
- // ... set the correct sizes, ...
+ // ... set the correct sizes, ...
this->row_block_indices = block_sparsity_pattern.get_row_indices();
this->column_block_indices = block_sparsity_pattern.get_column_indices();
- // ... and then assign the correct
- // data to the blocks.
+ // ... and then assign the correct
+ // data to the blocks.
for (unsigned int r=0; r<this->n_block_rows(); ++r)
for (unsigned int c=0; c<this->n_block_cols(); ++c)
{
- this->sub_objects[r][c]->reinit (block_sparsity_pattern.block(r,c));
+ this->sub_objects[r][c]->reinit (block_sparsity_pattern.block(r,c));
}
}
void
BlockSparseMatrix::
reinit (const std::vector<Epetra_Map> ¶llel_partitioning,
- const ::dealii::BlockSparseMatrix<double> &dealii_block_sparse_matrix,
- const double drop_tolerance)
+ const ::dealii::BlockSparseMatrix<double> &dealii_block_sparse_matrix,
+ const double drop_tolerance)
{
const unsigned int n_block_rows = parallel_partitioning.size();
Assert (n_block_rows == dealii_block_sparse_matrix.n_block_rows(),
- ExcDimensionMismatch (n_block_rows,
- dealii_block_sparse_matrix.n_block_rows()));
+ ExcDimensionMismatch (n_block_rows,
+ dealii_block_sparse_matrix.n_block_rows()));
Assert (n_block_rows == dealii_block_sparse_matrix.n_block_cols(),
- ExcDimensionMismatch (n_block_rows,
- dealii_block_sparse_matrix.n_block_cols()));
+ ExcDimensionMismatch (n_block_rows,
+ dealii_block_sparse_matrix.n_block_cols()));
- // Call the other basic reinit function ...
+ // Call the other basic reinit function ...
reinit (n_block_rows, n_block_rows);
- // ... and then assign the correct
- // data to the blocks.
+ // ... and then assign the correct
+ // data to the blocks.
for (unsigned int r=0; r<this->n_block_rows(); ++r)
for (unsigned int c=0; c<this->n_block_cols(); ++c)
{
this->sub_objects[r][c]->reinit(parallel_partitioning[r],
- parallel_partitioning[c],
- dealii_block_sparse_matrix.block(r,c),
- drop_tolerance);
+ parallel_partitioning[c],
+ dealii_block_sparse_matrix.block(r,c),
+ drop_tolerance);
}
collect_sizes();
void
BlockSparseMatrix::
reinit (const ::dealii::BlockSparseMatrix<double> &dealii_block_sparse_matrix,
- const double drop_tolerance)
+ const double drop_tolerance)
{
Assert (dealii_block_sparse_matrix.n_block_rows() ==
- dealii_block_sparse_matrix.n_block_cols(),
- ExcDimensionMismatch (dealii_block_sparse_matrix.n_block_rows(),
- dealii_block_sparse_matrix.n_block_cols()));
+ dealii_block_sparse_matrix.n_block_cols(),
+ ExcDimensionMismatch (dealii_block_sparse_matrix.n_block_rows(),
+ dealii_block_sparse_matrix.n_block_cols()));
Assert (dealii_block_sparse_matrix.m() ==
- dealii_block_sparse_matrix.n(),
- ExcDimensionMismatch (dealii_block_sparse_matrix.m(),
- dealii_block_sparse_matrix.n()));
+ dealii_block_sparse_matrix.n(),
+ ExcDimensionMismatch (dealii_block_sparse_matrix.m(),
+ dealii_block_sparse_matrix.n()));
- // produce a dummy local map and pass it
- // off to the other function
+ // produce a dummy local map and pass it
+ // off to the other function
#ifdef DEAL_II_COMPILER_SUPPORTS_MPI
Epetra_MpiComm trilinos_communicator (MPI_COMM_SELF);
#else
std::vector<Epetra_Map> parallel_partitioning;
for (unsigned int i=0; i<dealii_block_sparse_matrix.n_block_rows(); ++i)
parallel_partitioning.push_back (Epetra_Map(dealii_block_sparse_matrix.block(i,0).m(),
- 0,
- trilinos_communicator));
+ 0,
+ trilinos_communicator));
reinit (parallel_partitioning, dealii_block_sparse_matrix, drop_tolerance);
}
{
for (unsigned int r=0; r<this->n_block_rows(); ++r)
for (unsigned int c=0; c<this->n_block_cols(); ++c)
- this->block(r,c).compress();
+ this->block(r,c).compress();
}
unsigned int n_nonzero = 0;
for (unsigned int rows = 0; rows<this->n_block_rows(); ++rows)
for (unsigned int cols = 0; cols<this->n_block_cols(); ++cols)
- n_nonzero += this->block(rows,cols).n_nonzero_elements();
+ n_nonzero += this->block(rows,cols).n_nonzero_elements();
return n_nonzero;
}
TrilinosScalar
BlockSparseMatrix::residual (MPI::BlockVector &dst,
- const MPI::BlockVector &x,
- const MPI::BlockVector &b) const
+ const MPI::BlockVector &x,
+ const MPI::BlockVector &b) const
{
vmult (dst, x);
dst -= b;
- // TODO: In the following we
- // use the same code as just
- // above six more times. Use
- // templates.
+ // TODO: In the following we
+ // use the same code as just
+ // above six more times. Use
+ // templates.
TrilinosScalar
BlockSparseMatrix::residual (BlockVector &dst,
- const BlockVector &x,
- const BlockVector &b) const
+ const BlockVector &x,
+ const BlockVector &b) const
{
vmult (dst, x);
dst -= b;
TrilinosScalar
BlockSparseMatrix::residual (MPI::BlockVector &dst,
- const MPI::Vector &x,
- const MPI::BlockVector &b) const
+ const MPI::Vector &x,
+ const MPI::BlockVector &b) const
{
vmult (dst, x);
dst -= b;
TrilinosScalar
BlockSparseMatrix::residual (BlockVector &dst,
- const Vector &x,
- const BlockVector &b) const
+ const Vector &x,
+ const BlockVector &b) const
{
vmult (dst, x);
dst -= b;
TrilinosScalar
BlockSparseMatrix::residual (MPI::Vector &dst,
- const MPI::BlockVector &x,
- const MPI::Vector &b) const
+ const MPI::BlockVector &x,
+ const MPI::Vector &b) const
{
vmult (dst, x);
dst -= b;
TrilinosScalar
BlockSparseMatrix::residual (Vector &dst,
- const BlockVector &x,
- const Vector &b) const
+ const BlockVector &x,
+ const Vector &b) const
{
vmult (dst, x);
dst -= b;
TrilinosScalar
BlockSparseMatrix::residual (VectorBase &dst,
- const VectorBase &x,
- const VectorBase &b) const
+ const VectorBase &x,
+ const VectorBase &b) const
{
vmult (dst, x);
dst -= b;
template void
BlockSparseMatrix::reinit (const std::vector<Epetra_Map> &,
- const dealii::BlockSparsityPattern &);
+ const dealii::BlockSparsityPattern &);
template void
BlockSparseMatrix::reinit (const std::vector<Epetra_Map> &,
- const dealii::BlockCompressedSparsityPattern &);
+ const dealii::BlockCompressedSparsityPattern &);
template void
BlockSparseMatrix::reinit (const std::vector<Epetra_Map> &,
- const dealii::BlockCompressedSetSparsityPattern &);
+ const dealii::BlockCompressedSetSparsityPattern &);
template void
BlockSparseMatrix::reinit (const std::vector<Epetra_Map> &,
- const dealii::BlockCompressedSimpleSparsityPattern &);
+ const dealii::BlockCompressedSimpleSparsityPattern &);
}
// $Id$
// Version: $Name$
//
-// Copyright (C) 2008, 2009, 2011 by the deal.II authors
+// Copyright (C) 2008, 2009, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
BlockVector::operator = (const BlockVector &v)
{
if (this->n_blocks() != v.n_blocks())
- reinit(v.n_blocks());
+ reinit(v.n_blocks());
for (unsigned int i=0; i<this->n_blocks(); ++i)
- this->components[i] = v.block(i);
+ this->components[i] = v.block(i);
collect_sizes();
BlockVector::operator = (const ::dealii::TrilinosWrappers::BlockVector &v)
{
Assert (n_blocks() == v.n_blocks(),
- ExcDimensionMismatch(n_blocks(),v.n_blocks()));
+ ExcDimensionMismatch(n_blocks(),v.n_blocks()));
for (unsigned int i=0; i<this->n_blocks(); ++i)
- this->components[i] = v.block(i);
+ this->components[i] = v.block(i);
return *this;
}
void
BlockVector::reinit (const std::vector<Epetra_Map> &input_maps,
- const bool fast)
+ const bool fast)
{
const unsigned int no_blocks = input_maps.size();
std::vector<unsigned int> block_sizes (no_blocks);
for (unsigned int i=0; i<no_blocks; ++i)
- {
- block_sizes[i] = input_maps[i].NumGlobalElements();
- }
+ {
+ block_sizes[i] = input_maps[i].NumGlobalElements();
+ }
this->block_indices.reinit (block_sizes);
if (components.size() != n_blocks())
void
BlockVector::reinit (const std::vector<IndexSet> ¶llel_partitioning,
- const MPI_Comm &communicator,
- const bool fast)
+ const MPI_Comm &communicator,
+ const bool fast)
{
const unsigned int no_blocks = parallel_partitioning.size();
std::vector<unsigned int> block_sizes (no_blocks);
for (unsigned int i=0; i<no_blocks; ++i)
- {
- block_sizes[i] = parallel_partitioning[i].size();
- }
+ {
+ block_sizes[i] = parallel_partitioning[i].size();
+ }
this->block_indices.reinit (block_sizes);
if (components.size() != n_blocks())
void
BlockVector::reinit (const BlockVector& v,
- const bool fast)
+ const bool fast)
{
block_indices = v.get_block_indices();
if (components.size() != n_blocks())
const BlockVector &v)
{
Assert (m.n_block_rows() == v.n_blocks(),
- ExcDimensionMismatch(m.n_block_rows(),v.n_blocks()));
+ ExcDimensionMismatch(m.n_block_rows(),v.n_blocks()));
Assert (m.n_block_cols() == v.n_blocks(),
- ExcDimensionMismatch(m.n_block_cols(),v.n_blocks()));
+ ExcDimensionMismatch(m.n_block_cols(),v.n_blocks()));
if (v.n_blocks() != n_blocks())
- {
- block_indices = v.get_block_indices();
- components.resize(v.n_blocks());
- }
+ {
+ block_indices = v.get_block_indices();
+ components.resize(v.n_blocks());
+ }
for (unsigned int i=0; i<this->n_blocks(); ++i)
- components[i].import_nonlocal_data_for_fe(m.block(i,i), v.block(i));
+ components[i].import_nonlocal_data_for_fe(m.block(i,i), v.block(i));
collect_sizes();
}
BlockVector::compress (const Epetra_CombineMode last_action)
{
for (unsigned int i=0; i<n_blocks(); ++i)
- components[i].compress(last_action);
+ components[i].compress(last_action);
}
void BlockVector::print (std::ostream &out,
- const unsigned int precision,
- const bool scientific,
- const bool across) const
+ const unsigned int precision,
+ const bool scientific,
+ const bool across) const
{
for (unsigned int i=0;i<this->n_blocks();++i)
- {
- if (across)
- out << 'C' << i << ':';
- else
- out << "Component " << i << std::endl;
- this->components[i].print(out, precision, scientific, across);
- }
+ {
+ if (across)
+ out << 'C' << i << ':';
+ else
+ out << "Component " << i << std::endl;
+ this->components[i].print(out, precision, scientific, across);
+ }
}
} /* end of namespace MPI */
void
BlockVector::reinit (const std::vector<Epetra_Map> &input_maps,
- const bool fast)
+ const bool fast)
{
unsigned int no_blocks = input_maps.size();
std::vector<unsigned int> block_sizes (no_blocks);
void
BlockVector::reinit (const std::vector<IndexSet> &partitioning,
- const MPI_Comm &communicator,
- const bool fast)
+ const MPI_Comm &communicator,
+ const bool fast)
{
unsigned int no_blocks = partitioning.size();
std::vector<unsigned int> block_sizes (no_blocks);
void
BlockVector::reinit (const std::vector<unsigned int> &block_sizes,
- const bool fast)
+ const bool fast)
{
this->block_indices.reinit (block_sizes);
if (components.size() != n_blocks())
void
BlockVector::reinit (const BlockVector &v,
- const bool fast)
+ const bool fast)
{
block_indices = v.get_block_indices();
if (components.size() != n_blocks())
{
if (n_blocks() != v.n_blocks())
{
- std::vector<unsigned int> block_sizes (v.n_blocks(), 0);
- block_indices.reinit (block_sizes);
- if (components.size() != n_blocks())
- components.resize(n_blocks());
+ std::vector<unsigned int> block_sizes (v.n_blocks(), 0);
+ block_indices.reinit (block_sizes);
+ if (components.size() != n_blocks())
+ components.resize(n_blocks());
}
for (unsigned int i=0; i<this->n_blocks(); ++i)
void BlockVector::print (std::ostream &out,
- const unsigned int precision,
- const bool scientific,
- const bool across) const
+ const unsigned int precision,
+ const bool scientific,
+ const bool across) const
{
for (unsigned int i=0;i<this->n_blocks();++i)
{
- if (across)
- out << 'C' << i << ':';
- else
- out << "Component " << i << std::endl;
- this->components[i].print(out, precision, scientific, across);
+ if (across)
+ out << 'C' << i << ':';
+ else
+ out << "Component " << i << std::endl;
+ this->components[i].print(out, precision, scientific, across);
}
}
// $Id$
// Version: $Name$
//
-// Copyright (C) 2008, 2009, 2010, 2011 by the deal.II authors
+// Copyright (C) 2008, 2009, 2010, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
#ifdef DEAL_II_COMPILER_SUPPORTS_MPI
communicator (base.communicator),
#endif
- vector_distributor (new Epetra_Map(*base.vector_distributor))
+ vector_distributor (new Epetra_Map(*base.vector_distributor))
{}
PreconditionJacobi::AdditionalData::
AdditionalData (const double omega,
- const double min_diagonal)
+ const double min_diagonal)
:
omega (omega),
- min_diagonal (min_diagonal)
+ min_diagonal (min_diagonal)
{}
void
PreconditionJacobi::initialize (const SparseMatrix &matrix,
- const AdditionalData &additional_data)
+ const AdditionalData &additional_data)
{
- // release memory before reallocation
+ // release memory before reallocation
preconditioner.reset ();
preconditioner.reset (Ifpack().Create
- ("point relaxation",
- const_cast<Epetra_CrsMatrix*>(&matrix.trilinos_matrix()),
- 0));
+ ("point relaxation",
+ const_cast<Epetra_CrsMatrix*>(&matrix.trilinos_matrix()),
+ 0));
Ifpack_Preconditioner * ifpack = static_cast<Ifpack_Preconditioner*>
(preconditioner.get());
Assert (ifpack != 0, ExcMessage ("Trilinos could not create this "
- "preconditioner"));
+ "preconditioner"));
int ierr;
parameter_list.set ("relaxation: type", "Jacobi");
parameter_list.set ("relaxation: damping factor", additional_data.omega);
parameter_list.set ("relaxation: min diagonal value",
- additional_data.min_diagonal);
+ additional_data.min_diagonal);
ierr = ifpack->SetParameters(parameter_list);
AssertThrow (ierr == 0, ExcTrilinosError(ierr));
PreconditionSSOR::AdditionalData::
AdditionalData (const double omega,
- const double min_diagonal,
- const unsigned int overlap)
+ const double min_diagonal,
+ const unsigned int overlap)
:
omega (omega),
- min_diagonal (min_diagonal),
- overlap (overlap)
+ min_diagonal (min_diagonal),
+ overlap (overlap)
{}
void
PreconditionSSOR::initialize (const SparseMatrix &matrix,
- const AdditionalData &additional_data)
+ const AdditionalData &additional_data)
{
preconditioner.reset ();
preconditioner.reset (Ifpack().Create
- ("point relaxation",
- const_cast<Epetra_CrsMatrix*>(&matrix.trilinos_matrix()),
- additional_data.overlap));
+ ("point relaxation",
+ const_cast<Epetra_CrsMatrix*>(&matrix.trilinos_matrix()),
+ additional_data.overlap));
Ifpack_Preconditioner * ifpack = static_cast<Ifpack_Preconditioner*>
(preconditioner.get());
Assert (ifpack != 0, ExcMessage ("Trilinos could not create this "
- "preconditioner"));
+ "preconditioner"));
int ierr;
parameter_list.set ("relaxation: type", "symmetric Gauss-Seidel");
parameter_list.set ("relaxation: damping factor", additional_data.omega);
parameter_list.set ("relaxation: min diagonal value",
- additional_data.min_diagonal);
+ additional_data.min_diagonal);
parameter_list.set ("schwarz: combine mode", "Add");
ierr = ifpack->SetParameters(parameter_list);
PreconditionSOR::AdditionalData::
AdditionalData (const double omega,
- const double min_diagonal,
- const unsigned int overlap)
+ const double min_diagonal,
+ const unsigned int overlap)
:
omega (omega),
- min_diagonal (min_diagonal),
- overlap (overlap)
+ min_diagonal (min_diagonal),
+ overlap (overlap)
{}
void
PreconditionSOR::initialize (const SparseMatrix &matrix,
- const AdditionalData &additional_data)
+ const AdditionalData &additional_data)
{
preconditioner.reset ();
preconditioner.reset (Ifpack().Create
- ("point relaxation",
- const_cast<Epetra_CrsMatrix*>(&matrix.trilinos_matrix()),
- additional_data.overlap));
+ ("point relaxation",
+ const_cast<Epetra_CrsMatrix*>(&matrix.trilinos_matrix()),
+ additional_data.overlap));
Ifpack_Preconditioner * ifpack = static_cast<Ifpack_Preconditioner*>
(preconditioner.get());
Assert (ifpack != 0, ExcMessage ("Trilinos could not create this "
- "preconditioner"));
+ "preconditioner"));
int ierr;
parameter_list.set ("relaxation: type", "Gauss-Seidel");
parameter_list.set ("relaxation: damping factor", additional_data.omega);
parameter_list.set ("relaxation: min diagonal value",
- additional_data.min_diagonal);
+ additional_data.min_diagonal);
parameter_list.set ("schwarz: combine mode", "Add");
ierr = ifpack->SetParameters(parameter_list);
PreconditionIC::AdditionalData::
AdditionalData (const unsigned int ic_fill,
- const double ic_atol,
- const double ic_rtol,
- const unsigned int overlap)
+ const double ic_atol,
+ const double ic_rtol,
+ const unsigned int overlap)
:
ic_fill (ic_fill),
- ic_atol (ic_atol),
- ic_rtol (ic_rtol),
- overlap (overlap)
+ ic_atol (ic_atol),
+ ic_rtol (ic_rtol),
+ overlap (overlap)
{}
void
PreconditionIC::initialize (const SparseMatrix &matrix,
- const AdditionalData &additional_data)
+ const AdditionalData &additional_data)
{
preconditioner.reset ();
preconditioner.reset (Ifpack().Create
- ("IC",
- const_cast<Epetra_CrsMatrix*>(&matrix.trilinos_matrix()),
- additional_data.overlap));
+ ("IC",
+ const_cast<Epetra_CrsMatrix*>(&matrix.trilinos_matrix()),
+ additional_data.overlap));
Ifpack_Preconditioner * ifpack = static_cast<Ifpack_Preconditioner*>
(preconditioner.get());
Assert (ifpack != 0, ExcMessage ("Trilinos could not create this "
- "preconditioner"));
+ "preconditioner"));
int ierr;
PreconditionILU::AdditionalData::
AdditionalData (const unsigned int ilu_fill,
- const double ilu_atol,
- const double ilu_rtol,
- const unsigned int overlap)
+ const double ilu_atol,
+ const double ilu_rtol,
+ const unsigned int overlap)
:
ilu_fill (ilu_fill),
- ilu_atol (ilu_atol),
- ilu_rtol (ilu_rtol),
- overlap (overlap)
+ ilu_atol (ilu_atol),
+ ilu_rtol (ilu_rtol),
+ overlap (overlap)
{}
void
PreconditionILU::initialize (const SparseMatrix &matrix,
- const AdditionalData &additional_data)
+ const AdditionalData &additional_data)
{
preconditioner.reset ();
preconditioner.reset (Ifpack().Create
- ("ILU",
- const_cast<Epetra_CrsMatrix*>(&matrix.trilinos_matrix()),
- additional_data.overlap));
+ ("ILU",
+ const_cast<Epetra_CrsMatrix*>(&matrix.trilinos_matrix()),
+ additional_data.overlap));
Ifpack_Preconditioner * ifpack = static_cast<Ifpack_Preconditioner*>
(preconditioner.get());
Assert (ifpack != 0, ExcMessage ("Trilinos could not create this "
- "preconditioner"));
+ "preconditioner"));
int ierr;
PreconditionILUT::AdditionalData::
AdditionalData (const double ilut_drop,
- const unsigned int ilut_fill,
- const double ilut_atol,
- const double ilut_rtol,
- const unsigned int overlap)
+ const unsigned int ilut_fill,
+ const double ilut_atol,
+ const double ilut_rtol,
+ const unsigned int overlap)
:
ilut_drop (ilut_drop),
ilut_fill (ilut_fill),
- ilut_atol (ilut_atol),
- ilut_rtol (ilut_rtol),
- overlap (overlap)
+ ilut_atol (ilut_atol),
+ ilut_rtol (ilut_rtol),
+ overlap (overlap)
{}
void
PreconditionILUT::initialize (const SparseMatrix &matrix,
- const AdditionalData &additional_data)
+ const AdditionalData &additional_data)
{
preconditioner.reset ();
preconditioner.reset (Ifpack().Create
- ("ILUT",
- const_cast<Epetra_CrsMatrix*>(&matrix.trilinos_matrix()),
- additional_data.overlap));
+ ("ILUT",
+ const_cast<Epetra_CrsMatrix*>(&matrix.trilinos_matrix()),
+ additional_data.overlap));
Ifpack_Preconditioner * ifpack = static_cast<Ifpack_Preconditioner*>
(preconditioner.get());
Assert (ifpack != 0, ExcMessage ("Trilinos could not create this "
- "preconditioner"));
+ "preconditioner"));
int ierr;
void
PreconditionBlockwiseDirect::initialize (const SparseMatrix &matrix,
- const AdditionalData &additional_data)
+ const AdditionalData &additional_data)
{
preconditioner.reset ();
preconditioner.reset (Ifpack().Create
- ("Amesos",
- const_cast<Epetra_CrsMatrix*>(&matrix.trilinos_matrix()),
- additional_data.overlap));
+ ("Amesos",
+ const_cast<Epetra_CrsMatrix*>(&matrix.trilinos_matrix()),
+ additional_data.overlap));
Ifpack_Preconditioner * ifpack = static_cast<Ifpack_Preconditioner*>
(preconditioner.get());
Assert (ifpack != 0, ExcMessage ("Trilinos could not create this "
- "preconditioner"));
+ "preconditioner"));
int ierr;
PreconditionChebyshev::AdditionalData::
AdditionalData (const unsigned int degree,
- const double max_eigenvalue,
- const double eigenvalue_ratio,
- const double min_eigenvalue,
- const double min_diagonal,
- const bool nonzero_starting)
+ const double max_eigenvalue,
+ const double eigenvalue_ratio,
+ const double min_eigenvalue,
+ const double min_diagonal,
+ const bool nonzero_starting)
:
degree (degree),
- max_eigenvalue (max_eigenvalue),
- eigenvalue_ratio (eigenvalue_ratio),
- min_eigenvalue (min_eigenvalue),
- min_diagonal (min_diagonal),
- nonzero_starting (nonzero_starting)
+ max_eigenvalue (max_eigenvalue),
+ eigenvalue_ratio (eigenvalue_ratio),
+ min_eigenvalue (min_eigenvalue),
+ min_diagonal (min_diagonal),
+ nonzero_starting (nonzero_starting)
{}
void
PreconditionChebyshev::initialize (const SparseMatrix &matrix,
- const AdditionalData &additional_data)
+ const AdditionalData &additional_data)
{
preconditioner.reset ();
preconditioner.reset (new Ifpack_Chebyshev (&matrix.trilinos_matrix()));
Ifpack_Chebyshev * ifpack = static_cast<Ifpack_Chebyshev*>
(preconditioner.get());
Assert (ifpack != 0, ExcMessage ("Trilinos could not create this "
- "preconditioner"));
+ "preconditioner"));
int ierr;
Teuchos::ParameterList parameter_list;
parameter_list.set ("chebyshev: ratio eigenvalue",
- additional_data.eigenvalue_ratio);
+ additional_data.eigenvalue_ratio);
parameter_list.set ("chebyshev: min eigenvalue",
- additional_data.min_eigenvalue);
+ additional_data.min_eigenvalue);
parameter_list.set ("chebyshev: max eigenvalue",
- additional_data.max_eigenvalue);
+ additional_data.max_eigenvalue);
parameter_list.set ("chebyshev: degree",
- (int)additional_data.degree);
+ (int)additional_data.degree);
parameter_list.set ("chebyshev: min diagonal value",
- additional_data.min_diagonal);
+ additional_data.min_diagonal);
parameter_list.set ("chebyshev: zero starting solution",
- !additional_data.nonzero_starting);
+ !additional_data.nonzero_starting);
ierr = ifpack->SetParameters(parameter_list);
AssertThrow (ierr == 0, ExcTrilinosError(ierr));
PreconditionAMG::AdditionalData::
AdditionalData (const bool elliptic,
- const bool higher_order_elements,
- const unsigned int n_cycles,
- const bool w_cycle,
- const double aggregation_threshold,
- const std::vector<std::vector<bool> > &constant_modes,
- const unsigned int smoother_sweeps,
- const unsigned int smoother_overlap,
- const bool output_details)
+ const bool higher_order_elements,
+ const unsigned int n_cycles,
+ const bool w_cycle,
+ const double aggregation_threshold,
+ const std::vector<std::vector<bool> > &constant_modes,
+ const unsigned int smoother_sweeps,
+ const unsigned int smoother_overlap,
+ const bool output_details)
:
elliptic (elliptic),
- higher_order_elements (higher_order_elements),
- n_cycles (n_cycles),
- w_cycle (w_cycle),
- aggregation_threshold (aggregation_threshold),
- constant_modes (constant_modes),
- smoother_sweeps (smoother_sweeps),
- smoother_overlap (smoother_overlap),
- output_details (output_details)
+ higher_order_elements (higher_order_elements),
+ n_cycles (n_cycles),
+ w_cycle (w_cycle),
+ aggregation_threshold (aggregation_threshold),
+ constant_modes (constant_modes),
+ smoother_sweeps (smoother_sweeps),
+ smoother_overlap (smoother_overlap),
+ output_details (output_details)
{}
void
PreconditionAMG:: initialize (const SparseMatrix &matrix,
- const AdditionalData &additional_data)
+ const AdditionalData &additional_data)
{
const unsigned int n_rows = matrix.m();
- // Build the AMG preconditioner.
+ // Build the AMG preconditioner.
Teuchos::ParameterList parameter_list;
if (additional_data.elliptic == true)
{
- ML_Epetra::SetDefaults("SA",parameter_list);
- parameter_list.set("smoother: type", "Chebyshev");
-
- // uncoupled mode can give a lot of
- // warnings or even fail when there
- // are too many entries per row and
- // aggreggation gets complicated, but
- // MIS does not work if too few
- // elements are located on one
- // processor. work around these
- // warnings by choosing the different
- // strategies in different
- // situations: for low order, always
- // use the standard choice
- // uncoupled. if higher order, right
- // now we also just use Uncoupled,
- // but we should be aware that maybe
- // MIS might be needed
- //
- // TODO: Maybe there are any
- // other/better options?
- if (additional_data.higher_order_elements)
- {
- //if (matrix.m()/matrix.matrix->Comm().NumProc() < 50000)
- parameter_list.set("aggregation: type", "Uncoupled");
- //else
- //parameter_list.set("aggregation: type", "MIS");
- }
+ ML_Epetra::SetDefaults("SA",parameter_list);
+ parameter_list.set("smoother: type", "Chebyshev");
+
+ // uncoupled mode can give a lot of
+ // warnings or even fail when there
+ // are too many entries per row and
+ // aggreggation gets complicated, but
+ // MIS does not work if too few
+ // elements are located on one
+ // processor. work around these
+ // warnings by choosing the different
+ // strategies in different
+ // situations: for low order, always
+ // use the standard choice
+ // uncoupled. if higher order, right
+ // now we also just use Uncoupled,
+ // but we should be aware that maybe
+ // MIS might be needed
+ //
+ // TODO: Maybe there are any
+ // other/better options?
+ if (additional_data.higher_order_elements)
+ {
+ //if (matrix.m()/matrix.matrix->Comm().NumProc() < 50000)
+ parameter_list.set("aggregation: type", "Uncoupled");
+ //else
+ //parameter_list.set("aggregation: type", "MIS");
+ }
}
else
{
- ML_Epetra::SetDefaults("NSSA",parameter_list);
- parameter_list.set("aggregation: type", "Uncoupled");
- parameter_list.set("aggregation: block scaling", true);
+ ML_Epetra::SetDefaults("NSSA",parameter_list);
+ parameter_list.set("aggregation: type", "Uncoupled");
+ parameter_list.set("aggregation: block scaling", true);
}
parameter_list.set("smoother: sweeps",
- static_cast<int>(additional_data.smoother_sweeps));
+ static_cast<int>(additional_data.smoother_sweeps));
parameter_list.set("cycle applications",
- static_cast<int>(additional_data.n_cycles));
+ static_cast<int>(additional_data.n_cycles));
if (additional_data.w_cycle == true)
parameter_list.set("prec type", "MGW");
else
parameter_list.set("smoother: Chebyshev alpha",10.);
parameter_list.set("smoother: ifpack overlap",
- static_cast<int>(additional_data.smoother_overlap));
+ static_cast<int>(additional_data.smoother_overlap));
parameter_list.set("aggregation: threshold",
- additional_data.aggregation_threshold);
+ additional_data.aggregation_threshold);
if (additional_data.output_details)
parameter_list.set("ML output", 10);
const unsigned int constant_modes_dimension =
additional_data.constant_modes.size();
Epetra_MultiVector distributed_constant_modes (domain_map,
- constant_modes_dimension);
+ constant_modes_dimension);
std::vector<double> dummy (constant_modes_dimension);
if (constant_modes_dimension > 1)
{
- const bool constant_modes_are_global =
- additional_data.constant_modes[0].size() == n_rows;
- const unsigned int n_relevant_rows =
- constant_modes_are_global ? n_rows : additional_data.constant_modes[0].size();
- const unsigned int my_size = domain_map.NumMyElements();
- if (constant_modes_are_global == false)
- Assert (n_relevant_rows == my_size,
- ExcDimensionMismatch(n_relevant_rows, my_size));
- Assert (n_rows ==
- static_cast<unsigned int>(distributed_constant_modes.GlobalLength()),
- ExcDimensionMismatch(n_rows,
- distributed_constant_modes.GlobalLength()));
-
- // Reshape null space as a
- // contiguous vector of
- // doubles so that Trilinos
- // can read from it.
- for (unsigned int d=0; d<constant_modes_dimension; ++d)
- for (unsigned int row=0; row<my_size; ++row)
- {
- int global_row_id = constant_modes_are_global ? domain_map.GID(row) : row;
- distributed_constant_modes[d][row] =
- additional_data.constant_modes[d][global_row_id];
- }
-
- parameter_list.set("null space: type", "pre-computed");
- parameter_list.set("null space: dimension",
- distributed_constant_modes.NumVectors());
- if (my_size > 0)
- parameter_list.set("null space: vectors",
- distributed_constant_modes.Values());
- // We need to set a valid pointer to data even
- // if there is no data on the current
- // processor. Therefore, pass a dummy in that
- // case
- else
- parameter_list.set("null space: vectors",
- &dummy[0]);
+ const bool constant_modes_are_global =
+ additional_data.constant_modes[0].size() == n_rows;
+ const unsigned int n_relevant_rows =
+ constant_modes_are_global ? n_rows : additional_data.constant_modes[0].size();
+ const unsigned int my_size = domain_map.NumMyElements();
+ if (constant_modes_are_global == false)
+ Assert (n_relevant_rows == my_size,
+ ExcDimensionMismatch(n_relevant_rows, my_size));
+ Assert (n_rows ==
+ static_cast<unsigned int>(distributed_constant_modes.GlobalLength()),
+ ExcDimensionMismatch(n_rows,
+ distributed_constant_modes.GlobalLength()));
+
+ // Reshape null space as a
+ // contiguous vector of
+ // doubles so that Trilinos
+ // can read from it.
+ for (unsigned int d=0; d<constant_modes_dimension; ++d)
+ for (unsigned int row=0; row<my_size; ++row)
+ {
+ int global_row_id = constant_modes_are_global ? domain_map.GID(row) : row;
+ distributed_constant_modes[d][row] =
+ additional_data.constant_modes[d][global_row_id];
+ }
+
+ parameter_list.set("null space: type", "pre-computed");
+ parameter_list.set("null space: dimension",
+ distributed_constant_modes.NumVectors());
+ if (my_size > 0)
+ parameter_list.set("null space: vectors",
+ distributed_constant_modes.Values());
+ // We need to set a valid pointer to data even
+ // if there is no data on the current
+ // processor. Therefore, pass a dummy in that
+ // case
+ else
+ parameter_list.set("null space: vectors",
+ &dummy[0]);
}
initialize (matrix, parameter_list);
if (additional_data.output_details)
{
- ML_Epetra::MultiLevelPreconditioner * multilevel_operator =
- dynamic_cast<ML_Epetra::MultiLevelPreconditioner*> (preconditioner.get());
- Assert (multilevel_operator != 0,
- ExcMessage ("Preconditioner setup failed."));
- multilevel_operator->PrintUnused(0);
+ ML_Epetra::MultiLevelPreconditioner * multilevel_operator =
+ dynamic_cast<ML_Epetra::MultiLevelPreconditioner*> (preconditioner.get());
+ Assert (multilevel_operator != 0,
+ ExcMessage ("Preconditioner setup failed."));
+ multilevel_operator->PrintUnused(0);
}
}
void
PreconditionAMG::initialize (const SparseMatrix &matrix,
- const Teuchos::ParameterList &ml_parameters)
+ const Teuchos::ParameterList &ml_parameters)
{
preconditioner.reset ();
preconditioner.reset (new ML_Epetra::MultiLevelPreconditioner
- (matrix.trilinos_matrix(), ml_parameters));
+ (matrix.trilinos_matrix(), ml_parameters));
}
void
PreconditionAMG::
initialize (const ::dealii::SparseMatrix<number> &deal_ii_sparse_matrix,
- const AdditionalData &additional_data,
- const double drop_tolerance,
- const ::dealii::SparsityPattern *use_this_sparsity)
+ const AdditionalData &additional_data,
+ const double drop_tolerance,
+ const ::dealii::SparsityPattern *use_this_sparsity)
{
preconditioner.reset();
const unsigned int n_rows = deal_ii_sparse_matrix.m();
- // Init Epetra Matrix using an
- // equidistributed map; avoid
- // storing the nonzero
- // elements.
+ // Init Epetra Matrix using an
+ // equidistributed map; avoid
+ // storing the nonzero
+ // elements.
vector_distributor.reset (new Epetra_Map(n_rows, 0, communicator));
if (trilinos_matrix.get() == 0)
trilinos_matrix.reset (new SparseMatrix());
trilinos_matrix->reinit (*vector_distributor, *vector_distributor,
- deal_ii_sparse_matrix, drop_tolerance, true,
- use_this_sparsity);
+ deal_ii_sparse_matrix, drop_tolerance, true,
+ use_this_sparsity);
initialize (*trilinos_matrix, additional_data);
}
void PreconditionAMG::reinit ()
{
- ML_Epetra::MultiLevelPreconditioner * multilevel_operator =
+ ML_Epetra::MultiLevelPreconditioner * multilevel_operator =
dynamic_cast<ML_Epetra::MultiLevelPreconditioner*> (preconditioner.get());
multilevel_operator->ReComputePreconditioner();
}
{
unsigned int memory = sizeof(this);
- // todo: find a way to read out ML's data
- // sizes
+ // todo: find a way to read out ML's data
+ // sizes
if (trilinos_matrix.get() != 0)
memory += trilinos_matrix->memory_consumption();
return memory;
- // explicit instantiations
+ // explicit instantiations
template void PreconditionAMG::initialize (const ::dealii::SparseMatrix<double> &,
- const AdditionalData &, const double,
- const ::dealii::SparsityPattern*);
+ const AdditionalData &, const double,
+ const ::dealii::SparsityPattern*);
template void PreconditionAMG::initialize (const ::dealii::SparseMatrix<float> &,
- const AdditionalData &, const double,
- const ::dealii::SparsityPattern*);
+ const AdditionalData &, const double,
+ const ::dealii::SparsityPattern*);
}
// $Id$
// Version: $Name$
//
-// Copyright (C) 2008, 2010 by the deal.II authors
+// Copyright (C) 2008, 2010, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
{
SolverBase::AdditionalData::AdditionalData (const bool output_solver_details,
- const unsigned int gmres_restart_parameter)
+ const unsigned int gmres_restart_parameter)
:
- output_solver_details (output_solver_details),
+ output_solver_details (output_solver_details),
gmres_restart_parameter (gmres_restart_parameter)
{}
SolverBase::SolverBase (SolverControl &cn)
:
- solver_name (gmres),
+ solver_name (gmres),
solver_control (cn)
{}
SolverBase::SolverBase (const enum SolverBase::SolverName solver_name,
- SolverControl &cn)
+ SolverControl &cn)
:
- solver_name (solver_name),
+ solver_name (solver_name),
solver_control (cn)
{}
linear_problem.reset();
- // We need an
- // Epetra_LinearProblem object
- // to let the AztecOO solver
- // know about the matrix and
- // vectors.
+ // We need an
+ // Epetra_LinearProblem object
+ // to let the AztecOO solver
+ // know about the matrix and
+ // vectors.
linear_problem.reset
(new Epetra_LinearProblem(const_cast<Epetra_CrsMatrix*>(&A.trilinos_matrix()),
- &x.trilinos_vector(),
- const_cast<Epetra_MultiVector*>(&b.trilinos_vector())));
+ &x.trilinos_vector(),
+ const_cast<Epetra_MultiVector*>(&b.trilinos_vector())));
- // Next we can allocate the
- // AztecOO solver...
+ // Next we can allocate the
+ // AztecOO solver...
solver.SetProblem(*linear_problem);
- // ... and we can specify the
- // solver to be used.
+ // ... and we can specify the
+ // solver to be used.
switch (solver_name)
{
case cg:
- solver.SetAztecOption(AZ_solver, AZ_cg);
- break;
+ solver.SetAztecOption(AZ_solver, AZ_cg);
+ break;
case cgs:
- solver.SetAztecOption(AZ_solver, AZ_cgs);
- break;
+ solver.SetAztecOption(AZ_solver, AZ_cgs);
+ break;
case gmres:
- solver.SetAztecOption(AZ_solver, AZ_gmres);
- solver.SetAztecOption(AZ_kspace, additional_data.gmres_restart_parameter);
- break;
+ solver.SetAztecOption(AZ_solver, AZ_gmres);
+ solver.SetAztecOption(AZ_kspace, additional_data.gmres_restart_parameter);
+ break;
case bicgstab:
- solver.SetAztecOption(AZ_solver, AZ_bicgstab);
- break;
+ solver.SetAztecOption(AZ_solver, AZ_bicgstab);
+ break;
case tfqmr:
- solver.SetAztecOption(AZ_solver, AZ_tfqmr);
- break;
+ solver.SetAztecOption(AZ_solver, AZ_tfqmr);
+ break;
default:
- Assert (false, ExcNotImplemented());
+ Assert (false, ExcNotImplemented());
}
- // Introduce the
- // preconditioner, ...
+ // Introduce the
+ // preconditioner, ...
ierr = solver.SetPrecOperator (const_cast<Epetra_Operator*>
- (preconditioner.preconditioner.get()));
+ (preconditioner.preconditioner.get()));
AssertThrow (ierr == 0, ExcTrilinosError(ierr));
- // ... set some options, ...
+ // ... set some options, ...
solver.SetAztecOption (AZ_output, additional_data.output_solver_details ?
- AZ_all : AZ_none);
+ AZ_all : AZ_none);
solver.SetAztecOption (AZ_conv, AZ_noscaled);
- // ... and then solve!
+ // ... and then solve!
ierr = solver.Iterate (solver_control.max_steps(),
- solver_control.tolerance());
-
- // report errors in more detail
- // than just by checking whether
- // the return status is zero or
- // greater. the error strings are
- // taken from the implementation
- // of the AztecOO::Iterate
- // function
+ solver_control.tolerance());
+
+ // report errors in more detail
+ // than just by checking whether
+ // the return status is zero or
+ // greater. the error strings are
+ // taken from the implementation
+ // of the AztecOO::Iterate
+ // function
switch (ierr)
{
- case -1:
- AssertThrow (false, ExcMessage("AztecOO::Iterate error code -1: "
- "option not implemented"));
- case -2:
- AssertThrow (false, ExcMessage("AztecOO::Iterate error code -2: "
- "numerical breakdown"));
- case -3:
- AssertThrow (false, ExcMessage("AztecOO::Iterate error code -3: "
- "loss of precision"));
- case -4:
- AssertThrow (false, ExcMessage("AztecOO::Iterate error code -4: "
- "GMRES hessenberg ill-conditioned"));
- default:
- AssertThrow (ierr >= 0, ExcTrilinosError(ierr));
+ case -1:
+ AssertThrow (false, ExcMessage("AztecOO::Iterate error code -1: "
+ "option not implemented"));
+ case -2:
+ AssertThrow (false, ExcMessage("AztecOO::Iterate error code -2: "
+ "numerical breakdown"));
+ case -3:
+ AssertThrow (false, ExcMessage("AztecOO::Iterate error code -3: "
+ "loss of precision"));
+ case -4:
+ AssertThrow (false, ExcMessage("AztecOO::Iterate error code -4: "
+ "GMRES hessenberg ill-conditioned"));
+ default:
+ AssertThrow (ierr >= 0, ExcTrilinosError(ierr));
}
- // Finally, let the deal.II
- // SolverControl object know
- // what has happened. If the
- // solve succeeded, the status
- // of the solver control will
- // turn into
- // SolverControl::success.
+ // Finally, let the deal.II
+ // SolverControl object know
+ // what has happened. If the
+ // solve succeeded, the status
+ // of the solver control will
+ // turn into
+ // SolverControl::success.
solver_control.check (solver.NumIters(), solver.TrueResidual());
if (solver_control.last_check() != SolverControl::success)
linear_problem.reset();
- // In case we call the solver with
- // deal.II vectors, we create views
- // of the vectors in Epetra format.
+ // In case we call the solver with
+ // deal.II vectors, we create views
+ // of the vectors in Epetra format.
Assert (x.size() == A.n(),
- ExcDimensionMismatch(x.size(), A.n()));
+ ExcDimensionMismatch(x.size(), A.n()));
Assert (b.size() == A.m(),
- ExcDimensionMismatch(b.size(), A.m()));
+ ExcDimensionMismatch(b.size(), A.m()));
Assert (A.local_range ().second == A.m(),
- ExcMessage ("Can only work in serial when using deal.II vectors."));
+ ExcMessage ("Can only work in serial when using deal.II vectors."));
Assert (A.trilinos_matrix().Filled(),
- ExcMessage ("Matrix is not compressed. Call compress() method."));
+ ExcMessage ("Matrix is not compressed. Call compress() method."));
Epetra_Vector ep_x (View, A.domain_partitioner(), x.begin());
Epetra_Vector ep_b (View, A.range_partitioner(), const_cast<double*>(b.begin()));
- // We need an
- // Epetra_LinearProblem object
- // to let the AztecOO solver
- // know about the matrix and
- // vectors.
+ // We need an
+ // Epetra_LinearProblem object
+ // to let the AztecOO solver
+ // know about the matrix and
+ // vectors.
linear_problem.reset (new Epetra_LinearProblem
- (const_cast<Epetra_CrsMatrix*>(&A.trilinos_matrix()),
- &ep_x, &ep_b));
+ (const_cast<Epetra_CrsMatrix*>(&A.trilinos_matrix()),
+ &ep_x, &ep_b));
- // Next we can allocate the
- // AztecOO solver...
+ // Next we can allocate the
+ // AztecOO solver...
solver.SetProblem(*linear_problem);
- // ... and we can specify the
- // solver to be used.
+ // ... and we can specify the
+ // solver to be used.
switch (solver_name)
{
case cg:
- solver.SetAztecOption(AZ_solver, AZ_cg);
- break;
+ solver.SetAztecOption(AZ_solver, AZ_cg);
+ break;
case cgs:
- solver.SetAztecOption(AZ_solver, AZ_cgs);
- break;
+ solver.SetAztecOption(AZ_solver, AZ_cgs);
+ break;
case gmres:
- solver.SetAztecOption(AZ_solver, AZ_gmres);
- solver.SetAztecOption(AZ_kspace, additional_data.gmres_restart_parameter);
- break;
+ solver.SetAztecOption(AZ_solver, AZ_gmres);
+ solver.SetAztecOption(AZ_kspace, additional_data.gmres_restart_parameter);
+ break;
case bicgstab:
- solver.SetAztecOption(AZ_solver, AZ_bicgstab);
- break;
+ solver.SetAztecOption(AZ_solver, AZ_bicgstab);
+ break;
case tfqmr:
- solver.SetAztecOption(AZ_solver, AZ_tfqmr);
- break;
+ solver.SetAztecOption(AZ_solver, AZ_tfqmr);
+ break;
default:
- Assert (false, ExcNotImplemented());
+ Assert (false, ExcNotImplemented());
}
- // Introduce the
- // preconditioner, ...
+ // Introduce the
+ // preconditioner, ...
ierr = solver.SetPrecOperator (const_cast<Epetra_Operator*>
- (preconditioner.preconditioner.get()));
+ (preconditioner.preconditioner.get()));
AssertThrow (ierr == 0, ExcTrilinosError(ierr));
- // ... set some options, ...
+ // ... set some options, ...
solver.SetAztecOption (AZ_output, additional_data.output_solver_details ?
- AZ_all : AZ_none);
+ AZ_all : AZ_none);
solver.SetAztecOption (AZ_conv, AZ_noscaled);
- // ... and then solve!
+ // ... and then solve!
ierr = solver.Iterate (solver_control.max_steps(),
- solver_control.tolerance());
+ solver_control.tolerance());
AssertThrow (ierr >= 0, ExcTrilinosError(ierr));
- // Finally, let the deal.II
- // SolverControl object know
- // what has happened. If the
- // solve succeeded, the status
- // of the solver control will
- // turn into
- // SolverControl::success.
+ // Finally, let the deal.II
+ // SolverControl object know
+ // what has happened. If the
+ // solve succeeded, the status
+ // of the solver control will
+ // turn into
+ // SolverControl::success.
solver_control.check (solver.NumIters(), solver.TrueResidual());
if (solver_control.last_check() != SolverControl::success)
SolverGMRES::AdditionalData::
AdditionalData (const bool output_solver_details,
- const unsigned int restart_parameter)
+ const unsigned int restart_parameter)
:
output_solver_details (output_solver_details),
restart_parameter (restart_parameter)
:
SolverBase (cn),
additional_data (data.output_solver_details,
- data.restart_parameter)
+ data.restart_parameter)
{
solver_name = gmres;
}
SolverDirect::SolverDirect (SolverControl &cn,
- const AdditionalData &data)
+ const AdditionalData &data)
:
solver_control (cn),
additional_data (data.output_solver_details)
void
SolverDirect::solve (const SparseMatrix &A,
- VectorBase &x,
- const VectorBase &b)
+ VectorBase &x,
+ const VectorBase &b)
{
- // First set whether we want to print
- // the solver information to screen
- // or not.
+ // First set whether we want to print
+ // the solver information to screen
+ // or not.
ConditionalOStream verbose_cout (std::cout,
- additional_data.output_solver_details);
+ additional_data.output_solver_details);
linear_problem.reset();
solver.reset();
- // We need an
- // Epetra_LinearProblem object
- // to let the AztecOO solver
- // know about the matrix and
- // vectors.
+ // We need an
+ // Epetra_LinearProblem object
+ // to let the AztecOO solver
+ // know about the matrix and
+ // vectors.
linear_problem.reset
(new Epetra_LinearProblem(const_cast<Epetra_CrsMatrix*>(&A.trilinos_matrix()),
- &x.trilinos_vector(),
- const_cast<Epetra_MultiVector*>(&b.trilinos_vector())));
+ &x.trilinos_vector(),
+ const_cast<Epetra_MultiVector*>(&b.trilinos_vector())));
- // Next we can allocate the
- // AztecOO solver...
+ // Next we can allocate the
+ // AztecOO solver...
solver.reset (Amesos().Create("Amesos_Klu", *linear_problem));
verbose_cout << "Starting symbolic factorization" << std::endl;
verbose_cout << "Starting solve" << std::endl;
solver->Solve();
- // Finally, let the deal.II
- // SolverControl object know
- // what has happened. If the
- // solve succeeded, the status
- // of the solver control will
- // turn into
- // SolverControl::success.
+ // Finally, let the deal.II
+ // SolverControl object know
+ // what has happened. If the
+ // solve succeeded, the status
+ // of the solver control will
+ // turn into
+ // SolverControl::success.
solver_control.check (0, 0);
if (solver_control.last_check() != SolverControl::success)
void
SolverDirect::solve (const SparseMatrix &A,
- dealii::Vector<double> &x,
- const dealii::Vector<double> &b)
+ dealii::Vector<double> &x,
+ const dealii::Vector<double> &b)
{
- // First set whether we want to print
- // the solver information to screen
- // or not.
+ // First set whether we want to print
+ // the solver information to screen
+ // or not.
ConditionalOStream verbose_cout (std::cout,
- additional_data.output_solver_details);
+ additional_data.output_solver_details);
linear_problem.reset();
solver.reset();
- // In case we call the solver with
- // deal.II vectors, we create views
- // of the vectors in Epetra format.
+ // In case we call the solver with
+ // deal.II vectors, we create views
+ // of the vectors in Epetra format.
Assert (x.size() == A.n(),
- ExcDimensionMismatch(x.size(), A.n()));
+ ExcDimensionMismatch(x.size(), A.n()));
Assert (b.size() == A.m(),
- ExcDimensionMismatch(b.size(), A.m()));
+ ExcDimensionMismatch(b.size(), A.m()));
Assert (A.local_range ().second == A.m(),
- ExcMessage ("Can only work in serial when using deal.II vectors."));
+ ExcMessage ("Can only work in serial when using deal.II vectors."));
Epetra_Vector ep_x (View, A.domain_partitioner(), x.begin());
Epetra_Vector ep_b (View, A.range_partitioner(), const_cast<double*>(b.begin()));
- // We need an
- // Epetra_LinearProblem object
- // to let the AztecOO solver
- // know about the matrix and
- // vectors.
+ // We need an
+ // Epetra_LinearProblem object
+ // to let the AztecOO solver
+ // know about the matrix and
+ // vectors.
linear_problem.reset (new Epetra_LinearProblem
- (const_cast<Epetra_CrsMatrix*>(&A.trilinos_matrix()),
- &ep_x, &ep_b));
+ (const_cast<Epetra_CrsMatrix*>(&A.trilinos_matrix()),
+ &ep_x, &ep_b));
- // Next we can allocate the
- // AztecOO solver...
+ // Next we can allocate the
+ // AztecOO solver...
solver.reset (Amesos().Create("Amesos_Klu", *linear_problem));
verbose_cout << "Starting symbolic factorization" << std::endl;
verbose_cout << "Starting solve" << std::endl;
solver->Solve();
- // Finally, let the deal.II
- // SolverControl object know
- // what has happened. If the
- // solve succeeded, the status
- // of the solver control will
- // turn into
- // SolverControl::success.
+ // Finally, let the deal.II
+ // SolverControl object know
+ // what has happened. If the
+ // solve succeeded, the status
+ // of the solver control will
+ // turn into
+ // SolverControl::success.
solver_control.check (0, 0);
if (solver_control.last_check() != SolverControl::success)
// $Id$
// Version: $Name$
//
-// Copyright (C) 2008, 2009, 2010, 2011 by the deal.II authors
+// Copyright (C) 2008, 2009, 2010, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
SparseMatrix::const_iterator::Accessor::
visit_present_row ()
{
- // if we are asked to visit the
- // past-the-end line, then simply
- // release all our caches and go on
- // with life
+ // if we are asked to visit the
+ // past-the-end line, then simply
+ // release all our caches and go on
+ // with life
if (this->a_row == matrix->m())
- {
- colnum_cache.reset ();
- value_cache.reset ();
+ {
+ colnum_cache.reset ();
+ value_cache.reset ();
- return;
- }
+ return;
+ }
- // otherwise first flush Trilinos caches
+ // otherwise first flush Trilinos caches
matrix->compress ();
- // get a representation of the present
- // row
+ // get a representation of the present
+ // row
int ncols;
int colnums = matrix->n();
if (value_cache.get() == 0)
- {
- value_cache.reset (new std::vector<TrilinosScalar> (matrix->n()));
- colnum_cache.reset (new std::vector<unsigned int> (matrix->n()));
- }
+ {
+ value_cache.reset (new std::vector<TrilinosScalar> (matrix->n()));
+ colnum_cache.reset (new std::vector<unsigned int> (matrix->n()));
+ }
else
- {
- value_cache->resize (matrix->n());
- colnum_cache->resize (matrix->n());
- }
+ {
+ value_cache->resize (matrix->n());
+ colnum_cache->resize (matrix->n());
+ }
int ierr = matrix->trilinos_matrix().
- ExtractGlobalRowCopy((int)this->a_row,
- colnums,
- ncols, &((*value_cache)[0]),
- reinterpret_cast<int*>(&((*colnum_cache)[0])));
+ ExtractGlobalRowCopy((int)this->a_row,
+ colnums,
+ ncols, &((*value_cache)[0]),
+ reinterpret_cast<int*>(&((*colnum_cache)[0])));
value_cache->resize (ncols);
colnum_cache->resize (ncols);
AssertThrow (ierr == 0, ExcTrilinosError(ierr));
- // copy it into our caches if the
- // line isn't empty. if it is, then
- // we've done something wrong, since
- // we shouldn't have initialized an
- // iterator for an empty line (what
- // would it point to?)
+ // copy it into our caches if the
+ // line isn't empty. if it is, then
+ // we've done something wrong, since
+ // we shouldn't have initialized an
+ // iterator for an empty line (what
+ // would it point to?)
}
}
- // The constructor is actually the
- // only point where we have to check
- // whether we build a serial or a
- // parallel Trilinos matrix.
- // Actually, it does not even matter
- // how many threads there are, but
- // only if we use an MPI compiler or
- // a standard compiler. So, even one
- // thread on a configuration with
- // MPI will still get a parallel
- // interface.
+ // The constructor is actually the
+ // only point where we have to check
+ // whether we build a serial or a
+ // parallel Trilinos matrix.
+ // Actually, it does not even matter
+ // how many threads there are, but
+ // only if we use an MPI compiler or
+ // a standard compiler. So, even one
+ // thread on a configuration with
+ // MPI will still get a parallel
+ // interface.
SparseMatrix::SparseMatrix ()
- :
+ :
column_space_map (new Epetra_Map (0, 0,
- Utilities::Trilinos::comm_self())),
- matrix (new Epetra_FECrsMatrix(View, *column_space_map,
- *column_space_map, 0)),
- last_action (Zero),
- compressed (true)
+ Utilities::Trilinos::comm_self())),
+ matrix (new Epetra_FECrsMatrix(View, *column_space_map,
+ *column_space_map, 0)),
+ last_action (Zero),
+ compressed (true)
{
matrix->FillComplete();
}
SparseMatrix::SparseMatrix (const Epetra_Map &input_map,
- const unsigned int n_max_entries_per_row)
- :
+ const unsigned int n_max_entries_per_row)
+ :
column_space_map (new Epetra_Map (input_map)),
- matrix (new Epetra_FECrsMatrix(Copy, *column_space_map,
- int(n_max_entries_per_row), false)),
- last_action (Zero),
- compressed (false)
+ matrix (new Epetra_FECrsMatrix(Copy, *column_space_map,
+ int(n_max_entries_per_row), false)),
+ last_action (Zero),
+ compressed (false)
{}
SparseMatrix::SparseMatrix (const Epetra_Map &input_map,
- const std::vector<unsigned int> &n_entries_per_row)
- :
+ const std::vector<unsigned int> &n_entries_per_row)
+ :
column_space_map (new Epetra_Map (input_map)),
- matrix (new Epetra_FECrsMatrix
- (Copy, *column_space_map,
- (int*)const_cast<unsigned int*>(&(n_entries_per_row[0])),
- false)),
- last_action (Zero),
- compressed (false)
+ matrix (new Epetra_FECrsMatrix
+ (Copy, *column_space_map,
+ (int*)const_cast<unsigned int*>(&(n_entries_per_row[0])),
+ false)),
+ last_action (Zero),
+ compressed (false)
{}
SparseMatrix::SparseMatrix (const Epetra_Map &input_row_map,
- const Epetra_Map &input_col_map,
- const unsigned int n_max_entries_per_row)
- :
+ const Epetra_Map &input_col_map,
+ const unsigned int n_max_entries_per_row)
+ :
column_space_map (new Epetra_Map (input_col_map)),
- matrix (new Epetra_FECrsMatrix(Copy, input_row_map,
- int(n_max_entries_per_row), false)),
- last_action (Zero),
- compressed (false)
+ matrix (new Epetra_FECrsMatrix(Copy, input_row_map,
+ int(n_max_entries_per_row), false)),
+ last_action (Zero),
+ compressed (false)
{}
SparseMatrix::SparseMatrix (const Epetra_Map &input_row_map,
- const Epetra_Map &input_col_map,
- const std::vector<unsigned int> &n_entries_per_row)
- :
+ const Epetra_Map &input_col_map,
+ const std::vector<unsigned int> &n_entries_per_row)
+ :
column_space_map (new Epetra_Map (input_col_map)),
- matrix (new Epetra_FECrsMatrix(Copy, input_row_map,
- (int*)const_cast<unsigned int*>(&(n_entries_per_row[0])),
- false)),
- last_action (Zero),
- compressed (false)
+ matrix (new Epetra_FECrsMatrix(Copy, input_row_map,
+ (int*)const_cast<unsigned int*>(&(n_entries_per_row[0])),
+ false)),
+ last_action (Zero),
+ compressed (false)
{}
SparseMatrix::SparseMatrix (const unsigned int m,
- const unsigned int n,
- const unsigned int n_max_entries_per_row)
- :
+ const unsigned int n,
+ const unsigned int n_max_entries_per_row)
+ :
column_space_map (new Epetra_Map (n, 0,
- Utilities::Trilinos::comm_self())),
-
- // on one processor only, we know how the
- // columns of the matrix will be
- // distributed (everything on one
- // processor), so we can hand in this
- // information to the constructor. we
- // can't do so in parallel, where the
- // information from columns is only
- // available when entries have been added
- matrix (new Epetra_FECrsMatrix(Copy,
- Epetra_Map (m, 0,
- Utilities::Trilinos::comm_self()),
- *column_space_map,
- n_max_entries_per_row,
- false)),
- last_action (Zero),
- compressed (false)
+ Utilities::Trilinos::comm_self())),
+
+ // on one processor only, we know how the
+ // columns of the matrix will be
+ // distributed (everything on one
+ // processor), so we can hand in this
+ // information to the constructor. we
+ // can't do so in parallel, where the
+ // information from columns is only
+ // available when entries have been added
+ matrix (new Epetra_FECrsMatrix(Copy,
+ Epetra_Map (m, 0,
+ Utilities::Trilinos::comm_self()),
+ *column_space_map,
+ n_max_entries_per_row,
+ false)),
+ last_action (Zero),
+ compressed (false)
{}
SparseMatrix::SparseMatrix (const unsigned int m,
- const unsigned int n,
- const std::vector<unsigned int> &n_entries_per_row)
- :
+ const unsigned int n,
+ const std::vector<unsigned int> &n_entries_per_row)
+ :
column_space_map (new Epetra_Map (n, 0,
- Utilities::Trilinos::comm_self())),
- matrix (new Epetra_FECrsMatrix(Copy,
- Epetra_Map (m, 0,
- Utilities::Trilinos::comm_self()),
- *column_space_map,
- (int*)const_cast<unsigned int*>(&(n_entries_per_row[0])),
- false)),
- last_action (Zero),
- compressed (false)
+ Utilities::Trilinos::comm_self())),
+ matrix (new Epetra_FECrsMatrix(Copy,
+ Epetra_Map (m, 0,
+ Utilities::Trilinos::comm_self()),
+ *column_space_map,
+ (int*)const_cast<unsigned int*>(&(n_entries_per_row[0])),
+ false)),
+ last_action (Zero),
+ compressed (false)
{}
SparseMatrix::SparseMatrix (const IndexSet ¶llel_partitioning,
- const MPI_Comm &communicator,
- const unsigned int n_max_entries_per_row)
- :
+ const MPI_Comm &communicator,
+ const unsigned int n_max_entries_per_row)
+ :
column_space_map (new Epetra_Map(parallel_partitioning.
- make_trilinos_map(communicator, false))),
- matrix (new Epetra_FECrsMatrix(Copy,
- *column_space_map,
- n_max_entries_per_row,
- false)),
- last_action (Zero),
- compressed (false)
+ make_trilinos_map(communicator, false))),
+ matrix (new Epetra_FECrsMatrix(Copy,
+ *column_space_map,
+ n_max_entries_per_row,
+ false)),
+ last_action (Zero),
+ compressed (false)
{}
SparseMatrix::SparseMatrix (const IndexSet ¶llel_partitioning,
- const MPI_Comm &communicator,
- const std::vector<unsigned int> &n_entries_per_row)
- :
+ const MPI_Comm &communicator,
+ const std::vector<unsigned int> &n_entries_per_row)
+ :
column_space_map (new Epetra_Map(parallel_partitioning.
- make_trilinos_map(communicator, false))),
- matrix (new Epetra_FECrsMatrix(Copy,
- *column_space_map,
- (int*)const_cast<unsigned int*>(&(n_entries_per_row[0])),
- false)),
- last_action (Zero),
- compressed (false)
+ make_trilinos_map(communicator, false))),
+ matrix (new Epetra_FECrsMatrix(Copy,
+ *column_space_map,
+ (int*)const_cast<unsigned int*>(&(n_entries_per_row[0])),
+ false)),
+ last_action (Zero),
+ compressed (false)
{}
SparseMatrix::SparseMatrix (const IndexSet &row_parallel_partitioning,
- const IndexSet &col_parallel_partitioning,
- const MPI_Comm &communicator,
- const unsigned int n_max_entries_per_row)
- :
+ const IndexSet &col_parallel_partitioning,
+ const MPI_Comm &communicator,
+ const unsigned int n_max_entries_per_row)
+ :
column_space_map (new Epetra_Map(col_parallel_partitioning.
- make_trilinos_map(communicator, false))),
- matrix (new Epetra_FECrsMatrix(Copy,
- row_parallel_partitioning.
- make_trilinos_map(communicator, false),
- n_max_entries_per_row,
- false)),
- last_action (Zero),
- compressed (false)
+ make_trilinos_map(communicator, false))),
+ matrix (new Epetra_FECrsMatrix(Copy,
+ row_parallel_partitioning.
+ make_trilinos_map(communicator, false),
+ n_max_entries_per_row,
+ false)),
+ last_action (Zero),
+ compressed (false)
{}
SparseMatrix::SparseMatrix (const IndexSet &row_parallel_partitioning,
- const IndexSet &col_parallel_partitioning,
- const MPI_Comm &communicator,
- const std::vector<unsigned int> &n_entries_per_row)
- :
+ const IndexSet &col_parallel_partitioning,
+ const MPI_Comm &communicator,
+ const std::vector<unsigned int> &n_entries_per_row)
+ :
column_space_map (new Epetra_Map(col_parallel_partitioning.
- make_trilinos_map(communicator, false))),
- matrix (new Epetra_FECrsMatrix(Copy,
- row_parallel_partitioning.
- make_trilinos_map(communicator, false),
- (int*)const_cast<unsigned int*>(&(n_entries_per_row[0])),
- false)),
- last_action (Zero),
- compressed (false)
+ make_trilinos_map(communicator, false))),
+ matrix (new Epetra_FECrsMatrix(Copy,
+ row_parallel_partitioning.
+ make_trilinos_map(communicator, false),
+ (int*)const_cast<unsigned int*>(&(n_entries_per_row[0])),
+ false)),
+ last_action (Zero),
+ compressed (false)
{}
SparseMatrix::SparseMatrix (const SparsityPattern &sparsity_pattern)
- :
- column_space_map (new Epetra_Map (sparsity_pattern.domain_partitioner())),
- matrix (new Epetra_FECrsMatrix(Copy,
- sparsity_pattern.trilinos_sparsity_pattern(),
- false)),
- last_action (Zero),
- compressed (true)
+ :
+ column_space_map (new Epetra_Map (sparsity_pattern.domain_partitioner())),
+ matrix (new Epetra_FECrsMatrix(Copy,
+ sparsity_pattern.trilinos_sparsity_pattern(),
+ false)),
+ last_action (Zero),
+ compressed (true)
{
Assert(sparsity_pattern.trilinos_sparsity_pattern().Filled() == true,
- ExcMessage("The Trilinos sparsity pattern has not been compressed."));
+ ExcMessage("The Trilinos sparsity pattern has not been compressed."));
compress();
}
SparseMatrix::SparseMatrix (const SparseMatrix &input_matrix)
- :
+ :
Subscriptor(),
- column_space_map (new Epetra_Map (input_matrix.domain_partitioner())),
- matrix (new Epetra_FECrsMatrix(*input_matrix.matrix)),
- last_action (Zero),
- compressed (true)
+ column_space_map (new Epetra_Map (input_matrix.domain_partitioner())),
+ matrix (new Epetra_FECrsMatrix(*input_matrix.matrix)),
+ last_action (Zero),
+ compressed (true)
{}
SparseMatrix::copy_from (const SparseMatrix &m)
{
- // check whether we need to update the
- // partitioner or can just copy the data:
- // in case we have the same distribution,
- // we can just copy the data.
+ // check whether we need to update the
+ // partitioner or can just copy the data:
+ // in case we have the same distribution,
+ // we can just copy the data.
if (local_range() == m.local_range())
*matrix = *m.matrix;
else
{
- column_space_map.reset (new Epetra_Map (m.domain_partitioner()));
+ column_space_map.reset (new Epetra_Map (m.domain_partitioner()));
- // release memory before reallocation
- matrix.reset ();
- temp_vector.clear ();
- matrix.reset (new Epetra_FECrsMatrix(*m.matrix));
+ // release memory before reallocation
+ matrix.reset ();
+ temp_vector.clear ();
+ matrix.reset (new Epetra_FECrsMatrix(*m.matrix));
}
compress();
SparseMatrix::reinit (const SparsityType &sparsity_pattern)
{
const Epetra_Map rows (sparsity_pattern.n_rows(),
- 0,
- Utilities::Trilinos::comm_self());
+ 0,
+ Utilities::Trilinos::comm_self());
const Epetra_Map columns (sparsity_pattern.n_cols(),
- 0,
- Utilities::Trilinos::comm_self());
+ 0,
+ Utilities::Trilinos::comm_self());
reinit (rows, columns, sparsity_pattern);
}
template <typename SparsityType>
void
SparseMatrix::reinit (const Epetra_Map &input_map,
- const SparsityType &sparsity_pattern,
- const bool exchange_data)
+ const SparsityType &sparsity_pattern,
+ const bool exchange_data)
{
reinit (input_map, input_map, sparsity_pattern, exchange_data);
}
template <typename SparsityType>
void
SparseMatrix::reinit (const Epetra_Map &input_row_map,
- const Epetra_Map &input_col_map,
- const SparsityType &sparsity_pattern,
- const bool exchange_data)
+ const Epetra_Map &input_col_map,
+ const SparsityType &sparsity_pattern,
+ const bool exchange_data)
{
- // release memory before reallocation
+ // release memory before reallocation
temp_vector.clear();
matrix.reset();
- // if we want to exchange data, build
- // a usual Trilinos sparsity pattern
- // and let that handle the
- // exchange. otherwise, manually
- // create a CrsGraph, which consumes
- // considerably less memory because it
- // can set correct number of indices
- // right from the start
+ // if we want to exchange data, build
+ // a usual Trilinos sparsity pattern
+ // and let that handle the
+ // exchange. otherwise, manually
+ // create a CrsGraph, which consumes
+ // considerably less memory because it
+ // can set correct number of indices
+ // right from the start
if (exchange_data)
{
- SparsityPattern trilinos_sparsity;
- trilinos_sparsity.reinit (input_row_map, input_col_map,
- sparsity_pattern, exchange_data);
- reinit (trilinos_sparsity);
+ SparsityPattern trilinos_sparsity;
+ trilinos_sparsity.reinit (input_row_map, input_col_map,
+ sparsity_pattern, exchange_data);
+ reinit (trilinos_sparsity);
- return;
+ return;
}
Assert (exchange_data == false, ExcNotImplemented());
if (input_row_map.Comm().MyPID() == 0)
{
- AssertDimension (sparsity_pattern.n_rows(),
- static_cast<unsigned int>(input_row_map.NumGlobalElements()));
- AssertDimension (sparsity_pattern.n_cols(),
- static_cast<unsigned int>(input_col_map.NumGlobalElements()));
+ AssertDimension (sparsity_pattern.n_rows(),
+ static_cast<unsigned int>(input_row_map.NumGlobalElements()));
+ AssertDimension (sparsity_pattern.n_cols(),
+ static_cast<unsigned int>(input_col_map.NumGlobalElements()));
}
column_space_map.reset (new Epetra_Map (input_col_map));
for (unsigned int row=first_row; row<last_row; ++row)
n_entries_per_row[row-first_row] = sparsity_pattern.row_length(row);
- // The deal.II notation of a Sparsity
- // pattern corresponds to the Epetra
- // concept of a Graph. Hence, we generate
- // a graph by copying the sparsity pattern
- // into it, and then build up the matrix
- // from the graph. This is considerable
- // faster than directly filling elements
- // into the matrix. Moreover, it consumes
- // less memory, since the internal
- // reordering is done on ints only, and we
- // can leave the doubles aside.
-
- // for more than one processor, need to
- // specify only row map first and let the
- // matrix entries decide about the column
- // map (which says which columns are
- // present in the matrix, not to be
- // confused with the col_map that tells
- // how the domain dofs of the matrix will
- // be distributed). for only one
- // processor, we can directly assign the
- // columns as well. Compare this with bug
- // # 4123 in the Sandia Bugzilla.
+ // The deal.II notation of a Sparsity
+ // pattern corresponds to the Epetra
+ // concept of a Graph. Hence, we generate
+ // a graph by copying the sparsity pattern
+ // into it, and then build up the matrix
+ // from the graph. This is considerable
+ // faster than directly filling elements
+ // into the matrix. Moreover, it consumes
+ // less memory, since the internal
+ // reordering is done on ints only, and we
+ // can leave the doubles aside.
+
+ // for more than one processor, need to
+ // specify only row map first and let the
+ // matrix entries decide about the column
+ // map (which says which columns are
+ // present in the matrix, not to be
+ // confused with the col_map that tells
+ // how the domain dofs of the matrix will
+ // be distributed). for only one
+ // processor, we can directly assign the
+ // columns as well. Compare this with bug
+ // # 4123 in the Sandia Bugzilla.
std_cxx1x::shared_ptr<Epetra_CrsGraph> graph;
if (input_row_map.Comm().NumProc() > 1)
graph.reset (new Epetra_CrsGraph (Copy, input_row_map,
- &n_entries_per_row[0], true));
+ &n_entries_per_row[0], true));
else
graph.reset (new Epetra_CrsGraph (Copy, input_row_map, input_col_map,
- &n_entries_per_row[0], true));
+ &n_entries_per_row[0], true));
- // This functions assumes that the
- // sparsity pattern sits on all processors
- // (completely). The parallel version uses
- // an Epetra graph that is already
- // distributed.
+ // This functions assumes that the
+ // sparsity pattern sits on all processors
+ // (completely). The parallel version uses
+ // an Epetra graph that is already
+ // distributed.
- // now insert the indices
+ // now insert the indices
std::vector<int> row_indices;
for (unsigned int row=first_row; row<last_row; ++row)
{
- const int row_length = sparsity_pattern.row_length(row);
- if (row_length == 0)
- continue;
+ const int row_length = sparsity_pattern.row_length(row);
+ if (row_length == 0)
+ continue;
- row_indices.resize (row_length, -1);
+ row_indices.resize (row_length, -1);
- typename SparsityType::row_iterator col_num = sparsity_pattern.row_begin (row),
- row_end = sparsity_pattern.row_end(row);
- for (unsigned int col = 0; col_num != row_end; ++col_num, ++col)
- row_indices[col] = *col_num;
+ typename SparsityType::row_iterator col_num = sparsity_pattern.row_begin (row),
+ row_end = sparsity_pattern.row_end(row);
+ for (unsigned int col = 0; col_num != row_end; ++col_num, ++col)
+ row_indices[col] = *col_num;
- graph->Epetra_CrsGraph::InsertGlobalIndices (row, row_length,
- &row_indices[0]);
+ graph->Epetra_CrsGraph::InsertGlobalIndices (row, row_length,
+ &row_indices[0]);
}
- // Eventually, optimize the graph
- // structure (sort indices, make memory
- // contiguous, etc).
+ // Eventually, optimize the graph
+ // structure (sort indices, make memory
+ // contiguous, etc).
graph->FillComplete(input_col_map, input_row_map);
graph->OptimizeStorage();
- // check whether we got the number of
- // columns right.
+ // check whether we got the number of
+ // columns right.
AssertDimension (sparsity_pattern.n_cols(),
- static_cast<unsigned int>(graph->NumGlobalCols()));
+ static_cast<unsigned int>(graph->NumGlobalCols()));
- // And now finally generate the matrix.
+ // And now finally generate the matrix.
matrix.reset (new Epetra_FECrsMatrix(Copy, *graph, false));
last_action = Zero;
- // In the end, the matrix needs to
- // be compressed in order to be
- // really ready.
+ // In the end, the matrix needs to
+ // be compressed in order to be
+ // really ready.
compress();
}
temp_vector.clear ();
matrix.reset ();
- // reinit with a (parallel) Trilinos
- // sparsity pattern.
+ // reinit with a (parallel) Trilinos
+ // sparsity pattern.
column_space_map.reset (new Epetra_Map
- (sparsity_pattern.domain_partitioner()));
+ (sparsity_pattern.domain_partitioner()));
matrix.reset (new Epetra_FECrsMatrix
- (Copy, sparsity_pattern.trilinos_sparsity_pattern(), false));
+ (Copy, sparsity_pattern.trilinos_sparsity_pattern(), false));
compress();
}
temp_vector.clear ();
matrix.reset ();
matrix.reset (new Epetra_FECrsMatrix
- (Copy, sparse_matrix.trilinos_sparsity_pattern(), false));
+ (Copy, sparse_matrix.trilinos_sparsity_pattern(), false));
compress();
}
template <typename number>
void
SparseMatrix::reinit (const ::dealii::SparseMatrix<number> &dealii_sparse_matrix,
- const double drop_tolerance,
- const bool copy_values,
- const ::dealii::SparsityPattern *use_this_sparsity)
+ const double drop_tolerance,
+ const bool copy_values,
+ const ::dealii::SparsityPattern *use_this_sparsity)
{
const Epetra_Map rows (dealii_sparse_matrix.m(),
- 0,
- Utilities::Trilinos::comm_self());
+ 0,
+ Utilities::Trilinos::comm_self());
const Epetra_Map columns (dealii_sparse_matrix.n(),
- 0,
- Utilities::Trilinos::comm_self());
+ 0,
+ Utilities::Trilinos::comm_self());
reinit (rows, columns, dealii_sparse_matrix, drop_tolerance,
- copy_values, use_this_sparsity);
+ copy_values, use_this_sparsity);
}
template <typename number>
void
SparseMatrix::reinit (const Epetra_Map &input_map,
- const ::dealii::SparseMatrix<number> &dealii_sparse_matrix,
- const double drop_tolerance,
- const bool copy_values,
- const ::dealii::SparsityPattern *use_this_sparsity)
+ const ::dealii::SparseMatrix<number> &dealii_sparse_matrix,
+ const double drop_tolerance,
+ const bool copy_values,
+ const ::dealii::SparsityPattern *use_this_sparsity)
{
reinit (input_map, input_map, dealii_sparse_matrix, drop_tolerance,
- copy_values, use_this_sparsity);
+ copy_values, use_this_sparsity);
}
template <typename number>
void
SparseMatrix::reinit (const Epetra_Map &input_row_map,
- const Epetra_Map &input_col_map,
- const ::dealii::SparseMatrix<number> &dealii_sparse_matrix,
- const double drop_tolerance,
- const bool copy_values,
- const ::dealii::SparsityPattern *use_this_sparsity)
+ const Epetra_Map &input_col_map,
+ const ::dealii::SparseMatrix<number> &dealii_sparse_matrix,
+ const double drop_tolerance,
+ const bool copy_values,
+ const ::dealii::SparsityPattern *use_this_sparsity)
{
if (copy_values == false)
{
- // in case we do not copy values, just
- // call the other function.
- if (use_this_sparsity == 0)
- reinit (input_row_map, input_col_map,
- dealii_sparse_matrix.get_sparsity_pattern());
- else
- reinit (input_row_map, input_col_map,
- *use_this_sparsity);
- return;
+ // in case we do not copy values, just
+ // call the other function.
+ if (use_this_sparsity == 0)
+ reinit (input_row_map, input_col_map,
+ dealii_sparse_matrix.get_sparsity_pattern());
+ else
+ reinit (input_row_map, input_col_map,
+ *use_this_sparsity);
+ return;
}
unsigned int n_rows = dealii_sparse_matrix.m();
Assert (input_row_map.NumGlobalElements() == (int)n_rows,
- ExcDimensionMismatch (input_row_map.NumGlobalElements(),
- n_rows));
+ ExcDimensionMismatch (input_row_map.NumGlobalElements(),
+ n_rows));
Assert (input_col_map.NumGlobalElements() == (int)dealii_sparse_matrix.n(),
- ExcDimensionMismatch (input_col_map.NumGlobalElements(),
- dealii_sparse_matrix.n()));
+ ExcDimensionMismatch (input_col_map.NumGlobalElements(),
+ dealii_sparse_matrix.n()));
const ::dealii::SparsityPattern & sparsity_pattern =
(use_this_sparsity!=0)? *use_this_sparsity :
dealii_sparse_matrix.get_sparsity_pattern();
if (matrix.get() != 0 && m() == n_rows &&
- n_nonzero_elements() == sparsity_pattern.n_nonzero_elements())
+ n_nonzero_elements() == sparsity_pattern.n_nonzero_elements())
goto set_matrix_values;
{
}
set_matrix_values:
- // fill the values. the same as above: go
- // through all rows of the matrix, and then
- // all columns. since the sparsity patterns of
- // the input matrix and the specified sparsity
- // pattern might be different, need to go
- // through the row for both these sparsity
- // structures simultaneously in order to
- // really set the correct values.
+ // fill the values. the same as above: go
+ // through all rows of the matrix, and then
+ // all columns. since the sparsity patterns of
+ // the input matrix and the specified sparsity
+ // pattern might be different, need to go
+ // through the row for both these sparsity
+ // structures simultaneously in order to
+ // really set the correct values.
const std::size_t * const in_rowstart_indices
= dealii_sparse_matrix.get_sparsity_pattern().get_rowstart_indices();
const unsigned int * const in_cols
for (unsigned int row=0; row<n_rows; ++row)
if (input_row_map.MyGID(row))
- {
- index = rowstart_indices[row];
- in_index = in_rowstart_indices[row];
- unsigned int col = 0;
- if (sparsity_pattern.optimize_diagonal())
- {
- values[col] = dealii_sparse_matrix.global_entry(in_index);
- row_indices[col++] = row;
- ++index;
- ++in_index;
- }
-
- while (in_index < in_rowstart_indices[row+1] &&
- index < rowstart_indices[row+1])
- {
- while (cols[index] < in_cols[in_index] && index < rowstart_indices[row+1])
- ++index;
- while (in_cols[in_index] < cols[index] && in_index < in_rowstart_indices[row+1])
- ++in_index;
-
- if (std::fabs(dealii_sparse_matrix.global_entry(in_index)) > drop_tolerance)
- {
- values[col] = dealii_sparse_matrix.global_entry(in_index);
- row_indices[col++] = in_cols[in_index];
- }
- ++index;
- ++in_index;
- }
- set (row, col, reinterpret_cast<unsigned int*>(&row_indices[0]),
- &values[0], false);
- }
+ {
+ index = rowstart_indices[row];
+ in_index = in_rowstart_indices[row];
+ unsigned int col = 0;
+ if (sparsity_pattern.optimize_diagonal())
+ {
+ values[col] = dealii_sparse_matrix.global_entry(in_index);
+ row_indices[col++] = row;
+ ++index;
+ ++in_index;
+ }
+
+ while (in_index < in_rowstart_indices[row+1] &&
+ index < rowstart_indices[row+1])
+ {
+ while (cols[index] < in_cols[in_index] && index < rowstart_indices[row+1])
+ ++index;
+ while (in_cols[in_index] < cols[index] && in_index < in_rowstart_indices[row+1])
+ ++in_index;
+
+ if (std::fabs(dealii_sparse_matrix.global_entry(in_index)) > drop_tolerance)
+ {
+ values[col] = dealii_sparse_matrix.global_entry(in_index);
+ row_indices[col++] = in_cols[in_index];
+ }
+ ++index;
+ ++in_index;
+ }
+ set (row, col, reinterpret_cast<unsigned int*>(&row_indices[0]),
+ &values[0], false);
+ }
compress();
}
void
SparseMatrix::reinit (const Epetra_CrsMatrix &input_matrix,
- const bool copy_values)
+ const bool copy_values)
{
Assert (input_matrix.Filled()==true,
- ExcMessage("Input CrsMatrix has not called FillComplete()!"));
+ ExcMessage("Input CrsMatrix has not called FillComplete()!"));
column_space_map.reset (new Epetra_Map (input_matrix.DomainMap()));
if (copy_values == true)
{
- // point to the first data entry in the two
- // matrices and copy the content
- const TrilinosScalar * in_values = input_matrix[0];
- TrilinosScalar * values = (*matrix)[0];
- const unsigned int my_nonzeros = input_matrix.NumMyNonzeros();
- std::memcpy (&values[0], &in_values[0],
- my_nonzeros*sizeof (TrilinosScalar));
+ // point to the first data entry in the two
+ // matrices and copy the content
+ const TrilinosScalar * in_values = input_matrix[0];
+ TrilinosScalar * values = (*matrix)[0];
+ const unsigned int my_nonzeros = input_matrix.NumMyNonzeros();
+ std::memcpy (&values[0], &in_values[0],
+ my_nonzeros*sizeof (TrilinosScalar));
}
compress();
void
SparseMatrix::clear ()
{
- // When we clear the matrix, reset
- // the pointer and generate an
- // empty matrix.
+ // When we clear the matrix, reset
+ // the pointer and generate an
+ // empty matrix.
column_space_map.reset (new Epetra_Map (0, 0,
- Utilities::Trilinos::comm_self()));
+ Utilities::Trilinos::comm_self()));
temp_vector.clear();
matrix.reset (new Epetra_FECrsMatrix(View, *column_space_map, 0));
void
SparseMatrix::clear_row (const unsigned int row,
- const TrilinosScalar new_diag_value)
+ const TrilinosScalar new_diag_value)
{
Assert (matrix->Filled()==true, ExcMatrixNotCompressed());
- // Only do this on the rows owned
- // locally on this processor.
+ // Only do this on the rows owned
+ // locally on this processor.
int local_row = matrix->LRID(row);
if (local_row >= 0)
{
- TrilinosScalar *values;
- int *col_indices;
- int num_entries;
- const int ierr = matrix->ExtractMyRowView(local_row, num_entries,
- values, col_indices);
-
- Assert (ierr == 0,
- ExcTrilinosError(ierr));
-
- int* diag_find = std::find(col_indices,col_indices+num_entries,
- local_row);
- int diag_index = (int)(diag_find - col_indices);
-
- for (int j=0; j<num_entries; ++j)
- if (diag_index != j || new_diag_value == 0)
- values[j] = 0.;
-
- if (diag_find && std::fabs(values[diag_index]) == 0.0 &&
- new_diag_value != 0.0)
- values[diag_index] = new_diag_value;
+ TrilinosScalar *values;
+ int *col_indices;
+ int num_entries;
+ const int ierr = matrix->ExtractMyRowView(local_row, num_entries,
+ values, col_indices);
+
+ Assert (ierr == 0,
+ ExcTrilinosError(ierr));
+
+ int* diag_find = std::find(col_indices,col_indices+num_entries,
+ local_row);
+ int diag_index = (int)(diag_find - col_indices);
+
+ for (int j=0; j<num_entries; ++j)
+ if (diag_index != j || new_diag_value == 0)
+ values[j] = 0.;
+
+ if (diag_find && std::fabs(values[diag_index]) == 0.0 &&
+ new_diag_value != 0.0)
+ values[diag_index] = new_diag_value;
}
}
void
SparseMatrix::clear_rows (const std::vector<unsigned int> &rows,
- const TrilinosScalar new_diag_value)
+ const TrilinosScalar new_diag_value)
{
compress();
for (unsigned int row=0; row<rows.size(); ++row)
clear_row(rows[row], new_diag_value);
- // This function needs to be called
- // on all processors. We change some
- // data, so we need to flush the
- // buffers to make sure that the
- // right data is used.
+ // This function needs to be called
+ // on all processors. We change some
+ // data, so we need to flush the
+ // buffers to make sure that the
+ // right data is used.
compress();
}
TrilinosScalar
SparseMatrix::operator() (const unsigned int i,
- const unsigned int j) const
+ const unsigned int j) const
{
- // Extract local indices in
- // the matrix.
+ // Extract local indices in
+ // the matrix.
int trilinos_i = matrix->LRID(i), trilinos_j = matrix->LCID(j);
TrilinosScalar value = 0.;
- // If the data is not on the
- // present processor, we throw
- // an exception. This is one of
- // the two tiny differences to
- // the el(i,j) call, which does
- // not throw any assertions.
+ // If the data is not on the
+ // present processor, we throw
+ // an exception. This is one of
+ // the two tiny differences to
+ // the el(i,j) call, which does
+ // not throw any assertions.
if (trilinos_i == -1)
{
- Assert (false, ExcAccessToNonLocalElement(i, j, local_range().first,
- local_range().second));
+ Assert (false, ExcAccessToNonLocalElement(i, j, local_range().first,
+ local_range().second));
}
else
{
- // Check whether the matrix has
- // already been transformed to local
- // indices.
- Assert (matrix->Filled(), ExcMatrixNotCompressed());
-
- // Prepare pointers for extraction
- // of a view of the row.
- int nnz_present = matrix->NumMyEntries(trilinos_i);
- int nnz_extracted;
- int *col_indices;
- TrilinosScalar *values;
-
- // Generate the view and make
- // sure that we have not generated
- // an error.
- int ierr = matrix->ExtractMyRowView(trilinos_i, nnz_extracted,
- values, col_indices);
- Assert (ierr==0, ExcTrilinosError(ierr));
-
- Assert (nnz_present == nnz_extracted,
- ExcDimensionMismatch(nnz_present, nnz_extracted));
-
- // Search the index where we
- // look for the value, and then
- // finally get it.
-
- int* el_find = std::find(col_indices, col_indices + nnz_present,
- trilinos_j);
-
- int local_col_index = (int)(el_find - col_indices);
-
- // This is actually the only
- // difference to the el(i,j)
- // function, which means that
- // we throw an exception in
- // this case instead of just
- // returning zero for an
- // element that is not present
- // in the sparsity pattern.
- if (local_col_index == nnz_present)
- {
- Assert (false, ExcInvalidIndex (i,j));
- }
- else
- value = values[local_col_index];
+ // Check whether the matrix has
+ // already been transformed to local
+ // indices.
+ Assert (matrix->Filled(), ExcMatrixNotCompressed());
+
+ // Prepare pointers for extraction
+ // of a view of the row.
+ int nnz_present = matrix->NumMyEntries(trilinos_i);
+ int nnz_extracted;
+ int *col_indices;
+ TrilinosScalar *values;
+
+ // Generate the view and make
+ // sure that we have not generated
+ // an error.
+ int ierr = matrix->ExtractMyRowView(trilinos_i, nnz_extracted,
+ values, col_indices);
+ Assert (ierr==0, ExcTrilinosError(ierr));
+
+ Assert (nnz_present == nnz_extracted,
+ ExcDimensionMismatch(nnz_present, nnz_extracted));
+
+ // Search the index where we
+ // look for the value, and then
+ // finally get it.
+
+ int* el_find = std::find(col_indices, col_indices + nnz_present,
+ trilinos_j);
+
+ int local_col_index = (int)(el_find - col_indices);
+
+ // This is actually the only
+ // difference to the el(i,j)
+ // function, which means that
+ // we throw an exception in
+ // this case instead of just
+ // returning zero for an
+ // element that is not present
+ // in the sparsity pattern.
+ if (local_col_index == nnz_present)
+ {
+ Assert (false, ExcInvalidIndex (i,j));
+ }
+ else
+ value = values[local_col_index];
}
return value;
TrilinosScalar
SparseMatrix::el (const unsigned int i,
- const unsigned int j) const
+ const unsigned int j) const
{
- // Extract local indices in
- // the matrix.
+ // Extract local indices in
+ // the matrix.
int trilinos_i = matrix->LRID(i), trilinos_j = matrix->LCID(j);
TrilinosScalar value = 0.;
- // If the data is not on the
- // present processor, we can't
- // continue. Just print out zero
- // as discussed in the
- // documentation of this
- // function. if you want error
- // checking, use operator().
+ // If the data is not on the
+ // present processor, we can't
+ // continue. Just print out zero
+ // as discussed in the
+ // documentation of this
+ // function. if you want error
+ // checking, use operator().
if ((trilinos_i == -1 ) || (trilinos_j == -1))
return 0.;
else
{
- // Check whether the matrix
- // already is transformed to
- // local indices.
+ // Check whether the matrix
+ // already is transformed to
+ // local indices.
Assert (matrix->Filled(), ExcMatrixNotCompressed());
- // Prepare pointers for extraction
- // of a view of the row.
+ // Prepare pointers for extraction
+ // of a view of the row.
int nnz_present = matrix->NumMyEntries(trilinos_i);
int nnz_extracted;
int *col_indices;
TrilinosScalar *values;
- // Generate the view and make
- // sure that we have not generated
- // an error.
+ // Generate the view and make
+ // sure that we have not generated
+ // an error.
int ierr = matrix->ExtractMyRowView(trilinos_i, nnz_extracted,
- values, col_indices);
+ values, col_indices);
Assert (ierr==0, ExcTrilinosError(ierr));
Assert (nnz_present == nnz_extracted,
- ExcDimensionMismatch(nnz_present, nnz_extracted));
+ ExcDimensionMismatch(nnz_present, nnz_extracted));
- // Search the index where we
- // look for the value, and then
- // finally get it.
+ // Search the index where we
+ // look for the value, and then
+ // finally get it.
int* el_find = std::find(col_indices, col_indices + nnz_present,
- trilinos_j);
+ trilinos_j);
int local_col_index = (int)(el_find - col_indices);
- // This is actually the only
- // difference to the () function
- // querying (i,j), where we throw an
- // exception instead of just
- // returning zero for an element
- // that is not present in the
- // sparsity pattern.
+ // This is actually the only
+ // difference to the () function
+ // querying (i,j), where we throw an
+ // exception instead of just
+ // returning zero for an element
+ // that is not present in the
+ // sparsity pattern.
if (local_col_index == nnz_present)
- value = 0;
+ value = 0;
else
- value = values[local_col_index];
+ value = values[local_col_index];
}
return value;
{
Assert (m() == n(), ExcNotQuadratic());
- // Trilinos doesn't seem to have a
- // more efficient way to access the
- // diagonal than by just using the
- // standard el(i,j) function.
+ // Trilinos doesn't seem to have a
+ // more efficient way to access the
+ // diagonal than by just using the
+ // standard el(i,j) function.
return el(i,i);
}
{
Assert (row < m(), ExcInternalError());
- // get a representation of the
- // present row
+ // get a representation of the
+ // present row
int ncols = -1;
int local_row = matrix->LRID(row);
- // on the processor who owns this
- // row, we'll have a non-negative
- // value.
+ // on the processor who owns this
+ // row, we'll have a non-negative
+ // value.
if (local_row >= 0)
{
- int ierr = matrix->NumMyRowEntries (local_row, ncols);
- AssertThrow (ierr == 0, ExcTrilinosError(ierr));
+ int ierr = matrix->NumMyRowEntries (local_row, ncols);
+ AssertThrow (ierr == 0, ExcTrilinosError(ierr));
}
return ncols;
namespace internals
{
void perform_mmult (const SparseMatrix &inputleft,
- const SparseMatrix &inputright,
- SparseMatrix &result,
- const VectorBase &V,
- const bool transpose_left)
+ const SparseMatrix &inputright,
+ SparseMatrix &result,
+ const VectorBase &V,
+ const bool transpose_left)
{
const bool use_vector = (V.size() == inputright.m() ? true : false);
if (transpose_left == false)
- {
- Assert (inputleft.n() == inputright.m(),
- ExcDimensionMismatch(inputleft.n(), inputright.m()));
- Assert (inputleft.domain_partitioner().SameAs(inputright.range_partitioner()),
- ExcMessage ("Parallel partitioning of A and B does not fit."));
- }
+ {
+ Assert (inputleft.n() == inputright.m(),
+ ExcDimensionMismatch(inputleft.n(), inputright.m()));
+ Assert (inputleft.domain_partitioner().SameAs(inputright.range_partitioner()),
+ ExcMessage ("Parallel partitioning of A and B does not fit."));
+ }
else
- {
- Assert (inputleft.m() == inputright.m(),
- ExcDimensionMismatch(inputleft.m(), inputright.m()));
- Assert (inputleft.range_partitioner().SameAs(inputright.range_partitioner()),
- ExcMessage ("Parallel partitioning of A and B does not fit."));
- }
+ {
+ Assert (inputleft.m() == inputright.m(),
+ ExcDimensionMismatch(inputleft.m(), inputright.m()));
+ Assert (inputleft.range_partitioner().SameAs(inputright.range_partitioner()),
+ ExcMessage ("Parallel partitioning of A and B does not fit."));
+ }
result.clear();
- // create a suitable operator B: in case
- // we do not use a vector, all we need to
- // do is to set the pointer. Otherwise,
- // we insert the data from B, but
- // multiply each row with the respective
- // vector element.
+ // create a suitable operator B: in case
+ // we do not use a vector, all we need to
+ // do is to set the pointer. Otherwise,
+ // we insert the data from B, but
+ // multiply each row with the respective
+ // vector element.
Teuchos::RCP<Epetra_CrsMatrix> mod_B;
if (use_vector == false)
- {
- mod_B = Teuchos::rcp(const_cast<Epetra_CrsMatrix*>
- (&inputright.trilinos_matrix()),
- false);
- }
+ {
+ mod_B = Teuchos::rcp(const_cast<Epetra_CrsMatrix*>
+ (&inputright.trilinos_matrix()),
+ false);
+ }
else
- {
- mod_B = Teuchos::rcp(new Epetra_CrsMatrix
- (Copy, inputright.trilinos_sparsity_pattern()),
- true);
- mod_B->FillComplete(inputright.domain_partitioner(),
- inputright.range_partitioner());
- Assert (inputright.local_range() == V.local_range(),
- ExcMessage ("Parallel distribution of matrix B and vector V "
- "does not match."));
-
- const int local_N = inputright.local_size();
- for (int i=0; i<local_N; ++i)
- {
- int N_entries = -1;
- double *new_data, *B_data;
- mod_B->ExtractMyRowView (i, N_entries, new_data);
- inputright.trilinos_matrix().ExtractMyRowView (i, N_entries, B_data);
- double value = V.trilinos_vector()[0][i];
- for (int j=0; j<N_entries; ++j)
- new_data[j] = value * B_data[j];
- }
- }
-
- // use ML built-in method for performing
- // the matrix-matrix product.
- // create ML operators on top of the
- // Epetra matrices. if we use a
- // transposed matrix, let ML know it
+ {
+ mod_B = Teuchos::rcp(new Epetra_CrsMatrix
+ (Copy, inputright.trilinos_sparsity_pattern()),
+ true);
+ mod_B->FillComplete(inputright.domain_partitioner(),
+ inputright.range_partitioner());
+ Assert (inputright.local_range() == V.local_range(),
+ ExcMessage ("Parallel distribution of matrix B and vector V "
+ "does not match."));
+
+ const int local_N = inputright.local_size();
+ for (int i=0; i<local_N; ++i)
+ {
+ int N_entries = -1;
+ double *new_data, *B_data;
+ mod_B->ExtractMyRowView (i, N_entries, new_data);
+ inputright.trilinos_matrix().ExtractMyRowView (i, N_entries, B_data);
+ double value = V.trilinos_vector()[0][i];
+ for (int j=0; j<N_entries; ++j)
+ new_data[j] = value * B_data[j];
+ }
+ }
+
+ // use ML built-in method for performing
+ // the matrix-matrix product.
+ // create ML operators on top of the
+ // Epetra matrices. if we use a
+ // transposed matrix, let ML know it
ML_Comm* comm;
ML_Comm_Create(&comm);
#ifdef ML_MPI
SparseMatrix transposed_mat;
if (transpose_left == false)
- ML_Operator_WrapEpetraCrsMatrix
- (const_cast<Epetra_CrsMatrix*>(&inputleft.trilinos_matrix()),A_,
- false);
+ ML_Operator_WrapEpetraCrsMatrix
+ (const_cast<Epetra_CrsMatrix*>(&inputleft.trilinos_matrix()),A_,
+ false);
else
- {
- // create transposed matrix
- SparsityPattern sparsity_transposed (inputleft.domain_partitioner(),
- inputleft.range_partitioner());
- Assert (inputleft.domain_partitioner().LinearMap() == true,
- ExcMessage("Matrix must be partitioned contiguously between procs."));
- for (unsigned int i=0; i<inputleft.local_size(); ++i)
- {
- int num_entries, * indices;
- inputleft.trilinos_sparsity_pattern().ExtractMyRowView(i, num_entries,
- indices);
- Assert (num_entries >= 0, ExcInternalError());
- const unsigned int GID = inputleft.row_partitioner().GID(i);
- for (int j=0; j<num_entries; ++j)
- sparsity_transposed.add (inputleft.col_partitioner().GID(indices[j]),
- GID);
- }
-
- sparsity_transposed.compress();
- transposed_mat.reinit (sparsity_transposed);
- for (unsigned int i=0; i<inputleft.local_size(); ++i)
- {
- int num_entries, * indices;
- double * values;
- inputleft.trilinos_matrix().ExtractMyRowView(i, num_entries,
- values, indices);
- Assert (num_entries >= 0, ExcInternalError());
- const unsigned int GID = inputleft.row_partitioner().GID(i);
- for (int j=0; j<num_entries; ++j)
- transposed_mat.set (inputleft.col_partitioner().GID(indices[j]),
- GID, values[j]);
- }
- transposed_mat.compress();
- ML_Operator_WrapEpetraCrsMatrix
- (const_cast<Epetra_CrsMatrix*>(&transposed_mat.trilinos_matrix()),
- A_,false);
- }
+ {
+ // create transposed matrix
+ SparsityPattern sparsity_transposed (inputleft.domain_partitioner(),
+ inputleft.range_partitioner());
+ Assert (inputleft.domain_partitioner().LinearMap() == true,
+ ExcMessage("Matrix must be partitioned contiguously between procs."));
+ for (unsigned int i=0; i<inputleft.local_size(); ++i)
+ {
+ int num_entries, * indices;
+ inputleft.trilinos_sparsity_pattern().ExtractMyRowView(i, num_entries,
+ indices);
+ Assert (num_entries >= 0, ExcInternalError());
+ const unsigned int GID = inputleft.row_partitioner().GID(i);
+ for (int j=0; j<num_entries; ++j)
+ sparsity_transposed.add (inputleft.col_partitioner().GID(indices[j]),
+ GID);
+ }
+
+ sparsity_transposed.compress();
+ transposed_mat.reinit (sparsity_transposed);
+ for (unsigned int i=0; i<inputleft.local_size(); ++i)
+ {
+ int num_entries, * indices;
+ double * values;
+ inputleft.trilinos_matrix().ExtractMyRowView(i, num_entries,
+ values, indices);
+ Assert (num_entries >= 0, ExcInternalError());
+ const unsigned int GID = inputleft.row_partitioner().GID(i);
+ for (int j=0; j<num_entries; ++j)
+ transposed_mat.set (inputleft.col_partitioner().GID(indices[j]),
+ GID, values[j]);
+ }
+ transposed_mat.compress();
+ ML_Operator_WrapEpetraCrsMatrix
+ (const_cast<Epetra_CrsMatrix*>(&transposed_mat.trilinos_matrix()),
+ A_,false);
+ }
ML_Operator_WrapEpetraCrsMatrix(mod_B.get(),B_,false);
- // We implement the multiplication by
- // hand in a similar way as is done in
- // ml/src/Operator/ml_rap.c for a triple
- // matrix product. This means that the
- // code is very similar to the one found
- // in ml/src/Operator/ml_rap.c
+ // We implement the multiplication by
+ // hand in a similar way as is done in
+ // ml/src/Operator/ml_rap.c for a triple
+ // matrix product. This means that the
+ // code is very similar to the one found
+ // in ml/src/Operator/ml_rap.c
- // import data if necessary
+ // import data if necessary
ML_Operator *Btmp, *Ctmp, *Ctmp2, *tptr;
ML_CommInfoOP *getrow_comm;
int max_per_proc;
int N_input_vector = B_->invec_leng;
getrow_comm = B_->getrow->pre_comm;
if ( getrow_comm != NULL)
- for (int i = 0; i < getrow_comm->N_neighbors; i++)
- for (int j = 0; j < getrow_comm->neighbors[i].N_send; j++)
- AssertThrow (getrow_comm->neighbors[i].send_list[j] < N_input_vector,
- ExcInternalError());
+ for (int i = 0; i < getrow_comm->N_neighbors; i++)
+ for (int j = 0; j < getrow_comm->neighbors[i].N_send; j++)
+ AssertThrow (getrow_comm->neighbors[i].send_list[j] < N_input_vector,
+ ExcInternalError());
ML_create_unique_col_id(N_input_vector, &(B_->getrow->loc_glob_map),
- getrow_comm, &max_per_proc, B_->comm);
+ getrow_comm, &max_per_proc, B_->comm);
B_->getrow->use_loc_glob_map = ML_YES;
if (A_->getrow->pre_comm != NULL)
- ML_exchange_rows( B_, &Btmp, A_->getrow->pre_comm);
+ ML_exchange_rows( B_, &Btmp, A_->getrow->pre_comm);
else Btmp = B_;
- // perform matrix-matrix product
+ // perform matrix-matrix product
ML_matmat_mult(A_, Btmp , &Ctmp);
- // release temporary structures we needed
- // for multiplication
+ // release temporary structures we needed
+ // for multiplication
ML_free(B_->getrow->loc_glob_map);
B_->getrow->loc_glob_map = NULL;
B_->getrow->use_loc_glob_map = ML_NO;
if (A_->getrow->pre_comm != NULL)
- {
- tptr = Btmp;
- while ( (tptr!= NULL) && (tptr->sub_matrix != B_))
- tptr = tptr->sub_matrix;
- if (tptr != NULL) tptr->sub_matrix = NULL;
- ML_RECUR_CSR_MSRdata_Destroy(Btmp);
- ML_Operator_Destroy(&Btmp);
- }
-
- // make correct data structures
+ {
+ tptr = Btmp;
+ while ( (tptr!= NULL) && (tptr->sub_matrix != B_))
+ tptr = tptr->sub_matrix;
+ if (tptr != NULL) tptr->sub_matrix = NULL;
+ ML_RECUR_CSR_MSRdata_Destroy(Btmp);
+ ML_Operator_Destroy(&Btmp);
+ }
+
+ // make correct data structures
if (A_->getrow->post_comm != NULL)
- ML_exchange_rows(Ctmp, &Ctmp2, A_->getrow->post_comm);
+ ML_exchange_rows(Ctmp, &Ctmp2, A_->getrow->post_comm);
else
- Ctmp2 = Ctmp;
+ Ctmp2 = Ctmp;
ML_back_to_csrlocal(Ctmp2, C_, max_per_proc);
ML_Operator_Destroy (&Ctmp);
if (A_->getrow->post_comm != NULL)
- {
- ML_RECUR_CSR_MSRdata_Destroy(Ctmp2);
- ML_Operator_Destroy (&Ctmp2);
- }
+ {
+ ML_RECUR_CSR_MSRdata_Destroy(Ctmp2);
+ ML_Operator_Destroy (&Ctmp2);
+ }
- // create an Epetra matrix from the ML
- // matrix that we got as a result.
+ // create an Epetra matrix from the ML
+ // matrix that we got as a result.
Epetra_CrsMatrix * C_mat;
ML_Operator2EpetraCrsMatrix(C_, C_mat);
C_mat->FillComplete();
C_mat->OptimizeStorage();
result.reinit (*C_mat);
- // destroy allocated memory
+ // destroy allocated memory
delete C_mat;
ML_Operator_Destroy (&A_);
ML_Operator_Destroy (&B_);
void
SparseMatrix::mmult (SparseMatrix &C,
- const SparseMatrix &B,
- const VectorBase &V) const
+ const SparseMatrix &B,
+ const VectorBase &V) const
{
internals::perform_mmult (*this, B, C, V, false);
}
void
SparseMatrix::Tmmult (SparseMatrix &C,
- const SparseMatrix &B,
- const VectorBase &V) const
+ const SparseMatrix &B,
+ const VectorBase &V) const
{
internals::perform_mmult (*this, B, C, V, true);
}
void
SparseMatrix::add (const TrilinosScalar factor,
- const SparseMatrix &rhs)
+ const SparseMatrix &rhs)
{
Assert (rhs.m() == m(), ExcDimensionMismatch (rhs.m(), m()));
Assert (rhs.n() == n(), ExcDimensionMismatch (rhs.n(), n()));
int ierr;
- // If both matrices have been transformed
- // to local index space (in Trilinos
- // speak: they are filled), we're having
- // matrices based on the same indices
- // with the same number of nonzeros
- // (actually, we'd need sparsity pattern,
- // but that is too expensive to check),
- // we can extract views of the column
- // data on both matrices and simply
- // manipulate the values that are
- // addressed by the pointers.
+ // If both matrices have been transformed
+ // to local index space (in Trilinos
+ // speak: they are filled), we're having
+ // matrices based on the same indices
+ // with the same number of nonzeros
+ // (actually, we'd need sparsity pattern,
+ // but that is too expensive to check),
+ // we can extract views of the column
+ // data on both matrices and simply
+ // manipulate the values that are
+ // addressed by the pointers.
if (matrix->Filled() == true &&
- rhs.matrix->Filled() == true &&
- this->local_range() == local_range &&
- matrix->NumMyNonzeros() == rhs.matrix->NumMyNonzeros())
+ rhs.matrix->Filled() == true &&
+ this->local_range() == local_range &&
+ matrix->NumMyNonzeros() == rhs.matrix->NumMyNonzeros())
for (unsigned int row=local_range.first;
- row < local_range.second; ++row)
- {
- Assert (matrix->NumGlobalEntries(row) ==
- rhs.matrix->NumGlobalEntries(row),
- ExcDimensionMismatch(matrix->NumGlobalEntries(row),
- rhs.matrix->NumGlobalEntries(row)));
-
- const int row_local = matrix->RowMap().LID(row);
- int n_entries, rhs_n_entries;
- TrilinosScalar *value_ptr, *rhs_value_ptr;
-
- // In debug mode, we want to check
- // whether the indices really are the
- // same in the calling matrix and the
- // input matrix. The reason for doing
- // this only in debug mode is that both
- // extracting indices and comparing
- // indices is relatively slow compared to
- // just working with the values.
+ row < local_range.second; ++row)
+ {
+ Assert (matrix->NumGlobalEntries(row) ==
+ rhs.matrix->NumGlobalEntries(row),
+ ExcDimensionMismatch(matrix->NumGlobalEntries(row),
+ rhs.matrix->NumGlobalEntries(row)));
+
+ const int row_local = matrix->RowMap().LID(row);
+ int n_entries, rhs_n_entries;
+ TrilinosScalar *value_ptr, *rhs_value_ptr;
+
+ // In debug mode, we want to check
+ // whether the indices really are the
+ // same in the calling matrix and the
+ // input matrix. The reason for doing
+ // this only in debug mode is that both
+ // extracting indices and comparing
+ // indices is relatively slow compared to
+ // just working with the values.
#ifdef DEBUG
- int *index_ptr, *rhs_index_ptr;
- ierr = rhs.matrix->ExtractMyRowView (row_local, rhs_n_entries,
- rhs_value_ptr, rhs_index_ptr);
- Assert (ierr == 0, ExcTrilinosError(ierr));
-
- ierr = matrix->ExtractMyRowView (row_local, n_entries, value_ptr,
- index_ptr);
- Assert (ierr == 0, ExcTrilinosError(ierr));
+ int *index_ptr, *rhs_index_ptr;
+ ierr = rhs.matrix->ExtractMyRowView (row_local, rhs_n_entries,
+ rhs_value_ptr, rhs_index_ptr);
+ Assert (ierr == 0, ExcTrilinosError(ierr));
+
+ ierr = matrix->ExtractMyRowView (row_local, n_entries, value_ptr,
+ index_ptr);
+ Assert (ierr == 0, ExcTrilinosError(ierr));
#else
- rhs.matrix->ExtractMyRowView (row_local, rhs_n_entries,rhs_value_ptr);
- matrix->ExtractMyRowView (row_local, n_entries, value_ptr);
+ rhs.matrix->ExtractMyRowView (row_local, rhs_n_entries,rhs_value_ptr);
+ matrix->ExtractMyRowView (row_local, n_entries, value_ptr);
#endif
- AssertThrow (n_entries == rhs_n_entries,
- ExcDimensionMismatch (n_entries, rhs_n_entries));
+ AssertThrow (n_entries == rhs_n_entries,
+ ExcDimensionMismatch (n_entries, rhs_n_entries));
- for (int i=0; i<n_entries; ++i)
- {
- *value_ptr++ += *rhs_value_ptr++ * factor;
+ for (int i=0; i<n_entries; ++i)
+ {
+ *value_ptr++ += *rhs_value_ptr++ * factor;
#ifdef DEBUG
- Assert (*index_ptr++ == *rhs_index_ptr++,
- ExcInternalError());
+ Assert (*index_ptr++ == *rhs_index_ptr++,
+ ExcInternalError());
#endif
- }
- }
- // If we have different sparsity patterns
- // (expressed by a different number of
- // nonzero elements), we have to be more
- // careful and extract a copy of the row
- // data, multiply it by the factor and
- // then add it to the matrix using the
- // respective add() function.
+ }
+ }
+ // If we have different sparsity patterns
+ // (expressed by a different number of
+ // nonzero elements), we have to be more
+ // careful and extract a copy of the row
+ // data, multiply it by the factor and
+ // then add it to the matrix using the
+ // respective add() function.
else
{
- unsigned int max_row_length = 0;
- for (unsigned int row=local_range.first;
- row < local_range.second; ++row)
- max_row_length
- = std::max (max_row_length,
- static_cast<unsigned int>(rhs.matrix->NumGlobalEntries(row)));
-
- std::vector<int> column_indices (max_row_length);
- std::vector<TrilinosScalar> values (max_row_length);
-
- if (matrix->Filled() == true && rhs.matrix->Filled() == true &&
- this->local_range() == local_range)
- for (unsigned int row=local_range.first;
- row < local_range.second; ++row)
- {
- const int row_local = matrix->RowMap().LID(row);
- int n_entries;
-
- ierr = rhs.matrix->ExtractMyRowCopy (row_local, max_row_length,
- n_entries,
- &values[0],
- &column_indices[0]);
- Assert (ierr == 0, ExcTrilinosError(ierr));
-
- for (int i=0; i<n_entries; ++i)
- values[i] *= factor;
-
- TrilinosScalar *value_ptr = &values[0];
-
- ierr = matrix->SumIntoMyValues (row_local, n_entries, value_ptr,
- &column_indices[0]);
- Assert (ierr == 0, ExcTrilinosError(ierr));
- }
- else
- {
- for (unsigned int row=local_range.first;
- row < local_range.second; ++row)
- {
- int n_entries;
- ierr = rhs.matrix->Epetra_CrsMatrix::ExtractGlobalRowCopy
- ((int)row, max_row_length, n_entries, &values[0], &column_indices[0]);
- Assert (ierr == 0, ExcTrilinosError(ierr));
-
- for (int i=0; i<n_entries; ++i)
- values[i] *= factor;
-
- ierr = matrix->Epetra_CrsMatrix::SumIntoGlobalValues
- ((int)row, n_entries, &values[0], &column_indices[0]);
- Assert (ierr == 0, ExcTrilinosError(ierr));
- }
- compress ();
-
- }
+ unsigned int max_row_length = 0;
+ for (unsigned int row=local_range.first;
+ row < local_range.second; ++row)
+ max_row_length
+ = std::max (max_row_length,
+ static_cast<unsigned int>(rhs.matrix->NumGlobalEntries(row)));
+
+ std::vector<int> column_indices (max_row_length);
+ std::vector<TrilinosScalar> values (max_row_length);
+
+ if (matrix->Filled() == true && rhs.matrix->Filled() == true &&
+ this->local_range() == local_range)
+ for (unsigned int row=local_range.first;
+ row < local_range.second; ++row)
+ {
+ const int row_local = matrix->RowMap().LID(row);
+ int n_entries;
+
+ ierr = rhs.matrix->ExtractMyRowCopy (row_local, max_row_length,
+ n_entries,
+ &values[0],
+ &column_indices[0]);
+ Assert (ierr == 0, ExcTrilinosError(ierr));
+
+ for (int i=0; i<n_entries; ++i)
+ values[i] *= factor;
+
+ TrilinosScalar *value_ptr = &values[0];
+
+ ierr = matrix->SumIntoMyValues (row_local, n_entries, value_ptr,
+ &column_indices[0]);
+ Assert (ierr == 0, ExcTrilinosError(ierr));
+ }
+ else
+ {
+ for (unsigned int row=local_range.first;
+ row < local_range.second; ++row)
+ {
+ int n_entries;
+ ierr = rhs.matrix->Epetra_CrsMatrix::ExtractGlobalRowCopy
+ ((int)row, max_row_length, n_entries, &values[0], &column_indices[0]);
+ Assert (ierr == 0, ExcTrilinosError(ierr));
+
+ for (int i=0; i<n_entries; ++i)
+ values[i] *= factor;
+
+ ierr = matrix->Epetra_CrsMatrix::SumIntoGlobalValues
+ ((int)row, n_entries, &values[0], &column_indices[0]);
+ Assert (ierr == 0, ExcTrilinosError(ierr));
+ }
+ compress ();
+
+ }
}
}
void
SparseMatrix::transpose ()
{
- // This only flips a flag that tells
- // Trilinos that any vmult operation
- // should be done with the
- // transpose. However, the matrix
- // structure is not reset.
+ // This only flips a flag that tells
+ // Trilinos that any vmult operation
+ // should be done with the
+ // transpose. However, the matrix
+ // structure is not reset.
int ierr;
if (!matrix->UseTranspose())
{
- ierr = matrix->SetUseTranspose (true);
- AssertThrow (ierr == 0, ExcTrilinosError(ierr));
+ ierr = matrix->SetUseTranspose (true);
+ AssertThrow (ierr == 0, ExcTrilinosError(ierr));
}
else
{
- ierr = matrix->SetUseTranspose (false);
- AssertThrow (ierr == 0, ExcTrilinosError(ierr));
+ ierr = matrix->SetUseTranspose (false);
+ AssertThrow (ierr == 0, ExcTrilinosError(ierr));
}
}
- // As of now, no particularly neat
- // ouput is generated in case of
- // multiple processors.
+ // As of now, no particularly neat
+ // ouput is generated in case of
+ // multiple processors.
void
SparseMatrix::print (std::ostream &out,
- const bool print_detailed_trilinos_information) const
+ const bool print_detailed_trilinos_information) const
{
if (print_detailed_trilinos_information == true)
out << *matrix;
else
{
- double * values;
- int * indices;
- int num_entries;
-
- for (int i=0; i<matrix->NumMyRows(); ++i)
- {
- matrix->ExtractMyRowView (i, num_entries, values, indices);
- for (int j=0; j<num_entries; ++j)
- out << "(" << matrix->GRID(i) << "," << matrix->GCID(indices[j]) << ") "
- << values[j] << std::endl;
- }
+ double * values;
+ int * indices;
+ int num_entries;
+
+ for (int i=0; i<matrix->NumMyRows(); ++i)
+ {
+ matrix->ExtractMyRowView (i, num_entries, values, indices);
+ for (int j=0; j<num_entries; ++j)
+ out << "(" << matrix->GRID(i) << "," << matrix->GCID(indices[j]) << ") "
+ << values[j] << std::endl;
+ }
}
AssertThrow (out, ExcIO());
unsigned int static_memory = sizeof(this) + sizeof (*matrix)
+ sizeof(*matrix->Graph().DataPtr());
return ((sizeof(TrilinosScalar)+sizeof(int))*matrix->NumMyNonzeros() +
- sizeof(int)*local_size() +
- static_memory);
+ sizeof(int)*local_size() +
+ static_memory);
}
template void
SparseMatrix::reinit (const Epetra_Map &,
- const dealii::SparsityPattern &,
- const bool);
+ const dealii::SparsityPattern &,
+ const bool);
template void
SparseMatrix::reinit (const Epetra_Map &,
- const CompressedSparsityPattern &,
- const bool);
+ const CompressedSparsityPattern &,
+ const bool);
template void
SparseMatrix::reinit (const Epetra_Map &,
- const CompressedSetSparsityPattern &,
- const bool);
+ const CompressedSetSparsityPattern &,
+ const bool);
template void
SparseMatrix::reinit (const Epetra_Map &,
- const CompressedSimpleSparsityPattern &,
- const bool);
+ const CompressedSimpleSparsityPattern &,
+ const bool);
template void
SparseMatrix::reinit (const Epetra_Map &,
- const Epetra_Map &,
- const dealii::SparsityPattern &,
- const bool);
+ const Epetra_Map &,
+ const dealii::SparsityPattern &,
+ const bool);
template void
SparseMatrix::reinit (const Epetra_Map &,
- const Epetra_Map &,
- const CompressedSparsityPattern &,
- const bool);
+ const Epetra_Map &,
+ const CompressedSparsityPattern &,
+ const bool);
template void
SparseMatrix::reinit (const Epetra_Map &,
- const Epetra_Map &,
- const CompressedSimpleSparsityPattern &,
- const bool);
+ const Epetra_Map &,
+ const CompressedSimpleSparsityPattern &,
+ const bool);
template void
SparseMatrix::reinit (const Epetra_Map &,
- const Epetra_Map &,
- const CompressedSetSparsityPattern &,
- const bool);
+ const Epetra_Map &,
+ const CompressedSetSparsityPattern &,
+ const bool);
template void
SparseMatrix::reinit (const dealii::SparseMatrix<float> &,
- const double,
- const bool,
- const dealii::SparsityPattern *);
+ const double,
+ const bool,
+ const dealii::SparsityPattern *);
template void
SparseMatrix::reinit (const dealii::SparseMatrix<double> &,
- const double,
- const bool,
- const dealii::SparsityPattern *);
+ const double,
+ const bool,
+ const dealii::SparsityPattern *);
template void
SparseMatrix::reinit (const dealii::SparseMatrix<long double> &,
- const double,
- const bool,
- const dealii::SparsityPattern *);
+ const double,
+ const bool,
+ const dealii::SparsityPattern *);
template void
SparseMatrix::reinit (const Epetra_Map &,
- const dealii::SparseMatrix<float> &,
- const double,
- const bool,
- const dealii::SparsityPattern *);
+ const dealii::SparseMatrix<float> &,
+ const double,
+ const bool,
+ const dealii::SparsityPattern *);
template void
SparseMatrix::reinit (const Epetra_Map &,
- const dealii::SparseMatrix<double> &,
- const double,
- const bool,
- const dealii::SparsityPattern *);
+ const dealii::SparseMatrix<double> &,
+ const double,
+ const bool,
+ const dealii::SparsityPattern *);
template void
SparseMatrix::reinit (const Epetra_Map &,
- const dealii::SparseMatrix<long double> &,
- const double,
- const bool,
- const dealii::SparsityPattern *);
+ const dealii::SparseMatrix<long double> &,
+ const double,
+ const bool,
+ const dealii::SparsityPattern *);
template void
SparseMatrix::reinit (const Epetra_Map &,
- const Epetra_Map &,
- const dealii::SparseMatrix<float> &,
- const double,
- const bool,
- const dealii::SparsityPattern *);
+ const Epetra_Map &,
+ const dealii::SparseMatrix<float> &,
+ const double,
+ const bool,
+ const dealii::SparsityPattern *);
template void
SparseMatrix::reinit (const Epetra_Map &,
- const Epetra_Map &,
- const dealii::SparseMatrix<double> &,
- const double,
- const bool,
- const dealii::SparsityPattern *);
+ const Epetra_Map &,
+ const dealii::SparseMatrix<double> &,
+ const double,
+ const bool,
+ const dealii::SparsityPattern *);
template void
SparseMatrix::reinit (const Epetra_Map &,
- const Epetra_Map &,
- const dealii::SparseMatrix<long double> &,
- const double,
- const bool,
- const dealii::SparsityPattern *);
+ const Epetra_Map &,
+ const dealii::SparseMatrix<long double> &,
+ const double,
+ const bool,
+ const dealii::SparsityPattern *);
}
// $Id$
// Version: $Name$
//
-// Copyright (C) 2008, 2009, 2010, 2011 by the deal.II authors
+// Copyright (C) 2008, 2009, 2010, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
const_iterator::Accessor::
visit_present_row ()
{
- // if we are asked to visit the
- // past-the-end line, then simply
- // release all our caches and go on
- // with life
+ // if we are asked to visit the
+ // past-the-end line, then simply
+ // release all our caches and go on
+ // with life
if (this->a_row == sparsity_pattern->n_rows())
- {
- colnum_cache.reset ();
+ {
+ colnum_cache.reset ();
- return;
- }
+ return;
+ }
- // otherwise first flush Trilinos caches
+ // otherwise first flush Trilinos caches
sparsity_pattern->compress ();
- // get a representation of the present
- // row
+ // get a representation of the present
+ // row
int ncols;
int colnums = sparsity_pattern->n_cols();
int ierr;
ierr = sparsity_pattern->graph->ExtractGlobalRowCopy((int)this->a_row,
- colnums,
- ncols,
- (int*)&(*colnum_cache)[0]);
+ colnums,
+ ncols,
+ (int*)&(*colnum_cache)[0]);
AssertThrow (ierr == 0, ExcTrilinosError(ierr));
- // copy it into our caches if the
- // line isn't empty. if it is, then
- // we've done something wrong, since
- // we shouldn't have initialized an
- // iterator for an empty line (what
- // would it point to?)
+ // copy it into our caches if the
+ // line isn't empty. if it is, then
+ // we've done something wrong, since
+ // we shouldn't have initialized an
+ // iterator for an empty line (what
+ // would it point to?)
Assert (ncols != 0, ExcInternalError());
colnum_cache.reset (new std::vector<unsigned int> (colnums,
- colnums+ncols));
+ colnums+ncols));
}
}
- // The constructor is actually the
- // only point where we have to check
- // whether we build a serial or a
- // parallel Trilinos matrix.
- // Actually, it does not even matter
- // how many threads there are, but
- // only if we use an MPI compiler or
- // a standard compiler. So, even one
- // thread on a configuration with
- // MPI will still get a parallel
- // interface.
+ // The constructor is actually the
+ // only point where we have to check
+ // whether we build a serial or a
+ // parallel Trilinos matrix.
+ // Actually, it does not even matter
+ // how many threads there are, but
+ // only if we use an MPI compiler or
+ // a standard compiler. So, even one
+ // thread on a configuration with
+ // MPI will still get a parallel
+ // interface.
SparsityPattern::SparsityPattern ()
- :
- compressed (true)
+ :
+ compressed (true)
{
column_space_map.reset(new Epetra_Map (0, 0, Utilities::Trilinos::comm_self()));
graph.reset (new Epetra_FECrsGraph(View, *column_space_map, *column_space_map, 0));
SparsityPattern::SparsityPattern (const Epetra_Map &input_map,
- const unsigned int n_entries_per_row)
+ const unsigned int n_entries_per_row)
{
reinit (input_map, input_map, n_entries_per_row);
}
SparsityPattern::SparsityPattern (const Epetra_Map &input_map,
- const std::vector<unsigned int> &n_entries_per_row)
+ const std::vector<unsigned int> &n_entries_per_row)
{
reinit (input_map, input_map, n_entries_per_row);
}
SparsityPattern::SparsityPattern (const Epetra_Map &input_row_map,
- const Epetra_Map &input_col_map,
- const unsigned int n_entries_per_row)
+ const Epetra_Map &input_col_map,
+ const unsigned int n_entries_per_row)
{
reinit (input_row_map, input_col_map, n_entries_per_row);
}
SparsityPattern::SparsityPattern (const Epetra_Map &input_row_map,
- const Epetra_Map &input_col_map,
- const std::vector<unsigned int> &n_entries_per_row)
+ const Epetra_Map &input_col_map,
+ const std::vector<unsigned int> &n_entries_per_row)
{
reinit (input_row_map, input_col_map, n_entries_per_row);
}
SparsityPattern::SparsityPattern (const unsigned int m,
- const unsigned int n,
- const unsigned int n_entries_per_row)
+ const unsigned int n,
+ const unsigned int n_entries_per_row)
{
reinit (m, n, n_entries_per_row);
}
SparsityPattern::SparsityPattern (const unsigned int m,
- const unsigned int n,
- const std::vector<unsigned int> &n_entries_per_row)
+ const unsigned int n,
+ const std::vector<unsigned int> &n_entries_per_row)
{
reinit (m, n, n_entries_per_row);
}
- // Copy function only works if the
- // sparsity pattern is empty.
+ // Copy function only works if the
+ // sparsity pattern is empty.
SparsityPattern::SparsityPattern (const SparsityPattern &input_sparsity)
- :
+ :
Subscriptor(),
column_space_map (new Epetra_Map(0, 0, Utilities::Trilinos::comm_self())),
compressed (false),
graph (new Epetra_FECrsGraph(View, *column_space_map,
- *column_space_map, 0))
+ *column_space_map, 0))
{
Assert (input_sparsity.n_rows() == 0,
- ExcMessage ("Copy constructor only works for empty sparsity patterns."));
+ ExcMessage ("Copy constructor only works for empty sparsity patterns."));
}
void
SparsityPattern::reinit (const Epetra_Map &input_map,
- const unsigned int n_entries_per_row)
+ const unsigned int n_entries_per_row)
{
reinit (input_map, input_map, n_entries_per_row);
}
void
SparsityPattern::reinit (const unsigned int m,
- const unsigned int n,
- const unsigned int n_entries_per_row)
+ const unsigned int n,
+ const unsigned int n_entries_per_row)
{
const Epetra_Map rows (m, 0, Utilities::Trilinos::comm_self());
const Epetra_Map columns (n, 0, Utilities::Trilinos::comm_self());
void
SparsityPattern::reinit (const Epetra_Map &input_row_map,
- const Epetra_Map &input_col_map,
- const unsigned int n_entries_per_row)
+ const Epetra_Map &input_col_map,
+ const unsigned int n_entries_per_row)
{
graph.reset ();
column_space_map.reset (new Epetra_Map (input_col_map));
compressed = false;
- // for more than one processor, need to
- // specify only row map first and let the
- // matrix entries decide about the column
- // map (which says which columns are
- // present in the matrix, not to be
- // confused with the col_map that tells
- // how the domain dofs of the matrix will
- // be distributed). for only one
- // processor, we can directly assign the
- // columns as well.
+ // for more than one processor, need to
+ // specify only row map first and let the
+ // matrix entries decide about the column
+ // map (which says which columns are
+ // present in the matrix, not to be
+ // confused with the col_map that tells
+ // how the domain dofs of the matrix will
+ // be distributed). for only one
+ // processor, we can directly assign the
+ // columns as well.
if (input_row_map.Comm().NumProc() > 1)
graph.reset (new Epetra_FECrsGraph(Copy, input_row_map,
- n_entries_per_row, false));
+ n_entries_per_row, false));
else
graph.reset (new Epetra_FECrsGraph(Copy, input_row_map, input_col_map,
- n_entries_per_row, false));
+ n_entries_per_row, false));
}
void
SparsityPattern::reinit (const Epetra_Map &input_map,
- const std::vector<unsigned int> &n_entries_per_row)
+ const std::vector<unsigned int> &n_entries_per_row)
{
reinit (input_map, input_map, n_entries_per_row);
}
void
SparsityPattern::reinit (const unsigned int m,
- const unsigned int n,
- const std::vector<unsigned int> &n_entries_per_row)
+ const unsigned int n,
+ const std::vector<unsigned int> &n_entries_per_row)
{
const Epetra_Map rows (m, 0, Utilities::Trilinos::comm_self());
const Epetra_Map columns (n, 0, Utilities::Trilinos::comm_self());
void
SparsityPattern::reinit (const Epetra_Map &input_row_map,
- const Epetra_Map &input_col_map,
- const std::vector<unsigned int> &n_entries_per_row)
+ const Epetra_Map &input_col_map,
+ const std::vector<unsigned int> &n_entries_per_row)
{
- // release memory before reallocation
+ // release memory before reallocation
graph.reset ();
AssertDimension (n_entries_per_row.size(),
- static_cast<unsigned int>(input_row_map.NumGlobalElements()));
+ static_cast<unsigned int>(input_row_map.NumGlobalElements()));
column_space_map.reset (new Epetra_Map (input_col_map));
compressed = false;
if (input_row_map.Comm().NumProc() > 1)
graph.reset(new Epetra_FECrsGraph(Copy, input_row_map,
- n_entries_per_row[input_row_map.MinMyGID()],
- false));
+ n_entries_per_row[input_row_map.MinMyGID()],
+ false));
else
graph.reset(new Epetra_FECrsGraph(Copy, input_row_map, input_col_map,
- n_entries_per_row[input_row_map.MinMyGID()],
- false));
+ n_entries_per_row[input_row_map.MinMyGID()],
+ false));
}
template <typename SparsityType>
void
SparsityPattern::reinit (const Epetra_Map &input_map,
- const SparsityType &sp,
- const bool exchange_data)
+ const SparsityType &sp,
+ const bool exchange_data)
{
reinit (input_map, input_map, sp, exchange_data);
}
template <typename SparsityType>
void
SparsityPattern::reinit (const Epetra_Map &input_row_map,
- const Epetra_Map &input_col_map,
- const SparsityType &sp,
- const bool exchange_data)
+ const Epetra_Map &input_col_map,
+ const SparsityType &sp,
+ const bool exchange_data)
{
graph.reset ();
AssertDimension (sp.n_rows(),
- static_cast<unsigned int>(input_row_map.NumGlobalElements()));
+ static_cast<unsigned int>(input_row_map.NumGlobalElements()));
AssertDimension (sp.n_cols(),
- static_cast<unsigned int>(input_col_map.NumGlobalElements()));
+ static_cast<unsigned int>(input_col_map.NumGlobalElements()));
column_space_map.reset (new Epetra_Map (input_col_map));
compressed = false;
Assert (input_row_map.LinearMap() == true,
- ExcMessage ("This function is not efficient if the map is not contiguous."));
+ ExcMessage ("This function is not efficient if the map is not contiguous."));
const unsigned int first_row = input_row_map.MinMyGID(),
last_row = input_row_map.MaxMyGID()+1;
if (input_row_map.Comm().NumProc() > 1)
graph.reset(new Epetra_FECrsGraph(Copy, input_row_map,
- &n_entries_per_row[0],
- false));
+ &n_entries_per_row[0],
+ false));
else
graph.reset (new Epetra_FECrsGraph(Copy, input_row_map, input_col_map,
- &n_entries_per_row[0],
- false));
+ &n_entries_per_row[0],
+ false));
AssertDimension (sp.n_rows(),
- static_cast<unsigned int>(graph->NumGlobalRows()));
+ static_cast<unsigned int>(graph->NumGlobalRows()));
std::vector<int> row_indices;
- // Include possibility to exchange data
- // since CompressedSimpleSparsityPattern is
- // able to do so
+ // Include possibility to exchange data
+ // since CompressedSimpleSparsityPattern is
+ // able to do so
if (exchange_data==false)
for (unsigned int row=first_row; row<last_row; ++row)
- {
- const int row_length = sp.row_length(row);
- if (row_length == 0)
- continue;
+ {
+ const int row_length = sp.row_length(row);
+ if (row_length == 0)
+ continue;
- row_indices.resize (row_length, -1);
+ row_indices.resize (row_length, -1);
- typename SparsityType::row_iterator col_num = sp.row_begin (row),
- row_end = sp.row_end(row);
- for (unsigned int col = 0; col_num != row_end; ++col_num, ++col)
- row_indices[col] = *col_num;
+ typename SparsityType::row_iterator col_num = sp.row_begin (row),
+ row_end = sp.row_end(row);
+ for (unsigned int col = 0; col_num != row_end; ++col_num, ++col)
+ row_indices[col] = *col_num;
- graph->Epetra_CrsGraph::InsertGlobalIndices (row, row_length,
- &row_indices[0]);
- }
+ graph->Epetra_CrsGraph::InsertGlobalIndices (row, row_length,
+ &row_indices[0]);
+ }
else
for (unsigned int row=0; row<sp.n_rows(); ++row)
- {
- const int row_length = sp.row_length(row);
- if (row_length == 0)
- continue;
+ {
+ const int row_length = sp.row_length(row);
+ if (row_length == 0)
+ continue;
- row_indices.resize (row_length, -1);
+ row_indices.resize (row_length, -1);
- typename SparsityType::row_iterator col_num = sp.row_begin (row),
- row_end = sp.row_end(row);
- for (unsigned int col = 0; col_num != row_end; ++col_num, ++col)
- row_indices[col] = *col_num;
+ typename SparsityType::row_iterator col_num = sp.row_begin (row),
+ row_end = sp.row_end(row);
+ for (unsigned int col = 0; col_num != row_end; ++col_num, ++col)
+ row_indices[col] = *col_num;
- graph->InsertGlobalIndices (1, reinterpret_cast<int*>(&row), row_length,
- &row_indices[0]);
- }
+ graph->InsertGlobalIndices (1, reinterpret_cast<int*>(&row), row_length,
+ &row_indices[0]);
+ }
compress();
}
void
SparsityPattern::clear ()
{
- // When we clear the matrix, reset
- // the pointer and generate an
- // empty sparsity pattern.
+ // When we clear the matrix, reset
+ // the pointer and generate an
+ // empty sparsity pattern.
column_space_map.reset (new Epetra_Map (0, 0, Utilities::Trilinos::comm_self()));
graph.reset (new Epetra_FECrsGraph(View, *column_space_map,
- *column_space_map, 0));
+ *column_space_map, 0));
graph->FillComplete();
compressed = true;
int ierr;
Assert (column_space_map.get() != 0, ExcInternalError());
ierr = graph->GlobalAssemble (*column_space_map,
- static_cast<const Epetra_Map&>(graph->RangeMap()),
- true);
+ static_cast<const Epetra_Map&>(graph->RangeMap()),
+ true);
AssertThrow (ierr == 0, ExcTrilinosError(ierr));
bool
SparsityPattern::exists (const unsigned int i,
- const unsigned int j) const
+ const unsigned int j) const
{
- // Extract local indices in
- // the matrix.
+ // Extract local indices in
+ // the matrix.
int trilinos_i = graph->LRID(i), trilinos_j = graph->LCID(j);
- // If the data is not on the
- // present processor, we throw
- // an exception. This is on of
- // the two tiny differences to
- // the el(i,j) call, which does
- // not throw any assertions.
+ // If the data is not on the
+ // present processor, we throw
+ // an exception. This is on of
+ // the two tiny differences to
+ // the el(i,j) call, which does
+ // not throw any assertions.
if (trilinos_i == -1)
{
- return false;
+ return false;
}
else
{
- // Check whether the matrix
- // already is transformed to
- // local indices.
- if (graph->Filled() == false)
- {
- int nnz_present = graph->NumGlobalIndices(i);
- int nnz_extracted;
- int *col_indices;
-
- // Generate the view and make
- // sure that we have not generated
- // an error.
- int ierr = graph->ExtractGlobalRowView(trilinos_i, nnz_extracted,
- col_indices);
- Assert (ierr==0, ExcTrilinosError(ierr));
- Assert (nnz_present == nnz_extracted,
- ExcDimensionMismatch(nnz_present, nnz_extracted));
-
- // Search the index
- int* el_find = std::find(col_indices, col_indices + nnz_present,
- trilinos_j);
-
- int local_col_index = (int)(el_find - col_indices);
-
- if (local_col_index == nnz_present)
- return false;
- }
- else
- {
- // Prepare pointers for extraction
- // of a view of the row.
- int nnz_present = graph->NumGlobalIndices(i);
- int nnz_extracted;
- int *col_indices;
-
- // Generate the view and make
- // sure that we have not generated
- // an error.
- int ierr = graph->ExtractMyRowView(trilinos_i, nnz_extracted,
- col_indices);
- Assert (ierr==0, ExcTrilinosError(ierr));
-
- Assert (nnz_present == nnz_extracted,
- ExcDimensionMismatch(nnz_present, nnz_extracted));
-
- // Search the index
- int* el_find = std::find(col_indices, col_indices + nnz_present,
- trilinos_j);
-
- int local_col_index = (int)(el_find - col_indices);
-
- if (local_col_index == nnz_present)
- return false;
- }
+ // Check whether the matrix
+ // already is transformed to
+ // local indices.
+ if (graph->Filled() == false)
+ {
+ int nnz_present = graph->NumGlobalIndices(i);
+ int nnz_extracted;
+ int *col_indices;
+
+ // Generate the view and make
+ // sure that we have not generated
+ // an error.
+ int ierr = graph->ExtractGlobalRowView(trilinos_i, nnz_extracted,
+ col_indices);
+ Assert (ierr==0, ExcTrilinosError(ierr));
+ Assert (nnz_present == nnz_extracted,
+ ExcDimensionMismatch(nnz_present, nnz_extracted));
+
+ // Search the index
+ int* el_find = std::find(col_indices, col_indices + nnz_present,
+ trilinos_j);
+
+ int local_col_index = (int)(el_find - col_indices);
+
+ if (local_col_index == nnz_present)
+ return false;
+ }
+ else
+ {
+ // Prepare pointers for extraction
+ // of a view of the row.
+ int nnz_present = graph->NumGlobalIndices(i);
+ int nnz_extracted;
+ int *col_indices;
+
+ // Generate the view and make
+ // sure that we have not generated
+ // an error.
+ int ierr = graph->ExtractMyRowView(trilinos_i, nnz_extracted,
+ col_indices);
+ Assert (ierr==0, ExcTrilinosError(ierr));
+
+ Assert (nnz_present == nnz_extracted,
+ ExcDimensionMismatch(nnz_present, nnz_extracted));
+
+ // Search the index
+ int* el_find = std::find(col_indices, col_indices + nnz_present,
+ trilinos_j);
+
+ int local_col_index = (int)(el_find - col_indices);
+
+ if (local_col_index == nnz_present)
+ return false;
+ }
}
return true;
int global_b=0;
for (unsigned int i=0; i<local_size(); ++i)
{
- int * indices;
- int num_entries;
- graph->ExtractMyRowView(i, num_entries, indices);
- for (unsigned int j=0; j<(unsigned int)num_entries; ++j)
- {
- if (static_cast<unsigned int>(std::abs(static_cast<int>(i-indices[j]))) > local_b)
- local_b = std::abs(static_cast<signed int>(i-indices[j]));
- }
+ int * indices;
+ int num_entries;
+ graph->ExtractMyRowView(i, num_entries, indices);
+ for (unsigned int j=0; j<(unsigned int)num_entries; ++j)
+ {
+ if (static_cast<unsigned int>(std::abs(static_cast<int>(i-indices[j]))) > local_b)
+ local_b = std::abs(static_cast<signed int>(i-indices[j]));
+ }
}
graph->Comm().MaxAll((int *)&local_b, &global_b, 1);
return static_cast<unsigned int>(global_b);
{
Assert (row < n_rows(), ExcInternalError());
- // get a representation of the
- // present row
+ // get a representation of the
+ // present row
int ncols = -1;
int local_row = graph->LRID(row);
- // on the processor who owns this
- // row, we'll have a non-negative
- // value.
+ // on the processor who owns this
+ // row, we'll have a non-negative
+ // value.
if (local_row >= 0)
ncols = graph->NumMyIndices (local_row);
- // As of now, no particularly neat
- // ouput is generated in case of
- // multiple processors.
+ // As of now, no particularly neat
+ // ouput is generated in case of
+ // multiple processors.
void
SparsityPattern::print (std::ostream &out,
- const bool write_extended_trilinos_info) const
+ const bool write_extended_trilinos_info) const
{
if (write_extended_trilinos_info)
out << *graph;
else
{
- int * indices;
- int num_entries;
-
- for (int i=0; i<graph->NumMyRows(); ++i)
- {
- graph->ExtractMyRowView (i, num_entries, indices);
- for (int j=0; j<num_entries; ++j)
- out << "(" << i << "," << indices[graph->GRID(j)] << ") "
- << std::endl;
- }
+ int * indices;
+ int num_entries;
+
+ for (int i=0; i<graph->NumMyRows(); ++i)
+ {
+ graph->ExtractMyRowView (i, num_entries, indices);
+ for (int j=0; j<num_entries; ++j)
+ out << "(" << i << "," << indices[graph->GRID(j)] << ") "
+ << std::endl;
+ }
}
AssertThrow (out, ExcIO());
Assert (graph->Filled() == true, ExcInternalError());
for (unsigned int row=0; row<local_size(); ++row)
{
- signed int * indices;
- int num_entries;
- graph->ExtractMyRowView (row, num_entries, indices);
+ signed int * indices;
+ int num_entries;
+ graph->ExtractMyRowView (row, num_entries, indices);
- for (unsigned int j=0; j<(unsigned int)num_entries; ++j)
+ for (unsigned int j=0; j<(unsigned int)num_entries; ++j)
// while matrix entries are usually
// written (i,j), with i vertical and
// j horizontal, gnuplot output is
// x-y, that is we have to exchange
// the order of output
- out << indices[graph->GRID(j)] << " " << -static_cast<signed int>(row)
- << std::endl;
+ out << indices[graph->GRID(j)] << " " << -static_cast<signed int>(row)
+ << std::endl;
}
AssertThrow (out, ExcIO());
template void
SparsityPattern::reinit (const Epetra_Map &,
- const dealii::SparsityPattern &,
- bool);
+ const dealii::SparsityPattern &,
+ bool);
template void
SparsityPattern::reinit (const Epetra_Map &,
- const dealii::CompressedSparsityPattern &,
- bool);
+ const dealii::CompressedSparsityPattern &,
+ bool);
template void
SparsityPattern::reinit (const Epetra_Map &,
- const dealii::CompressedSetSparsityPattern &,
- bool);
+ const dealii::CompressedSetSparsityPattern &,
+ bool);
template void
SparsityPattern::reinit (const Epetra_Map &,
- const dealii::CompressedSimpleSparsityPattern &,
- bool);
+ const dealii::CompressedSimpleSparsityPattern &,
+ bool);
template void
SparsityPattern::reinit (const Epetra_Map &,
- const Epetra_Map &,
- const dealii::SparsityPattern &,
- bool);
+ const Epetra_Map &,
+ const dealii::SparsityPattern &,
+ bool);
template void
SparsityPattern::reinit (const Epetra_Map &,
- const Epetra_Map &,
- const dealii::CompressedSparsityPattern &,
- bool);
+ const Epetra_Map &,
+ const dealii::CompressedSparsityPattern &,
+ bool);
template void
SparsityPattern::reinit (const Epetra_Map &,
- const Epetra_Map &,
- const dealii::CompressedSetSparsityPattern &,
- bool);
+ const Epetra_Map &,
+ const dealii::CompressedSetSparsityPattern &,
+ bool);
template void
SparsityPattern::reinit (const Epetra_Map &,
- const Epetra_Map &,
- const dealii::CompressedSimpleSparsityPattern &,
- bool);
+ const Epetra_Map &,
+ const dealii::CompressedSimpleSparsityPattern &,
+ bool);
}
// $Id$
// Version: $Name$
//
-// Copyright (C) 2008, 2009 by the deal.II authors
+// Copyright (C) 2008, 2009, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
Vector::Vector (const IndexSet ¶llel_partitioning,
- const MPI_Comm &communicator)
+ const MPI_Comm &communicator)
{
reinit (parallel_partitioning, communicator);
}
Vector::Vector (const Epetra_Map &input_map,
- const VectorBase &v)
+ const VectorBase &v)
:
VectorBase()
{
AssertThrow (input_map.NumGlobalElements() == v.vector->Map().NumGlobalElements(),
- ExcDimensionMismatch (input_map.NumGlobalElements(),
- v.vector->Map().NumGlobalElements()));
+ ExcDimensionMismatch (input_map.NumGlobalElements(),
+ v.vector->Map().NumGlobalElements()));
last_action = Zero;
if (input_map.SameAs(v.vector->Map()) == true)
- vector.reset (new Epetra_FEVector(*v.vector));
+ vector.reset (new Epetra_FEVector(*v.vector));
else
- {
- vector.reset (new Epetra_FEVector(input_map));
- reinit (v, false, true);
- }
+ {
+ vector.reset (new Epetra_FEVector(input_map));
+ reinit (v, false, true);
+ }
}
Vector::Vector (const IndexSet ¶llel_partitioner,
- const VectorBase &v,
- const MPI_Comm &communicator)
+ const VectorBase &v,
+ const MPI_Comm &communicator)
:
VectorBase()
{
AssertThrow ((int)parallel_partitioner.size() == v.vector->Map().NumGlobalElements(),
- ExcDimensionMismatch (parallel_partitioner.size(),
- v.vector->Map().NumGlobalElements()));
+ ExcDimensionMismatch (parallel_partitioner.size(),
+ v.vector->Map().NumGlobalElements()));
last_action = Zero;
vector.reset (new Epetra_FEVector
- (parallel_partitioner.make_trilinos_map(communicator,
- true)));
+ (parallel_partitioner.make_trilinos_map(communicator,
+ true)));
reinit (v, false, true);
}
void
Vector::reinit (const Epetra_Map &input_map,
- const bool fast)
+ const bool fast)
{
if (vector->Map().SameAs(input_map)==false)
- vector.reset (new Epetra_FEVector(input_map));
+ vector.reset (new Epetra_FEVector(input_map));
else if (fast == false)
- {
- const int ierr = vector->PutScalar(0.);
- Assert (ierr == 0, ExcTrilinosError(ierr));
- }
+ {
+ const int ierr = vector->PutScalar(0.);
+ Assert (ierr == 0, ExcTrilinosError(ierr));
+ }
last_action = Zero;
}
void
Vector::reinit (const IndexSet ¶llel_partitioner,
- const MPI_Comm &communicator,
- const bool fast)
+ const MPI_Comm &communicator,
+ const bool fast)
{
Epetra_Map map = parallel_partitioner.make_trilinos_map (communicator,
- true);
+ true);
reinit (map, fast);
}
void
Vector::reinit (const VectorBase &v,
- const bool fast,
- const bool allow_different_maps)
+ const bool fast,
+ const bool allow_different_maps)
{
- // In case we do not allow to
- // have different maps, this
- // call means that we have to
- // reset the vector. So clear
- // the vector, initialize our
- // map with the map in v, and
- // generate the vector.
+ // In case we do not allow to
+ // have different maps, this
+ // call means that we have to
+ // reset the vector. So clear
+ // the vector, initialize our
+ // map with the map in v, and
+ // generate the vector.
if (allow_different_maps == false)
{
- if (vector->Map().SameAs(v.vector->Map()) == false)
- {
- vector.reset (new Epetra_FEVector(v.vector->Map()));
- last_action = Zero;
- }
- else if (fast == false)
- {
- // old and new vectors
- // have exactly the
- // same map, i.e. size
- // and parallel
- // distribution
- int ierr;
- ierr = vector->GlobalAssemble (last_action);
- Assert (ierr == 0, ExcTrilinosError(ierr));
-
- ierr = vector->PutScalar(0.0);
- Assert (ierr == 0, ExcTrilinosError(ierr));
-
- last_action = Zero;
- }
- }
-
- // Otherwise, we have to check
- // that the two vectors are
- // already of the same size,
- // create an object for the data
- // exchange and then insert all
- // the data. The first assertion
- // is only a check whether the
- // user knows what she is doing.
+ if (vector->Map().SameAs(v.vector->Map()) == false)
+ {
+ vector.reset (new Epetra_FEVector(v.vector->Map()));
+ last_action = Zero;
+ }
+ else if (fast == false)
+ {
+ // old and new vectors
+ // have exactly the
+ // same map, i.e. size
+ // and parallel
+ // distribution
+ int ierr;
+ ierr = vector->GlobalAssemble (last_action);
+ Assert (ierr == 0, ExcTrilinosError(ierr));
+
+ ierr = vector->PutScalar(0.0);
+ Assert (ierr == 0, ExcTrilinosError(ierr));
+
+ last_action = Zero;
+ }
+ }
+
+ // Otherwise, we have to check
+ // that the two vectors are
+ // already of the same size,
+ // create an object for the data
+ // exchange and then insert all
+ // the data. The first assertion
+ // is only a check whether the
+ // user knows what she is doing.
else
{
- Assert (fast == false,
- ExcMessage ("It is not possible to exchange data with the "
- "option fast set, which would not write "
- "elements."));
+ Assert (fast == false,
+ ExcMessage ("It is not possible to exchange data with the "
+ "option fast set, which would not write "
+ "elements."));
- AssertThrow (size() == v.size(),
- ExcDimensionMismatch (size(), v.size()));
+ AssertThrow (size() == v.size(),
+ ExcDimensionMismatch (size(), v.size()));
- Epetra_Import data_exchange (vector->Map(), v.vector->Map());
+ Epetra_Import data_exchange (vector->Map(), v.vector->Map());
- const int ierr = vector->Import(*v.vector, data_exchange, Insert);
- AssertThrow (ierr == 0, ExcTrilinosError(ierr));
+ const int ierr = vector->Import(*v.vector, data_exchange, Insert);
+ AssertThrow (ierr == 0, ExcTrilinosError(ierr));
- last_action = Insert;
- }
+ last_action = Insert;
+ }
}
void
Vector::reinit (const BlockVector &v,
- const bool import_data)
+ const bool import_data)
{
- // In case we do not allow to
- // have different maps, this
- // call means that we have to
- // reset the vector. So clear
- // the vector, initialize our
- // map with the map in v, and
- // generate the vector.
+ // In case we do not allow to
+ // have different maps, this
+ // call means that we have to
+ // reset the vector. So clear
+ // the vector, initialize our
+ // map with the map in v, and
+ // generate the vector.
if (v.n_blocks() == 0)
- return;
+ return;
- // create a vector that holds all the elements
- // contained in the block vector. need to
- // manually create an Epetra_Map.
+ // create a vector that holds all the elements
+ // contained in the block vector. need to
+ // manually create an Epetra_Map.
unsigned int n_elements = 0, added_elements = 0, block_offset = 0;
for (unsigned int block=0; block<v.n_blocks();++block)
- n_elements += v.block(block).local_size();
+ n_elements += v.block(block).local_size();
std::vector<int> global_ids (n_elements, -1);
for (unsigned int block=0; block<v.n_blocks();++block)
- {
- int * glob_elements = v.block(block).vector_partitioner().MyGlobalElements();
- for (unsigned int i=0; i<v.block(block).local_size(); ++i)
- global_ids[added_elements++] = glob_elements[i] + block_offset;
- block_offset += v.block(block).size();
- }
+ {
+ int * glob_elements = v.block(block).vector_partitioner().MyGlobalElements();
+ for (unsigned int i=0; i<v.block(block).local_size(); ++i)
+ global_ids[added_elements++] = glob_elements[i] + block_offset;
+ block_offset += v.block(block).size();
+ }
Assert (n_elements == added_elements, ExcInternalError());
Epetra_Map new_map (v.size(), n_elements, &global_ids[0], 0,
- v.block(0).vector_partitioner().Comm());
+ v.block(0).vector_partitioner().Comm());
std_cxx1x::shared_ptr<Epetra_FEVector> actual_vec;
if ( import_data == true )
- actual_vec.reset (new Epetra_FEVector (new_map));
+ actual_vec.reset (new Epetra_FEVector (new_map));
else
- {
- vector.reset (new Epetra_FEVector (new_map));
- actual_vec = vector;
- }
+ {
+ vector.reset (new Epetra_FEVector (new_map));
+ actual_vec = vector;
+ }
TrilinosScalar* entries = (*actual_vec)[0];
block_offset = 0;
for (unsigned int block=0; block<v.n_blocks();++block)
- {
- v.block(block).trilinos_vector().ExtractCopy (entries, 0);
- entries += v.block(block).local_size();
- }
+ {
+ v.block(block).trilinos_vector().ExtractCopy (entries, 0);
+ entries += v.block(block).local_size();
+ }
if (import_data == true)
{
- AssertThrow (static_cast<unsigned int>(actual_vec->GlobalLength())
- == v.size(),
- ExcDimensionMismatch (actual_vec->GlobalLength(),
- v.size()));
+ AssertThrow (static_cast<unsigned int>(actual_vec->GlobalLength())
+ == v.size(),
+ ExcDimensionMismatch (actual_vec->GlobalLength(),
+ v.size()));
- Epetra_Import data_exchange (vector->Map(), actual_vec->Map());
+ Epetra_Import data_exchange (vector->Map(), actual_vec->Map());
- const int ierr = vector->Import(*actual_vec, data_exchange, Insert);
- AssertThrow (ierr == 0, ExcTrilinosError(ierr));
+ const int ierr = vector->Import(*actual_vec, data_exchange, Insert);
+ AssertThrow (ierr == 0, ExcTrilinosError(ierr));
- last_action = Insert;
- }
+ last_action = Insert;
+ }
}
Vector &
Vector::operator = (const Vector &v)
{
- // distinguish three cases. First case: both
- // vectors have the same layout (just need to
- // copy the local data, not reset the memory
- // and the underlying Epetra_Map). The third
- // case means that we have to rebuild the
- // calling vector.
+ // distinguish three cases. First case: both
+ // vectors have the same layout (just need to
+ // copy the local data, not reset the memory
+ // and the underlying Epetra_Map). The third
+ // case means that we have to rebuild the
+ // calling vector.
if (vector->Map().SameAs(v.vector->Map()))
- {
- *vector = *v.vector;
- last_action = Zero;
- }
- // Second case: vectors have the same global
- // size, but different parallel layouts (and
- // one of them a one-to-one mapping). Then we
- // can call the import/export functionality.
+ {
+ *vector = *v.vector;
+ last_action = Zero;
+ }
+ // Second case: vectors have the same global
+ // size, but different parallel layouts (and
+ // one of them a one-to-one mapping). Then we
+ // can call the import/export functionality.
else if (size() == v.size() &&
- (v.vector->Map().UniqueGIDs() || vector->Map().UniqueGIDs()))
- {
- reinit (v, false, true);
- }
- // Third case: Vectors do not have the same
- // size.
+ (v.vector->Map().UniqueGIDs() || vector->Map().UniqueGIDs()))
+ {
+ reinit (v, false, true);
+ }
+ // Third case: Vectors do not have the same
+ // size.
else
- {
- vector.reset (new Epetra_FEVector(*v.vector));
- last_action = Zero;
- }
+ {
+ vector.reset (new Epetra_FEVector(*v.vector));
+ last_action = Zero;
+ }
return *this;
}
void
Vector::import_nonlocal_data_for_fe (const TrilinosWrappers::SparseMatrix &m,
- const Vector &v)
+ const Vector &v)
{
Assert (m.trilinos_matrix().Filled() == true,
- ExcMessage ("Matrix is not compressed. "
- "Cannot find exchange information!"));
+ ExcMessage ("Matrix is not compressed. "
+ "Cannot find exchange information!"));
Assert (v.vector->Map().UniqueGIDs() == true,
- ExcMessage ("The input vector has overlapping data, "
- "which is not allowed."));
+ ExcMessage ("The input vector has overlapping data, "
+ "which is not allowed."));
if (vector->Map().SameAs(m.col_partitioner()) == false)
- {
- Epetra_Map map = m.col_partitioner();
- vector.reset (new Epetra_FEVector(map));
- }
+ {
+ Epetra_Map map = m.col_partitioner();
+ vector.reset (new Epetra_FEVector(map));
+ }
Epetra_Import data_exchange (vector->Map(), v.vector->Map());
const int ierr = vector->Import(*v.vector, data_exchange, Insert);
{
last_action = Zero;
Epetra_LocalMap map (input_map.NumGlobalElements(),
- input_map.IndexBase(),
- input_map.Comm());
+ input_map.IndexBase(),
+ input_map.Comm());
vector.reset (new Epetra_FEVector(map));
}
Vector::Vector (const IndexSet &partitioning,
- const MPI_Comm &communicator)
+ const MPI_Comm &communicator)
{
last_action = Zero;
Epetra_LocalMap map (partitioning.size(),
- 0,
+ 0,
#ifdef DEAL_II_COMPILER_SUPPORTS_MPI
- Epetra_MpiComm(communicator));
+ Epetra_MpiComm(communicator));
#else
Epetra_SerialComm());
(void)communicator;
{
last_action = Zero;
Epetra_LocalMap map (v.vector->Map().NumGlobalElements(),
- v.vector->Map().IndexBase(),
- v.vector->Map().Comm());
+ v.vector->Map().IndexBase(),
+ v.vector->Map().Comm());
vector.reset (new Epetra_FEVector(map));
if (vector->Map().SameAs(v.vector->Map()) == true)
{
- const int ierr = vector->Update(1.0, *v.vector, 0.0);
- AssertThrow (ierr == 0, ExcTrilinosError(ierr));
+ const int ierr = vector->Update(1.0, *v.vector, 0.0);
+ AssertThrow (ierr == 0, ExcTrilinosError(ierr));
}
else
reinit (v, false, true);
void
Vector::reinit (const unsigned int n,
- const bool fast)
+ const bool fast)
{
if (size() != n)
{
- Epetra_LocalMap map ((int)n, 0,
- Utilities::Trilinos::comm_self());
- vector.reset (new Epetra_FEVector (map));
+ Epetra_LocalMap map ((int)n, 0,
+ Utilities::Trilinos::comm_self());
+ vector.reset (new Epetra_FEVector (map));
}
else if (fast == false)
{
- int ierr;
- ierr = vector->GlobalAssemble(last_action);
- Assert (ierr == 0, ExcTrilinosError(ierr));
+ int ierr;
+ ierr = vector->GlobalAssemble(last_action);
+ Assert (ierr == 0, ExcTrilinosError(ierr));
- ierr = vector->PutScalar(0.0);
- Assert (ierr == 0, ExcTrilinosError(ierr));
+ ierr = vector->PutScalar(0.0);
+ Assert (ierr == 0, ExcTrilinosError(ierr));
}
last_action = Zero;
{
if (vector->Map().NumGlobalElements() != input_map.NumGlobalElements())
{
- Epetra_LocalMap map (input_map.NumGlobalElements(),
- input_map.IndexBase(),
- input_map.Comm());
- vector.reset (new Epetra_FEVector (map));
+ Epetra_LocalMap map (input_map.NumGlobalElements(),
+ input_map.IndexBase(),
+ input_map.Comm());
+ vector.reset (new Epetra_FEVector (map));
}
else if (fast == false)
{
- int ierr;
- ierr = vector->GlobalAssemble(last_action);
- Assert (ierr == 0, ExcTrilinosError(ierr));
+ int ierr;
+ ierr = vector->GlobalAssemble(last_action);
+ Assert (ierr == 0, ExcTrilinosError(ierr));
- ierr = vector->PutScalar(0.0);
- Assert (ierr == 0, ExcTrilinosError(ierr));
+ ierr = vector->PutScalar(0.0);
+ Assert (ierr == 0, ExcTrilinosError(ierr));
}
last_action = Zero;
void
Vector::reinit (const IndexSet &partitioning,
- const MPI_Comm &communicator,
+ const MPI_Comm &communicator,
const bool fast)
{
if (vector->Map().NumGlobalElements() !=
- static_cast<int>(partitioning.size()))
+ static_cast<int>(partitioning.size()))
{
- Epetra_LocalMap map (partitioning.size(),
- 0,
+ Epetra_LocalMap map (partitioning.size(),
+ 0,
#ifdef DEAL_II_COMPILER_SUPPORTS_MPI
- Epetra_MpiComm(communicator));
+ Epetra_MpiComm(communicator));
#else
Epetra_SerialComm());
(void)communicator;
#endif
- vector.reset (new Epetra_FEVector(map));
+ vector.reset (new Epetra_FEVector(map));
}
else if (fast == false)
{
- int ierr;
- ierr = vector->GlobalAssemble(last_action);
- Assert (ierr == 0, ExcTrilinosError(ierr));
+ int ierr;
+ ierr = vector->GlobalAssemble(last_action);
+ Assert (ierr == 0, ExcTrilinosError(ierr));
- ierr = vector->PutScalar(0.0);
- Assert (ierr == 0, ExcTrilinosError(ierr));
+ ierr = vector->PutScalar(0.0);
+ Assert (ierr == 0, ExcTrilinosError(ierr));
}
last_action = Zero;
void
Vector::reinit (const VectorBase &v,
- const bool fast,
- const bool allow_different_maps)
+ const bool fast,
+ const bool allow_different_maps)
{
- // In case we do not allow to
- // have different maps, this
- // call means that we have to
- // reset the vector. So clear
- // the vector, initialize our
- // map with the map in v, and
- // generate the vector.
+ // In case we do not allow to
+ // have different maps, this
+ // call means that we have to
+ // reset the vector. So clear
+ // the vector, initialize our
+ // map with the map in v, and
+ // generate the vector.
if (allow_different_maps == false)
{
- if (local_range() != v.local_range())
- {
- Epetra_LocalMap map (v.vector->GlobalLength(),
- v.vector->Map().IndexBase(),
- v.vector->Comm());
- vector.reset (new Epetra_FEVector(map));
- }
- else
- {
- int ierr;
- Assert (vector->Map().SameAs(v.vector->Map()) == true,
- ExcMessage ("The Epetra maps in the assignment operator ="
- " do not match, even though the local_range "
- " seems to be the same. Check vector setup!"));
-
- ierr = vector->GlobalAssemble(last_action);
- Assert (ierr == 0, ExcTrilinosError(ierr));
-
- ierr = vector->PutScalar(0.0);
- Assert (ierr == 0, ExcTrilinosError(ierr));
- }
- last_action = Zero;
+ if (local_range() != v.local_range())
+ {
+ Epetra_LocalMap map (v.vector->GlobalLength(),
+ v.vector->Map().IndexBase(),
+ v.vector->Comm());
+ vector.reset (new Epetra_FEVector(map));
+ }
+ else
+ {
+ int ierr;
+ Assert (vector->Map().SameAs(v.vector->Map()) == true,
+ ExcMessage ("The Epetra maps in the assignment operator ="
+ " do not match, even though the local_range "
+ " seems to be the same. Check vector setup!"));
+
+ ierr = vector->GlobalAssemble(last_action);
+ Assert (ierr == 0, ExcTrilinosError(ierr));
+
+ ierr = vector->PutScalar(0.0);
+ Assert (ierr == 0, ExcTrilinosError(ierr));
+ }
+ last_action = Zero;
}
- // Otherwise, we have to check
- // that the two vectors are
- // already of the same size,
- // create an object for the data
- // exchange and then insert all
- // the data.
+ // Otherwise, we have to check
+ // that the two vectors are
+ // already of the same size,
+ // create an object for the data
+ // exchange and then insert all
+ // the data.
else
{
- Assert (fast == false,
- ExcMessage ("It is not possible to exchange data with the "
- "option fast set, which would not write "
- "elements."));
+ Assert (fast == false,
+ ExcMessage ("It is not possible to exchange data with the "
+ "option fast set, which would not write "
+ "elements."));
- AssertThrow (size() == v.size(),
- ExcDimensionMismatch (size(), v.size()));
+ AssertThrow (size() == v.size(),
+ ExcDimensionMismatch (size(), v.size()));
- Epetra_Import data_exchange (vector->Map(), v.vector->Map());
+ Epetra_Import data_exchange (vector->Map(), v.vector->Map());
- const int ierr = vector->Import(*v.vector, data_exchange, Insert);
- AssertThrow (ierr == 0, ExcTrilinosError(ierr));
+ const int ierr = vector->Import(*v.vector, data_exchange, Insert);
+ AssertThrow (ierr == 0, ExcTrilinosError(ierr));
- last_action = Insert;
+ last_action = Insert;
}
}
{
if (size() != v.size())
{
- Epetra_LocalMap map (v.vector->Map().NumGlobalElements(),
- v.vector->Map().IndexBase(),
- v.vector->Comm());
- vector.reset (new Epetra_FEVector(map));
+ Epetra_LocalMap map (v.vector->Map().NumGlobalElements(),
+ v.vector->Map().IndexBase(),
+ v.vector->Comm());
+ vector.reset (new Epetra_FEVector(map));
}
reinit (v, false, true);
{
if (size() != v.size())
{
- Epetra_LocalMap map (v.vector->Map().NumGlobalElements(),
- v.vector->Map().IndexBase(),
- v.vector->Comm());
- vector.reset (new Epetra_FEVector(map));
+ Epetra_LocalMap map (v.vector->Map().NumGlobalElements(),
+ v.vector->Map().IndexBase(),
+ v.vector->Comm());
+ vector.reset (new Epetra_FEVector(map));
}
const int ierr = vector->Update(1.0, *v.vector, 0.0);
VectorReference::operator TrilinosScalar () const
{
Assert (index < vector.size(),
- ExcIndexRange (index, 0, vector.size()));
+ ExcIndexRange (index, 0, vector.size()));
// Trilinos allows for vectors
// to be referenced by the [] or
const int local_index = vector.vector->Map().LID(index);
Assert (local_index >= 0,
- ExcAccessToNonLocalElement (index,
- vector.vector->Map().MinMyGID(),
- vector.vector->Map().MaxMyGID()));
+ ExcAccessToNonLocalElement (index,
+ vector.vector->Map().MinMyGID(),
+ vector.vector->Map().MaxMyGID()));
return (*(vector.vector))[0][local_index];
VectorBase::VectorBase ()
:
last_action (Zero),
- compressed (true),
+ compressed (true),
#ifdef DEAL_II_COMPILER_SUPPORTS_MPI
- vector(new Epetra_FEVector(
- Epetra_Map(0,0,Epetra_MpiComm(MPI_COMM_SELF))))
+ vector(new Epetra_FEVector(
+ Epetra_Map(0,0,Epetra_MpiComm(MPI_COMM_SELF))))
#else
- vector(new Epetra_FEVector(
- Epetra_Map(0,0,Epetra_SerialComm())))
+ vector(new Epetra_FEVector(
+ Epetra_Map(0,0,Epetra_SerialComm())))
#endif
{}
VectorBase::VectorBase (const VectorBase &v)
:
- Subscriptor(),
- last_action (Zero),
- compressed (true),
- vector(new Epetra_FEVector(*v.vector))
+ Subscriptor(),
+ last_action (Zero),
+ compressed (true),
+ vector(new Epetra_FEVector(*v.vector))
{}
VectorBase::clear ()
{
// When we clear the vector,
- // reset the pointer and generate
- // an empty vector.
+ // reset the pointer and generate
+ // an empty vector.
#ifdef DEAL_II_COMPILER_SUPPORTS_MPI
Epetra_Map map (0, 0, Epetra_MpiComm(MPI_COMM_SELF));
#else
VectorBase::operator = (const VectorBase &v)
{
Assert (vector.get() != 0,
- ExcMessage("Vector is not constructed properly."));
+ ExcMessage("Vector is not constructed properly."));
if (local_range() != v.local_range())
{
- last_action = Zero;
- vector.reset (new Epetra_FEVector(*v.vector));
+ last_action = Zero;
+ vector.reset (new Epetra_FEVector(*v.vector));
}
else
{
- Assert (vector->Map().SameAs(v.vector->Map()) == true,
- ExcMessage ("The Epetra maps in the assignment operator ="
- " do not match, even though the local_range "
- " seems to be the same. Check vector setup!"));
- int ierr;
- ierr = vector->GlobalAssemble(last_action);
- AssertThrow (ierr == 0, ExcTrilinosError(ierr));
-
- ierr = vector->Update(1.0, *v.vector, 0.0);
- AssertThrow (ierr == 0, ExcTrilinosError(ierr));
-
- last_action = Zero;
+ Assert (vector->Map().SameAs(v.vector->Map()) == true,
+ ExcMessage ("The Epetra maps in the assignment operator ="
+ " do not match, even though the local_range "
+ " seems to be the same. Check vector setup!"));
+ int ierr;
+ ierr = vector->GlobalAssemble(last_action);
+ AssertThrow (ierr == 0, ExcTrilinosError(ierr));
+
+ ierr = vector->Update(1.0, *v.vector, 0.0);
+ AssertThrow (ierr == 0, ExcTrilinosError(ierr));
+
+ last_action = Zero;
}
return *this;
VectorBase::operator = (const ::dealii::Vector<number> &v)
{
Assert (size() == v.size(),
- ExcDimensionMismatch(size(), v.size()));
-
- // this is probably not very efficient
- // but works. in particular, we could do
- // better if we know that
- // number==TrilinosScalar because then we
- // could elide the copying of elements
- //
- // let's hope this isn't a
- // particularly frequent operation
+ ExcDimensionMismatch(size(), v.size()));
+
+ // this is probably not very efficient
+ // but works. in particular, we could do
+ // better if we know that
+ // number==TrilinosScalar because then we
+ // could elide the copying of elements
+ //
+ // let's hope this isn't a
+ // particularly frequent operation
std::pair<unsigned int, unsigned int>
local_range = this->local_range ();
for (unsigned int i=local_range.first; i<local_range.second; ++i)
int trilinos_i = vector->Map().LID(index);
TrilinosScalar value = 0.;
- // If the element is not
- // present on the current
- // processor, we can't
- // continue. Just print out 0.
+ // If the element is not
+ // present on the current
+ // processor, we can't
+ // continue. Just print out 0.
- // TODO: Is this reasonable?
+ // TODO: Is this reasonable?
if (trilinos_i == -1 )
{
- return 0.;
+ return 0.;
//Assert (false, ExcAccessToNonlocalElement(index, local_range().first,
- // local_range().second-1));
+ // local_range().second-1));
}
else
value = (*vector)[0][trilinos_i];
int trilinos_i = vector->Map().LID(index);
TrilinosScalar value = 0.;
- // If the element is not present
- // on the current processor, we
- // can't continue. This is the
- // main difference to the el()
- // function.
+ // If the element is not present
+ // on the current processor, we
+ // can't continue. This is the
+ // main difference to the el()
+ // function.
if (trilinos_i == -1 )
{
- Assert (false, ExcAccessToNonlocalElement(index, local_range().first,
- local_range().second-1));
+ Assert (false, ExcAccessToNonlocalElement(index, local_range().first,
+ local_range().second-1));
}
else
value = (*vector)[0][trilinos_i];
void
VectorBase::add (const VectorBase &v,
- const bool allow_different_maps)
+ const bool allow_different_maps)
{
if (allow_different_maps == false)
*this += v;
else
{
- AssertThrow (size() == v.size(),
- ExcDimensionMismatch (size(), v.size()));
+ AssertThrow (size() == v.size(),
+ ExcDimensionMismatch (size(), v.size()));
- Epetra_Import data_exchange (vector->Map(), v.vector->Map());
+ Epetra_Import data_exchange (vector->Map(), v.vector->Map());
- int ierr = vector->Import(*v.vector, data_exchange, Add);
- AssertThrow (ierr == 0, ExcTrilinosError(ierr));
+ int ierr = vector->Import(*v.vector, data_exchange, Add);
+ AssertThrow (ierr == 0, ExcTrilinosError(ierr));
- last_action = Insert;
+ last_action = Insert;
}
}
VectorBase::operator == (const VectorBase &v) const
{
Assert (size() == v.size(),
- ExcDimensionMismatch(size(), v.size()));
+ ExcDimensionMismatch(size(), v.size()));
if (local_size() != v.local_size())
return false;
VectorBase::operator != (const VectorBase &v) const
{
Assert (size() == v.size(),
- ExcDimensionMismatch(size(), v.size()));
+ ExcDimensionMismatch(size(), v.size()));
return (!(*this==v));
}
unsigned int flag = 0;
while (ptr != eptr)
{
- if (*ptr != 0)
- {
- flag = 1;
- break;
- }
- ++ptr;
+ if (*ptr != 0)
+ {
+ flag = 1;
+ break;
+ }
+ ++ptr;
}
#ifdef DEAL_II_COMPILER_SUPPORTS_MPI
- // in parallel, check that the vector
- // is zero on _all_ processors.
+ // in parallel, check that the vector
+ // is zero on _all_ processors.
const Epetra_MpiComm *mpi_comm
= dynamic_cast<const Epetra_MpiComm*>(&vector->Map().Comm());
unsigned int num_nonzero = Utilities::MPI::sum(flag, mpi_comm->Comm());
VectorBase::is_non_negative () const
{
#ifdef DEAL_II_COMPILER_SUPPORTS_MPI
- // if this vector is a parallel one, then
- // we need to communicate to determine
- // the answer to the current
- // function. this still has to be
- // implemented
+ // if this vector is a parallel one, then
+ // we need to communicate to determine
+ // the answer to the current
+ // function. this still has to be
+ // implemented
AssertThrow(local_size() == size(), ExcNotImplemented());
#endif
// get a representation of the vector and
int ierr = vector->ExtractView (&start_ptr, &leading_dimension);
AssertThrow (ierr == 0, ExcTrilinosError(ierr));
- // TODO: This
- // won't work in parallel like
- // this. Find out a better way to
- // this in that case.
+ // TODO: This
+ // won't work in parallel like
+ // this. Find out a better way to
+ // this in that case.
const TrilinosScalar *ptr = start_ptr,
*eptr = start_ptr + size();
bool flag = true;
while (ptr != eptr)
{
- if (*ptr < 0.0)
- {
- flag = false;
- break;
- }
- ++ptr;
+ if (*ptr < 0.0)
+ {
+ flag = false;
+ break;
+ }
+ ++ptr;
}
return flag;
- // TODO: up to now only local
+ // TODO: up to now only local
// data printed out! Find a
// way to neatly output
// distributed data...
for (unsigned int j=0; j<size(); ++j)
{
- double t = (*vector)[0][j];
+ double t = (*vector)[0][j];
- if (format != 0)
- std::printf (format, t);
- else
- std::printf (" %5.2f", double(t));
+ if (format != 0)
+ std::printf (format, t);
+ else
+ std::printf (" %5.2f", double(t));
}
std::printf ("\n");
}
void
VectorBase::print (std::ostream &out,
- const unsigned int precision,
- const bool scientific,
- const bool across) const
+ const unsigned int precision,
+ const bool scientific,
+ const bool across) const
{
AssertThrow (out, ExcIO());
if (across)
for (unsigned int i=0; i<size(); ++i)
- out << static_cast<double>(val[i]) << ' ';
+ out << static_cast<double>(val[i]) << ' ';
else
for (unsigned int i=0; i<size(); ++i)
- out << static_cast<double>(val[i]) << std::endl;
+ out << static_cast<double>(val[i]) << std::endl;
out << std::endl;
// restore the representation
std::size_t
VectorBase::memory_consumption () const
{
- //TODO[TH]: No accurate memory
- //consumption for Trilinos vectors
- //yet. This is a rough approximation with
- //one index and the value per local
- //entry.
+ //TODO[TH]: No accurate memory
+ //consumption for Trilinos vectors
+ //yet. This is a rough approximation with
+ //one index and the value per local
+ //entry.
return sizeof(*this)
+ this->local_size()*( sizeof(double)+sizeof(int) );
}
// $Id$
// Version: $Name$
//
-// Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by the deal.II authors
+// Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
// arguments is covered by the default copy constructor and copy operator that
// is declared separately)
-#define TEMPL_COPY_CONSTRUCTOR(S1,S2) \
+#define TEMPL_COPY_CONSTRUCTOR(S1,S2) \
template Vector<S1>::Vector (const Vector<S2> &)
#ifndef DEAL_II_EXPLICIT_CONSTRUCTOR_BUG
#define TEMPL_OP_EQ(S1,S2) \
- template void Vector<S1>::scale (const Vector<S2>&); \
+ template void Vector<S1>::scale (const Vector<S2>&); \
template void Vector<S1>::equ (const S1, const Vector<S2>&)
TEMPL_OP_EQ(double,float);
// $Id$
// Version: $Name$
//
-// Copyright (C) 2007, 2008, 2010, 2011 by the deal.II authors
+// Copyright (C) 2007, 2008, 2010, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
template <typename VECTOR>
inline
GrowingVectorMemory<VECTOR>::Pool::Pool()
- :
- data(0)
+ :
+ data(0)
{}
inline
GrowingVectorMemory<VECTOR>::Pool::~Pool()
{
- // Nothing to do if memory was unused.
+ // Nothing to do if memory was unused.
if (data == 0) return;
- // First, delete all remaining
- // vectors. Actually, there should
- // be none, if there is no memory
- // leak
+ // First, delete all remaining
+ // vectors. Actually, there should
+ // be none, if there is no memory
+ // leak
unsigned int n=0;
for (typename std::vector<entry_type>::iterator i=data->begin();
i != data->end();
++i)
{
if (i->first == true)
- ++n;
+ ++n;
delete i->second;
}
delete data;
data = new std::vector<entry_type>(size);
for (typename std::vector<entry_type>::iterator i= data->begin();
- i != data->end();
- ++i)
- {
- i->first = false;
- i->second = new VECTOR;
- }
+ i != data->end();
+ ++i)
+ {
+ i->first = false;
+ i->second = new VECTOR;
+ }
}
}
template <typename VECTOR>
inline
GrowingVectorMemory<VECTOR>::GrowingVectorMemory (const unsigned int initial_size,
- const bool log_statistics)
+ const bool log_statistics)
- :
- total_alloc(0),
- current_alloc(0),
- log_statistics(log_statistics)
+ :
+ total_alloc(0),
+ current_alloc(0),
+ log_statistics(log_statistics)
{
Threads::ThreadMutex::ScopedLock lock(mutex);
pool.initialize(initial_size);
GrowingVectorMemory<VECTOR>::~GrowingVectorMemory()
{
AssertThrow(current_alloc == 0,
- StandardExceptions::ExcMemoryLeak(current_alloc));
+ StandardExceptions::ExcMemoryLeak(current_alloc));
if (log_statistics)
{
deallog << "GrowingVectorMemory:Overall allocated vectors: "
- << total_alloc << std::endl;
+ << total_alloc << std::endl;
deallog << "GrowingVectorMemory:Maximum allocated vectors: "
- << pool.data->size() << std::endl;
+ << pool.data->size() << std::endl;
}
}
Threads::ThreadMutex::ScopedLock lock(mutex);
++total_alloc;
++current_alloc;
- // see if there is a free vector
- // available in our list
+ // see if there is a free vector
+ // available in our list
for (typename std::vector<entry_type>::iterator i=pool.data->begin();
i != pool.data->end(); ++i)
{
if (i->first == false)
- {
- i->first = true;
- return (i->second);
- }
+ {
+ i->first = true;
+ return (i->second);
+ }
}
- // no free vector found, so let's
- // just allocate a new one
+ // no free vector found, so let's
+ // just allocate a new one
const entry_type t (true, new VECTOR);
pool.data->push_back(t);
i != pool.data->end(); ++i)
{
if (v == (i->second))
- {
- i->first = false;
- --current_alloc;
- return;
- }
+ {
+ i->first = false;
+ --current_alloc;
+ return;
+ }
}
Assert(false, typename VectorMemory<VECTOR>::ExcNotAllocatedHere());
}
if (pool.data != 0)
{
const typename std::vector<entry_type>::const_iterator
- end = pool.data->end();
+ end = pool.data->end();
for (typename std::vector<entry_type>::const_iterator
- i = pool.data->begin(); i != end ; ++i)
- if (i->first == false)
- delete i->second;
- else
- new_data.push_back (*i);
+ i = pool.data->begin(); i != end ; ++i)
+ if (i->first == false)
+ delete i->second;
+ else
+ new_data.push_back (*i);
*pool.data = new_data;
}
// $Id$
// Version: $Name$
//
-// Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by the deal.II authors
+// Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
// $Id$
// Version: $Name$
//
-// Copyright (C) 1999, 2000, 2001, 2002, 2003, 2005, 2006, 2010 by the deal.II authors
+// Copyright (C) 1999, 2000, 2001, 2002, 2003, 2005, 2006, 2010, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
// $Id$
// Version: $Name$
//
-// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 by the deal.II authors
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
template <int structdim, int dim, int spacedim>
MGDoFAccessor<structdim, dim, spacedim>::MGDoFAccessor ()
- :
- BaseClass (0, -1, -1, 0)
+ :
+ BaseClass (0, -1, -1, 0)
{
Assert (false, ExcInvalidObject());
}
template <int structdim, int dim, int spacedim>
MGDoFAccessor<structdim, dim, spacedim>::MGDoFAccessor (const Triangulation<dim,spacedim> *tria,
- const int level,
- const int index,
- const AccessorData *local_data)
- :
- BaseClass (tria, level, index, local_data),
- mg_dof_handler (const_cast<MGDoFHandler<dim,spacedim>*>(local_data))
+ const int level,
+ const int index,
+ const AccessorData *local_data)
+ :
+ BaseClass (tria, level, index, local_data),
+ mg_dof_handler (const_cast<MGDoFHandler<dim,spacedim>*>(local_data))
{}
template <int structdim,int dim, int spacedim>
unsigned int
MGDoFAccessor<structdim, dim, spacedim>::mg_vertex_dof_index (const int level,
- const unsigned int vertex,
- const unsigned int i) const
+ const unsigned int vertex,
+ const unsigned int i) const
{
Assert (this->dof_handler != 0,
- typename BaseClass::ExcInvalidObject());
+ typename BaseClass::ExcInvalidObject());
Assert (this->mg_dof_handler != 0,
- typename BaseClass::ExcInvalidObject());
+ typename BaseClass::ExcInvalidObject());
Assert (&this->dof_handler->get_fe() != 0,
- typename BaseClass::ExcInvalidObject());
+ typename BaseClass::ExcInvalidObject());
Assert (vertex<GeometryInfo<structdim>::vertices_per_cell,
- ExcIndexRange (i,0,GeometryInfo<structdim>::vertices_per_cell));
+ ExcIndexRange (i,0,GeometryInfo<structdim>::vertices_per_cell));
Assert (i<this->dof_handler->get_fe().dofs_per_vertex,
- ExcIndexRange (i, 0, this->dof_handler->get_fe().dofs_per_vertex));
+ ExcIndexRange (i, 0, this->dof_handler->get_fe().dofs_per_vertex));
return (this->mg_dof_handler->mg_vertex_dofs[this->vertex_index(vertex)]
- .get_index (level, i, this->dof_handler->get_fe().dofs_per_vertex));
+ .get_index (level, i, this->dof_handler->get_fe().dofs_per_vertex));
}
template <int structdim, int dim, int spacedim>
void
MGDoFAccessor<structdim, dim, spacedim>::set_mg_vertex_dof_index (const int level,
- const unsigned int vertex,
- const unsigned int i,
- const unsigned int index) const
+ const unsigned int vertex,
+ const unsigned int i,
+ const unsigned int index) const
{
Assert (this->dof_handler != 0,
- typename BaseClass::ExcInvalidObject());
+ typename BaseClass::ExcInvalidObject());
Assert (this->mg_dof_handler != 0,
- typename BaseClass::ExcInvalidObject());
+ typename BaseClass::ExcInvalidObject());
Assert (&this->dof_handler->get_fe() != 0,
- typename BaseClass::ExcInvalidObject());
+ typename BaseClass::ExcInvalidObject());
Assert (vertex<GeometryInfo<structdim>::vertices_per_cell,
- ExcIndexRange (i,0,GeometryInfo<structdim>::vertices_per_cell));
+ ExcIndexRange (i,0,GeometryInfo<structdim>::vertices_per_cell));
Assert (i<this->dof_handler->get_fe().dofs_per_vertex,
- ExcIndexRange (i, 0, this->dof_handler->get_fe().dofs_per_vertex));
+ ExcIndexRange (i, 0, this->dof_handler->get_fe().dofs_per_vertex));
this->mg_dof_handler->mg_vertex_dofs[this->vertex_index(vertex)]
.set_index (level, i, this->dof_handler->get_fe().dofs_per_vertex, index);
template <int structdim, int dim, int spacedim>
unsigned int
MGDoFAccessor<structdim, dim, spacedim>::mg_dof_index (const int level,
- const unsigned int i) const
+ const unsigned int i) const
{
return this->mg_dof_handler
->template get_dof_index<structdim>(level,
- this->present_index,
- 0,
- i);
+ this->present_index,
+ 0,
+ i);
}
template <int structdim, int dim, int spacedim>
void MGDoFAccessor<structdim, dim, spacedim>::set_mg_dof_index (const int level,
- const unsigned int i,
- const unsigned int index) const
+ const unsigned int i,
+ const unsigned int index) const
{
this->mg_dof_handler
->template set_dof_index<structdim>(level,
- this->present_index,
- 0,
- i,
- index);
+ this->present_index,
+ 0,
+ i,
+ index);
}
const TriaIterator<MGDoFAccessor<structdim,dim,spacedim> >
q (this->tria,
(structdim == dim ?
- this->level() + 1 :
- 0),
+ this->level() + 1 :
+ 0),
this->child_index (i),
this->mg_dof_handler);
- // make sure that we either created
- // a past-the-end iterator or one
- // pointing to a used cell
+ // make sure that we either created
+ // a past-the-end iterator or one
+ // pointing to a used cell
Assert ((q.state() == IteratorState::past_the_end)
- ||
- q->used(),
- TriaAccessorExceptions::ExcUnusedCellAsChild());
+ ||
+ q->used(),
+ TriaAccessorExceptions::ExcUnusedCellAsChild());
return q;
}
const TriaIterator<MGDoFAccessor<structdim,dim,spacedim> >
q (this->tria,
(structdim == dim ?
- this->level() - 1 :
- 0),
+ this->level() - 1 :
+ 0),
this->parent_index (),
this->mg_dof_handler);
MGDoFAccessor<structdim,dim,spacedim>::line (const unsigned int i) const
{
Assert (structdim > 1, ExcImpossibleInDim(structdim));
- // checking of 'i' happens in
- // line_index(i)
+ // checking of 'i' happens in
+ // line_index(i)
return typename internal::MGDoFHandler::Iterators<dim,spacedim>::line_iterator
(
MGDoFAccessor<structdim,dim,spacedim>::quad (const unsigned int i) const
{
Assert (structdim > 2, ExcImpossibleInDim(structdim));
- // checking of 'i' happens in
- // quad_index(i)
+ // checking of 'i' happens in
+ // quad_index(i)
return typename internal::MGDoFHandler::Iterators<dim,spacedim>::quad_iterator
(
template <int dim, int spacedim>
void
get_mg_dof_indices (const dealii::MGDoFAccessor<1, dim, spacedim> &accessor,
- const int level,
- std::vector<unsigned int> &dof_indices)
+ const int level,
+ std::vector<unsigned int> &dof_indices)
{
const unsigned int dofs_per_vertex = accessor.get_dof_handler().get_fe().dofs_per_vertex,
- dofs_per_line = accessor.get_dof_handler().get_fe().dofs_per_line;
+ dofs_per_line = accessor.get_dof_handler().get_fe().dofs_per_line;
std::vector<unsigned int>::iterator next = dof_indices.begin();
for (unsigned int vertex=0; vertex<2; ++vertex)
- for (unsigned int d=0; d<dofs_per_vertex; ++d)
- *next++ = accessor.mg_vertex_dof_index(level,vertex,d);
+ for (unsigned int d=0; d<dofs_per_vertex; ++d)
+ *next++ = accessor.mg_vertex_dof_index(level,vertex,d);
for (unsigned int d=0; d<dofs_per_line; ++d)
- *next++ = accessor.mg_dof_index(level,d);
+ *next++ = accessor.mg_dof_index(level,d);
Assert (next == dof_indices.end(),
- ExcInternalError());
+ ExcInternalError());
}
template <int dim, int spacedim, typename number>
void
get_mg_dof_values (const dealii::MGDoFAccessor<1, dim, spacedim> &accessor,
- const int level,
- const dealii::Vector<number> &values,
- dealii::Vector<number> &dof_values)
+ const int level,
+ const dealii::Vector<number> &values,
+ dealii::Vector<number> &dof_values)
{
const unsigned int dofs_per_vertex = accessor.get_dof_handler().get_fe().dofs_per_vertex,
- dofs_per_line = accessor.get_dof_handler().get_fe().dofs_per_line;
+ dofs_per_line = accessor.get_dof_handler().get_fe().dofs_per_line;
typename dealii::Vector<number>::iterator next_dof_value=dof_values.begin();
for (unsigned int vertex=0; vertex<2; ++vertex)
- for (unsigned int d=0; d<dofs_per_vertex; ++d)
- *next_dof_value++ = values(accessor.mg_vertex_dof_index(level,vertex,d));
+ for (unsigned int d=0; d<dofs_per_vertex; ++d)
+ *next_dof_value++ = values(accessor.mg_vertex_dof_index(level,vertex,d));
for (unsigned int d=0; d<dofs_per_line; ++d)
- *next_dof_value++ = values(accessor.mg_dof_index(level,d));
+ *next_dof_value++ = values(accessor.mg_dof_index(level,d));
Assert (next_dof_value == dof_values.end(),
- ExcInternalError());
+ ExcInternalError());
}
template <int dim, int spacedim>
void
get_mg_dof_indices (const dealii::MGDoFAccessor<2, dim, spacedim> &accessor,
- const int level,
- std::vector<unsigned int> &dof_indices)
+ const int level,
+ std::vector<unsigned int> &dof_indices)
{
const unsigned int dofs_per_vertex = accessor.get_dof_handler().get_fe().dofs_per_vertex,
- dofs_per_line = accessor.get_dof_handler().get_fe().dofs_per_line,
- dofs_per_quad = accessor.get_dof_handler().get_fe().dofs_per_quad;
+ dofs_per_line = accessor.get_dof_handler().get_fe().dofs_per_line,
+ dofs_per_quad = accessor.get_dof_handler().get_fe().dofs_per_quad;
std::vector<unsigned int>::iterator next = dof_indices.begin();
for (unsigned int vertex=0; vertex<4; ++vertex)
- for (unsigned int d=0; d<dofs_per_vertex; ++d)
- *next++ = accessor.mg_vertex_dof_index(level,vertex,d);
+ for (unsigned int d=0; d<dofs_per_vertex; ++d)
+ *next++ = accessor.mg_vertex_dof_index(level,vertex,d);
for (unsigned int line=0; line<4; ++line)
- for (unsigned int d=0; d<dofs_per_line; ++d)
- *next++ = accessor.line(line)->mg_dof_index(level,d);
+ for (unsigned int d=0; d<dofs_per_line; ++d)
+ *next++ = accessor.line(line)->mg_dof_index(level,d);
for (unsigned int d=0; d<dofs_per_quad; ++d)
- *next++ = accessor.mg_dof_index(level,d);
+ *next++ = accessor.mg_dof_index(level,d);
Assert (next == dof_indices.end(),
- ExcInternalError());
+ ExcInternalError());
}
template <int dim, int spacedim, typename number>
void
get_mg_dof_values (const dealii::MGDoFAccessor<2, dim, spacedim> &accessor,
- const int level,
- const dealii::Vector<number> &values,
- dealii::Vector<number> &dof_values)
+ const int level,
+ const dealii::Vector<number> &values,
+ dealii::Vector<number> &dof_values)
{
const unsigned int dofs_per_vertex = accessor.get_dof_handler().get_fe().dofs_per_vertex,
- dofs_per_line = accessor.get_dof_handler().get_fe().dofs_per_line,
- dofs_per_quad = accessor.get_dof_handler().get_fe().dofs_per_quad;
+ dofs_per_line = accessor.get_dof_handler().get_fe().dofs_per_line,
+ dofs_per_quad = accessor.get_dof_handler().get_fe().dofs_per_quad;
typename dealii::Vector<number>::iterator next_dof_value=dof_values.begin();
for (unsigned int vertex=0; vertex<4; ++vertex)
- for (unsigned int d=0; d<dofs_per_vertex; ++d)
- *next_dof_value++ = values(accessor.mg_vertex_dof_index(level,vertex,d));
+ for (unsigned int d=0; d<dofs_per_vertex; ++d)
+ *next_dof_value++ = values(accessor.mg_vertex_dof_index(level,vertex,d));
for (unsigned int line=0; line<4; ++line)
- for (unsigned int d=0; d<dofs_per_line; ++d)
- *next_dof_value++ = values(accessor.line(line)->mg_dof_index(level,d));
+ for (unsigned int d=0; d<dofs_per_line; ++d)
+ *next_dof_value++ = values(accessor.line(line)->mg_dof_index(level,d));
for (unsigned int d=0; d<dofs_per_quad; ++d)
- *next_dof_value++ = values(accessor.mg_dof_index(level,d));
+ *next_dof_value++ = values(accessor.mg_dof_index(level,d));
Assert (next_dof_value == dof_values.end(),
- ExcInternalError());
+ ExcInternalError());
}
template <int dim, int spacedim>
void
get_mg_dof_indices (const dealii::MGDoFAccessor<3, dim, spacedim> &accessor,
- const int level,
- std::vector<unsigned int> &dof_indices)
+ const int level,
+ std::vector<unsigned int> &dof_indices)
{
const unsigned int dofs_per_vertex = accessor.get_dof_handler().get_fe().dofs_per_vertex,
- dofs_per_line = accessor.get_dof_handler().get_fe().dofs_per_line,
- dofs_per_quad = accessor.get_dof_handler().get_fe().dofs_per_quad,
- dofs_per_hex = accessor.get_dof_handler().get_fe().dofs_per_hex;
+ dofs_per_line = accessor.get_dof_handler().get_fe().dofs_per_line,
+ dofs_per_quad = accessor.get_dof_handler().get_fe().dofs_per_quad,
+ dofs_per_hex = accessor.get_dof_handler().get_fe().dofs_per_hex;
std::vector<unsigned int>::iterator next = dof_indices.begin();
for (unsigned int vertex=0; vertex<8; ++vertex)
- for (unsigned int d=0; d<dofs_per_vertex; ++d)
- *next++ = accessor.mg_vertex_dof_index(level,vertex,d);
+ for (unsigned int d=0; d<dofs_per_vertex; ++d)
+ *next++ = accessor.mg_vertex_dof_index(level,vertex,d);
for (unsigned int line=0; line<12; ++line)
- for (unsigned int d=0; d<dofs_per_line; ++d)
- *next++ = accessor.line(line)->mg_dof_index(level,d);
+ for (unsigned int d=0; d<dofs_per_line; ++d)
+ *next++ = accessor.line(line)->mg_dof_index(level,d);
for (unsigned int quad=0; quad<6; ++quad)
- for (unsigned int d=0; d<dofs_per_quad; ++d)
- *next++ = accessor.quad(quad)->mg_dof_index(level,d);
+ for (unsigned int d=0; d<dofs_per_quad; ++d)
+ *next++ = accessor.quad(quad)->mg_dof_index(level,d);
for (unsigned int d=0; d<dofs_per_hex; ++d)
- *next++ = accessor.mg_dof_index(level,d);
+ *next++ = accessor.mg_dof_index(level,d);
Assert (next == dof_indices.end(),
- ExcInternalError());
+ ExcInternalError());
}
template <int dim, int spacedim, typename number>
void
get_mg_dof_values (const dealii::MGDoFAccessor<3, dim, spacedim> &accessor,
- const int level,
- const dealii::Vector<number> &values,
- dealii::Vector<number> &dof_values)
+ const int level,
+ const dealii::Vector<number> &values,
+ dealii::Vector<number> &dof_values)
{
const unsigned int dofs_per_vertex = accessor.get_dof_handler().get_fe().dofs_per_vertex,
- dofs_per_line = accessor.get_dof_handler().get_fe().dofs_per_line,
- dofs_per_quad = accessor.get_dof_handler().get_fe().dofs_per_quad,
- dofs_per_hex = accessor.get_dof_handler().get_fe().dofs_per_hex;
+ dofs_per_line = accessor.get_dof_handler().get_fe().dofs_per_line,
+ dofs_per_quad = accessor.get_dof_handler().get_fe().dofs_per_quad,
+ dofs_per_hex = accessor.get_dof_handler().get_fe().dofs_per_hex;
typename dealii::Vector<number>::iterator next_dof_value=dof_values.begin();
for (unsigned int vertex=0; vertex<8; ++vertex)
- for (unsigned int d=0; d<dofs_per_vertex; ++d)
- *next_dof_value++ = values(accessor.mg_vertex_dof_index(level,vertex,d));
+ for (unsigned int d=0; d<dofs_per_vertex; ++d)
+ *next_dof_value++ = values(accessor.mg_vertex_dof_index(level,vertex,d));
for (unsigned int line=0; line<12; ++line)
- for (unsigned int d=0; d<dofs_per_line; ++d)
- *next_dof_value++ = values(accessor.line(line)->mg_dof_index(level,d));
+ for (unsigned int d=0; d<dofs_per_line; ++d)
+ *next_dof_value++ = values(accessor.line(line)->mg_dof_index(level,d));
for (unsigned int quad=0; quad<6; ++quad)
- for (unsigned int d=0; d<dofs_per_quad; ++d)
- *next_dof_value++ = values(accessor.quad(quad)->mg_dof_index(level,d));
+ for (unsigned int d=0; d<dofs_per_quad; ++d)
+ *next_dof_value++ = values(accessor.quad(quad)->mg_dof_index(level,d));
for (unsigned int d=0; d<dofs_per_hex; ++d)
- *next_dof_value++ = values(accessor.dof_index(d));
+ *next_dof_value++ = values(accessor.dof_index(d));
Assert (next_dof_value == dof_values.end(),
- ExcInternalError());
+ ExcInternalError());
}
}
}
void
MGDoFAccessor<structdim, dim, spacedim>::
get_mg_dof_indices (const int level,
- std::vector<unsigned int> &dof_indices) const
+ std::vector<unsigned int> &dof_indices) const
{
Assert (this->dof_handler != 0,
- ExcInvalidObject());
+ ExcInvalidObject());
Assert (this->mg_dof_handler != 0,
- ExcInvalidObject());
+ ExcInvalidObject());
Assert (&this->dof_handler->get_fe() != 0,
- ExcInvalidObject());
+ ExcInvalidObject());
switch (structdim)
{
case 1:
- Assert (dof_indices.size() ==
- (2*this->dof_handler->get_fe().dofs_per_vertex +
- this->dof_handler->get_fe().dofs_per_line),
- typename BaseClass::ExcVectorDoesNotMatch());
- break;
+ Assert (dof_indices.size() ==
+ (2*this->dof_handler->get_fe().dofs_per_vertex +
+ this->dof_handler->get_fe().dofs_per_line),
+ typename BaseClass::ExcVectorDoesNotMatch());
+ break;
case 2:
- Assert (dof_indices.size() ==
- (4*this->dof_handler->get_fe().dofs_per_vertex +
- 4*this->dof_handler->get_fe().dofs_per_line +
- this->dof_handler->get_fe().dofs_per_quad),
- typename BaseClass::ExcVectorDoesNotMatch());
- break;
+ Assert (dof_indices.size() ==
+ (4*this->dof_handler->get_fe().dofs_per_vertex +
+ 4*this->dof_handler->get_fe().dofs_per_line +
+ this->dof_handler->get_fe().dofs_per_quad),
+ typename BaseClass::ExcVectorDoesNotMatch());
+ break;
case 3:
- Assert (dof_indices.size() ==
- (8*this->dof_handler->get_fe().dofs_per_vertex +
- 12*this->dof_handler->get_fe().dofs_per_line +
- 6*this->dof_handler->get_fe().dofs_per_quad +
- this->dof_handler->get_fe().dofs_per_hex),
- typename BaseClass::ExcVectorDoesNotMatch());
-
- break;
+ Assert (dof_indices.size() ==
+ (8*this->dof_handler->get_fe().dofs_per_vertex +
+ 12*this->dof_handler->get_fe().dofs_per_line +
+ 6*this->dof_handler->get_fe().dofs_per_quad +
+ this->dof_handler->get_fe().dofs_per_hex),
+ typename BaseClass::ExcVectorDoesNotMatch());
+
+ break;
default:
- Assert (false, ExcNotImplemented());
+ Assert (false, ExcNotImplemented());
}
internal::MGDoFAccessor::get_mg_dof_indices (*this, level, dof_indices);
void
MGDoFAccessor<structdim,dim,spacedim>::
get_mg_dof_values (const int level,
- const Vector<number> &values,
- Vector<number> &dof_values) const
+ const Vector<number> &values,
+ Vector<number> &dof_values) const
{
Assert (this->dof_handler != 0,
- typename BaseClass::ExcInvalidObject());
+ typename BaseClass::ExcInvalidObject());
Assert (this->mg_dof_handler != 0,
- typename BaseClass::ExcInvalidObject());
+ typename BaseClass::ExcInvalidObject());
Assert (&this->dof_handler->get_fe() != 0,
- typename BaseClass::ExcInvalidObject());
+ typename BaseClass::ExcInvalidObject());
Assert (dof_values.size() == this->dof_handler->get_fe().dofs_per_cell,
- typename BaseClass::ExcVectorDoesNotMatch());
+ typename BaseClass::ExcVectorDoesNotMatch());
Assert (values.size() == this->mg_dof_handler->n_dofs(level),
- typename BaseClass::ExcVectorDoesNotMatch());
+ typename BaseClass::ExcVectorDoesNotMatch());
internal::MGDoFAccessor::get_mg_dof_values (*this, level, values, dof_values);
}
template <int spacedim>
MGDoFAccessor<0,1,spacedim>::MGDoFAccessor ()
- :
- BaseClass ()
+ :
+ BaseClass ()
{
Assert (false, typename BaseClass::ExcInvalidObject());
}
template <int spacedim>
MGDoFAccessor<0,1,spacedim>::
MGDoFAccessor (const Triangulation<1,spacedim> *tria,
- const typename TriaAccessor<0,1,spacedim>::VertexKind vertex_kind,
- const unsigned int vertex_index,
- const MGDoFHandler<1,spacedim> * dof_handler)
- :
- BaseClass (tria,
- vertex_kind,
- vertex_index),
+ const typename TriaAccessor<0,1,spacedim>::VertexKind vertex_kind,
+ const unsigned int vertex_index,
+ const MGDoFHandler<1,spacedim> * dof_handler)
+ :
+ BaseClass (tria,
+ vertex_kind,
+ vertex_index),
mg_dof_handler(const_cast<MGDoFHandler<1,spacedim>*>(dof_handler))
{}
template <int spacedim>
MGDoFAccessor<0,1,spacedim>::
MGDoFAccessor (const Triangulation<1,spacedim> *,
- const int ,
- const int ,
- const MGDoFHandler<1,spacedim> *)
- :
+ const int ,
+ const int ,
+ const MGDoFHandler<1,spacedim> *)
+ :
mg_dof_handler(0)
{
Assert (false,
- ExcMessage ("This constructor can not be called for face iterators in 1d."));
+ ExcMessage ("This constructor can not be called for face iterators in 1d."));
}
template <int dim, int spacedim>
MGDoFCellAccessor<dim,spacedim>::MGDoFCellAccessor (const Triangulation<dim,spacedim> *tria,
- const int level,
- const int index,
- const AccessorData *local_data)
- :
- MGDoFAccessor<dim, dim, spacedim> (tria,level,index,local_data)
+ const int level,
+ const int index,
+ const AccessorData *local_data)
+ :
+ MGDoFAccessor<dim, dim, spacedim> (tria,level,index,local_data)
{}
template <typename number>
void
MGDoFCellAccessor<dim,spacedim>::get_mg_dof_values (const Vector<number> &values,
- Vector<number> &dof_values) const
+ Vector<number> &dof_values) const
{
MGDoFAccessor<dim,dim,spacedim>::get_mg_dof_values (this->level(), values, dof_values);
}
MGDoFCellAccessor<dim,spacedim>::neighbor (const unsigned int i) const
{
TriaIterator<MGDoFCellAccessor<dim,spacedim> > q (this->tria,
- this->neighbor_level (i),
- this->neighbor_index (i),
- this->mg_dof_handler);
+ this->neighbor_level (i),
+ this->neighbor_index (i),
+ this->mg_dof_handler);
#ifdef DEBUG
if (q.state() != IteratorState::past_the_end)
MGDoFCellAccessor<dim,spacedim>::child (const unsigned int i) const
{
TriaIterator<MGDoFCellAccessor<dim,spacedim> > q (this->tria,
- this->present_level+1,
- this->child_index (i),
- this->mg_dof_handler);
+ this->present_level+1,
+ this->child_index (i),
+ this->mg_dof_handler);
#ifdef DEBUG
if (q.state() != IteratorState::past_the_end)
{
const TriaIterator<MGDoFCellAccessor<dim,spacedim> >
q (this->tria,
- this->level() - 1,
+ this->level() - 1,
this->parent_index (),
this->mg_dof_handler);
inline
typename internal::MGDoFHandler::Iterators<1,spacedim>::face_iterator
get_face (const dealii::MGDoFCellAccessor<1,spacedim> &cell,
- const unsigned int i,
- const internal::int2type<1>)
+ const unsigned int i,
+ const internal::int2type<1>)
{
dealii::MGDoFAccessor<0,1,spacedim>
- a (&cell.get_triangulation(),
- ((i == 0) && cell.at_boundary(0)
- ?
- dealii::TriaAccessor<0, 1, spacedim>::left_vertex
- :
- ((i == 1) && cell.at_boundary(1)
- ?
- dealii::TriaAccessor<0, 1, spacedim>::right_vertex
- :
- dealii::TriaAccessor<0, 1, spacedim>::interior_vertex)),
- cell.vertex_index(i),
- &cell.get_mg_dof_handler());
+ a (&cell.get_triangulation(),
+ ((i == 0) && cell.at_boundary(0)
+ ?
+ dealii::TriaAccessor<0, 1, spacedim>::left_vertex
+ :
+ ((i == 1) && cell.at_boundary(1)
+ ?
+ dealii::TriaAccessor<0, 1, spacedim>::right_vertex
+ :
+ dealii::TriaAccessor<0, 1, spacedim>::interior_vertex)),
+ cell.vertex_index(i),
+ &cell.get_mg_dof_handler());
return typename internal::MGDoFHandler::Iterators<1,spacedim>::face_iterator(a);
}
inline
typename internal::MGDoFHandler::Iterators<2,spacedim>::face_iterator
get_face (const dealii::MGDoFCellAccessor<2,spacedim> &cell,
- const unsigned int i,
- const internal::int2type<2>)
+ const unsigned int i,
+ const internal::int2type<2>)
{
return cell.line(i);
}
inline
typename internal::MGDoFHandler::Iterators<3,spacedim>::face_iterator
get_face (const dealii::MGDoFCellAccessor<3,spacedim> &cell,
- const unsigned int i,
- const internal::int2type<3>)
+ const unsigned int i,
+ const internal::int2type<3>)
{
return cell.quad(i);
}
const TriaIterator<CellAccessor<dim,spacedim> > q
= CellAccessor<dim,spacedim>::neighbor_child_on_subface (face, subface);
return TriaIterator<MGDoFCellAccessor<dim,spacedim> > (this->tria,
- q->level (),
- q->index (),
- this->mg_dof_handler);
+ q->level (),
+ q->index (),
+ this->mg_dof_handler);
}
// $Id$
// Version: $Name$
//
-// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2010, 2011 by the deal.II authors
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2010, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
{
namespace MGDoFHandler
{
- // access class
- // dealii::MGDoFHandler instead
- // of namespace
- // internal::MGDoFHandler. same
- // for dealii::DoFHandler
+ // access class
+ // dealii::MGDoFHandler instead
+ // of namespace
+ // internal::MGDoFHandler. same
+ // for dealii::DoFHandler
using dealii::MGDoFHandler;
using dealii::DoFHandler;
struct Implementation
{
- /**
- * Distribute dofs on the given
- * cell, with new dofs starting
- * with index
- * @p next_free_dof. Return the
- * next unused index number.
- *
- * This function is excluded from
- * the @p distribute_dofs
- * function since it can not be
- * implemented dimension
- * independent.
- *
- * Note that unlike for the usual
- * dofs, here all cells and not
- * only active ones are allowed.
- */
- template <int spacedim>
- static
- unsigned int
- distribute_dofs_on_cell (typename MGDoFHandler<1,spacedim>::cell_iterator &cell,
- unsigned int next_free_dof)
- {
- const unsigned int dim = 1;
-
- // distribute dofs of vertices
- if (cell->get_fe().dofs_per_vertex > 0)
- for (unsigned int v=0; v<GeometryInfo<1>::vertices_per_cell; ++v)
- {
- typename MGDoFHandler<dim,spacedim>::cell_iterator neighbor = cell->neighbor(v);
-
- if (neighbor.state() == IteratorState::valid)
- {
- // has neighbor already been processed?
- if (neighbor->user_flag_set() &&
- (neighbor->level() == cell->level()))
- // copy dofs if the neighbor is on
- // the same level (only then are
- // mg dofs the same)
- {
- if (v==0)
- for (unsigned int d=0; d<cell->get_fe().dofs_per_vertex; ++d)
- cell->set_mg_vertex_dof_index (cell->level(), 0, d,
- neighbor->mg_vertex_dof_index (cell->level(), 1, d));
- else
- for (unsigned int d=0; d<cell->get_fe().dofs_per_vertex; ++d)
- cell->set_mg_vertex_dof_index (cell->level(), 1, d,
- neighbor->mg_vertex_dof_index (cell->level(), 0, d));
-
- // next neighbor
- continue;
- };
- };
-
- // otherwise: create dofs newly
- for (unsigned int d=0; d<cell->get_fe().dofs_per_vertex; ++d)
- cell->set_mg_vertex_dof_index (cell->level(), v, d, next_free_dof++);
- };
-
- // dofs of line
- if (cell->get_fe().dofs_per_line > 0)
- for (unsigned int d=0; d<cell->get_fe().dofs_per_line; ++d)
- cell->set_mg_dof_index (cell->level(), d, next_free_dof++);
-
- // note that this cell has been processed
- cell->set_user_flag ();
-
- return next_free_dof;
- }
-
-
- template <int spacedim>
- static
- unsigned int
- distribute_dofs_on_cell (typename MGDoFHandler<2,spacedim>::cell_iterator &cell,
- unsigned int next_free_dof)
- {
- const unsigned int dim = 2;
- if (cell->get_fe().dofs_per_vertex > 0)
- // number dofs on vertices
- for (unsigned int vertex=0; vertex<GeometryInfo<2>::vertices_per_cell; ++vertex)
- // check whether dofs for this
- // vertex have been distributed
- // (only check the first dof)
- if (cell->mg_vertex_dof_index(cell->level(), vertex, 0) == DoFHandler<2>::invalid_dof_index)
- for (unsigned int d=0; d<cell->get_fe().dofs_per_vertex; ++d)
- cell->set_mg_vertex_dof_index (cell->level(), vertex, d, next_free_dof++);
-
- // for the four sides
- if (cell->get_fe().dofs_per_line > 0)
- for (unsigned int side=0; side<GeometryInfo<2>::faces_per_cell; ++side)
- {
- typename MGDoFHandler<dim,spacedim>::line_iterator line = cell->line(side);
-
- // distribute dofs if necessary:
- // check whether line dof is already
- // numbered (check only first dof)
- if (line->mg_dof_index(cell->level(), 0) == DoFHandler<2>::invalid_dof_index)
- // if not: distribute dofs
- for (unsigned int d=0; d<cell->get_fe().dofs_per_line; ++d)
- line->set_mg_dof_index (cell->level(), d, next_free_dof++);
- };
-
-
- // dofs of quad
- if (cell->get_fe().dofs_per_quad > 0)
- for (unsigned int d=0; d<cell->get_fe().dofs_per_quad; ++d)
- cell->set_mg_dof_index (cell->level(), d, next_free_dof++);
-
-
- // note that this cell has been processed
- cell->set_user_flag ();
-
- return next_free_dof;
- }
-
-
- template <int spacedim>
- static
- unsigned int
- distribute_dofs_on_cell (typename MGDoFHandler<3,spacedim>::cell_iterator &cell,
- unsigned int next_free_dof)
- {
- const unsigned int dim = 3;
- if (cell->get_fe().dofs_per_vertex > 0)
- // number dofs on vertices
- for (unsigned int vertex=0; vertex<GeometryInfo<3>::vertices_per_cell; ++vertex)
- // check whether dofs for this
- // vertex have been distributed
- // (only check the first dof)
- if (cell->mg_vertex_dof_index(cell->level(), vertex, 0) == DoFHandler<3>::invalid_dof_index)
- for (unsigned int d=0; d<cell->get_fe().dofs_per_vertex; ++d)
- cell->set_mg_vertex_dof_index (cell->level(), vertex, d, next_free_dof++);
-
- // for the lines
- if (cell->get_fe().dofs_per_line > 0)
- for (unsigned int l=0; l<GeometryInfo<3>::lines_per_cell; ++l)
- {
- typename MGDoFHandler<dim,spacedim>::line_iterator line = cell->line(l);
-
- // distribute dofs if necessary:
- // check whether line dof is already
- // numbered (check only first dof)
- if (line->mg_dof_index(cell->level(), 0) == DoFHandler<3>::invalid_dof_index)
- // if not: distribute dofs
- for (unsigned int d=0; d<cell->get_fe().dofs_per_line; ++d)
- line->set_mg_dof_index (cell->level(), d, next_free_dof++);
- };
-
- // for the quads
- if (cell->get_fe().dofs_per_quad > 0)
- for (unsigned int q=0; q<GeometryInfo<3>::quads_per_cell; ++q)
- {
- typename MGDoFHandler<dim,spacedim>::quad_iterator quad = cell->quad(q);
-
- // distribute dofs if necessary:
- // check whether line dof is already
- // numbered (check only first dof)
- if (quad->mg_dof_index(cell->level(), 0) == DoFHandler<3>::invalid_dof_index)
- // if not: distribute dofs
- for (unsigned int d=0; d<cell->get_fe().dofs_per_quad; ++d)
- quad->set_mg_dof_index (cell->level(), d, next_free_dof++);
- };
-
-
- // dofs of cell
- if (cell->get_fe().dofs_per_hex > 0)
- for (unsigned int d=0; d<cell->get_fe().dofs_per_hex; ++d)
- cell->set_mg_dof_index (cell->level(), d, next_free_dof++);
-
-
- // note that this cell has
- // been processed
- cell->set_user_flag ();
-
- return next_free_dof;
- }
-
-
-
- template <int spacedim>
- static
- unsigned int
- get_dof_index (const MGDoFHandler<1,spacedim> &mg_dof_handler,
- const internal::DoFHandler::DoFLevel<1> &mg_level,
- const internal::DoFHandler::DoFFaces<1> &,
- const unsigned int obj_index,
- const unsigned int fe_index,
- const unsigned int local_index,
- const int2type<1>)
- {
- return mg_level.lines.
- get_dof_index (mg_dof_handler,
- obj_index,
- fe_index,
- local_index);
- }
-
-
- template <int spacedim>
- static
- void
- set_dof_index (const MGDoFHandler<1,spacedim> &mg_dof_handler,
- internal::DoFHandler::DoFLevel<1> &mg_level,
- internal::DoFHandler::DoFFaces<1> &,
- const unsigned int obj_index,
- const unsigned int fe_index,
- const unsigned int local_index,
- const unsigned int global_index,
- const int2type<1>)
- {
- mg_level.lines.
- set_dof_index (mg_dof_handler,
- obj_index,
- fe_index,
- local_index,
- global_index);
-
- }
-
-
- template <int spacedim>
- static
- unsigned int
- get_dof_index(const MGDoFHandler<2,spacedim> &mg_dof_handler,
- const internal::DoFHandler::DoFLevel<2> &,
- const internal::DoFHandler::DoFFaces<2> &mg_faces,
- const unsigned int obj_index,
- const unsigned int fe_index,
- const unsigned int local_index,
- const int2type<1>)
- {
- return mg_faces.lines.
- get_dof_index (mg_dof_handler,
- obj_index,
- fe_index,
- local_index);
- }
-
-
- template <int spacedim>
- static
- void
- set_dof_index (const MGDoFHandler<2,spacedim> &mg_dof_handler,
- internal::DoFHandler::DoFLevel<2> &,
- internal::DoFHandler::DoFFaces<2> &mg_faces,
- const unsigned int obj_index,
- const unsigned int fe_index,
- const unsigned int local_index,
- const unsigned int global_index,
- const int2type<1>)
- {
- mg_faces.lines.
- set_dof_index (mg_dof_handler,
- obj_index,
- fe_index,
- local_index,
- global_index);
-
- }
-
-
- template <int spacedim>
- static
- unsigned int
- get_dof_index (const MGDoFHandler<2,spacedim> &mg_dof_handler,
- const internal::DoFHandler::DoFLevel<2> &mg_level,
- const internal::DoFHandler::DoFFaces<2> &,
- const unsigned int obj_index,
- const unsigned int fe_index,
- const unsigned int local_index,
- const int2type<2>)
- {
- return mg_level.quads.
- get_dof_index (mg_dof_handler,
- obj_index,
- fe_index,
- local_index);
- }
-
-
- template <int spacedim>
- static
- void
- set_dof_index (const MGDoFHandler<2,spacedim> &mg_dof_handler,
- internal::DoFHandler::DoFLevel<2> &mg_level,
- internal::DoFHandler::DoFFaces<2> &,
- const unsigned int obj_index,
- const unsigned int fe_index,
- const unsigned int local_index,
- const unsigned int global_index,
- const int2type<2>)
- {
- mg_level.quads.
- set_dof_index (mg_dof_handler,
- obj_index,
- fe_index,
- local_index,
- global_index);
-
- }
-
-
- template <int spacedim>
- static
- unsigned int
- get_dof_index (const MGDoFHandler<3,spacedim> &mg_dof_handler,
- const internal::DoFHandler::DoFLevel<3> &,
- const internal::DoFHandler::DoFFaces<3> &mg_faces,
- const unsigned int obj_index,
- const unsigned int fe_index,
- const unsigned int local_index,
- const int2type<1>)
- {
- return mg_faces.lines.
- get_dof_index (mg_dof_handler,
- obj_index,
- fe_index,
- local_index);
- }
-
-
- template <int spacedim>
- static
- void
- set_dof_index (const MGDoFHandler<3,spacedim> &mg_dof_handler,
- internal::DoFHandler::DoFLevel<3> &,
- internal::DoFHandler::DoFFaces<3> &mg_faces,
- const unsigned int obj_index,
- const unsigned int fe_index,
- const unsigned int local_index,
- const unsigned int global_index,
- const int2type<1>)
- {
- mg_faces.lines.
- set_dof_index (mg_dof_handler,
- obj_index,
- fe_index,
- local_index,
- global_index);
-
- }
-
-
- template <int spacedim>
- static
- unsigned int
- get_dof_index (const MGDoFHandler<3,spacedim> &mg_dof_handler,
- const internal::DoFHandler::DoFLevel<3> &,
- const internal::DoFHandler::DoFFaces<3> &mg_faces,
- const unsigned int obj_index,
- const unsigned int fe_index,
- const unsigned int local_index,
- const int2type<2>)
- {
- return mg_faces.quads.
- get_dof_index (mg_dof_handler,
- obj_index,
- fe_index,
- local_index);
- }
-
-
- template <int spacedim>
- static
- unsigned int
- get_dof_index (const MGDoFHandler<3,spacedim> &mg_dof_handler,
- const internal::DoFHandler::DoFLevel<3> &mg_level,
- const internal::DoFHandler::DoFFaces<3> &,
- const unsigned int obj_index,
- const unsigned int fe_index,
- const unsigned int local_index,
- const int2type<3>)
- {
- return mg_level.hexes.
- get_dof_index (mg_dof_handler,
- obj_index,
- fe_index,
- local_index);
- }
-
-
- template <int spacedim>
- static
- void
- set_dof_index (const MGDoFHandler<3,spacedim> &mg_dof_handler,
- internal::DoFHandler::DoFLevel<3> &,
- internal::DoFHandler::DoFFaces<3> &mg_faces,
- const unsigned int obj_index,
- const unsigned int fe_index,
- const unsigned int local_index,
- const unsigned int global_index,
- const int2type<2>)
- {
- mg_faces.quads.
- set_dof_index (mg_dof_handler,
- obj_index,
- fe_index,
- local_index,
- global_index);
-
- }
-
-
- template <int spacedim>
- static
- void
- set_dof_index (const MGDoFHandler<3,spacedim> &mg_dof_handler,
- internal::DoFHandler::DoFLevel<3> &mg_level,
- internal::DoFHandler::DoFFaces<3> &,
- const unsigned int obj_index,
- const unsigned int fe_index,
- const unsigned int local_index,
- const unsigned int global_index,
- const int2type<3>)
- {
- mg_level.hexes.
- set_dof_index (mg_dof_handler,
- obj_index,
- fe_index,
- local_index,
- global_index);
-
- }
-
-
-
-
- template <int spacedim>
- static
- void reserve_space (MGDoFHandler<1,spacedim> &mg_dof_handler)
- {
- const unsigned int dim = 1;
-
- Assert (mg_dof_handler.get_tria().n_levels() > 0,
- ExcMessage("Invalid triangulation"));
-
- //////////////////////////
- // DESTRUCTION
- mg_dof_handler.clear_space ();
-
- ////////////////////////////
- // CONSTRUCTION
-
- // first allocate space for the
- // lines on each level
- for (unsigned int i=0; i<mg_dof_handler.get_tria().n_levels(); ++i)
- {
- mg_dof_handler.mg_levels.push_back (new internal::DoFHandler::DoFLevel<1>);
-
- mg_dof_handler.mg_levels.back()->lines.dofs = std::vector<unsigned int>(mg_dof_handler.get_tria().n_raw_lines(i) *
- mg_dof_handler.get_fe().dofs_per_line,
- DoFHandler<1>::invalid_dof_index);
- }
-
- // now allocate space for the
- // vertices. To this end, we need
- // to construct as many objects as
- // there are vertices and let them
- // allocate enough space for their
- // vertex indices on the levels they
- // live on. We need therefore to
- // count to how many levels a cell
- // belongs to, which we do by looping
- // over all cells and storing the
- // maximum and minimum level each
- // vertex we pass by belongs to
- mg_dof_handler.mg_vertex_dofs.resize (mg_dof_handler.get_tria().n_vertices());
-
- std::vector<unsigned int> min_level (mg_dof_handler.get_tria().n_vertices(), mg_dof_handler.get_tria().n_levels());
- std::vector<unsigned int> max_level (mg_dof_handler.get_tria().n_vertices(), 0);
-
- typename dealii::Triangulation<dim,spacedim>::cell_iterator cell = mg_dof_handler.get_tria().begin(),
- endc = mg_dof_handler.get_tria().end();
- for (; cell!=endc; ++cell)
- for (unsigned int vertex=0; vertex<GeometryInfo<dim>::vertices_per_cell;
- ++vertex)
- {
- const unsigned int vertex_index = cell->vertex_index(vertex);
- if (min_level[vertex_index] > static_cast<unsigned int>(cell->level()))
- min_level[vertex_index] = cell->level();
- if (max_level[vertex_index] < static_cast<unsigned int>(cell->level()))
- max_level[vertex_index] = cell->level();
- }
-
- // now allocate the needed space
- for (unsigned int vertex=0; vertex<mg_dof_handler.get_tria().n_vertices(); ++vertex)
- if (mg_dof_handler.get_tria().vertex_used(vertex))
- {
- Assert (min_level[vertex] < mg_dof_handler.get_tria().n_levels(), ExcInternalError());
- Assert (max_level[vertex] >= min_level[vertex], ExcInternalError());
-
- mg_dof_handler.mg_vertex_dofs[vertex].init (min_level[vertex],
- max_level[vertex],
- mg_dof_handler.get_fe().dofs_per_vertex);
- }
- else
- {
- Assert (min_level[vertex] == mg_dof_handler.get_tria().n_levels(), ExcInternalError());
- Assert (max_level[vertex] == 0, ExcInternalError());
-
- // reset to original state
- mg_dof_handler.mg_vertex_dofs[vertex].init (1, 0, 0);
- }
- }
-
-
-
- template <int spacedim>
- static
- void reserve_space (MGDoFHandler<2,spacedim> &mg_dof_handler)
- {
- const unsigned int dim = 2;
- Assert (mg_dof_handler.get_tria().n_levels() > 0,
- ExcMessage("Invalid triangulation"));
-
- ////////////////////////////
- // DESTRUCTION
- mg_dof_handler.clear_space ();
-
- ////////////////////////////
- // CONSTRUCTION
-
- // first allocate space for the
- // lines and quads on each level
- for (unsigned int i=0; i<mg_dof_handler.get_tria().n_levels(); ++i)
- {
- mg_dof_handler.mg_levels.push_back (new internal::DoFHandler::DoFLevel<2>);
-
- mg_dof_handler.mg_levels.back()->quads.dofs = std::vector<unsigned int> (mg_dof_handler.get_tria().n_raw_quads(i) *
- mg_dof_handler.get_fe().dofs_per_quad,
- DoFHandler<2>::invalid_dof_index);
- }
-
- mg_dof_handler.mg_faces = new internal::DoFHandler::DoFFaces<2>;
- mg_dof_handler.mg_faces->lines.dofs = std::vector<unsigned int> (mg_dof_handler.get_tria().n_raw_lines() *
- mg_dof_handler.get_fe().dofs_per_line,
- DoFHandler<2>::invalid_dof_index);
-
-
- // now allocate space for the
- // vertices. To this end, we need
- // to construct as many objects as
- // there are vertices and let them
- // allocate enough space for their
- // vertex indices on the levels they
- // live on. We need therefore to
- // count to how many levels a cell
- // belongs to, which we do by looping
- // over all cells and storing the
- // maximum and minimum level each
- // vertex we pass by belongs to
- mg_dof_handler.mg_vertex_dofs.resize (mg_dof_handler.get_tria().n_vertices());
-
- // initialize these arrays with
- // invalid values (min>max)
- std::vector<unsigned int> min_level (mg_dof_handler.get_tria().n_vertices(),
- mg_dof_handler.get_tria().n_levels());
- std::vector<unsigned int> max_level (mg_dof_handler.get_tria().n_vertices(), 0);
-
- typename dealii::Triangulation<dim,spacedim>::cell_iterator cell = mg_dof_handler.get_tria().begin(),
- endc = mg_dof_handler.get_tria().end();
- for (; cell!=endc; ++cell)
- for (unsigned int vertex=0; vertex<GeometryInfo<dim>::vertices_per_cell;
- ++vertex)
- {
- const unsigned int vertex_index = cell->vertex_index(vertex);
- if (min_level[vertex_index] > static_cast<unsigned int>(cell->level()))
- min_level[vertex_index] = cell->level();
- if (max_level[vertex_index] < static_cast<unsigned int>(cell->level()))
- max_level[vertex_index] = cell->level();
- }
-
-
- // now allocate the needed space
- for (unsigned int vertex=0; vertex<mg_dof_handler.get_tria().n_vertices(); ++vertex)
- if (mg_dof_handler.get_tria().vertex_used(vertex))
- {
- Assert (min_level[vertex] < mg_dof_handler.get_tria().n_levels(), ExcInternalError());
- Assert (max_level[vertex] >= min_level[vertex], ExcInternalError());
-
- mg_dof_handler.mg_vertex_dofs[vertex].init (min_level[vertex],
- max_level[vertex],
- mg_dof_handler.get_fe().dofs_per_vertex);
- }
- else
- {
- Assert (min_level[vertex] == mg_dof_handler.get_tria().n_levels(), ExcInternalError());
- Assert (max_level[vertex] == 0, ExcInternalError());
-
- // reset to original state
- mg_dof_handler.mg_vertex_dofs[vertex].init (1, 0, 0);
- }
- }
-
-
-
- template <int spacedim>
- static
- void reserve_space (MGDoFHandler<3,spacedim> &mg_dof_handler)
- {
- const unsigned int dim = 3;
-
- Assert (mg_dof_handler.get_tria().n_levels() > 0,
- ExcMessage("Invalid triangulation"));
-
- ////////////////////////////
- // DESTRUCTION
- mg_dof_handler.clear_space ();
-
- ////////////////////////////
- // CONSTRUCTION
-
- // first allocate space for the
- // lines and quads on each level
- for (unsigned int i=0; i<mg_dof_handler.get_tria().n_levels(); ++i)
- {
- mg_dof_handler.mg_levels.push_back (new internal::DoFHandler::DoFLevel<3>);
-
- mg_dof_handler.mg_levels.back()->hexes.dofs
- = std::vector<unsigned int> (mg_dof_handler.get_tria().n_raw_hexs(i) *
- mg_dof_handler.get_fe().dofs_per_hex,
- DoFHandler<3>::invalid_dof_index);
- }
- mg_dof_handler.mg_faces = new internal::DoFHandler::DoFFaces<3>;
- mg_dof_handler.mg_faces->lines.dofs = std::vector<unsigned int> (mg_dof_handler.get_tria().n_raw_lines() *
- mg_dof_handler.get_fe().dofs_per_line,
- DoFHandler<3>::invalid_dof_index);
- mg_dof_handler.mg_faces->quads.dofs = std::vector<unsigned int> (mg_dof_handler.get_tria().n_raw_quads() *
- mg_dof_handler.get_fe().dofs_per_quad,
- DoFHandler<3>::invalid_dof_index);
-
-
- // now allocate space for the
- // vertices. To this end, we need
- // to construct as many objects as
- // there are vertices and let them
- // allocate enough space for their
- // vertex indices on the levels they
- // live on. We need therefore to
- // count to how many levels a cell
- // belongs to, which we do by looping
- // over all cells and storing the
- // maximum and minimum level each
- // vertex we pass by belongs to
- mg_dof_handler.mg_vertex_dofs.resize (mg_dof_handler.get_tria().n_vertices());
-
- std::vector<unsigned int> min_level (mg_dof_handler.get_tria().n_vertices(), mg_dof_handler.get_tria().n_levels());
- std::vector<unsigned int> max_level (mg_dof_handler.get_tria().n_vertices(), 0);
-
- typename dealii::Triangulation<dim,spacedim>::cell_iterator cell = mg_dof_handler.get_tria().begin(),
- endc = mg_dof_handler.get_tria().end();
- for (; cell!=endc; ++cell)
- for (unsigned int vertex=0; vertex<GeometryInfo<dim>::vertices_per_cell;
- ++vertex)
- {
- const unsigned int vertex_index = cell->vertex_index(vertex);
- if (min_level[vertex_index] > static_cast<unsigned int>(cell->level()))
- min_level[vertex_index] = cell->level();
- if (max_level[vertex_index] < static_cast<unsigned int>(cell->level()))
- max_level[vertex_index] = cell->level();
- }
-
-
- // now allocate the needed space
- for (unsigned int vertex=0; vertex<mg_dof_handler.get_tria().n_vertices(); ++vertex)
- if (mg_dof_handler.get_tria().vertex_used(vertex))
- {
- Assert (min_level[vertex] < mg_dof_handler.get_tria().n_levels(), ExcInternalError());
- Assert (max_level[vertex] >= min_level[vertex], ExcInternalError());
-
- mg_dof_handler.mg_vertex_dofs[vertex].init (min_level[vertex],
- max_level[vertex],
- mg_dof_handler.get_fe().dofs_per_vertex);
- }
- else
- {
- Assert (min_level[vertex] == mg_dof_handler.get_tria().n_levels(), ExcInternalError());
- Assert (max_level[vertex] == 0, ExcInternalError());
-
- // reset to original state
- mg_dof_handler.mg_vertex_dofs[vertex].init (1, 0, 0);
- }
- }
+ /**
+ * Distribute dofs on the given
+ * cell, with new dofs starting
+ * with index
+ * @p next_free_dof. Return the
+ * next unused index number.
+ *
+ * This function is excluded from
+ * the @p distribute_dofs
+ * function since it can not be
+ * implemented dimension
+ * independent.
+ *
+ * Note that unlike for the usual
+ * dofs, here all cells and not
+ * only active ones are allowed.
+ */
+ template <int spacedim>
+ static
+ unsigned int
+ distribute_dofs_on_cell (typename MGDoFHandler<1,spacedim>::cell_iterator &cell,
+ unsigned int next_free_dof)
+ {
+ const unsigned int dim = 1;
+
+ // distribute dofs of vertices
+ if (cell->get_fe().dofs_per_vertex > 0)
+ for (unsigned int v=0; v<GeometryInfo<1>::vertices_per_cell; ++v)
+ {
+ typename MGDoFHandler<dim,spacedim>::cell_iterator neighbor = cell->neighbor(v);
+
+ if (neighbor.state() == IteratorState::valid)
+ {
+ // has neighbor already been processed?
+ if (neighbor->user_flag_set() &&
+ (neighbor->level() == cell->level()))
+ // copy dofs if the neighbor is on
+ // the same level (only then are
+ // mg dofs the same)
+ {
+ if (v==0)
+ for (unsigned int d=0; d<cell->get_fe().dofs_per_vertex; ++d)
+ cell->set_mg_vertex_dof_index (cell->level(), 0, d,
+ neighbor->mg_vertex_dof_index (cell->level(), 1, d));
+ else
+ for (unsigned int d=0; d<cell->get_fe().dofs_per_vertex; ++d)
+ cell->set_mg_vertex_dof_index (cell->level(), 1, d,
+ neighbor->mg_vertex_dof_index (cell->level(), 0, d));
+
+ // next neighbor
+ continue;
+ };
+ };
+
+ // otherwise: create dofs newly
+ for (unsigned int d=0; d<cell->get_fe().dofs_per_vertex; ++d)
+ cell->set_mg_vertex_dof_index (cell->level(), v, d, next_free_dof++);
+ };
+
+ // dofs of line
+ if (cell->get_fe().dofs_per_line > 0)
+ for (unsigned int d=0; d<cell->get_fe().dofs_per_line; ++d)
+ cell->set_mg_dof_index (cell->level(), d, next_free_dof++);
+
+ // note that this cell has been processed
+ cell->set_user_flag ();
+
+ return next_free_dof;
+ }
+
+
+ template <int spacedim>
+ static
+ unsigned int
+ distribute_dofs_on_cell (typename MGDoFHandler<2,spacedim>::cell_iterator &cell,
+ unsigned int next_free_dof)
+ {
+ const unsigned int dim = 2;
+ if (cell->get_fe().dofs_per_vertex > 0)
+ // number dofs on vertices
+ for (unsigned int vertex=0; vertex<GeometryInfo<2>::vertices_per_cell; ++vertex)
+ // check whether dofs for this
+ // vertex have been distributed
+ // (only check the first dof)
+ if (cell->mg_vertex_dof_index(cell->level(), vertex, 0) == DoFHandler<2>::invalid_dof_index)
+ for (unsigned int d=0; d<cell->get_fe().dofs_per_vertex; ++d)
+ cell->set_mg_vertex_dof_index (cell->level(), vertex, d, next_free_dof++);
+
+ // for the four sides
+ if (cell->get_fe().dofs_per_line > 0)
+ for (unsigned int side=0; side<GeometryInfo<2>::faces_per_cell; ++side)
+ {
+ typename MGDoFHandler<dim,spacedim>::line_iterator line = cell->line(side);
+
+ // distribute dofs if necessary:
+ // check whether line dof is already
+ // numbered (check only first dof)
+ if (line->mg_dof_index(cell->level(), 0) == DoFHandler<2>::invalid_dof_index)
+ // if not: distribute dofs
+ for (unsigned int d=0; d<cell->get_fe().dofs_per_line; ++d)
+ line->set_mg_dof_index (cell->level(), d, next_free_dof++);
+ };
+
+
+ // dofs of quad
+ if (cell->get_fe().dofs_per_quad > 0)
+ for (unsigned int d=0; d<cell->get_fe().dofs_per_quad; ++d)
+ cell->set_mg_dof_index (cell->level(), d, next_free_dof++);
+
+
+ // note that this cell has been processed
+ cell->set_user_flag ();
+
+ return next_free_dof;
+ }
+
+
+ template <int spacedim>
+ static
+ unsigned int
+ distribute_dofs_on_cell (typename MGDoFHandler<3,spacedim>::cell_iterator &cell,
+ unsigned int next_free_dof)
+ {
+ const unsigned int dim = 3;
+ if (cell->get_fe().dofs_per_vertex > 0)
+ // number dofs on vertices
+ for (unsigned int vertex=0; vertex<GeometryInfo<3>::vertices_per_cell; ++vertex)
+ // check whether dofs for this
+ // vertex have been distributed
+ // (only check the first dof)
+ if (cell->mg_vertex_dof_index(cell->level(), vertex, 0) == DoFHandler<3>::invalid_dof_index)
+ for (unsigned int d=0; d<cell->get_fe().dofs_per_vertex; ++d)
+ cell->set_mg_vertex_dof_index (cell->level(), vertex, d, next_free_dof++);
+
+ // for the lines
+ if (cell->get_fe().dofs_per_line > 0)
+ for (unsigned int l=0; l<GeometryInfo<3>::lines_per_cell; ++l)
+ {
+ typename MGDoFHandler<dim,spacedim>::line_iterator line = cell->line(l);
+
+ // distribute dofs if necessary:
+ // check whether line dof is already
+ // numbered (check only first dof)
+ if (line->mg_dof_index(cell->level(), 0) == DoFHandler<3>::invalid_dof_index)
+ // if not: distribute dofs
+ for (unsigned int d=0; d<cell->get_fe().dofs_per_line; ++d)
+ line->set_mg_dof_index (cell->level(), d, next_free_dof++);
+ };
+
+ // for the quads
+ if (cell->get_fe().dofs_per_quad > 0)
+ for (unsigned int q=0; q<GeometryInfo<3>::quads_per_cell; ++q)
+ {
+ typename MGDoFHandler<dim,spacedim>::quad_iterator quad = cell->quad(q);
+
+ // distribute dofs if necessary:
+ // check whether line dof is already
+ // numbered (check only first dof)
+ if (quad->mg_dof_index(cell->level(), 0) == DoFHandler<3>::invalid_dof_index)
+ // if not: distribute dofs
+ for (unsigned int d=0; d<cell->get_fe().dofs_per_quad; ++d)
+ quad->set_mg_dof_index (cell->level(), d, next_free_dof++);
+ };
+
+
+ // dofs of cell
+ if (cell->get_fe().dofs_per_hex > 0)
+ for (unsigned int d=0; d<cell->get_fe().dofs_per_hex; ++d)
+ cell->set_mg_dof_index (cell->level(), d, next_free_dof++);
+
+
+ // note that this cell has
+ // been processed
+ cell->set_user_flag ();
+
+ return next_free_dof;
+ }
+
+
+
+ template <int spacedim>
+ static
+ unsigned int
+ get_dof_index (const MGDoFHandler<1,spacedim> &mg_dof_handler,
+ const internal::DoFHandler::DoFLevel<1> &mg_level,
+ const internal::DoFHandler::DoFFaces<1> &,
+ const unsigned int obj_index,
+ const unsigned int fe_index,
+ const unsigned int local_index,
+ const int2type<1>)
+ {
+ return mg_level.lines.
+ get_dof_index (mg_dof_handler,
+ obj_index,
+ fe_index,
+ local_index);
+ }
+
+
+ template <int spacedim>
+ static
+ void
+ set_dof_index (const MGDoFHandler<1,spacedim> &mg_dof_handler,
+ internal::DoFHandler::DoFLevel<1> &mg_level,
+ internal::DoFHandler::DoFFaces<1> &,
+ const unsigned int obj_index,
+ const unsigned int fe_index,
+ const unsigned int local_index,
+ const unsigned int global_index,
+ const int2type<1>)
+ {
+ mg_level.lines.
+ set_dof_index (mg_dof_handler,
+ obj_index,
+ fe_index,
+ local_index,
+ global_index);
+
+ }
+
+
+ template <int spacedim>
+ static
+ unsigned int
+ get_dof_index(const MGDoFHandler<2,spacedim> &mg_dof_handler,
+ const internal::DoFHandler::DoFLevel<2> &,
+ const internal::DoFHandler::DoFFaces<2> &mg_faces,
+ const unsigned int obj_index,
+ const unsigned int fe_index,
+ const unsigned int local_index,
+ const int2type<1>)
+ {
+ return mg_faces.lines.
+ get_dof_index (mg_dof_handler,
+ obj_index,
+ fe_index,
+ local_index);
+ }
+
+
+ template <int spacedim>
+ static
+ void
+ set_dof_index (const MGDoFHandler<2,spacedim> &mg_dof_handler,
+ internal::DoFHandler::DoFLevel<2> &,
+ internal::DoFHandler::DoFFaces<2> &mg_faces,
+ const unsigned int obj_index,
+ const unsigned int fe_index,
+ const unsigned int local_index,
+ const unsigned int global_index,
+ const int2type<1>)
+ {
+ mg_faces.lines.
+ set_dof_index (mg_dof_handler,
+ obj_index,
+ fe_index,
+ local_index,
+ global_index);
+
+ }
+
+
+ template <int spacedim>
+ static
+ unsigned int
+ get_dof_index (const MGDoFHandler<2,spacedim> &mg_dof_handler,
+ const internal::DoFHandler::DoFLevel<2> &mg_level,
+ const internal::DoFHandler::DoFFaces<2> &,
+ const unsigned int obj_index,
+ const unsigned int fe_index,
+ const unsigned int local_index,
+ const int2type<2>)
+ {
+ return mg_level.quads.
+ get_dof_index (mg_dof_handler,
+ obj_index,
+ fe_index,
+ local_index);
+ }
+
+
+ template <int spacedim>
+ static
+ void
+ set_dof_index (const MGDoFHandler<2,spacedim> &mg_dof_handler,
+ internal::DoFHandler::DoFLevel<2> &mg_level,
+ internal::DoFHandler::DoFFaces<2> &,
+ const unsigned int obj_index,
+ const unsigned int fe_index,
+ const unsigned int local_index,
+ const unsigned int global_index,
+ const int2type<2>)
+ {
+ mg_level.quads.
+ set_dof_index (mg_dof_handler,
+ obj_index,
+ fe_index,
+ local_index,
+ global_index);
+
+ }
+
+
+ template <int spacedim>
+ static
+ unsigned int
+ get_dof_index (const MGDoFHandler<3,spacedim> &mg_dof_handler,
+ const internal::DoFHandler::DoFLevel<3> &,
+ const internal::DoFHandler::DoFFaces<3> &mg_faces,
+ const unsigned int obj_index,
+ const unsigned int fe_index,
+ const unsigned int local_index,
+ const int2type<1>)
+ {
+ return mg_faces.lines.
+ get_dof_index (mg_dof_handler,
+ obj_index,
+ fe_index,
+ local_index);
+ }
+
+
+ template <int spacedim>
+ static
+ void
+ set_dof_index (const MGDoFHandler<3,spacedim> &mg_dof_handler,
+ internal::DoFHandler::DoFLevel<3> &,
+ internal::DoFHandler::DoFFaces<3> &mg_faces,
+ const unsigned int obj_index,
+ const unsigned int fe_index,
+ const unsigned int local_index,
+ const unsigned int global_index,
+ const int2type<1>)
+ {
+ mg_faces.lines.
+ set_dof_index (mg_dof_handler,
+ obj_index,
+ fe_index,
+ local_index,
+ global_index);
+
+ }
+
+
+ template <int spacedim>
+ static
+ unsigned int
+ get_dof_index (const MGDoFHandler<3,spacedim> &mg_dof_handler,
+ const internal::DoFHandler::DoFLevel<3> &,
+ const internal::DoFHandler::DoFFaces<3> &mg_faces,
+ const unsigned int obj_index,
+ const unsigned int fe_index,
+ const unsigned int local_index,
+ const int2type<2>)
+ {
+ return mg_faces.quads.
+ get_dof_index (mg_dof_handler,
+ obj_index,
+ fe_index,
+ local_index);
+ }
+
+
+ template <int spacedim>
+ static
+ unsigned int
+ get_dof_index (const MGDoFHandler<3,spacedim> &mg_dof_handler,
+ const internal::DoFHandler::DoFLevel<3> &mg_level,
+ const internal::DoFHandler::DoFFaces<3> &,
+ const unsigned int obj_index,
+ const unsigned int fe_index,
+ const unsigned int local_index,
+ const int2type<3>)
+ {
+ return mg_level.hexes.
+ get_dof_index (mg_dof_handler,
+ obj_index,
+ fe_index,
+ local_index);
+ }
+
+
+ template <int spacedim>
+ static
+ void
+ set_dof_index (const MGDoFHandler<3,spacedim> &mg_dof_handler,
+ internal::DoFHandler::DoFLevel<3> &,
+ internal::DoFHandler::DoFFaces<3> &mg_faces,
+ const unsigned int obj_index,
+ const unsigned int fe_index,
+ const unsigned int local_index,
+ const unsigned int global_index,
+ const int2type<2>)
+ {
+ mg_faces.quads.
+ set_dof_index (mg_dof_handler,
+ obj_index,
+ fe_index,
+ local_index,
+ global_index);
+
+ }
+
+
+ template <int spacedim>
+ static
+ void
+ set_dof_index (const MGDoFHandler<3,spacedim> &mg_dof_handler,
+ internal::DoFHandler::DoFLevel<3> &mg_level,
+ internal::DoFHandler::DoFFaces<3> &,
+ const unsigned int obj_index,
+ const unsigned int fe_index,
+ const unsigned int local_index,
+ const unsigned int global_index,
+ const int2type<3>)
+ {
+ mg_level.hexes.
+ set_dof_index (mg_dof_handler,
+ obj_index,
+ fe_index,
+ local_index,
+ global_index);
+
+ }
+
+
+
+
+ template <int spacedim>
+ static
+ void reserve_space (MGDoFHandler<1,spacedim> &mg_dof_handler)
+ {
+ const unsigned int dim = 1;
+
+ Assert (mg_dof_handler.get_tria().n_levels() > 0,
+ ExcMessage("Invalid triangulation"));
+
+ //////////////////////////
+ // DESTRUCTION
+ mg_dof_handler.clear_space ();
+
+ ////////////////////////////
+ // CONSTRUCTION
+
+ // first allocate space for the
+ // lines on each level
+ for (unsigned int i=0; i<mg_dof_handler.get_tria().n_levels(); ++i)
+ {
+ mg_dof_handler.mg_levels.push_back (new internal::DoFHandler::DoFLevel<1>);
+
+ mg_dof_handler.mg_levels.back()->lines.dofs = std::vector<unsigned int>(mg_dof_handler.get_tria().n_raw_lines(i) *
+ mg_dof_handler.get_fe().dofs_per_line,
+ DoFHandler<1>::invalid_dof_index);
+ }
+
+ // now allocate space for the
+ // vertices. To this end, we need
+ // to construct as many objects as
+ // there are vertices and let them
+ // allocate enough space for their
+ // vertex indices on the levels they
+ // live on. We need therefore to
+ // count to how many levels a cell
+ // belongs to, which we do by looping
+ // over all cells and storing the
+ // maximum and minimum level each
+ // vertex we pass by belongs to
+ mg_dof_handler.mg_vertex_dofs.resize (mg_dof_handler.get_tria().n_vertices());
+
+ std::vector<unsigned int> min_level (mg_dof_handler.get_tria().n_vertices(), mg_dof_handler.get_tria().n_levels());
+ std::vector<unsigned int> max_level (mg_dof_handler.get_tria().n_vertices(), 0);
+
+ typename dealii::Triangulation<dim,spacedim>::cell_iterator cell = mg_dof_handler.get_tria().begin(),
+ endc = mg_dof_handler.get_tria().end();
+ for (; cell!=endc; ++cell)
+ for (unsigned int vertex=0; vertex<GeometryInfo<dim>::vertices_per_cell;
+ ++vertex)
+ {
+ const unsigned int vertex_index = cell->vertex_index(vertex);
+ if (min_level[vertex_index] > static_cast<unsigned int>(cell->level()))
+ min_level[vertex_index] = cell->level();
+ if (max_level[vertex_index] < static_cast<unsigned int>(cell->level()))
+ max_level[vertex_index] = cell->level();
+ }
+
+ // now allocate the needed space
+ for (unsigned int vertex=0; vertex<mg_dof_handler.get_tria().n_vertices(); ++vertex)
+ if (mg_dof_handler.get_tria().vertex_used(vertex))
+ {
+ Assert (min_level[vertex] < mg_dof_handler.get_tria().n_levels(), ExcInternalError());
+ Assert (max_level[vertex] >= min_level[vertex], ExcInternalError());
+
+ mg_dof_handler.mg_vertex_dofs[vertex].init (min_level[vertex],
+ max_level[vertex],
+ mg_dof_handler.get_fe().dofs_per_vertex);
+ }
+ else
+ {
+ Assert (min_level[vertex] == mg_dof_handler.get_tria().n_levels(), ExcInternalError());
+ Assert (max_level[vertex] == 0, ExcInternalError());
+
+ // reset to original state
+ mg_dof_handler.mg_vertex_dofs[vertex].init (1, 0, 0);
+ }
+ }
+
+
+
+ template <int spacedim>
+ static
+ void reserve_space (MGDoFHandler<2,spacedim> &mg_dof_handler)
+ {
+ const unsigned int dim = 2;
+ Assert (mg_dof_handler.get_tria().n_levels() > 0,
+ ExcMessage("Invalid triangulation"));
+
+ ////////////////////////////
+ // DESTRUCTION
+ mg_dof_handler.clear_space ();
+
+ ////////////////////////////
+ // CONSTRUCTION
+
+ // first allocate space for the
+ // lines and quads on each level
+ for (unsigned int i=0; i<mg_dof_handler.get_tria().n_levels(); ++i)
+ {
+ mg_dof_handler.mg_levels.push_back (new internal::DoFHandler::DoFLevel<2>);
+
+ mg_dof_handler.mg_levels.back()->quads.dofs = std::vector<unsigned int> (mg_dof_handler.get_tria().n_raw_quads(i) *
+ mg_dof_handler.get_fe().dofs_per_quad,
+ DoFHandler<2>::invalid_dof_index);
+ }
+
+ mg_dof_handler.mg_faces = new internal::DoFHandler::DoFFaces<2>;
+ mg_dof_handler.mg_faces->lines.dofs = std::vector<unsigned int> (mg_dof_handler.get_tria().n_raw_lines() *
+ mg_dof_handler.get_fe().dofs_per_line,
+ DoFHandler<2>::invalid_dof_index);
+
+
+ // now allocate space for the
+ // vertices. To this end, we need
+ // to construct as many objects as
+ // there are vertices and let them
+ // allocate enough space for their
+ // vertex indices on the levels they
+ // live on. We need therefore to
+ // count to how many levels a cell
+ // belongs to, which we do by looping
+ // over all cells and storing the
+ // maximum and minimum level each
+ // vertex we pass by belongs to
+ mg_dof_handler.mg_vertex_dofs.resize (mg_dof_handler.get_tria().n_vertices());
+
+ // initialize these arrays with
+ // invalid values (min>max)
+ std::vector<unsigned int> min_level (mg_dof_handler.get_tria().n_vertices(),
+ mg_dof_handler.get_tria().n_levels());
+ std::vector<unsigned int> max_level (mg_dof_handler.get_tria().n_vertices(), 0);
+
+ typename dealii::Triangulation<dim,spacedim>::cell_iterator cell = mg_dof_handler.get_tria().begin(),
+ endc = mg_dof_handler.get_tria().end();
+ for (; cell!=endc; ++cell)
+ for (unsigned int vertex=0; vertex<GeometryInfo<dim>::vertices_per_cell;
+ ++vertex)
+ {
+ const unsigned int vertex_index = cell->vertex_index(vertex);
+ if (min_level[vertex_index] > static_cast<unsigned int>(cell->level()))
+ min_level[vertex_index] = cell->level();
+ if (max_level[vertex_index] < static_cast<unsigned int>(cell->level()))
+ max_level[vertex_index] = cell->level();
+ }
+
+
+ // now allocate the needed space
+ for (unsigned int vertex=0; vertex<mg_dof_handler.get_tria().n_vertices(); ++vertex)
+ if (mg_dof_handler.get_tria().vertex_used(vertex))
+ {
+ Assert (min_level[vertex] < mg_dof_handler.get_tria().n_levels(), ExcInternalError());
+ Assert (max_level[vertex] >= min_level[vertex], ExcInternalError());
+
+ mg_dof_handler.mg_vertex_dofs[vertex].init (min_level[vertex],
+ max_level[vertex],
+ mg_dof_handler.get_fe().dofs_per_vertex);
+ }
+ else
+ {
+ Assert (min_level[vertex] == mg_dof_handler.get_tria().n_levels(), ExcInternalError());
+ Assert (max_level[vertex] == 0, ExcInternalError());
+
+ // reset to original state
+ mg_dof_handler.mg_vertex_dofs[vertex].init (1, 0, 0);
+ }
+ }
+
+
+
+ template <int spacedim>
+ static
+ void reserve_space (MGDoFHandler<3,spacedim> &mg_dof_handler)
+ {
+ const unsigned int dim = 3;
+
+ Assert (mg_dof_handler.get_tria().n_levels() > 0,
+ ExcMessage("Invalid triangulation"));
+
+ ////////////////////////////
+ // DESTRUCTION
+ mg_dof_handler.clear_space ();
+
+ ////////////////////////////
+ // CONSTRUCTION
+
+ // first allocate space for the
+ // lines and quads on each level
+ for (unsigned int i=0; i<mg_dof_handler.get_tria().n_levels(); ++i)
+ {
+ mg_dof_handler.mg_levels.push_back (new internal::DoFHandler::DoFLevel<3>);
+
+ mg_dof_handler.mg_levels.back()->hexes.dofs
+ = std::vector<unsigned int> (mg_dof_handler.get_tria().n_raw_hexs(i) *
+ mg_dof_handler.get_fe().dofs_per_hex,
+ DoFHandler<3>::invalid_dof_index);
+ }
+ mg_dof_handler.mg_faces = new internal::DoFHandler::DoFFaces<3>;
+ mg_dof_handler.mg_faces->lines.dofs = std::vector<unsigned int> (mg_dof_handler.get_tria().n_raw_lines() *
+ mg_dof_handler.get_fe().dofs_per_line,
+ DoFHandler<3>::invalid_dof_index);
+ mg_dof_handler.mg_faces->quads.dofs = std::vector<unsigned int> (mg_dof_handler.get_tria().n_raw_quads() *
+ mg_dof_handler.get_fe().dofs_per_quad,
+ DoFHandler<3>::invalid_dof_index);
+
+
+ // now allocate space for the
+ // vertices. To this end, we need
+ // to construct as many objects as
+ // there are vertices and let them
+ // allocate enough space for their
+ // vertex indices on the levels they
+ // live on. We need therefore to
+ // count to how many levels a cell
+ // belongs to, which we do by looping
+ // over all cells and storing the
+ // maximum and minimum level each
+ // vertex we pass by belongs to
+ mg_dof_handler.mg_vertex_dofs.resize (mg_dof_handler.get_tria().n_vertices());
+
+ std::vector<unsigned int> min_level (mg_dof_handler.get_tria().n_vertices(), mg_dof_handler.get_tria().n_levels());
+ std::vector<unsigned int> max_level (mg_dof_handler.get_tria().n_vertices(), 0);
+
+ typename dealii::Triangulation<dim,spacedim>::cell_iterator cell = mg_dof_handler.get_tria().begin(),
+ endc = mg_dof_handler.get_tria().end();
+ for (; cell!=endc; ++cell)
+ for (unsigned int vertex=0; vertex<GeometryInfo<dim>::vertices_per_cell;
+ ++vertex)
+ {
+ const unsigned int vertex_index = cell->vertex_index(vertex);
+ if (min_level[vertex_index] > static_cast<unsigned int>(cell->level()))
+ min_level[vertex_index] = cell->level();
+ if (max_level[vertex_index] < static_cast<unsigned int>(cell->level()))
+ max_level[vertex_index] = cell->level();
+ }
+
+
+ // now allocate the needed space
+ for (unsigned int vertex=0; vertex<mg_dof_handler.get_tria().n_vertices(); ++vertex)
+ if (mg_dof_handler.get_tria().vertex_used(vertex))
+ {
+ Assert (min_level[vertex] < mg_dof_handler.get_tria().n_levels(), ExcInternalError());
+ Assert (max_level[vertex] >= min_level[vertex], ExcInternalError());
+
+ mg_dof_handler.mg_vertex_dofs[vertex].init (min_level[vertex],
+ max_level[vertex],
+ mg_dof_handler.get_fe().dofs_per_vertex);
+ }
+ else
+ {
+ Assert (min_level[vertex] == mg_dof_handler.get_tria().n_levels(), ExcInternalError());
+ Assert (max_level[vertex] == 0, ExcInternalError());
+
+ // reset to original state
+ mg_dof_handler.mg_vertex_dofs[vertex].init (1, 0, 0);
+ }
+ }
};
template <int dim, int spacedim>
MGDoFHandler<dim,spacedim>::MGVertexDoFs::MGVertexDoFs ()
- :
- coarsest_level (numbers::invalid_unsigned_int),
- finest_level (0),
- indices (0)
+ :
+ coarsest_level (numbers::invalid_unsigned_int),
+ finest_level (0),
+ indices (0)
{}
template <int dim, int spacedim>
void MGDoFHandler<dim,spacedim>::MGVertexDoFs::init (const unsigned int cl,
- const unsigned int fl,
- const unsigned int dofs_per_vertex)
+ const unsigned int fl,
+ const unsigned int dofs_per_vertex)
{
if (indices != 0)
{
coarsest_level = cl;
finest_level = fl;
- // in the case where an invalid
- // entry is requested, just leave
- // everything else alone
+ // in the case where an invalid
+ // entry is requested, just leave
+ // everything else alone
if (cl > fl)
return;
MGDoFHandler<dim,spacedim>::MGVertexDoFs::operator = (const MGVertexDoFs &)
{
Assert (false,
- ExcMessage ("We don't know how many dofs per vertex there are, so there's "
- "no way we can copy the 'indices' array"));
+ ExcMessage ("We don't know how many dofs per vertex there are, so there's "
+ "no way we can copy the 'indices' array"));
return *this;
}
template <int dim, int spacedim>
MGDoFHandler<dim,spacedim>::MGDoFHandler ()
- :
- mg_faces (NULL)
+ :
+ mg_faces (NULL)
{}
template <int dim, int spacedim>
MGDoFHandler<dim,spacedim>::MGDoFHandler (const Triangulation<dim,spacedim> &tria)
- :
- DoFHandler<dim,spacedim> (tria),
- mg_faces (NULL)
+ :
+ DoFHandler<dim,spacedim> (tria),
+ mg_faces (NULL)
{
Assert ((dynamic_cast<const parallel::distributed::Triangulation< dim, spacedim >*>
- (&tria)
- == 0),
- ExcMessage ("The given triangulation is parallel distributed but "
- "this class does not currently support this."));
+ (&tria)
+ == 0),
+ ExcMessage ("The given triangulation is parallel distributed but "
+ "this class does not currently support this."));
}
for (unsigned int l=0;l<mg_vertex_dofs.size();++l)
mem += sizeof(MGVertexDoFs)
- + (1+mg_vertex_dofs[l].get_finest_level()-mg_vertex_dofs[l].get_coarsest_level())
- * sizeof(unsigned int);
+ + (1+mg_vertex_dofs[l].get_finest_level()-mg_vertex_dofs[l].get_coarsest_level())
+ * sizeof(unsigned int);
mem += MemoryConsumption::memory_consumption(mg_used_dofs);
return mem;
}
switch (dim)
{
case 1:
- return begin_raw_line (level);
+ return begin_raw_line (level);
case 2:
- return begin_raw_quad (level);
+ return begin_raw_quad (level);
case 3:
- return begin_raw_hex (level);
+ return begin_raw_hex (level);
default:
- Assert (false, ExcNotImplemented());
- return raw_cell_iterator();
+ Assert (false, ExcNotImplemented());
+ return raw_cell_iterator();
}
}
switch (dim)
{
case 1:
- return begin_line (level);
+ return begin_line (level);
case 2:
- return begin_quad (level);
+ return begin_quad (level);
case 3:
- return begin_hex (level);
+ return begin_hex (level);
default:
- Assert (false, ExcImpossibleInDim(dim));
- return cell_iterator();
+ Assert (false, ExcImpossibleInDim(dim));
+ return cell_iterator();
}
}
switch (dim)
{
case 1:
- return begin_active_line (level);
+ return begin_active_line (level);
case 2:
- return begin_active_quad (level);
+ return begin_active_quad (level);
case 3:
- return begin_active_hex (level);
+ return begin_active_hex (level);
default:
- Assert (false, ExcNotImplemented());
- return active_cell_iterator();
+ Assert (false, ExcNotImplemented());
+ return active_cell_iterator();
}
}
switch (dim)
{
case 1:
- return last_raw_line ();
+ return last_raw_line ();
case 2:
- return last_raw_quad ();
+ return last_raw_quad ();
case 3:
- return last_raw_hex ();
+ return last_raw_hex ();
default:
- Assert (false, ExcNotImplemented());
- return raw_cell_iterator();
+ Assert (false, ExcNotImplemented());
+ return raw_cell_iterator();
}
}
switch (dim)
{
case 1:
- return last_raw_line (level);
+ return last_raw_line (level);
case 2:
- return last_raw_quad (level);
+ return last_raw_quad (level);
case 3:
- return last_raw_hex (level);
+ return last_raw_hex (level);
default:
- Assert (false, ExcNotImplemented());
- return raw_cell_iterator();
+ Assert (false, ExcNotImplemented());
+ return raw_cell_iterator();
}
}
switch (dim)
{
case 1:
- return last_line ();
+ return last_line ();
case 2:
- return last_quad ();
+ return last_quad ();
case 3:
- return last_hex ();
+ return last_hex ();
default:
- Assert (false, ExcNotImplemented());
- return cell_iterator();
+ Assert (false, ExcNotImplemented());
+ return cell_iterator();
}
}
switch (dim)
{
case 1:
- return last_line (level);
+ return last_line (level);
case 2:
- return last_quad (level);
+ return last_quad (level);
case 3:
- return last_hex (level);
+ return last_hex (level);
default:
- Assert (false, ExcNotImplemented());
- return cell_iterator();
+ Assert (false, ExcNotImplemented());
+ return cell_iterator();
}
}
switch (dim)
{
case 1:
- return last_active_line ();
+ return last_active_line ();
case 2:
- return last_active_quad ();
+ return last_active_quad ();
case 3:
- return last_active_hex ();
+ return last_active_hex ();
default:
- Assert (false, ExcNotImplemented());
- return active_cell_iterator();
+ Assert (false, ExcNotImplemented());
+ return active_cell_iterator();
}
}
switch (dim)
{
case 1:
- return last_active_line (level);
+ return last_active_line (level);
case 2:
- return last_active_quad (level);
+ return last_active_quad (level);
case 3:
- return last_active_hex (level);
+ return last_active_hex (level);
default:
- Assert (false, ExcNotImplemented());
- return active_cell_iterator();
+ Assert (false, ExcNotImplemented());
+ return active_cell_iterator();
}
}
switch (dim)
{
case 1:
- return end_line();
+ return end_line();
case 2:
- return end_quad();
+ return end_quad();
case 3:
- return end_hex();
+ return end_hex();
default:
- Assert (false, ExcImpossibleInDim(dim));
- return raw_cell_iterator();
+ Assert (false, ExcImpossibleInDim(dim));
+ return raw_cell_iterator();
}
}
MGDoFHandler<dim, spacedim>::end_raw (const unsigned int level) const
{
return (level == this->get_tria().n_levels()-1 ?
- end() :
- begin_raw (level+1));
+ end() :
+ begin_raw (level+1));
}
MGDoFHandler<dim, spacedim>::end (const unsigned int level) const
{
return (level == this->get_tria().n_levels()-1 ?
- cell_iterator(end()) :
- begin (level+1));
+ cell_iterator(end()) :
+ begin (level+1));
}
MGDoFHandler<dim, spacedim>::end_active (const unsigned int level) const
{
return (level == this->get_tria().n_levels()-1 ?
- active_cell_iterator(end()) :
- begin_active (level+1));
+ active_cell_iterator(end()) :
+ begin_active (level+1));
}
switch (dim)
{
case 1:
- Assert (false, ExcImpossibleInDim(1));
- return raw_face_iterator();
+ Assert (false, ExcImpossibleInDim(1));
+ return raw_face_iterator();
case 2:
- return begin_raw_line ();
+ return begin_raw_line ();
case 3:
- return begin_raw_quad ();
+ return begin_raw_quad ();
default:
- Assert (false, ExcNotImplemented());
- return raw_face_iterator ();
+ Assert (false, ExcNotImplemented());
+ return raw_face_iterator ();
}
}
switch (dim)
{
case 1:
- Assert (false, ExcImpossibleInDim(1));
- return raw_face_iterator();
+ Assert (false, ExcImpossibleInDim(1));
+ return raw_face_iterator();
case 2:
- return begin_line ();
+ return begin_line ();
case 3:
- return begin_quad ();
+ return begin_quad ();
default:
- Assert (false, ExcNotImplemented());
- return face_iterator ();
+ Assert (false, ExcNotImplemented());
+ return face_iterator ();
}
}
switch (dim)
{
case 1:
- Assert (false, ExcImpossibleInDim(1));
- return raw_face_iterator();
+ Assert (false, ExcImpossibleInDim(1));
+ return raw_face_iterator();
case 2:
- return begin_active_line ();
+ return begin_active_line ();
case 3:
- return begin_active_quad ();
+ return begin_active_quad ();
default:
- Assert (false, ExcNotImplemented());
- return active_face_iterator ();
+ Assert (false, ExcNotImplemented());
+ return active_face_iterator ();
}
}
switch (dim)
{
case 1:
- Assert (false, ExcImpossibleInDim(1));
- return raw_face_iterator();
+ Assert (false, ExcImpossibleInDim(1));
+ return raw_face_iterator();
case 2:
- return end_line ();
+ return end_line ();
case 3:
- return end_quad ();
+ return end_quad ();
default:
- Assert (false, ExcNotImplemented());
- return raw_face_iterator ();
+ Assert (false, ExcNotImplemented());
+ return raw_face_iterator ();
}
}
switch (dim)
{
case 1:
- Assert (false, ExcImpossibleInDim(1));
- return raw_face_iterator();
+ Assert (false, ExcImpossibleInDim(1));
+ return raw_face_iterator();
case 2:
- return last_raw_line ();
+ return last_raw_line ();
case 3:
- return last_raw_quad ();
+ return last_raw_quad ();
default:
- Assert (false, ExcNotImplemented());
- return raw_face_iterator ();
+ Assert (false, ExcNotImplemented());
+ return raw_face_iterator ();
}
}
switch (dim)
{
case 1:
- Assert (false, ExcImpossibleInDim(1));
- return raw_face_iterator();
+ Assert (false, ExcImpossibleInDim(1));
+ return raw_face_iterator();
case 2:
- return last_line ();
+ return last_line ();
case 3:
- return last_quad ();
+ return last_quad ();
default:
- Assert (false, ExcNotImplemented());
- return raw_face_iterator ();
+ Assert (false, ExcNotImplemented());
+ return raw_face_iterator ();
}
}
switch (dim)
{
case 1:
- Assert (false, ExcImpossibleInDim(1));
- return raw_face_iterator();
+ Assert (false, ExcImpossibleInDim(1));
+ return raw_face_iterator();
case 2:
- return last_active_line ();
+ return last_active_line ();
case 3:
- return last_active_quad ();
+ return last_active_quad ();
default:
- Assert (false, ExcNotImplemented());
- return raw_face_iterator ();
+ Assert (false, ExcNotImplemented());
+ return raw_face_iterator ();
}
}
switch (dim)
{
case 1:
- Assert (level<this->get_tria().n_levels(), ExcInvalidLevel(level));
+ Assert (level<this->get_tria().n_levels(), ExcInvalidLevel(level));
- if (this->get_tria().n_raw_lines(level) == 0)
- return end_line ();
+ if (this->get_tria().n_raw_lines(level) == 0)
+ return end_line ();
- return raw_line_iterator (&this->get_tria(),
- level,
- 0,
- this);
+ return raw_line_iterator (&this->get_tria(),
+ level,
+ 0,
+ this);
default:
- Assert (level == 0, ExcFacesHaveNoLevel());
- return raw_line_iterator (&this->get_tria(),
- 0,
- 0,
- this);
+ Assert (level == 0, ExcFacesHaveNoLevel());
+ return raw_line_iterator (&this->get_tria(),
+ 0,
+ 0,
+ this);
}
}
typename MGDoFHandler<dim, spacedim>::line_iterator
MGDoFHandler<dim, spacedim>::begin_line (const unsigned int level) const
{
- // level is checked in begin_raw
+ // level is checked in begin_raw
raw_line_iterator ri = begin_raw_line (level);
if (ri.state() != IteratorState::valid)
return ri;
typename MGDoFHandler<dim, spacedim>::active_line_iterator
MGDoFHandler<dim, spacedim>::begin_active_line (const unsigned int level) const
{
- // level is checked in begin_raw
+ // level is checked in begin_raw
line_iterator i = begin_line (level);
if (i.state() != IteratorState::valid)
return i;
MGDoFHandler<dim, spacedim>::end_line () const
{
return raw_line_iterator (&this->get_tria(),
- -1,
- -1,
- this);
+ -1,
+ -1,
+ this);
}
switch (dim)
{
case 1:
- Assert (level<this->get_tria().n_levels(), ExcInvalidLevel(level));
- Assert (this->get_tria().n_raw_lines(level) != 0,
- ExcEmptyLevel (level));
+ Assert (level<this->get_tria().n_levels(), ExcInvalidLevel(level));
+ Assert (this->get_tria().n_raw_lines(level) != 0,
+ ExcEmptyLevel (level));
- return raw_line_iterator (&this->get_tria(),
- level,
- this->get_tria().n_raw_lines(level)-1,
- this);
+ return raw_line_iterator (&this->get_tria(),
+ level,
+ this->get_tria().n_raw_lines(level)-1,
+ this);
default:
- Assert (level == 0, ExcFacesHaveNoLevel());
- return raw_line_iterator (&this->get_tria(),
- 0,
- this->get_tria().n_raw_lines()-1,
- this);
+ Assert (level == 0, ExcFacesHaveNoLevel());
+ return raw_line_iterator (&this->get_tria(),
+ 0,
+ this->get_tria().n_raw_lines()-1,
+ this);
}
}
typename MGDoFHandler<dim, spacedim>::line_iterator
MGDoFHandler<dim, spacedim>::last_line (const unsigned int level) const
{
- // level is checked in last_raw
+ // level is checked in last_raw
raw_line_iterator ri = last_raw_line(level);
if (ri->used()==true)
return ri;
typename MGDoFHandler<dim, spacedim>::active_line_iterator
MGDoFHandler<dim, spacedim>::last_active_line (const unsigned int level) const
{
- // level is checked in last_raw
+ // level is checked in last_raw
line_iterator i = last_line(level);
if (i->has_children()==false)
return i;
Assert (dim == 1 || level == 0, ExcFacesHaveNoLevel());
if (dim == 1)
return (level == this->get_tria().n_levels()-1 ?
- end_line() :
- begin_raw_line (level+1));
+ end_line() :
+ begin_raw_line (level+1));
else
return end_line();
}
Assert (dim == 1 || level == 0, ExcFacesHaveNoLevel());
if (dim == 1)
return (level == this->get_tria().n_levels()-1 ?
- line_iterator(end_line()) :
- begin_line (level+1));
+ line_iterator(end_line()) :
+ begin_line (level+1));
else
return line_iterator(end_line());
}
Assert (dim == 1 || level == 0, ExcFacesHaveNoLevel());
if (dim == 1)
return (level == this->get_tria().n_levels()-1 ?
- active_line_iterator(end_line()) :
- begin_active_line (level+1));
+ active_line_iterator(end_line()) :
+ begin_active_line (level+1));
else
return active_line_iterator(end_line());
}
switch (dim)
{
case 1:
- Assert (false, ExcImpossibleInDim(1));
- return raw_hex_iterator();
+ Assert (false, ExcImpossibleInDim(1));
+ return raw_hex_iterator();
case 2:
{
- Assert (level<this->get_tria().n_levels(), ExcInvalidLevel(level));
+ Assert (level<this->get_tria().n_levels(), ExcInvalidLevel(level));
- if (this->get_tria().n_raw_quads(level) == 0)
- return end_quad();
+ if (this->get_tria().n_raw_quads(level) == 0)
+ return end_quad();
- return raw_quad_iterator (&this->get_tria(),
- level,
- 0,
- this);
+ return raw_quad_iterator (&this->get_tria(),
+ level,
+ 0,
+ this);
}
case 3:
{
- Assert (level == 0, ExcFacesHaveNoLevel());
+ Assert (level == 0, ExcFacesHaveNoLevel());
- return raw_quad_iterator (&this->get_tria(),
- 0,
- 0,
- this);
+ return raw_quad_iterator (&this->get_tria(),
+ 0,
+ 0,
+ this);
}
default:
- Assert (false, ExcNotImplemented());
- return raw_hex_iterator();
+ Assert (false, ExcNotImplemented());
+ return raw_hex_iterator();
}
}
typename MGDoFHandler<dim,spacedim>::quad_iterator
MGDoFHandler<dim,spacedim>::begin_quad (const unsigned int level) const
{
- // level is checked in begin_raw
+ // level is checked in begin_raw
raw_quad_iterator ri = begin_raw_quad (level);
if (ri.state() != IteratorState::valid)
return ri;
typename MGDoFHandler<dim,spacedim>::active_quad_iterator
MGDoFHandler<dim,spacedim>::begin_active_quad (const unsigned int level) const
{
- // level is checked in begin_raw
+ // level is checked in begin_raw
quad_iterator i = begin_quad (level);
if (i.state() != IteratorState::valid)
return i;
Assert (dim == 2 || level == 0, ExcFacesHaveNoLevel());
if (dim == 2)
return (level == this->get_tria().n_levels()-1 ?
- end_quad() :
- begin_raw_quad (level+1));
+ end_quad() :
+ begin_raw_quad (level+1));
else
return end_quad();
}
Assert (dim == 2 || level == 0, ExcFacesHaveNoLevel());
if (dim == 2)
return (level == this->get_tria().n_levels()-1 ?
- quad_iterator(end_quad()) :
- begin_quad (level+1));
+ quad_iterator(end_quad()) :
+ begin_quad (level+1));
else
return quad_iterator(end_quad());
}
Assert(dim == 2 || level == 0, ExcFacesHaveNoLevel());
if (dim == 2)
return (level == this->get_tria().n_levels()-1 ?
- active_quad_iterator(end_quad()) :
- begin_active_quad (level+1));
+ active_quad_iterator(end_quad()) :
+ begin_active_quad (level+1));
else
return active_quad_iterator(end_quad());
}
MGDoFHandler<dim,spacedim>::end_quad () const
{
return raw_quad_iterator (&this->get_tria(),
- -1,
- -1,
- this);
+ -1,
+ -1,
+ this);
}
switch (dim)
{
case 1:
- Assert (false, ExcImpossibleInDim(1));
- return raw_quad_iterator();
+ Assert (false, ExcImpossibleInDim(1));
+ return raw_quad_iterator();
case 2:
- Assert (level<this->get_tria().n_levels(),
- ExcInvalidLevel(level));
- Assert (this->get_tria().n_raw_quads(level) != 0,
- ExcEmptyLevel (level));
- return raw_quad_iterator (&this->get_tria(),
- level,
- this->get_tria().n_raw_quads(level)-1,
- this);
+ Assert (level<this->get_tria().n_levels(),
+ ExcInvalidLevel(level));
+ Assert (this->get_tria().n_raw_quads(level) != 0,
+ ExcEmptyLevel (level));
+ return raw_quad_iterator (&this->get_tria(),
+ level,
+ this->get_tria().n_raw_quads(level)-1,
+ this);
case 3:
- Assert (level == 0, ExcFacesHaveNoLevel());
- return raw_quad_iterator (&this->get_tria(),
- 0,
- this->get_tria().n_raw_quads()-1,
- this);
+ Assert (level == 0, ExcFacesHaveNoLevel());
+ return raw_quad_iterator (&this->get_tria(),
+ 0,
+ this->get_tria().n_raw_quads()-1,
+ this);
default:
- Assert (false, ExcNotImplemented());
- return raw_quad_iterator();
+ Assert (false, ExcNotImplemented());
+ return raw_quad_iterator();
}
}
typename MGDoFHandler<dim,spacedim>::quad_iterator
MGDoFHandler<dim,spacedim>::last_quad (const unsigned int level) const
{
- // level is checked in last_raw
+ // level is checked in last_raw
raw_quad_iterator ri = last_raw_quad(level);
if (ri->used()==true)
return ri;
typename MGDoFHandler<dim,spacedim>::active_quad_iterator
MGDoFHandler<dim,spacedim>::last_active_quad (const unsigned int level) const
{
- // level is checked in last_raw
+ // level is checked in last_raw
quad_iterator i = last_quad(level);
if (i->has_children()==false)
return i;
{
case 1:
case 2:
- Assert (false, ExcImpossibleInDim(1));
- return raw_hex_iterator();
+ Assert (false, ExcImpossibleInDim(1));
+ return raw_hex_iterator();
case 3:
{
- Assert (level<this->get_tria().n_levels(), ExcInvalidLevel(level));
+ Assert (level<this->get_tria().n_levels(), ExcInvalidLevel(level));
- if (this->get_tria().n_raw_hexs(level) == 0)
- return end_hex();
+ if (this->get_tria().n_raw_hexs(level) == 0)
+ return end_hex();
- return raw_hex_iterator (&this->get_tria(),
- level,
- 0,
- this);
+ return raw_hex_iterator (&this->get_tria(),
+ level,
+ 0,
+ this);
}
default:
- Assert (false, ExcNotImplemented());
- return raw_hex_iterator();
+ Assert (false, ExcNotImplemented());
+ return raw_hex_iterator();
}
}
typename MGDoFHandler<dim,spacedim>::hex_iterator
MGDoFHandler<dim,spacedim>::begin_hex (const unsigned int level) const
{
- // level is checked in begin_raw
+ // level is checked in begin_raw
raw_hex_iterator ri = begin_raw_hex (level);
if (ri.state() != IteratorState::valid)
return ri;
typename MGDoFHandler<dim, spacedim>::active_hex_iterator
MGDoFHandler<dim, spacedim>::begin_active_hex (const unsigned int level) const
{
- // level is checked in begin_raw
+ // level is checked in begin_raw
hex_iterator i = begin_hex (level);
if (i.state() != IteratorState::valid)
return i;
MGDoFHandler<dim, spacedim>::end_raw_hex (const unsigned int level) const
{
return (level == this->get_tria().n_levels()-1 ?
- end_hex() :
- begin_raw_hex (level+1));
+ end_hex() :
+ begin_raw_hex (level+1));
}
MGDoFHandler<dim, spacedim>::end_hex (const unsigned int level) const
{
return (level == this->get_tria().n_levels()-1 ?
- hex_iterator(end_hex()) :
- begin_hex (level+1));
+ hex_iterator(end_hex()) :
+ begin_hex (level+1));
}
MGDoFHandler<dim, spacedim>::end_active_hex (const unsigned int level) const
{
return (level == this->get_tria().n_levels()-1 ?
- active_hex_iterator(end_hex()) :
- begin_active_hex (level+1));
+ active_hex_iterator(end_hex()) :
+ begin_active_hex (level+1));
}
MGDoFHandler<dim, spacedim>::end_hex () const
{
return raw_hex_iterator (&this->get_tria(),
- -1,
- -1,
- this);
+ -1,
+ -1,
+ this);
}
{
case 1:
case 2:
- Assert (false, ExcImpossibleInDim(dim));
- return raw_hex_iterator();
+ Assert (false, ExcImpossibleInDim(dim));
+ return raw_hex_iterator();
case 3:
- Assert (level<this->get_tria().n_levels(),
- ExcInvalidLevel(level));
- Assert (this->get_tria().n_raw_hexs(level) != 0,
- ExcEmptyLevel (level));
-
- return raw_hex_iterator (&this->get_tria(),
- level,
- this->get_tria().n_raw_hexs(level)-1,
- this);
+ Assert (level<this->get_tria().n_levels(),
+ ExcInvalidLevel(level));
+ Assert (this->get_tria().n_raw_hexs(level) != 0,
+ ExcEmptyLevel (level));
+
+ return raw_hex_iterator (&this->get_tria(),
+ level,
+ this->get_tria().n_raw_hexs(level)-1,
+ this);
default:
- Assert (false, ExcNotImplemented());
- return raw_hex_iterator();
+ Assert (false, ExcNotImplemented());
+ return raw_hex_iterator();
}
}
typename MGDoFHandler<dim, spacedim>::hex_iterator
MGDoFHandler<dim, spacedim>::last_hex (const unsigned int level) const
{
- // level is checked in last_raw
+ // level is checked in last_raw
raw_hex_iterator ri = last_raw_hex(level);
if (ri->used()==true)
return ri;
typename MGDoFHandler<dim, spacedim>::active_hex_iterator
MGDoFHandler<dim, spacedim>::last_active_hex (const unsigned int level) const
{
- // level is checked in last_raw
+ // level is checked in last_raw
hex_iterator i = last_hex(level);
if (i->has_children()==false)
return i;
unsigned int
MGDoFHandler<dim,spacedim>::
get_dof_index (const unsigned int obj_level,
- const unsigned int obj_index,
- const unsigned int fe_index,
- const unsigned int local_index) const
+ const unsigned int obj_index,
+ const unsigned int fe_index,
+ const unsigned int local_index) const
{
return internal::MGDoFHandler::Implementation::
get_dof_index (*this,
- *this->mg_levels[obj_level],
- *this->mg_faces,
- obj_index,
- fe_index,
- local_index,
- internal::int2type<structdim>());
+ *this->mg_levels[obj_level],
+ *this->mg_faces,
+ obj_index,
+ fe_index,
+ local_index,
+ internal::int2type<structdim>());
}
void
MGDoFHandler<dim,spacedim>::
set_dof_index (const unsigned int obj_level,
- const unsigned int obj_index,
- const unsigned int fe_index,
- const unsigned int local_index,
- const unsigned int global_index) const
+ const unsigned int obj_index,
+ const unsigned int fe_index,
+ const unsigned int local_index,
+ const unsigned int global_index) const
{
internal::MGDoFHandler::Implementation::
set_dof_index (*this,
- *this->mg_levels[obj_level],
- *this->mg_faces,
- obj_index,
- fe_index,
- local_index,
- global_index,
- internal::int2type<structdim>());
+ *this->mg_levels[obj_level],
+ *this->mg_faces,
+ obj_index,
+ fe_index,
+ local_index,
+ global_index,
+ internal::int2type<structdim>());
}
template <int dim, int spacedim>
void MGDoFHandler<dim,spacedim>::distribute_dofs (const FiniteElement<dim,spacedim> &fe,
- const unsigned int offset)
-{
- // first distribute global dofs
+ const unsigned int offset)
+{
+ // first distribute global dofs
DoFHandler<dim,spacedim>::distribute_dofs (fe);
- // reserve space for the MG dof numbers
+ // reserve space for the MG dof numbers
reserve_space ();
mg_used_dofs.resize (this->get_tria().n_levels(), 0);
- // Clear user flags because we will
- // need them. But first we save
- // them and make sure that we
- // restore them later such that at
- // the end of this function the
- // Triangulation will be in the
- // same state as it was at the
- // beginning of this function.
+ // Clear user flags because we will
+ // need them. But first we save
+ // them and make sure that we
+ // restore them later such that at
+ // the end of this function the
+ // Triangulation will be in the
+ // same state as it was at the
+ // beginning of this function.
std::vector<bool> user_flags;
this->get_tria().save_user_flags(user_flags);
const_cast<Triangulation<dim,spacedim> &>(this->get_tria()).clear_user_flags ();
- // now distribute indices on each level
- // separately
+ // now distribute indices on each level
+ // separately
for (unsigned int level=0; level<this->get_tria().n_levels(); ++level)
{
unsigned int next_free_dof = offset;
cell_iterator cell = begin(level),
- endc = end(level);
+ endc = end(level);
for (; cell != endc; ++cell)
- next_free_dof = internal::MGDoFHandler::Implementation::distribute_dofs_on_cell<spacedim> (cell, next_free_dof);
+ next_free_dof = internal::MGDoFHandler::Implementation::distribute_dofs_on_cell<spacedim> (cell, next_free_dof);
mg_used_dofs[level] = next_free_dof;
}
- // finally restore the user flags
+ // finally restore the user flags
const_cast<Triangulation<dim,spacedim> &>(this->get_tria())
.load_user_flags(user_flags);
void
MGDoFHandler<dim,spacedim>::clear ()
{
- // release own memory
+ // release own memory
clear_space ();
- // let base class release its mem
- // as well
+ // let base class release its mem
+ // as well
DoFHandler<dim,spacedim>::clear ();
}
template <>
void MGDoFHandler<1>::renumber_dofs (const unsigned int level,
- const std::vector<unsigned int> &new_numbers) {
+ const std::vector<unsigned int> &new_numbers) {
Assert (new_numbers.size() == n_dofs(level), DoFHandler<1>::ExcRenumberingIncomplete());
- // note that we can not use cell iterators
- // in this function since then we would
- // renumber the dofs on the interface of
- // two cells more than once. Anyway, this
- // ways it's not only more correct but also
- // faster
+ // note that we can not use cell iterators
+ // in this function since then we would
+ // renumber the dofs on the interface of
+ // two cells more than once. Anyway, this
+ // ways it's not only more correct but also
+ // faster
for (std::vector<MGVertexDoFs>::iterator i=mg_vertex_dofs.begin();
i!=mg_vertex_dofs.end(); ++i)
- // if the present vertex lives on
- // the present level
+ // if the present vertex lives on
+ // the present level
if ((i->get_coarsest_level() <= level) &&
- (i->get_finest_level() >= level))
+ (i->get_finest_level() >= level))
for (unsigned int d=0; d<this->get_fe().dofs_per_vertex; ++d)
- i->set_index (level, d, this->get_fe().dofs_per_vertex,
- new_numbers[i->get_index (level, d,
- this->get_fe().dofs_per_vertex)]);
+ i->set_index (level, d, this->get_fe().dofs_per_vertex,
+ new_numbers[i->get_index (level, d,
+ this->get_fe().dofs_per_vertex)]);
for (std::vector<unsigned int>::iterator i=mg_levels[level]->lines.dofs.begin();
i!=mg_levels[level]->lines.dofs.end(); ++i)
{
if (*i != DoFHandler<1>::invalid_dof_index)
- {
- Assert(*i<new_numbers.size(), ExcInternalError());
- *i = new_numbers[*i];
- }
+ {
+ Assert(*i<new_numbers.size(), ExcInternalError());
+ *i = new_numbers[*i];
+ }
}
}
template <>
void MGDoFHandler<2>::renumber_dofs (const unsigned int level,
- const std::vector<unsigned int> &new_numbers) {
+ const std::vector<unsigned int> &new_numbers) {
Assert (new_numbers.size() == n_dofs(level),
- DoFHandler<2>::ExcRenumberingIncomplete());
+ DoFHandler<2>::ExcRenumberingIncomplete());
for (std::vector<MGVertexDoFs>::iterator i=mg_vertex_dofs.begin();
i!=mg_vertex_dofs.end(); ++i)
- // if the present vertex lives on
- // the present level
+ // if the present vertex lives on
+ // the present level
if ((i->get_coarsest_level() <= level) &&
- (i->get_finest_level() >= level))
+ (i->get_finest_level() >= level))
for (unsigned int d=0; d<this->get_fe().dofs_per_vertex; ++d)
- i->set_index (level, d, this->get_fe().dofs_per_vertex,
- new_numbers[i->get_index (level, d,
- this->get_fe().dofs_per_vertex)]);
+ i->set_index (level, d, this->get_fe().dofs_per_vertex,
+ new_numbers[i->get_index (level, d,
+ this->get_fe().dofs_per_vertex)]);
if (this->get_fe().dofs_per_line > 0)
{
- // save user flags as they will be modified
+ // save user flags as they will be modified
std::vector<bool> user_flags;
this->get_tria().save_user_flags(user_flags);
const_cast<Triangulation<2> &>(this->get_tria()).clear_user_flags ();
- // flag all lines adjacent to cells of the current
- // level, as those lines logically belong to the same
- // level as the cell, at least for for isotropic
- // refinement
+ // flag all lines adjacent to cells of the current
+ // level, as those lines logically belong to the same
+ // level as the cell, at least for for isotropic
+ // refinement
cell_iterator cell = begin(level),
- endcell = end(level);
+ endcell = end(level);
for ( ; cell != endcell; ++cell)
- for (unsigned int line=0; line < GeometryInfo<2>::faces_per_cell; ++line)
- cell->face(line)->set_user_flag();
+ for (unsigned int line=0; line < GeometryInfo<2>::faces_per_cell; ++line)
+ cell->face(line)->set_user_flag();
line_iterator line = begin_line(),
- endline = end_line();
+ endline = end_line();
for( ; line != endline; ++line)
- if (line->user_flag_set())
- {
- for (unsigned int d=0; d<this->get_fe().dofs_per_line; ++d)
- line->set_mg_dof_index (level, d, new_numbers[line->mg_dof_index(level, d)]);
- line->clear_user_flag();
- }
- // finally, restore user flags
+ if (line->user_flag_set())
+ {
+ for (unsigned int d=0; d<this->get_fe().dofs_per_line; ++d)
+ line->set_mg_dof_index (level, d, new_numbers[line->mg_dof_index(level, d)]);
+ line->clear_user_flag();
+ }
+ // finally, restore user flags
const_cast<Triangulation<2> &>(this->get_tria()).load_user_flags (user_flags);
}
i!=mg_levels[level]->quads.dofs.end(); ++i)
{
if (*i != DoFHandler<2>::invalid_dof_index)
- {
- Assert(*i<new_numbers.size(), ExcInternalError());
- *i = new_numbers[*i];
- }
+ {
+ Assert(*i<new_numbers.size(), ExcInternalError());
+ *i = new_numbers[*i];
+ }
}
}
template <>
void MGDoFHandler<3>::renumber_dofs (const unsigned int level,
- const std::vector<unsigned int> &new_numbers) {
+ const std::vector<unsigned int> &new_numbers) {
Assert (new_numbers.size() == n_dofs(level),
- DoFHandler<3>::ExcRenumberingIncomplete());
+ DoFHandler<3>::ExcRenumberingIncomplete());
for (std::vector<MGVertexDoFs>::iterator i=mg_vertex_dofs.begin();
i!=mg_vertex_dofs.end(); ++i)
- // if the present vertex lives on
- // the present level
+ // if the present vertex lives on
+ // the present level
if ((i->get_coarsest_level() <= level) &&
- (i->get_finest_level() >= level))
+ (i->get_finest_level() >= level))
for (unsigned int d=0; d<this->get_fe().dofs_per_vertex; ++d)
- i->set_index (level, d, this->get_fe().dofs_per_vertex,
- new_numbers[i->get_index (level, d,
- this->get_fe().dofs_per_vertex)]);
+ i->set_index (level, d, this->get_fe().dofs_per_vertex,
+ new_numbers[i->get_index (level, d,
+ this->get_fe().dofs_per_vertex)]);
- // LINE DoFs
+ // LINE DoFs
if (this->get_fe().dofs_per_line > 0)
{
- // save user flags as they will be modified
+ // save user flags as they will be modified
std::vector<bool> user_flags;
this->get_tria().save_user_flags(user_flags);
const_cast<Triangulation<3> &>(this->get_tria()).clear_user_flags ();
- // flag all lines adjacent to cells of the current
- // level, as those lines logically belong to the same
- // level as the cell, at least for for isotropic
- // refinement
+ // flag all lines adjacent to cells of the current
+ // level, as those lines logically belong to the same
+ // level as the cell, at least for for isotropic
+ // refinement
cell_iterator cell = begin(level),
- endcell = end(level);
+ endcell = end(level);
for ( ; cell != endcell ; ++cell)
- for (unsigned int line=0; line < GeometryInfo<3>::lines_per_cell; ++line)
- cell->line(line)->set_user_flag();
+ for (unsigned int line=0; line < GeometryInfo<3>::lines_per_cell; ++line)
+ cell->line(line)->set_user_flag();
line_iterator line = begin_line(),
- endline = end_line();
+ endline = end_line();
for( ; line != endline; ++line)
- if (line->user_flag_set())
- {
- for (unsigned int d=0; d<this->get_fe().dofs_per_line; ++d)
- line->set_mg_dof_index (level, d, new_numbers[line->mg_dof_index(level, d)]);
- line->clear_user_flag();
- }
- // finally, restore user flags
+ if (line->user_flag_set())
+ {
+ for (unsigned int d=0; d<this->get_fe().dofs_per_line; ++d)
+ line->set_mg_dof_index (level, d, new_numbers[line->mg_dof_index(level, d)]);
+ line->clear_user_flag();
+ }
+ // finally, restore user flags
const_cast<Triangulation<3> &>(this->get_tria()).load_user_flags (user_flags);
}
- // QUAD DoFs
+ // QUAD DoFs
if (this->get_fe().dofs_per_quad > 0)
{
- // save user flags as they will be modified
+ // save user flags as they will be modified
std::vector<bool> user_flags;
this->get_tria().save_user_flags(user_flags);
const_cast<Triangulation<3> &>(this->get_tria()).clear_user_flags ();
- // flag all quads adjacent to cells of the current
- // level, as those lines logically belong to the same
- // level as the cell, at least for for isotropic
- // refinement
+ // flag all quads adjacent to cells of the current
+ // level, as those lines logically belong to the same
+ // level as the cell, at least for for isotropic
+ // refinement
cell_iterator cell = begin(level),
- endcell = end(level);
+ endcell = end(level);
for ( ; cell != endcell ; ++cell)
- for (unsigned int quad=0; quad < GeometryInfo<3>::faces_per_cell; ++quad)
- cell->face(quad)->set_user_flag();
+ for (unsigned int quad=0; quad < GeometryInfo<3>::faces_per_cell; ++quad)
+ cell->face(quad)->set_user_flag();
quad_iterator quad = begin_quad(),
- endline = end_quad();
+ endline = end_quad();
for( ; quad != endline; ++quad)
- if (quad->user_flag_set())
- {
- for (unsigned int d=0; d<this->get_fe().dofs_per_quad; ++d)
- quad->set_mg_dof_index (level, d, new_numbers[quad->mg_dof_index(level, d)]);
- quad->clear_user_flag();
- }
- // finally, restore user flags
+ if (quad->user_flag_set())
+ {
+ for (unsigned int d=0; d<this->get_fe().dofs_per_quad; ++d)
+ quad->set_mg_dof_index (level, d, new_numbers[quad->mg_dof_index(level, d)]);
+ quad->clear_user_flag();
+ }
+ // finally, restore user flags
const_cast<Triangulation<3> &>(this->get_tria()).load_user_flags (user_flags);
}
- //HEX DoFs
+ //HEX DoFs
for (std::vector<unsigned int>::iterator i=mg_levels[level]->hexes.dofs.begin();
i!=mg_levels[level]->hexes.dofs.end(); ++i)
{
if (*i != DoFHandler<3>::invalid_dof_index)
- {
- Assert(*i<new_numbers.size(), ExcInternalError());
- *i = new_numbers[*i];
- }
+ {
+ Assert(*i<new_numbers.size(), ExcInternalError());
+ *i = new_numbers[*i];
+ }
}
}
delete mg_faces;
mg_faces=NULL;
- // also delete vector of vertex
- // indices
+ // also delete vector of vertex
+ // indices
std::vector<MGVertexDoFs> tmp;
std::swap (mg_vertex_dofs, tmp);
}
// $Id$
// Version: $Name$
//
-// Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 by the deal.II authors
+// Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
{
- // specializations for 1D
+ // specializations for 1D
template <>
void
compute_row_length_vector(
const DoFTools::Coupling flux_coupling)
{
Assert (row_lengths.size() == dofs.n_dofs(),
- ExcDimensionMismatch(row_lengths.size(), dofs.n_dofs()));
+ ExcDimensionMismatch(row_lengths.size(), dofs.n_dofs()));
- // Function starts here by
- // resetting the counters.
+ // Function starts here by
+ // resetting the counters.
std::fill(row_lengths.begin(), row_lengths.end(), 0);
- // We need the user flags, so we
- // save them for later restoration
+ // We need the user flags, so we
+ // save them for later restoration
std::vector<bool> old_flags;
- // We need a non-constant
- // triangulation for the user
- // flags. Since we restore them in
- // the end, this cast is safe.
+ // We need a non-constant
+ // triangulation for the user
+ // flags. Since we restore them in
+ // the end, this cast is safe.
Triangulation<dim,spacedim>& user_flags_triangulation =
const_cast<Triangulation<dim,spacedim>&> (dofs.get_tria());
user_flags_triangulation.save_user_flags(old_flags);
std::vector<unsigned int> cell_indices;
std::vector<unsigned int> neighbor_indices;
- // We loop over cells and go from
- // cells to lower dimensional
- // objects. This is the only way to
- // cope with the fact, that an
- // unknown number of cells may
- // share an object of dimension
- // smaller than dim-1.
+ // We loop over cells and go from
+ // cells to lower dimensional
+ // objects. This is the only way to
+ // cope with the fact, that an
+ // unknown number of cells may
+ // share an object of dimension
+ // smaller than dim-1.
for (cell = dofs.begin(level); cell != end; ++cell)
{
- const FiniteElement<dim>& fe = cell->get_fe();
- cell_indices.resize(fe.dofs_per_cell);
- cell->get_mg_dof_indices(cell_indices);
- unsigned int i = 0;
- // First, dofs on
- // vertices. We assume that
- // each vertex dof couples
- // with all dofs on
- // adjacent grid cells.
-
- // Adding all dofs of the cells
- // will add dofs of the faces
- // of the cell adjacent to the
- // vertex twice. Therefore, we
- // subtract these here and add
- // them in a loop over the
- // faces below.
-
- // in 1d, faces and vertices
- // are identical. Nevertheless,
- // this will only work if
- // dofs_per_face is zero and
- // dofs_per_vertex is
- // arbitrary, not the other way
- // round.
+ const FiniteElement<dim>& fe = cell->get_fe();
+ cell_indices.resize(fe.dofs_per_cell);
+ cell->get_mg_dof_indices(cell_indices);
+ unsigned int i = 0;
+ // First, dofs on
+ // vertices. We assume that
+ // each vertex dof couples
+ // with all dofs on
+ // adjacent grid cells.
+
+ // Adding all dofs of the cells
+ // will add dofs of the faces
+ // of the cell adjacent to the
+ // vertex twice. Therefore, we
+ // subtract these here and add
+ // them in a loop over the
+ // faces below.
+
+ // in 1d, faces and vertices
+ // are identical. Nevertheless,
+ // this will only work if
+ // dofs_per_face is zero and
+ // dofs_per_vertex is
+ // arbitrary, not the other way
+ // round.
//TODO: This assumes that even in hp context, the dofs per face coincide!
- unsigned int increment = fe.dofs_per_cell - dim * fe.dofs_per_face;
- while (i < fe.first_line_index)
- row_lengths[cell_indices[i++]] += increment;
- // From now on, if an object is
- // a cell, its dofs only couple
- // inside the cell. Since the
- // faces are handled below, we
- // have to subtract ALL faces
- // in this case.
-
- // In all other cases we
- // subtract adjacent faces to be
- // added in the loop below.
- increment = (dim>1)
- ? fe.dofs_per_cell - (dim-1) * fe.dofs_per_face
- : fe.dofs_per_cell - GeometryInfo<dim>::faces_per_cell * fe.dofs_per_face;
- while (i < fe.first_quad_index)
- row_lengths[cell_indices[i++]] += increment;
-
- // Now quads in 2D and 3D
- increment = (dim>2)
- ? fe.dofs_per_cell - (dim-2) * fe.dofs_per_face
- : fe.dofs_per_cell - GeometryInfo<dim>::faces_per_cell * fe.dofs_per_face;
- while (i < fe.first_hex_index)
- row_lengths[cell_indices[i++]] += increment;
- // Finally, cells in 3D
- increment = fe.dofs_per_cell - GeometryInfo<dim>::faces_per_cell * fe.dofs_per_face;
- while (i < fe.dofs_per_cell)
- row_lengths[cell_indices[i++]] += increment;
-
- // At this point, we have
- // counted all dofs
- // contributiong from cells
- // coupled topologically to the
- // adjacent cells, but we
- // subtracted some faces.
-
- // Now, let's go by the faces
- // and add the missing
- // contribution as well as the
- // flux contributions.
- for (unsigned int iface=0;iface<GeometryInfo<dim>::faces_per_cell;++iface)
- {
- bool level_boundary = cell->at_boundary(iface);
- typename MGDoFHandler<dim,spacedim>::cell_iterator neighbor;
- if (!level_boundary)
- {
- neighbor = cell->neighbor(iface);
- if (static_cast<unsigned int>(neighbor->level()) != level)
- level_boundary = true;
- }
-
- if (level_boundary)
- {
- for (unsigned int i=0;i<fe.dofs_per_cell;++i)
- row_lengths[cell_indices[i]] += fe.dofs_per_face;
- continue;
- }
-
- const FiniteElement<dim>& nfe = neighbor->get_fe();
- typename MGDoFHandler<dim,spacedim>::face_iterator face = cell->face(iface);
-
- // Flux couplings are
- // computed from both sides
- // for simplicity.
-
- // The dofs on the common face
- // will be handled below,
- // therefore, we subtract them
- // here.
- if (flux_coupling != DoFTools::none)
- {
- unsigned int increment = nfe.dofs_per_cell - nfe.dofs_per_face;
- for (unsigned int i=0;i<fe.dofs_per_cell;++i)
- row_lengths[cell_indices[i]] += increment;
- }
-
- // Do this only once per
- // face.
- if (face->user_flag_set())
- continue;
- face->set_user_flag();
- // At this point, we assume
- // that each cell added its
- // dofs minus the face to
- // the couplings of the
- // face dofs. Since we
- // subtracted two faces, we
- // have to re-add one.
-
- // If one side of the face
- // is refined, all the fine
- // face dofs couple with
- // the coarse one.
- neighbor_indices.resize(nfe.dofs_per_cell);
- neighbor->get_mg_dof_indices(neighbor_indices);
- for (unsigned int i=0;i<fe.dofs_per_cell;++i)
- row_lengths[cell_indices[i]] += nfe.dofs_per_face;
- for (unsigned int i=0;i<nfe.dofs_per_cell;++i)
- row_lengths[neighbor_indices[i]] += fe.dofs_per_face;
- }
+ unsigned int increment = fe.dofs_per_cell - dim * fe.dofs_per_face;
+ while (i < fe.first_line_index)
+ row_lengths[cell_indices[i++]] += increment;
+ // From now on, if an object is
+ // a cell, its dofs only couple
+ // inside the cell. Since the
+ // faces are handled below, we
+ // have to subtract ALL faces
+ // in this case.
+
+ // In all other cases we
+ // subtract adjacent faces to be
+ // added in the loop below.
+ increment = (dim>1)
+ ? fe.dofs_per_cell - (dim-1) * fe.dofs_per_face
+ : fe.dofs_per_cell - GeometryInfo<dim>::faces_per_cell * fe.dofs_per_face;
+ while (i < fe.first_quad_index)
+ row_lengths[cell_indices[i++]] += increment;
+
+ // Now quads in 2D and 3D
+ increment = (dim>2)
+ ? fe.dofs_per_cell - (dim-2) * fe.dofs_per_face
+ : fe.dofs_per_cell - GeometryInfo<dim>::faces_per_cell * fe.dofs_per_face;
+ while (i < fe.first_hex_index)
+ row_lengths[cell_indices[i++]] += increment;
+ // Finally, cells in 3D
+ increment = fe.dofs_per_cell - GeometryInfo<dim>::faces_per_cell * fe.dofs_per_face;
+ while (i < fe.dofs_per_cell)
+ row_lengths[cell_indices[i++]] += increment;
+
+ // At this point, we have
+ // counted all dofs
+ // contributiong from cells
+ // coupled topologically to the
+ // adjacent cells, but we
+ // subtracted some faces.
+
+ // Now, let's go by the faces
+ // and add the missing
+ // contribution as well as the
+ // flux contributions.
+ for (unsigned int iface=0;iface<GeometryInfo<dim>::faces_per_cell;++iface)
+ {
+ bool level_boundary = cell->at_boundary(iface);
+ typename MGDoFHandler<dim,spacedim>::cell_iterator neighbor;
+ if (!level_boundary)
+ {
+ neighbor = cell->neighbor(iface);
+ if (static_cast<unsigned int>(neighbor->level()) != level)
+ level_boundary = true;
+ }
+
+ if (level_boundary)
+ {
+ for (unsigned int i=0;i<fe.dofs_per_cell;++i)
+ row_lengths[cell_indices[i]] += fe.dofs_per_face;
+ continue;
+ }
+
+ const FiniteElement<dim>& nfe = neighbor->get_fe();
+ typename MGDoFHandler<dim,spacedim>::face_iterator face = cell->face(iface);
+
+ // Flux couplings are
+ // computed from both sides
+ // for simplicity.
+
+ // The dofs on the common face
+ // will be handled below,
+ // therefore, we subtract them
+ // here.
+ if (flux_coupling != DoFTools::none)
+ {
+ unsigned int increment = nfe.dofs_per_cell - nfe.dofs_per_face;
+ for (unsigned int i=0;i<fe.dofs_per_cell;++i)
+ row_lengths[cell_indices[i]] += increment;
+ }
+
+ // Do this only once per
+ // face.
+ if (face->user_flag_set())
+ continue;
+ face->set_user_flag();
+ // At this point, we assume
+ // that each cell added its
+ // dofs minus the face to
+ // the couplings of the
+ // face dofs. Since we
+ // subtracted two faces, we
+ // have to re-add one.
+
+ // If one side of the face
+ // is refined, all the fine
+ // face dofs couple with
+ // the coarse one.
+ neighbor_indices.resize(nfe.dofs_per_cell);
+ neighbor->get_mg_dof_indices(neighbor_indices);
+ for (unsigned int i=0;i<fe.dofs_per_cell;++i)
+ row_lengths[cell_indices[i]] += nfe.dofs_per_face;
+ for (unsigned int i=0;i<nfe.dofs_per_cell;++i)
+ row_lengths[neighbor_indices[i]] += fe.dofs_per_face;
+ }
}
user_flags_triangulation.load_user_flags(old_flags);
}
const Table<2,DoFTools::Coupling>& flux_couplings)
{
Assert (row_lengths.size() == dofs.n_dofs(),
- ExcDimensionMismatch(row_lengths.size(), dofs.n_dofs()));
+ ExcDimensionMismatch(row_lengths.size(), dofs.n_dofs()));
- // Function starts here by
- // resetting the counters.
+ // Function starts here by
+ // resetting the counters.
std::fill(row_lengths.begin(), row_lengths.end(), 0);
- // We need the user flags, so we
- // save them for later restoration
+ // We need the user flags, so we
+ // save them for later restoration
std::vector<bool> old_flags;
- // We need a non-constant
- // triangulation for the user
- // flags. Since we restore them in
- // the end, this cast is safe.
+ // We need a non-constant
+ // triangulation for the user
+ // flags. Since we restore them in
+ // the end, this cast is safe.
Triangulation<dim,spacedim>& user_flags_triangulation =
const_cast<Triangulation<dim,spacedim>&> (dofs.get_tria());
user_flags_triangulation.save_user_flags(old_flags);
std::vector<unsigned int> cell_indices;
std::vector<unsigned int> neighbor_indices;
- // We have to translate the
- // couplings from components to
- // blocks, so this works for
- // nonprimitive elements as well.
+ // We have to translate the
+ // couplings from components to
+ // blocks, so this works for
+ // nonprimitive elements as well.
std::vector<Table<2, DoFTools::Coupling> > couple_cell;
std::vector<Table<2, DoFTools::Coupling> > couple_face;
DoFTools::convert_couplings_to_blocks(dofs, couplings, couple_cell);
DoFTools::convert_couplings_to_blocks(dofs, flux_couplings, couple_face);
- // We loop over cells and go from
- // cells to lower dimensional
- // objects. This is the only way to
- // cope withthe fact, that an
- // unknown number of cells may
- // share an object of dimension
- // smaller than dim-1.
+ // We loop over cells and go from
+ // cells to lower dimensional
+ // objects. This is the only way to
+ // cope withthe fact, that an
+ // unknown number of cells may
+ // share an object of dimension
+ // smaller than dim-1.
for (cell = dofs.begin_active(); cell != end; ++cell)
{
- const FiniteElement<dim>& fe = cell->get_fe();
- const unsigned int fe_index = cell->active_fe_index();
-
- Assert (couplings.n_rows()==fe.n_components(),
- ExcDimensionMismatch(couplings.n_rows(), fe.n_components()));
- Assert (couplings.n_cols()==fe.n_components(),
- ExcDimensionMismatch(couplings.n_cols(), fe.n_components()));
- Assert (flux_couplings.n_rows()==fe.n_components(),
- ExcDimensionMismatch(flux_couplings.n_rows(), fe.n_components()));
- Assert (flux_couplings.n_cols()==fe.n_components(),
- ExcDimensionMismatch(flux_couplings.n_cols(), fe.n_components()));
-
- cell_indices.resize(fe.dofs_per_cell);
- cell->get_mg_dof_indices(cell_indices);
- unsigned int i = 0;
- // First, dofs on
- // vertices. We assume that
- // each vertex dof couples
- // with all dofs on
- // adjacent grid cells.
-
- // Adding all dofs of the cells
- // will add dofs of the faces
- // of the cell adjacent to the
- // vertex twice. Therefore, we
- // subtract these here and add
- // them in a loop over the
- // faces below.
-
- // in 1d, faces and vertices
- // are identical. Nevertheless,
- // this will only work if
- // dofs_per_face is zero and
- // dofs_per_vertex is
- // arbitrary, not the other way
- // round.
- unsigned int increment;
- while (i < fe.first_line_index)
- {
- for (unsigned int base=0;base<fe.n_base_elements();++base)
- for (unsigned int mult=0;mult<fe.element_multiplicity(base);++mult)
- if (couple_cell[fe_index](fe.system_to_block_index(i).first,
- fe.first_block_of_base(base) + mult) != DoFTools::none)
- {
- increment = fe.base_element(base).dofs_per_cell
- - dim * fe.base_element(base).dofs_per_face;
- row_lengths[cell_indices[i]] += increment;
- }
- ++i;
- }
- // From now on, if an object is
- // a cell, its dofs only couple
- // inside the cell. Since the
- // faces are handled below, we
- // have to subtract ALL faces
- // in this case.
-
- // In all other cases we
- // subtract adjacent faces to be
- // added in the loop below.
- while (i < fe.first_quad_index)
- {
- for (unsigned int base=0;base<fe.n_base_elements();++base)
- for (unsigned int mult=0;mult<fe.element_multiplicity(base);++mult)
- if (couple_cell[fe_index](fe.system_to_block_index(i).first,
- fe.first_block_of_base(base) + mult) != DoFTools::none)
- {
- increment = fe.base_element(base).dofs_per_cell
- - ((dim>1)
- ? (dim-1)
- : GeometryInfo<dim>::faces_per_cell)
- * fe.base_element(base).dofs_per_face;
- row_lengths[cell_indices[i]] += increment;
- }
- ++i;
- }
-
- // Now quads in 2D and 3D
- while (i < fe.first_hex_index)
- {
- for (unsigned int base=0;base<fe.n_base_elements();++base)
- for (unsigned int mult=0;mult<fe.element_multiplicity(base);++mult)
- if (couple_cell[fe_index](fe.system_to_block_index(i).first,
- fe.first_block_of_base(base) + mult) != DoFTools::none)
- {
- increment = fe.base_element(base).dofs_per_cell
- - ((dim>2)
- ? (dim-2)
- : GeometryInfo<dim>::faces_per_cell)
- * fe.base_element(base).dofs_per_face;
- row_lengths[cell_indices[i]] += increment;
- }
- ++i;
- }
-
- // Finally, cells in 3D
- while (i < fe.dofs_per_cell)
- {
- for (unsigned int base=0;base<fe.n_base_elements();++base)
- for (unsigned int mult=0;mult<fe.element_multiplicity(base);++mult)
- if (couple_cell[fe_index](fe.system_to_block_index(i).first,
- fe.first_block_of_base(base) + mult) != DoFTools::none)
- {
- increment = fe.base_element(base).dofs_per_cell
- - GeometryInfo<dim>::faces_per_cell
- * fe.base_element(base).dofs_per_face;
- row_lengths[cell_indices[i]] += increment;
- }
- ++i;
- }
-
- // At this point, we have
- // counted all dofs
- // contributiong from cells
- // coupled topologically to the
- // adjacent cells, but we
- // subtracted some faces.
-
- // Now, let's go by the faces
- // and add the missing
- // contribution as well as the
- // flux contributions.
- for (unsigned int iface=0;iface<GeometryInfo<dim>::faces_per_cell;++iface)
- {
- bool level_boundary = cell->at_boundary(iface);
- typename MGDoFHandler<dim,spacedim>::cell_iterator neighbor;
- if (!level_boundary)
- {
- neighbor = cell->neighbor(iface);
- if (static_cast<unsigned int>(neighbor->level()) != level)
- level_boundary = true;
- }
-
- if (level_boundary)
- {
- for (unsigned int i=0;i<fe.dofs_per_cell;++i)
- row_lengths[cell_indices[i]] += fe.dofs_per_face;
- continue;
- }
-
- const FiniteElement<dim>& nfe = neighbor->get_fe();
- typename MGDoFHandler<dim,spacedim>::face_iterator face = cell->face(iface);
-
- // Flux couplings are
- // computed from both sides
- // for simplicity.
-
- // The dofs on the common face
- // will be handled below,
- // therefore, we subtract them
- // here.
- for (unsigned int base=0;base<nfe.n_base_elements();++base)
- for (unsigned int mult=0;mult<nfe.element_multiplicity(base);++mult)
- for (unsigned int i=0;i<fe.dofs_per_cell;++i)
- if (couple_face[fe_index](fe.system_to_block_index(i).first,
- nfe.first_block_of_base(base) + mult) != DoFTools::none)
- {
- unsigned int increment = nfe.base_element(base).dofs_per_cell
- - nfe.base_element(base).dofs_per_face;
- row_lengths[cell_indices[i]] += increment;
- }
-
- // Do this only once per
- // face and not on the
- // hanging faces.
- if (face->user_flag_set())
- continue;
- face->set_user_flag();
- // At this point, we assume
- // that each cell added its
- // dofs minus the face to
- // the couplings of the
- // face dofs. Since we
- // subtracted two faces, we
- // have to re-add one.
-
- // If one side of the face
- // is refined, all the fine
- // face dofs couple with
- // the coarse one.
-
- // Wolfgang, do they couple
- // with each other by
- // constraints?
-
- // This will not work with
- // different couplings on
- // different cells.
- neighbor_indices.resize(nfe.dofs_per_cell);
- neighbor->get_mg_dof_indices(neighbor_indices);
- for (unsigned int base=0;base<nfe.n_base_elements();++base)
- for (unsigned int mult=0;mult<nfe.element_multiplicity(base);++mult)
- for (unsigned int i=0;i<fe.dofs_per_cell;++i)
- if (couple_cell[fe_index](fe.system_to_component_index(i).first,
- nfe.first_block_of_base(base) + mult) != DoFTools::none)
- row_lengths[cell_indices[i]]
- += nfe.base_element(base).dofs_per_face;
- for (unsigned int base=0;base<fe.n_base_elements();++base)
- for (unsigned int mult=0;mult<fe.element_multiplicity(base);++mult)
- for (unsigned int i=0;i<nfe.dofs_per_cell;++i)
- if (couple_cell[fe_index](nfe.system_to_component_index(i).first,
- fe.first_block_of_base(base) + mult) != DoFTools::none)
- row_lengths[neighbor_indices[i]]
- += fe.base_element(base).dofs_per_face;
- }
+ const FiniteElement<dim>& fe = cell->get_fe();
+ const unsigned int fe_index = cell->active_fe_index();
+
+ Assert (couplings.n_rows()==fe.n_components(),
+ ExcDimensionMismatch(couplings.n_rows(), fe.n_components()));
+ Assert (couplings.n_cols()==fe.n_components(),
+ ExcDimensionMismatch(couplings.n_cols(), fe.n_components()));
+ Assert (flux_couplings.n_rows()==fe.n_components(),
+ ExcDimensionMismatch(flux_couplings.n_rows(), fe.n_components()));
+ Assert (flux_couplings.n_cols()==fe.n_components(),
+ ExcDimensionMismatch(flux_couplings.n_cols(), fe.n_components()));
+
+ cell_indices.resize(fe.dofs_per_cell);
+ cell->get_mg_dof_indices(cell_indices);
+ unsigned int i = 0;
+ // First, dofs on
+ // vertices. We assume that
+ // each vertex dof couples
+ // with all dofs on
+ // adjacent grid cells.
+
+ // Adding all dofs of the cells
+ // will add dofs of the faces
+ // of the cell adjacent to the
+ // vertex twice. Therefore, we
+ // subtract these here and add
+ // them in a loop over the
+ // faces below.
+
+ // in 1d, faces and vertices
+ // are identical. Nevertheless,
+ // this will only work if
+ // dofs_per_face is zero and
+ // dofs_per_vertex is
+ // arbitrary, not the other way
+ // round.
+ unsigned int increment;
+ while (i < fe.first_line_index)
+ {
+ for (unsigned int base=0;base<fe.n_base_elements();++base)
+ for (unsigned int mult=0;mult<fe.element_multiplicity(base);++mult)
+ if (couple_cell[fe_index](fe.system_to_block_index(i).first,
+ fe.first_block_of_base(base) + mult) != DoFTools::none)
+ {
+ increment = fe.base_element(base).dofs_per_cell
+ - dim * fe.base_element(base).dofs_per_face;
+ row_lengths[cell_indices[i]] += increment;
+ }
+ ++i;
+ }
+ // From now on, if an object is
+ // a cell, its dofs only couple
+ // inside the cell. Since the
+ // faces are handled below, we
+ // have to subtract ALL faces
+ // in this case.
+
+ // In all other cases we
+ // subtract adjacent faces to be
+ // added in the loop below.
+ while (i < fe.first_quad_index)
+ {
+ for (unsigned int base=0;base<fe.n_base_elements();++base)
+ for (unsigned int mult=0;mult<fe.element_multiplicity(base);++mult)
+ if (couple_cell[fe_index](fe.system_to_block_index(i).first,
+ fe.first_block_of_base(base) + mult) != DoFTools::none)
+ {
+ increment = fe.base_element(base).dofs_per_cell
+ - ((dim>1)
+ ? (dim-1)
+ : GeometryInfo<dim>::faces_per_cell)
+ * fe.base_element(base).dofs_per_face;
+ row_lengths[cell_indices[i]] += increment;
+ }
+ ++i;
+ }
+
+ // Now quads in 2D and 3D
+ while (i < fe.first_hex_index)
+ {
+ for (unsigned int base=0;base<fe.n_base_elements();++base)
+ for (unsigned int mult=0;mult<fe.element_multiplicity(base);++mult)
+ if (couple_cell[fe_index](fe.system_to_block_index(i).first,
+ fe.first_block_of_base(base) + mult) != DoFTools::none)
+ {
+ increment = fe.base_element(base).dofs_per_cell
+ - ((dim>2)
+ ? (dim-2)
+ : GeometryInfo<dim>::faces_per_cell)
+ * fe.base_element(base).dofs_per_face;
+ row_lengths[cell_indices[i]] += increment;
+ }
+ ++i;
+ }
+
+ // Finally, cells in 3D
+ while (i < fe.dofs_per_cell)
+ {
+ for (unsigned int base=0;base<fe.n_base_elements();++base)
+ for (unsigned int mult=0;mult<fe.element_multiplicity(base);++mult)
+ if (couple_cell[fe_index](fe.system_to_block_index(i).first,
+ fe.first_block_of_base(base) + mult) != DoFTools::none)
+ {
+ increment = fe.base_element(base).dofs_per_cell
+ - GeometryInfo<dim>::faces_per_cell
+ * fe.base_element(base).dofs_per_face;
+ row_lengths[cell_indices[i]] += increment;
+ }
+ ++i;
+ }
+
+ // At this point, we have
+ // counted all dofs
+ // contributiong from cells
+ // coupled topologically to the
+ // adjacent cells, but we
+ // subtracted some faces.
+
+ // Now, let's go by the faces
+ // and add the missing
+ // contribution as well as the
+ // flux contributions.
+ for (unsigned int iface=0;iface<GeometryInfo<dim>::faces_per_cell;++iface)
+ {
+ bool level_boundary = cell->at_boundary(iface);
+ typename MGDoFHandler<dim,spacedim>::cell_iterator neighbor;
+ if (!level_boundary)
+ {
+ neighbor = cell->neighbor(iface);
+ if (static_cast<unsigned int>(neighbor->level()) != level)
+ level_boundary = true;
+ }
+
+ if (level_boundary)
+ {
+ for (unsigned int i=0;i<fe.dofs_per_cell;++i)
+ row_lengths[cell_indices[i]] += fe.dofs_per_face;
+ continue;
+ }
+
+ const FiniteElement<dim>& nfe = neighbor->get_fe();
+ typename MGDoFHandler<dim,spacedim>::face_iterator face = cell->face(iface);
+
+ // Flux couplings are
+ // computed from both sides
+ // for simplicity.
+
+ // The dofs on the common face
+ // will be handled below,
+ // therefore, we subtract them
+ // here.
+ for (unsigned int base=0;base<nfe.n_base_elements();++base)
+ for (unsigned int mult=0;mult<nfe.element_multiplicity(base);++mult)
+ for (unsigned int i=0;i<fe.dofs_per_cell;++i)
+ if (couple_face[fe_index](fe.system_to_block_index(i).first,
+ nfe.first_block_of_base(base) + mult) != DoFTools::none)
+ {
+ unsigned int increment = nfe.base_element(base).dofs_per_cell
+ - nfe.base_element(base).dofs_per_face;
+ row_lengths[cell_indices[i]] += increment;
+ }
+
+ // Do this only once per
+ // face and not on the
+ // hanging faces.
+ if (face->user_flag_set())
+ continue;
+ face->set_user_flag();
+ // At this point, we assume
+ // that each cell added its
+ // dofs minus the face to
+ // the couplings of the
+ // face dofs. Since we
+ // subtracted two faces, we
+ // have to re-add one.
+
+ // If one side of the face
+ // is refined, all the fine
+ // face dofs couple with
+ // the coarse one.
+
+ // Wolfgang, do they couple
+ // with each other by
+ // constraints?
+
+ // This will not work with
+ // different couplings on
+ // different cells.
+ neighbor_indices.resize(nfe.dofs_per_cell);
+ neighbor->get_mg_dof_indices(neighbor_indices);
+ for (unsigned int base=0;base<nfe.n_base_elements();++base)
+ for (unsigned int mult=0;mult<nfe.element_multiplicity(base);++mult)
+ for (unsigned int i=0;i<fe.dofs_per_cell;++i)
+ if (couple_cell[fe_index](fe.system_to_component_index(i).first,
+ nfe.first_block_of_base(base) + mult) != DoFTools::none)
+ row_lengths[cell_indices[i]]
+ += nfe.base_element(base).dofs_per_face;
+ for (unsigned int base=0;base<fe.n_base_elements();++base)
+ for (unsigned int mult=0;mult<fe.element_multiplicity(base);++mult)
+ for (unsigned int i=0;i<nfe.dofs_per_cell;++i)
+ if (couple_cell[fe_index](nfe.system_to_component_index(i).first,
+ fe.first_block_of_base(base) + mult) != DoFTools::none)
+ row_lengths[neighbor_indices[i]]
+ += fe.base_element(base).dofs_per_face;
+ }
}
user_flags_triangulation.load_user_flags(old_flags);
}
const unsigned int n_dofs = dof.n_dofs(level);
Assert (sparsity.n_rows() == n_dofs,
- ExcDimensionMismatch (sparsity.n_rows(), n_dofs));
+ ExcDimensionMismatch (sparsity.n_rows(), n_dofs));
Assert (sparsity.n_cols() == n_dofs,
- ExcDimensionMismatch (sparsity.n_cols(), n_dofs));
+ ExcDimensionMismatch (sparsity.n_cols(), n_dofs));
const unsigned int dofs_per_cell = dof.get_fe().dofs_per_cell;
std::vector<unsigned int> dofs_on_this_cell(dofs_per_cell);
typename MGDoFHandler<dim,spacedim>::cell_iterator cell = dof.begin(level),
- endc = dof.end(level);
+ endc = dof.end(level);
for (; cell!=endc; ++cell)
{
- cell->get_mg_dof_indices (dofs_on_this_cell);
- // make sparsity pattern for this cell
- for (unsigned int i=0; i<dofs_per_cell; ++i)
- for (unsigned int j=0; j<dofs_per_cell; ++j)
- sparsity.add (dofs_on_this_cell[i],
- dofs_on_this_cell[j]);
+ cell->get_mg_dof_indices (dofs_on_this_cell);
+ // make sparsity pattern for this cell
+ for (unsigned int i=0; i<dofs_per_cell; ++i)
+ for (unsigned int j=0; j<dofs_per_cell; ++j)
+ sparsity.add (dofs_on_this_cell[i],
+ dofs_on_this_cell[j]);
}
}
const unsigned int n_dofs = dof.n_dofs(level);
Assert (sparsity.n_rows() == n_dofs,
- ExcDimensionMismatch (sparsity.n_rows(), n_dofs));
+ ExcDimensionMismatch (sparsity.n_rows(), n_dofs));
Assert (sparsity.n_cols() == n_dofs,
- ExcDimensionMismatch (sparsity.n_cols(), n_dofs));
+ ExcDimensionMismatch (sparsity.n_cols(), n_dofs));
const unsigned int dofs_per_cell = dof.get_fe().dofs_per_cell;
std::vector<unsigned int> dofs_on_this_cell(dofs_per_cell);
std::vector<unsigned int> dofs_on_other_cell(dofs_per_cell);
typename MGDoFHandler<dim,spacedim>::cell_iterator cell = dof.begin(level),
- endc = dof.end(level);
+ endc = dof.end(level);
for (; cell!=endc; ++cell)
{
- cell->get_mg_dof_indices (dofs_on_this_cell);
- // make sparsity pattern for this cell
- for (unsigned int i=0; i<dofs_per_cell; ++i)
- for (unsigned int j=0; j<dofs_per_cell; ++j)
- sparsity.add (dofs_on_this_cell[i],
- dofs_on_this_cell[j]);
-
- // Loop over all interior neighbors
- for (unsigned int face = 0;
- face < GeometryInfo<dim>::faces_per_cell;
- ++face)
- {
- if ( (! cell->at_boundary(face)) &&
- (static_cast<unsigned int>(cell->neighbor_level(face)) == level) )
- {
- typename MGDoFHandler<dim,spacedim>::cell_iterator
- neighbor = cell->neighbor(face);
- neighbor->get_mg_dof_indices (dofs_on_other_cell);
- // only add one direction
- // The other is taken care of
- // by neighbor.
- for (unsigned int i=0; i<dofs_per_cell; ++i)
- {
- for (unsigned int j=0; j<dofs_per_cell; ++j)
- {
- sparsity.add (dofs_on_this_cell[i],
- dofs_on_other_cell[j]);
- }
- }
- }
- }
+ cell->get_mg_dof_indices (dofs_on_this_cell);
+ // make sparsity pattern for this cell
+ for (unsigned int i=0; i<dofs_per_cell; ++i)
+ for (unsigned int j=0; j<dofs_per_cell; ++j)
+ sparsity.add (dofs_on_this_cell[i],
+ dofs_on_this_cell[j]);
+
+ // Loop over all interior neighbors
+ for (unsigned int face = 0;
+ face < GeometryInfo<dim>::faces_per_cell;
+ ++face)
+ {
+ if ( (! cell->at_boundary(face)) &&
+ (static_cast<unsigned int>(cell->neighbor_level(face)) == level) )
+ {
+ typename MGDoFHandler<dim,spacedim>::cell_iterator
+ neighbor = cell->neighbor(face);
+ neighbor->get_mg_dof_indices (dofs_on_other_cell);
+ // only add one direction
+ // The other is taken care of
+ // by neighbor.
+ for (unsigned int i=0; i<dofs_per_cell; ++i)
+ {
+ for (unsigned int j=0; j<dofs_per_cell; ++j)
+ {
+ sparsity.add (dofs_on_this_cell[i],
+ dofs_on_other_cell[j]);
+ }
+ }
+ }
+ }
}
}
const unsigned int level)
{
Assert ((level>=1) && (level<dof.get_tria().n_levels()),
- ExcIndexRange(level, 1, dof.get_tria().n_levels()));
+ ExcIndexRange(level, 1, dof.get_tria().n_levels()));
const unsigned int fine_dofs = dof.n_dofs(level);
const unsigned int coarse_dofs = dof.n_dofs(level-1);
- // Matrix maps from fine level to coarse level
+ // Matrix maps from fine level to coarse level
Assert (sparsity.n_rows() == coarse_dofs,
- ExcDimensionMismatch (sparsity.n_rows(), coarse_dofs));
+ ExcDimensionMismatch (sparsity.n_rows(), coarse_dofs));
Assert (sparsity.n_cols() == fine_dofs,
- ExcDimensionMismatch (sparsity.n_cols(), fine_dofs));
+ ExcDimensionMismatch (sparsity.n_cols(), fine_dofs));
const unsigned int dofs_per_cell = dof.get_fe().dofs_per_cell;
std::vector<unsigned int> dofs_on_this_cell(dofs_per_cell);
std::vector<unsigned int> dofs_on_other_cell(dofs_per_cell);
typename MGDoFHandler<dim,spacedim>::cell_iterator cell = dof.begin(level),
- endc = dof.end(level);
+ endc = dof.end(level);
for (; cell!=endc; ++cell)
{
- cell->get_mg_dof_indices (dofs_on_this_cell);
- // Loop over all interior neighbors
- for (unsigned int face = 0;
- face < GeometryInfo<dim>::faces_per_cell;
- ++face)
- {
- // Neighbor is coarser
-
- if ( (! cell->at_boundary(face)) &&
- (static_cast<unsigned int>(cell->neighbor_level(face)) != level) )
- {
- typename MGDoFHandler<dim,spacedim>::cell_iterator
- neighbor = cell->neighbor(face);
- neighbor->get_mg_dof_indices (dofs_on_other_cell);
-
- for (unsigned int i=0; i<dofs_per_cell; ++i)
- {
- for (unsigned int j=0; j<dofs_per_cell; ++j)
- {
- sparsity.add (dofs_on_other_cell[i],
- dofs_on_this_cell[j]);
- sparsity.add (dofs_on_other_cell[j],
- dofs_on_this_cell[i]);
- }
- }
- }
- }
+ cell->get_mg_dof_indices (dofs_on_this_cell);
+ // Loop over all interior neighbors
+ for (unsigned int face = 0;
+ face < GeometryInfo<dim>::faces_per_cell;
+ ++face)
+ {
+ // Neighbor is coarser
+
+ if ( (! cell->at_boundary(face)) &&
+ (static_cast<unsigned int>(cell->neighbor_level(face)) != level) )
+ {
+ typename MGDoFHandler<dim,spacedim>::cell_iterator
+ neighbor = cell->neighbor(face);
+ neighbor->get_mg_dof_indices (dofs_on_other_cell);
+
+ for (unsigned int i=0; i<dofs_per_cell; ++i)
+ {
+ for (unsigned int j=0; j<dofs_per_cell; ++j)
+ {
+ sparsity.add (dofs_on_other_cell[i],
+ dofs_on_this_cell[j]);
+ sparsity.add (dofs_on_other_cell[j],
+ dofs_on_this_cell[i]);
+ }
+ }
+ }
+ }
}
}
const unsigned int n_comp = fe.n_components();
Assert (sparsity.n_rows() == n_dofs,
- ExcDimensionMismatch (sparsity.n_rows(), n_dofs));
+ ExcDimensionMismatch (sparsity.n_rows(), n_dofs));
Assert (sparsity.n_cols() == n_dofs,
- ExcDimensionMismatch (sparsity.n_cols(), n_dofs));
+ ExcDimensionMismatch (sparsity.n_cols(), n_dofs));
Assert (int_mask.n_rows() == n_comp,
- ExcDimensionMismatch (int_mask.n_rows(), n_comp));
+ ExcDimensionMismatch (int_mask.n_rows(), n_comp));
Assert (int_mask.n_cols() == n_comp,
- ExcDimensionMismatch (int_mask.n_cols(), n_comp));
+ ExcDimensionMismatch (int_mask.n_cols(), n_comp));
Assert (flux_mask.n_rows() == n_comp,
- ExcDimensionMismatch (flux_mask.n_rows(), n_comp));
+ ExcDimensionMismatch (flux_mask.n_rows(), n_comp));
Assert (flux_mask.n_cols() == n_comp,
- ExcDimensionMismatch (flux_mask.n_cols(), n_comp));
+ ExcDimensionMismatch (flux_mask.n_cols(), n_comp));
const unsigned int total_dofs = fe.dofs_per_cell;
std::vector<unsigned int> dofs_on_this_cell(total_dofs);
Table<2,bool> support_on_face(total_dofs, GeometryInfo<dim>::faces_per_cell);
typename MGDoFHandler<dim,spacedim>::cell_iterator cell = dof.begin(level),
- endc = dof.end(level);
+ endc = dof.end(level);
const Table<2,DoFTools::Coupling>
int_dof_mask = DoFTools::dof_couplings_from_component_couplings(fe, int_mask),
for (unsigned int i=0; i<total_dofs; ++i)
for (unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell;++f)
- support_on_face(i,f) = fe.has_support_on_face(i,f);
-
- // Clear user flags because we will
- // need them. But first we save
- // them and make sure that we
- // restore them later such that at
- // the end of this function the
- // Triangulation will be in the
- // same state as it was at the
- // beginning of this function.
+ support_on_face(i,f) = fe.has_support_on_face(i,f);
+
+ // Clear user flags because we will
+ // need them. But first we save
+ // them and make sure that we
+ // restore them later such that at
+ // the end of this function the
+ // Triangulation will be in the
+ // same state as it was at the
+ // beginning of this function.
std::vector<bool> user_flags;
dof.get_tria().save_user_flags(user_flags);
const_cast<Triangulation<dim,spacedim> &>(dof.get_tria()).clear_user_flags ();
for (; cell!=endc; ++cell)
{
- cell->get_mg_dof_indices (dofs_on_this_cell);
- // make sparsity pattern for this cell
- for (unsigned int i=0; i<total_dofs; ++i)
- for (unsigned int j=0; j<total_dofs; ++j)
- if (int_dof_mask[i][j] != DoFTools::none)
- sparsity.add (dofs_on_this_cell[i],
- dofs_on_this_cell[j]);
-
- // Loop over all interior neighbors
- for (unsigned int face = 0;
- face < GeometryInfo<dim>::faces_per_cell;
- ++face)
- {
- typename MGDoFHandler<dim,spacedim>::face_iterator cell_face = cell->face(face);
- if (cell_face->user_flag_set ())
- continue;
-
- if (cell->at_boundary (face) )
- {
- for (unsigned int i=0; i<total_dofs; ++i)
- {
- const bool i_non_zero_i = support_on_face (i, face);
- for (unsigned int j=0; j<total_dofs; ++j)
- {
- const bool j_non_zero_i = support_on_face (j, face);
-
- if (flux_dof_mask(i,j) == DoFTools::always)
- sparsity.add (dofs_on_this_cell[i],
- dofs_on_this_cell[j]);
- if (flux_dof_mask(i,j) == DoFTools::nonzero
- && i_non_zero_i && j_non_zero_i)
- sparsity.add (dofs_on_this_cell[i],
- dofs_on_this_cell[j]);
- }
- }
- }
- else
- {
- typename MGDoFHandler<dim,spacedim>::cell_iterator
- neighbor = cell->neighbor(face);
-
- if (neighbor->level() < cell->level())
- continue;
-
- unsigned int neighbor_face = cell->neighbor_of_neighbor(face);
-
- neighbor->get_mg_dof_indices (dofs_on_other_cell);
- for (unsigned int i=0; i<total_dofs; ++i)
- {
- const bool i_non_zero_i = support_on_face (i, face);
- const bool i_non_zero_e = support_on_face (i, neighbor_face);
- for (unsigned int j=0; j<total_dofs; ++j)
- {
- const bool j_non_zero_i = support_on_face (j, face);
- const bool j_non_zero_e = support_on_face (j, neighbor_face);
- if (flux_dof_mask(i,j) == DoFTools::always)
- {
- sparsity.add (dofs_on_this_cell[i],
- dofs_on_other_cell[j]);
- sparsity.add (dofs_on_other_cell[i],
- dofs_on_this_cell[j]);
- sparsity.add (dofs_on_this_cell[i],
- dofs_on_this_cell[j]);
- sparsity.add (dofs_on_other_cell[i],
- dofs_on_other_cell[j]);
- }
- if (flux_dof_mask(i,j) == DoFTools::nonzero)
- {
- if (i_non_zero_i && j_non_zero_e)
- sparsity.add (dofs_on_this_cell[i],
- dofs_on_other_cell[j]);
- if (i_non_zero_e && j_non_zero_i)
- sparsity.add (dofs_on_other_cell[i],
- dofs_on_this_cell[j]);
- if (i_non_zero_i && j_non_zero_i)
- sparsity.add (dofs_on_this_cell[i],
- dofs_on_this_cell[j]);
- if (i_non_zero_e && j_non_zero_e)
- sparsity.add (dofs_on_other_cell[i],
- dofs_on_other_cell[j]);
- }
-
- if (flux_dof_mask(j,i) == DoFTools::always)
- {
- sparsity.add (dofs_on_this_cell[j],
- dofs_on_other_cell[i]);
- sparsity.add (dofs_on_other_cell[j],
- dofs_on_this_cell[i]);
- sparsity.add (dofs_on_this_cell[j],
- dofs_on_this_cell[i]);
- sparsity.add (dofs_on_other_cell[j],
- dofs_on_other_cell[i]);
- }
- if (flux_dof_mask(j,i) == DoFTools::nonzero)
- {
- if (j_non_zero_i && i_non_zero_e)
- sparsity.add (dofs_on_this_cell[j],
- dofs_on_other_cell[i]);
- if (j_non_zero_e && i_non_zero_i)
- sparsity.add (dofs_on_other_cell[j],
- dofs_on_this_cell[i]);
- if (j_non_zero_i && i_non_zero_i)
- sparsity.add (dofs_on_this_cell[j],
- dofs_on_this_cell[i]);
- if (j_non_zero_e && i_non_zero_e)
- sparsity.add (dofs_on_other_cell[j],
- dofs_on_other_cell[i]);
- }
- }
- }
- neighbor->face(neighbor_face)->set_user_flag ();
- }
- }
+ cell->get_mg_dof_indices (dofs_on_this_cell);
+ // make sparsity pattern for this cell
+ for (unsigned int i=0; i<total_dofs; ++i)
+ for (unsigned int j=0; j<total_dofs; ++j)
+ if (int_dof_mask[i][j] != DoFTools::none)
+ sparsity.add (dofs_on_this_cell[i],
+ dofs_on_this_cell[j]);
+
+ // Loop over all interior neighbors
+ for (unsigned int face = 0;
+ face < GeometryInfo<dim>::faces_per_cell;
+ ++face)
+ {
+ typename MGDoFHandler<dim,spacedim>::face_iterator cell_face = cell->face(face);
+ if (cell_face->user_flag_set ())
+ continue;
+
+ if (cell->at_boundary (face) )
+ {
+ for (unsigned int i=0; i<total_dofs; ++i)
+ {
+ const bool i_non_zero_i = support_on_face (i, face);
+ for (unsigned int j=0; j<total_dofs; ++j)
+ {
+ const bool j_non_zero_i = support_on_face (j, face);
+
+ if (flux_dof_mask(i,j) == DoFTools::always)
+ sparsity.add (dofs_on_this_cell[i],
+ dofs_on_this_cell[j]);
+ if (flux_dof_mask(i,j) == DoFTools::nonzero
+ && i_non_zero_i && j_non_zero_i)
+ sparsity.add (dofs_on_this_cell[i],
+ dofs_on_this_cell[j]);
+ }
+ }
+ }
+ else
+ {
+ typename MGDoFHandler<dim,spacedim>::cell_iterator
+ neighbor = cell->neighbor(face);
+
+ if (neighbor->level() < cell->level())
+ continue;
+
+ unsigned int neighbor_face = cell->neighbor_of_neighbor(face);
+
+ neighbor->get_mg_dof_indices (dofs_on_other_cell);
+ for (unsigned int i=0; i<total_dofs; ++i)
+ {
+ const bool i_non_zero_i = support_on_face (i, face);
+ const bool i_non_zero_e = support_on_face (i, neighbor_face);
+ for (unsigned int j=0; j<total_dofs; ++j)
+ {
+ const bool j_non_zero_i = support_on_face (j, face);
+ const bool j_non_zero_e = support_on_face (j, neighbor_face);
+ if (flux_dof_mask(i,j) == DoFTools::always)
+ {
+ sparsity.add (dofs_on_this_cell[i],
+ dofs_on_other_cell[j]);
+ sparsity.add (dofs_on_other_cell[i],
+ dofs_on_this_cell[j]);
+ sparsity.add (dofs_on_this_cell[i],
+ dofs_on_this_cell[j]);
+ sparsity.add (dofs_on_other_cell[i],
+ dofs_on_other_cell[j]);
+ }
+ if (flux_dof_mask(i,j) == DoFTools::nonzero)
+ {
+ if (i_non_zero_i && j_non_zero_e)
+ sparsity.add (dofs_on_this_cell[i],
+ dofs_on_other_cell[j]);
+ if (i_non_zero_e && j_non_zero_i)
+ sparsity.add (dofs_on_other_cell[i],
+ dofs_on_this_cell[j]);
+ if (i_non_zero_i && j_non_zero_i)
+ sparsity.add (dofs_on_this_cell[i],
+ dofs_on_this_cell[j]);
+ if (i_non_zero_e && j_non_zero_e)
+ sparsity.add (dofs_on_other_cell[i],
+ dofs_on_other_cell[j]);
+ }
+
+ if (flux_dof_mask(j,i) == DoFTools::always)
+ {
+ sparsity.add (dofs_on_this_cell[j],
+ dofs_on_other_cell[i]);
+ sparsity.add (dofs_on_other_cell[j],
+ dofs_on_this_cell[i]);
+ sparsity.add (dofs_on_this_cell[j],
+ dofs_on_this_cell[i]);
+ sparsity.add (dofs_on_other_cell[j],
+ dofs_on_other_cell[i]);
+ }
+ if (flux_dof_mask(j,i) == DoFTools::nonzero)
+ {
+ if (j_non_zero_i && i_non_zero_e)
+ sparsity.add (dofs_on_this_cell[j],
+ dofs_on_other_cell[i]);
+ if (j_non_zero_e && i_non_zero_i)
+ sparsity.add (dofs_on_other_cell[j],
+ dofs_on_this_cell[i]);
+ if (j_non_zero_i && i_non_zero_i)
+ sparsity.add (dofs_on_this_cell[j],
+ dofs_on_this_cell[i]);
+ if (j_non_zero_e && i_non_zero_e)
+ sparsity.add (dofs_on_other_cell[j],
+ dofs_on_other_cell[i]);
+ }
+ }
+ }
+ neighbor->face(neighbor_face)->set_user_flag ();
+ }
+ }
}
- // finally restore the user flags
+ // finally restore the user flags
const_cast<Triangulation<dim,spacedim> &>(dof.get_tria()).load_user_flags(user_flags);
}
const unsigned int n_comp = fe.n_components();
Assert ((level>=1) && (level<dof.get_tria().n_levels()),
- ExcIndexRange(level, 1, dof.get_tria().n_levels()));
+ ExcIndexRange(level, 1, dof.get_tria().n_levels()));
const unsigned int fine_dofs = dof.n_dofs(level);
const unsigned int coarse_dofs = dof.n_dofs(level-1);
- // Matrix maps from fine level to coarse level
+ // Matrix maps from fine level to coarse level
Assert (sparsity.n_rows() == coarse_dofs,
- ExcDimensionMismatch (sparsity.n_rows(), coarse_dofs));
+ ExcDimensionMismatch (sparsity.n_rows(), coarse_dofs));
Assert (sparsity.n_cols() == fine_dofs,
- ExcDimensionMismatch (sparsity.n_cols(), fine_dofs));
+ ExcDimensionMismatch (sparsity.n_cols(), fine_dofs));
Assert (flux_mask.n_rows() == n_comp,
- ExcDimensionMismatch (flux_mask.n_rows(), n_comp));
+ ExcDimensionMismatch (flux_mask.n_rows(), n_comp));
Assert (flux_mask.n_cols() == n_comp,
- ExcDimensionMismatch (flux_mask.n_cols(), n_comp));
+ ExcDimensionMismatch (flux_mask.n_cols(), n_comp));
const unsigned int dofs_per_cell = dof.get_fe().dofs_per_cell;
std::vector<unsigned int> dofs_on_this_cell(dofs_per_cell);
Table<2,bool> support_on_face(dofs_per_cell, GeometryInfo<dim>::faces_per_cell);
typename MGDoFHandler<dim,spacedim>::cell_iterator cell = dof.begin(level),
- endc = dof.end(level);
+ endc = dof.end(level);
const Table<2,DoFTools::Coupling> flux_dof_mask
= DoFTools::dof_couplings_from_component_couplings(fe, flux_mask);
for (unsigned int i=0; i<dofs_per_cell; ++i)
for (unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell;++f)
- support_on_face(i,f) = fe.has_support_on_face(i,f);
+ support_on_face(i,f) = fe.has_support_on_face(i,f);
for (; cell!=endc; ++cell)
{
- cell->get_mg_dof_indices (dofs_on_this_cell);
- // Loop over all interior neighbors
- for (unsigned int face = 0;
- face < GeometryInfo<dim>::faces_per_cell;
- ++face)
- {
- // Neighbor is coarser
-
- if ( (! cell->at_boundary(face)) &&
- (static_cast<unsigned int>(cell->neighbor_level(face)) != level) )
- {
- typename MGDoFHandler<dim,spacedim>::cell_iterator
- neighbor = cell->neighbor(face);
- neighbor->get_mg_dof_indices (dofs_on_other_cell);
-
- for (unsigned int i=0; i<dofs_per_cell; ++i)
- {
- for (unsigned int j=0; j<dofs_per_cell; ++j)
- {
- if (flux_dof_mask(i,j) != DoFTools::none)
- {
- sparsity.add (dofs_on_other_cell[i],
- dofs_on_this_cell[j]);
- sparsity.add (dofs_on_other_cell[j],
- dofs_on_this_cell[i]);
- }
- }
- }
- }
- }
+ cell->get_mg_dof_indices (dofs_on_this_cell);
+ // Loop over all interior neighbors
+ for (unsigned int face = 0;
+ face < GeometryInfo<dim>::faces_per_cell;
+ ++face)
+ {
+ // Neighbor is coarser
+
+ if ( (! cell->at_boundary(face)) &&
+ (static_cast<unsigned int>(cell->neighbor_level(face)) != level) )
+ {
+ typename MGDoFHandler<dim,spacedim>::cell_iterator
+ neighbor = cell->neighbor(face);
+ neighbor->get_mg_dof_indices (dofs_on_other_cell);
+
+ for (unsigned int i=0; i<dofs_per_cell; ++i)
+ {
+ for (unsigned int j=0; j<dofs_per_cell; ++j)
+ {
+ if (flux_dof_mask(i,j) != DoFTools::none)
+ {
+ sparsity.add (dofs_on_other_cell[i],
+ dofs_on_this_cell[j]);
+ sparsity.add (dofs_on_other_cell[j],
+ dofs_on_this_cell[i]);
+ }
+ }
+ }
+ }
+ }
}
}
void
count_dofs_per_component (const MGDoFHandler<dim,spacedim> &dof_handler,
- std::vector<std::vector<unsigned int> > &result,
- bool only_once,
- std::vector<unsigned int> target_component)
+ std::vector<std::vector<unsigned int> > &result,
+ bool only_once,
+ std::vector<unsigned int> target_component)
{
const FiniteElement<dim>& fe = dof_handler.get_fe();
const unsigned int n_components = fe.n_components();
const unsigned int nlevels = dof_handler.get_tria().n_levels();
Assert (result.size() == nlevels,
- ExcDimensionMismatch(result.size(), nlevels));
+ ExcDimensionMismatch(result.size(), nlevels));
if (target_component.size() == 0)
{
- target_component.resize(n_components);
- for (unsigned int i=0;i<n_components;++i)
- target_component[i] = i;
+ target_component.resize(n_components);
+ for (unsigned int i=0;i<n_components;++i)
+ target_component[i] = i;
}
Assert(target_component.size() == n_components,
- ExcDimensionMismatch(target_component.size(), n_components));
+ ExcDimensionMismatch(target_component.size(), n_components));
for (unsigned int l=0;l<nlevels;++l)
{
- result[l].resize (n_components);
- std::fill (result[l].begin(),result[l].end(), 0U);
-
- // special case for only one
- // component. treat this first
- // since it does not require any
- // computations
- if (n_components == 1)
- {
- result[l][0] = dof_handler.n_dofs(l);
- } else {
- // otherwise determine the number
- // of dofs in each component
- // separately. do so in parallel
- std::vector<std::vector<bool> >
- dofs_in_component (n_components,
- std::vector<bool>(dof_handler.n_dofs(l),
- false));
- std::vector<std::vector<bool> >
- component_select (n_components,
- std::vector<bool>(n_components, false));
- Threads::TaskGroup<> tasks;
- for (unsigned int i=0; i<n_components; ++i)
- {
- void (*fun_ptr) (const unsigned int level,
- const MGDoFHandler<dim,spacedim> &,
- const std::vector<bool> &,
- std::vector<bool> &,
- bool)
- = &DoFTools::template extract_level_dofs<dim>;
- component_select[i][i] = true;
- tasks += Threads::new_task (fun_ptr,
- l, dof_handler,
- component_select[i],
- dofs_in_component[i], false);
- }
- tasks.join_all();
-
- // next count what we got
- unsigned int component = 0;
- for (unsigned int b=0;b<fe.n_base_elements();++b)
- {
- const FiniteElement<dim>& base = fe.base_element(b);
- // Dimension of base element
- unsigned int d = base.n_components();
-
- for (unsigned int m=0;m<fe.element_multiplicity(b);++m)
- {
- for (unsigned int dd=0;dd<d;++dd)
- {
- if (base.is_primitive() || (!only_once || dd==0))
- result[l][target_component[component]]
- += std::count(dofs_in_component[component].begin(),
- dofs_in_component[component].end(),
- true);
- ++component;
- }
- }
- }
- // finally sanity check
- Assert (!dof_handler.get_fe().is_primitive()
- ||
- std::accumulate (result[l].begin(),
- result[l].end(), 0U)
- ==
- dof_handler.n_dofs(l),
- ExcInternalError());
- }
+ result[l].resize (n_components);
+ std::fill (result[l].begin(),result[l].end(), 0U);
+
+ // special case for only one
+ // component. treat this first
+ // since it does not require any
+ // computations
+ if (n_components == 1)
+ {
+ result[l][0] = dof_handler.n_dofs(l);
+ } else {
+ // otherwise determine the number
+ // of dofs in each component
+ // separately. do so in parallel
+ std::vector<std::vector<bool> >
+ dofs_in_component (n_components,
+ std::vector<bool>(dof_handler.n_dofs(l),
+ false));
+ std::vector<std::vector<bool> >
+ component_select (n_components,
+ std::vector<bool>(n_components, false));
+ Threads::TaskGroup<> tasks;
+ for (unsigned int i=0; i<n_components; ++i)
+ {
+ void (*fun_ptr) (const unsigned int level,
+ const MGDoFHandler<dim,spacedim> &,
+ const std::vector<bool> &,
+ std::vector<bool> &,
+ bool)
+ = &DoFTools::template extract_level_dofs<dim>;
+ component_select[i][i] = true;
+ tasks += Threads::new_task (fun_ptr,
+ l, dof_handler,
+ component_select[i],
+ dofs_in_component[i], false);
+ }
+ tasks.join_all();
+
+ // next count what we got
+ unsigned int component = 0;
+ for (unsigned int b=0;b<fe.n_base_elements();++b)
+ {
+ const FiniteElement<dim>& base = fe.base_element(b);
+ // Dimension of base element
+ unsigned int d = base.n_components();
+
+ for (unsigned int m=0;m<fe.element_multiplicity(b);++m)
+ {
+ for (unsigned int dd=0;dd<d;++dd)
+ {
+ if (base.is_primitive() || (!only_once || dd==0))
+ result[l][target_component[component]]
+ += std::count(dofs_in_component[component].begin(),
+ dofs_in_component[component].end(),
+ true);
+ ++component;
+ }
+ }
+ }
+ // finally sanity check
+ Assert (!dof_handler.get_fe().is_primitive()
+ ||
+ std::accumulate (result[l].begin(),
+ result[l].end(), 0U)
+ ==
+ dof_handler.n_dofs(l),
+ ExcInternalError());
+ }
}
}
void
count_dofs_per_component (const MGDoFHandler<dim,spacedim> &dof_handler,
- std::vector<std::vector<unsigned int> > &result,
- std::vector<unsigned int> target_component)
+ std::vector<std::vector<unsigned int> > &result,
+ std::vector<unsigned int> target_component)
{
count_dofs_per_component (dof_handler, result,
- false, target_component);
+ false, target_component);
}
for (unsigned int l=0;l<n_levels;++l)
std::fill (dofs_per_block[l].begin(), dofs_per_block[l].end(), 0U);
- // If the empty vector was given as
- // default argument, set up this
- // vector as identity.
+ // If the empty vector was given as
+ // default argument, set up this
+ // vector as identity.
if (target_block.size()==0)
{
- target_block.resize(n_blocks);
- for (unsigned int i=0;i<n_blocks;++i)
- target_block[i] = i;
+ target_block.resize(n_blocks);
+ for (unsigned int i=0;i<n_blocks;++i)
+ target_block[i] = i;
}
Assert(target_block.size()==n_blocks,
- ExcDimensionMismatch(target_block.size(),n_blocks));
+ ExcDimensionMismatch(target_block.size(),n_blocks));
const unsigned int max_block
= *std::max_element (target_block.begin(),
- target_block.end());
+ target_block.end());
const unsigned int n_target_blocks = max_block + 1;
for (unsigned int l=0;l<n_levels;++l)
AssertDimension (dofs_per_block[l].size(), n_target_blocks);
- // special case for only one
- // block. treat this first
- // since it does not require any
- // computations
+ // special case for only one
+ // block. treat this first
+ // since it does not require any
+ // computations
if (n_blocks == 1)
{
- for (unsigned int l=0;l<n_levels;++l)
- dofs_per_block[l][0] = dof_handler.n_dofs(l);
- return;
+ for (unsigned int l=0;l<n_levels;++l)
+ dofs_per_block[l][0] = dof_handler.n_dofs(l);
+ return;
}
- // otherwise determine the number
- // of dofs in each block
- // separately. do so in parallel
+ // otherwise determine the number
+ // of dofs in each block
+ // separately. do so in parallel
for (unsigned int l=0;l<n_levels;++l)
{
- std::vector<std::vector<bool> >
- dofs_in_block (n_blocks, std::vector<bool>(dof_handler.n_dofs(l), false));
- std::vector<std::vector<bool> >
- block_select (n_blocks, std::vector<bool>(n_blocks, false));
- Threads::TaskGroup<> tasks;
- for (unsigned int i=0; i<n_blocks; ++i)
- {
- void (*fun_ptr) (const unsigned int level,
- const MGDoFHandler<dim,spacedim>&,
- const std::vector<bool>&,
- std::vector<bool>&,
- bool)
- = &DoFTools::template extract_level_dofs<dim>;
- block_select[i][i] = true;
- tasks += Threads::new_task (fun_ptr,
- l, dof_handler, block_select[i],
- dofs_in_block[i], true);
- };
- tasks.join_all ();
-
- // next count what we got
- for (unsigned int block=0;block<fe.n_blocks();++block)
- dofs_per_block[l][target_block[block]]
- += std::count(dofs_in_block[block].begin(),
- dofs_in_block[block].end(),
- true);
+ std::vector<std::vector<bool> >
+ dofs_in_block (n_blocks, std::vector<bool>(dof_handler.n_dofs(l), false));
+ std::vector<std::vector<bool> >
+ block_select (n_blocks, std::vector<bool>(n_blocks, false));
+ Threads::TaskGroup<> tasks;
+ for (unsigned int i=0; i<n_blocks; ++i)
+ {
+ void (*fun_ptr) (const unsigned int level,
+ const MGDoFHandler<dim,spacedim>&,
+ const std::vector<bool>&,
+ std::vector<bool>&,
+ bool)
+ = &DoFTools::template extract_level_dofs<dim>;
+ block_select[i][i] = true;
+ tasks += Threads::new_task (fun_ptr,
+ l, dof_handler, block_select[i],
+ dofs_in_block[i], true);
+ };
+ tasks.join_all ();
+
+ // next count what we got
+ for (unsigned int block=0;block<fe.n_blocks();++block)
+ dofs_per_block[l][target_block[block]]
+ += std::count(dofs_in_block[block].begin(),
+ dofs_in_block[block].end(),
+ true);
}
}
std::vector<std::set<unsigned int> >& boundary_indices,
const std::vector<bool>& component_mask)
{
- // if for whatever reason we were
- // passed an empty map, return
- // immediately
+ // if for whatever reason we were
+ // passed an empty map, return
+ // immediately
if (function_map.size() == 0)
return;
std::vector<unsigned int> local_dofs;
local_dofs.reserve (DoFTools::max_dofs_per_face(dof));
std::fill (local_dofs.begin (), local_dofs.end (),
- DoFHandler<dim,spacedim>::invalid_dof_index);
+ DoFHandler<dim,spacedim>::invalid_dof_index);
- // First, deal with the simpler
- // case when we have to identify
- // all boundary dofs
+ // First, deal with the simpler
+ // case when we have to identify
+ // all boundary dofs
if (component_mask.size() == 0)
{
- typename MGDoFHandler<dim,spacedim>::cell_iterator
- cell = dof.begin(),
- endc = dof.end();
- for (; cell!=endc; ++cell)
- {
- const FiniteElement<dim> &fe = cell->get_fe();
- const unsigned int level = cell->level();
- local_dofs.resize(fe.dofs_per_face);
-
- for (unsigned int face_no = 0; face_no < GeometryInfo<dim>::faces_per_cell;
- ++face_no)
- if (cell->at_boundary(face_no) == true)
- {
- const typename MGDoFHandler<dim,spacedim>::face_iterator
- face = cell->face(face_no);
- const types::boundary_id_t bi = face->boundary_indicator();
- // Face is listed in
- // boundary map
- if (function_map.find(bi) != function_map.end())
- {
- face->get_mg_dof_indices(level, local_dofs);
- for (unsigned int i=0;i<fe.dofs_per_face;++i)
- boundary_indices[level].insert(local_dofs[i]);
- }
- }
- }
+ typename MGDoFHandler<dim,spacedim>::cell_iterator
+ cell = dof.begin(),
+ endc = dof.end();
+ for (; cell!=endc; ++cell)
+ {
+ const FiniteElement<dim> &fe = cell->get_fe();
+ const unsigned int level = cell->level();
+ local_dofs.resize(fe.dofs_per_face);
+
+ for (unsigned int face_no = 0; face_no < GeometryInfo<dim>::faces_per_cell;
+ ++face_no)
+ if (cell->at_boundary(face_no) == true)
+ {
+ const typename MGDoFHandler<dim,spacedim>::face_iterator
+ face = cell->face(face_no);
+ const types::boundary_id_t bi = face->boundary_indicator();
+ // Face is listed in
+ // boundary map
+ if (function_map.find(bi) != function_map.end())
+ {
+ face->get_mg_dof_indices(level, local_dofs);
+ for (unsigned int i=0;i<fe.dofs_per_face;++i)
+ boundary_indices[level].insert(local_dofs[i]);
+ }
+ }
+ }
}
else
{
- Assert (std::count(component_mask.begin(), component_mask.end(), true) > 0,
- ExcMessage("It's probably worthwhile to select at least one component."));
-
- typename MGDoFHandler<dim,spacedim>::cell_iterator
- cell = dof.begin(),
- endc = dof.end();
- for (; cell!=endc; ++cell)
- for (unsigned int face_no = 0; face_no < GeometryInfo<dim>::faces_per_cell;
- ++face_no)
- {
- if (cell->at_boundary(face_no) == false)
- continue;
-
- const FiniteElement<dim> &fe = cell->get_fe();
- const unsigned int level = cell->level();
-
- // we can presently deal only with
- // primitive elements for boundary
- // values. this does not preclude
- // us using non-primitive elements
- // in components that we aren't
- // interested in, however. make
- // sure that all shape functions
- // that are non-zero for the
- // components we are interested in,
- // are in fact primitive
- for (unsigned int i=0; i<cell->get_fe().dofs_per_cell; ++i)
- {
- const std::vector<bool> &nonzero_component_array
- = cell->get_fe().get_nonzero_components (i);
- for (unsigned int c=0; c<n_components; ++c)
- if ((nonzero_component_array[c] == true)
- &&
- (component_mask[c] == true))
- Assert (cell->get_fe().is_primitive (i),
- ExcMessage ("This function can only deal with requested boundary "
- "values that correspond to primitive (scalar) base "
- "elements"));
- }
-
- typename MGDoFHandler<dim,spacedim>::face_iterator face = cell->face(face_no);
- const types::boundary_id_t boundary_component = face->boundary_indicator();
- if (function_map.find(boundary_component) != function_map.end())
- // face is of the right component
- {
- // get indices, physical location and
- // boundary values of dofs on this
- // face
- local_dofs.resize (fe.dofs_per_face);
- face->get_mg_dof_indices (level, local_dofs);
- if (fe_is_system)
- {
- // enter those dofs
- // into the list that
- // match the
- // component
- // signature. avoid
- // the usual
- // complication that
- // we can't just use
- // *_system_to_component_index
- // for non-primitive
- // FEs
- for (unsigned int i=0; i<local_dofs.size(); ++i)
- {
- unsigned int component;
- if (fe.is_primitive())
- component = fe.face_system_to_component_index(i).first;
- else
- {
- // non-primitive
- // case. make
- // sure that
- // this
- // particular
- // shape
- // function
- // _is_
- // primitive,
- // and get at
- // it's
- // component. use
- // usual
- // trick to
- // transfer
- // face dof
- // index to
- // cell dof
-
- // index
- const unsigned int cell_i
- = (dim == 1 ?
- i
- :
- (dim == 2 ?
- (i<2*fe.dofs_per_vertex ? i : i+2*fe.dofs_per_vertex)
- :
- (dim == 3 ?
- (i<4*fe.dofs_per_vertex ?
- i
- :
- (i<4*fe.dofs_per_vertex+4*fe.dofs_per_line ?
- i+4*fe.dofs_per_vertex
- :
- i+4*fe.dofs_per_vertex+8*fe.dofs_per_line))
- :
- numbers::invalid_unsigned_int)));
- Assert (cell_i < fe.dofs_per_cell, ExcInternalError());
-
- // make sure
- // that if
- // this is
- // not a
- // primitive
- // shape function,
- // then all
- // the
- // corresponding
- // components
- // in the
- // mask are
- // not set
+ Assert (std::count(component_mask.begin(), component_mask.end(), true) > 0,
+ ExcMessage("It's probably worthwhile to select at least one component."));
+
+ typename MGDoFHandler<dim,spacedim>::cell_iterator
+ cell = dof.begin(),
+ endc = dof.end();
+ for (; cell!=endc; ++cell)
+ for (unsigned int face_no = 0; face_no < GeometryInfo<dim>::faces_per_cell;
+ ++face_no)
+ {
+ if (cell->at_boundary(face_no) == false)
+ continue;
+
+ const FiniteElement<dim> &fe = cell->get_fe();
+ const unsigned int level = cell->level();
+
+ // we can presently deal only with
+ // primitive elements for boundary
+ // values. this does not preclude
+ // us using non-primitive elements
+ // in components that we aren't
+ // interested in, however. make
+ // sure that all shape functions
+ // that are non-zero for the
+ // components we are interested in,
+ // are in fact primitive
+ for (unsigned int i=0; i<cell->get_fe().dofs_per_cell; ++i)
+ {
+ const std::vector<bool> &nonzero_component_array
+ = cell->get_fe().get_nonzero_components (i);
+ for (unsigned int c=0; c<n_components; ++c)
+ if ((nonzero_component_array[c] == true)
+ &&
+ (component_mask[c] == true))
+ Assert (cell->get_fe().is_primitive (i),
+ ExcMessage ("This function can only deal with requested boundary "
+ "values that correspond to primitive (scalar) base "
+ "elements"));
+ }
+
+ typename MGDoFHandler<dim,spacedim>::face_iterator face = cell->face(face_no);
+ const types::boundary_id_t boundary_component = face->boundary_indicator();
+ if (function_map.find(boundary_component) != function_map.end())
+ // face is of the right component
+ {
+ // get indices, physical location and
+ // boundary values of dofs on this
+ // face
+ local_dofs.resize (fe.dofs_per_face);
+ face->get_mg_dof_indices (level, local_dofs);
+ if (fe_is_system)
+ {
+ // enter those dofs
+ // into the list that
+ // match the
+ // component
+ // signature. avoid
+ // the usual
+ // complication that
+ // we can't just use
+ // *_system_to_component_index
+ // for non-primitive
+ // FEs
+ for (unsigned int i=0; i<local_dofs.size(); ++i)
+ {
+ unsigned int component;
+ if (fe.is_primitive())
+ component = fe.face_system_to_component_index(i).first;
+ else
+ {
+ // non-primitive
+ // case. make
+ // sure that
+ // this
+ // particular
+ // shape
+ // function
+ // _is_
+ // primitive,
+ // and get at
+ // it's
+ // component. use
+ // usual
+ // trick to
+ // transfer
+ // face dof
+ // index to
+ // cell dof
+
+ // index
+ const unsigned int cell_i
+ = (dim == 1 ?
+ i
+ :
+ (dim == 2 ?
+ (i<2*fe.dofs_per_vertex ? i : i+2*fe.dofs_per_vertex)
+ :
+ (dim == 3 ?
+ (i<4*fe.dofs_per_vertex ?
+ i
+ :
+ (i<4*fe.dofs_per_vertex+4*fe.dofs_per_line ?
+ i+4*fe.dofs_per_vertex
+ :
+ i+4*fe.dofs_per_vertex+8*fe.dofs_per_line))
+ :
+ numbers::invalid_unsigned_int)));
+ Assert (cell_i < fe.dofs_per_cell, ExcInternalError());
+
+ // make sure
+ // that if
+ // this is
+ // not a
+ // primitive
+ // shape function,
+ // then all
+ // the
+ // corresponding
+ // components
+ // in the
+ // mask are
+ // not set
// if (!fe.is_primitive(cell_i))
// for (unsigned int c=0; c<n_components; ++c)
// if (fe.get_nonzero_components(cell_i)[c])
// components. if shape function is non-primitive, then we will ignore
// the result in the following anyway, otherwise there's only one
// non-zero component which we will use
- component = (std::find (fe.get_nonzero_components(cell_i).begin(),
- fe.get_nonzero_components(cell_i).end(),
- true)
- -
- fe.get_nonzero_components(cell_i).begin());
- }
-
- if (component_mask[component] == true)
- boundary_indices[level].insert(local_dofs[i]);
- }
- }
- else
- for (unsigned int i=0; i<local_dofs.size(); ++i)
- boundary_indices[level].insert(local_dofs[i]);
- }
- }
+ component = (std::find (fe.get_nonzero_components(cell_i).begin(),
+ fe.get_nonzero_components(cell_i).end(),
+ true)
+ -
+ fe.get_nonzero_components(cell_i).begin());
+ }
+
+ if (component_mask[component] == true)
+ boundary_indices[level].insert(local_dofs[i]);
+ }
+ }
+ else
+ for (unsigned int i=0; i<local_dofs.size(); ++i)
+ boundary_indices[level].insert(local_dofs[i]);
+ }
+ }
}
}
void
make_boundary_list(const MGDoFHandler<dim,spacedim>& dof,
- const typename FunctionMap<dim>::type& function_map,
- std::vector<IndexSet>& boundary_indices,
- const std::vector<bool>& component_mask)
+ const typename FunctionMap<dim>::type& function_map,
+ std::vector<IndexSet>& boundary_indices,
+ const std::vector<bool>& component_mask)
{
Assert (boundary_indices.size() == dof.get_tria().n_levels(),
- ExcDimensionMismatch (boundary_indices.size(),
- dof.get_tria().n_levels()));
+ ExcDimensionMismatch (boundary_indices.size(),
+ dof.get_tria().n_levels()));
std::vector<std::set<unsigned int> >
my_boundary_indices (dof.get_tria().n_levels());
make_boundary_list (dof, function_map, my_boundary_indices, component_mask);
for (unsigned int i=0; i<dof.get_tria().n_levels(); ++i)
{
- boundary_indices[i] = IndexSet (dof.n_dofs(i));
- boundary_indices[i].add_indices (my_boundary_indices[i].begin(),
- my_boundary_indices[i].end());
+ boundary_indices[i] = IndexSet (dof.n_dofs(i));
+ boundary_indices[i].add_indices (my_boundary_indices[i].begin(),
+ my_boundary_indices[i].end());
}
}
template <int dim, int spacedim>
void
extract_inner_interface_dofs (const MGDoFHandler<dim,spacedim> &mg_dof_handler,
- std::vector<std::vector<bool> > &interface_dofs)
+ std::vector<std::vector<bool> > &interface_dofs)
{
Assert (interface_dofs.size() == mg_dof_handler.get_tria().n_levels(),
- ExcDimensionMismatch (interface_dofs.size(),
- mg_dof_handler.get_tria().n_levels()));
+ ExcDimensionMismatch (interface_dofs.size(),
+ mg_dof_handler.get_tria().n_levels()));
for (unsigned int l=0; l<mg_dof_handler.get_tria().n_levels(); ++l)
{
- Assert (interface_dofs[l].size() == mg_dof_handler.n_dofs(l),
- ExcDimensionMismatch (interface_dofs[l].size(),
- mg_dof_handler.n_dofs(l)));
+ Assert (interface_dofs[l].size() == mg_dof_handler.n_dofs(l),
+ ExcDimensionMismatch (interface_dofs[l].size(),
+ mg_dof_handler.n_dofs(l)));
- std::fill (interface_dofs[l].begin(),
- interface_dofs[l].end(),
- false);
+ std::fill (interface_dofs[l].begin(),
+ interface_dofs[l].end(),
+ false);
}
const FiniteElement<dim,spacedim> &fe = mg_dof_handler.get_fe();
std::vector<bool> cell_dofs(dofs_per_cell, false);
typename MGDoFHandler<dim>::cell_iterator cell = mg_dof_handler.begin(),
- endc = mg_dof_handler.end();
+ endc = mg_dof_handler.end();
for (; cell!=endc; ++cell)
{
- std::fill (cell_dofs.begin(), cell_dofs.end(), false);
-
- for (unsigned int face_nr=0; face_nr<GeometryInfo<dim>::faces_per_cell; ++face_nr)
- {
- const typename DoFHandler<dim,spacedim>::face_iterator face = cell->face(face_nr);
- if (!face->at_boundary())
- {
- //interior face
- const typename MGDoFHandler<dim>::cell_iterator
- neighbor = cell->neighbor(face_nr);
-
- if (neighbor->level() < cell->level())
- {
- for (unsigned int j=0; j<dofs_per_face; ++j)
- cell_dofs[fe.face_to_cell_index(j,face_nr)] = true;
-
- }
- }
- }
-
- const unsigned int level = cell->level();
- cell->get_mg_dof_indices (local_dof_indices);
-
- for(unsigned int i=0; i<dofs_per_cell; ++i)
- if (cell_dofs[i])
- interface_dofs[level][local_dof_indices[i]] = true;
+ std::fill (cell_dofs.begin(), cell_dofs.end(), false);
+
+ for (unsigned int face_nr=0; face_nr<GeometryInfo<dim>::faces_per_cell; ++face_nr)
+ {
+ const typename DoFHandler<dim,spacedim>::face_iterator face = cell->face(face_nr);
+ if (!face->at_boundary())
+ {
+ //interior face
+ const typename MGDoFHandler<dim>::cell_iterator
+ neighbor = cell->neighbor(face_nr);
+
+ if (neighbor->level() < cell->level())
+ {
+ for (unsigned int j=0; j<dofs_per_face; ++j)
+ cell_dofs[fe.face_to_cell_index(j,face_nr)] = true;
+
+ }
+ }
+ }
+
+ const unsigned int level = cell->level();
+ cell->get_mg_dof_indices (local_dof_indices);
+
+ for(unsigned int i=0; i<dofs_per_cell; ++i)
+ if (cell_dofs[i])
+ interface_dofs[level][local_dof_indices[i]] = true;
}
}
template <int dim, int spacedim>
void
extract_non_interface_dofs (const MGDoFHandler<dim,spacedim> &mg_dof_handler,
- std::vector<std::set<unsigned int> > &non_interface_dofs)
+ std::vector<std::set<unsigned int> > &non_interface_dofs)
{
Assert (non_interface_dofs.size() == mg_dof_handler.get_tria().n_levels(),
- ExcDimensionMismatch (non_interface_dofs.size(),
- mg_dof_handler.get_tria().n_levels()));
+ ExcDimensionMismatch (non_interface_dofs.size(),
+ mg_dof_handler.get_tria().n_levels()));
const FiniteElement<dim,spacedim> &fe = mg_dof_handler.get_fe();
std::vector<bool> cell_dofs_interface(dofs_per_cell, false);
typename MGDoFHandler<dim>::cell_iterator cell = mg_dof_handler.begin(),
- endc = mg_dof_handler.end();
+ endc = mg_dof_handler.end();
for (; cell!=endc; ++cell)
std::fill (cell_dofs_interface.begin(), cell_dofs_interface.end(), false);
for (unsigned int face_nr=0; face_nr<GeometryInfo<dim>::faces_per_cell; ++face_nr)
- {
- const typename DoFHandler<dim,spacedim>::face_iterator face = cell->face(face_nr);
- if (!face->at_boundary())
- {
- //interior face
- const typename MGDoFHandler<dim>::cell_iterator
- neighbor = cell->neighbor(face_nr);
-
- if ((neighbor->level() < cell->level()))
- {
- for (unsigned int j=0; j<dofs_per_face; ++j)
- cell_dofs_interface[fe.face_to_cell_index(j,face_nr)] = true;
- }
+ {
+ const typename DoFHandler<dim,spacedim>::face_iterator face = cell->face(face_nr);
+ if (!face->at_boundary())
+ {
+ //interior face
+ const typename MGDoFHandler<dim>::cell_iterator
+ neighbor = cell->neighbor(face_nr);
+
+ if ((neighbor->level() < cell->level()))
+ {
+ for (unsigned int j=0; j<dofs_per_face; ++j)
+ cell_dofs_interface[fe.face_to_cell_index(j,face_nr)] = true;
+ }
else
{
for (unsigned int j=0; j<dofs_per_face; ++j)
- cell_dofs[fe.face_to_cell_index(j,face_nr)] = true;
+ cell_dofs[fe.face_to_cell_index(j,face_nr)] = true;
}
- }
+ }
else
{
- //boundary face
+ //boundary face
for (unsigned int j=0; j<dofs_per_face; ++j)
- cell_dofs[fe.face_to_cell_index(j,face_nr)] = true;
+ cell_dofs[fe.face_to_cell_index(j,face_nr)] = true;
}
- }
+ }
const unsigned int level = cell->level();
cell->get_mg_dof_indices (local_dof_indices);
for(unsigned int i=0; i<dofs_per_cell; ++i)
- if (cell_dofs[i] && !cell_dofs_interface[i])
- non_interface_dofs[level].insert(local_dof_indices[i]);
+ if (cell_dofs[i] && !cell_dofs_interface[i])
+ non_interface_dofs[level].insert(local_dof_indices[i]);
}
}
template <int dim, int spacedim>
void
extract_inner_interface_dofs (const MGDoFHandler<dim,spacedim> &mg_dof_handler,
- std::vector<std::vector<bool> > &interface_dofs,
- std::vector<std::vector<bool> > &boundary_interface_dofs)
+ std::vector<std::vector<bool> > &interface_dofs,
+ std::vector<std::vector<bool> > &boundary_interface_dofs)
{
Assert (interface_dofs.size() == mg_dof_handler.get_tria().n_levels(),
- ExcDimensionMismatch (interface_dofs.size(),
- mg_dof_handler.get_tria().n_levels()));
+ ExcDimensionMismatch (interface_dofs.size(),
+ mg_dof_handler.get_tria().n_levels()));
Assert (boundary_interface_dofs.size() == mg_dof_handler.get_tria().n_levels(),
- ExcDimensionMismatch (boundary_interface_dofs.size(),
- mg_dof_handler.get_tria().n_levels()));
+ ExcDimensionMismatch (boundary_interface_dofs.size(),
+ mg_dof_handler.get_tria().n_levels()));
for (unsigned int l=0; l<mg_dof_handler.get_tria().n_levels(); ++l)
{
- Assert (interface_dofs[l].size() == mg_dof_handler.n_dofs(l),
- ExcDimensionMismatch (interface_dofs[l].size(),
- mg_dof_handler.n_dofs(l)));
- Assert (boundary_interface_dofs[l].size() == mg_dof_handler.n_dofs(l),
- ExcDimensionMismatch (boundary_interface_dofs[l].size(),
- mg_dof_handler.n_dofs(l)));
-
- std::fill (interface_dofs[l].begin(),
- interface_dofs[l].end(),
- false);
- std::fill (boundary_interface_dofs[l].begin(),
- boundary_interface_dofs[l].end(),
- false);
+ Assert (interface_dofs[l].size() == mg_dof_handler.n_dofs(l),
+ ExcDimensionMismatch (interface_dofs[l].size(),
+ mg_dof_handler.n_dofs(l)));
+ Assert (boundary_interface_dofs[l].size() == mg_dof_handler.n_dofs(l),
+ ExcDimensionMismatch (boundary_interface_dofs[l].size(),
+ mg_dof_handler.n_dofs(l)));
+
+ std::fill (interface_dofs[l].begin(),
+ interface_dofs[l].end(),
+ false);
+ std::fill (boundary_interface_dofs[l].begin(),
+ boundary_interface_dofs[l].end(),
+ false);
}
const FiniteElement<dim,spacedim> &fe = mg_dof_handler.get_fe();
std::vector<bool> boundary_cell_dofs(dofs_per_cell, false);
typename MGDoFHandler<dim>::cell_iterator cell = mg_dof_handler.begin(),
- endc = mg_dof_handler.end();
+ endc = mg_dof_handler.end();
for (; cell!=endc; ++cell)
{
- bool has_coarser_neighbor = false;
-
- std::fill (cell_dofs.begin(), cell_dofs.end(), false);
- std::fill (boundary_cell_dofs.begin(), boundary_cell_dofs.end(), false);
-
- for (unsigned int face_nr=0; face_nr<GeometryInfo<dim>::faces_per_cell; ++face_nr)
- {
- const typename DoFHandler<dim,spacedim>::face_iterator face = cell->face(face_nr);
- if (!face->at_boundary())
- {
- //interior face
- const typename MGDoFHandler<dim>::cell_iterator
- neighbor = cell->neighbor(face_nr);
-
- // Do refinement face
- // from the coarse side
- if (neighbor->level() < cell->level())
- {
- for (unsigned int j=0; j<dofs_per_face; ++j)
+ bool has_coarser_neighbor = false;
+
+ std::fill (cell_dofs.begin(), cell_dofs.end(), false);
+ std::fill (boundary_cell_dofs.begin(), boundary_cell_dofs.end(), false);
+
+ for (unsigned int face_nr=0; face_nr<GeometryInfo<dim>::faces_per_cell; ++face_nr)
+ {
+ const typename DoFHandler<dim,spacedim>::face_iterator face = cell->face(face_nr);
+ if (!face->at_boundary())
+ {
+ //interior face
+ const typename MGDoFHandler<dim>::cell_iterator
+ neighbor = cell->neighbor(face_nr);
+
+ // Do refinement face
+ // from the coarse side
+ if (neighbor->level() < cell->level())
+ {
+ for (unsigned int j=0; j<dofs_per_face; ++j)
cell_dofs[fe.face_to_cell_index(j,face_nr)] = true;
- has_coarser_neighbor = true;
- }
- }
- }
+ has_coarser_neighbor = true;
+ }
+ }
+ }
- if (has_coarser_neighbor == true)
- for (unsigned int face_nr=0; face_nr<GeometryInfo<dim>::faces_per_cell; ++face_nr)
- if(cell->at_boundary(face_nr))
- for(unsigned int j=0; j<dofs_per_face; ++j)
-// if (cell_dofs[fe.face_to_cell_index(j,face_nr)] == true) //is this necessary?
- boundary_cell_dofs[fe.face_to_cell_index(j,face_nr)] = true;
+ if (has_coarser_neighbor == true)
+ for (unsigned int face_nr=0; face_nr<GeometryInfo<dim>::faces_per_cell; ++face_nr)
+ if(cell->at_boundary(face_nr))
+ for(unsigned int j=0; j<dofs_per_face; ++j)
+// if (cell_dofs[fe.face_to_cell_index(j,face_nr)] == true) //is this necessary?
+ boundary_cell_dofs[fe.face_to_cell_index(j,face_nr)] = true;
- const unsigned int level = cell->level();
- cell->get_mg_dof_indices (local_dof_indices);
+ const unsigned int level = cell->level();
+ cell->get_mg_dof_indices (local_dof_indices);
- for(unsigned int i=0; i<dofs_per_cell; ++i)
- {
- if (cell_dofs[i])
- interface_dofs[level][local_dof_indices[i]] = true;
+ for(unsigned int i=0; i<dofs_per_cell; ++i)
+ {
+ if (cell_dofs[i])
+ interface_dofs[level][local_dof_indices[i]] = true;
- if (boundary_cell_dofs[i])
- boundary_interface_dofs[level][local_dof_indices[i]] = true;
- }
+ if (boundary_cell_dofs[i])
+ boundary_interface_dofs[level][local_dof_indices[i]] = true;
+ }
}
}
const bool preserve_symmetry,
const bool ignore_zeros)
{
- // if no boundary values are to be applied
- // simply return
+ // if no boundary values are to be applied
+ // simply return
if (boundary_dofs.size() == 0)
return;
const unsigned int n_dofs = matrix.m();
- // if a diagonal entry is zero
- // later, then we use another
- // number instead. take it to be
- // the first nonzero diagonal
- // element of the matrix, or 1 if
- // there is no such thing
+ // if a diagonal entry is zero
+ // later, then we use another
+ // number instead. take it to be
+ // the first nonzero diagonal
+ // element of the matrix, or 1 if
+ // there is no such thing
number first_nonzero_diagonal_entry = 1;
for (unsigned int i=0; i<n_dofs; ++i)
if (matrix.diag_element(i) != 0)
- {
- first_nonzero_diagonal_entry = matrix.diag_element(i);
- break;
- }
+ {
+ first_nonzero_diagonal_entry = matrix.diag_element(i);
+ break;
+ }
std::set<unsigned int>::const_iterator dof = boundary_dofs.begin(),
- endd = boundary_dofs.end();
+ endd = boundary_dofs.end();
const SparsityPattern &sparsity = matrix.get_sparsity_pattern();
const std::size_t *sparsity_rowstart = sparsity.get_rowstart_indices();
const unsigned int *sparsity_colnums = sparsity.get_column_numbers();
for (; dof != endd; ++dof)
{
- Assert (*dof < n_dofs, ExcInternalError());
-
- const unsigned int dof_number = *dof;
- // for each boundary dof:
-
- // set entries of this line
- // to zero except for the diagonal
- // entry. Note that the diagonal
- // entry is always the first one
- // for square matrices, i.e.
- // we shall not set
- // matrix.global_entry(
- // sparsity_rowstart[dof.first])
- const unsigned int last = sparsity_rowstart[dof_number+1];
- for (unsigned int j=sparsity_rowstart[dof_number]+1; j<last; ++j)
- matrix.global_entry(j) = 0.;
-
-
- // set right hand side to
- // wanted value: if main diagonal
- // entry nonzero, don't touch it
- // and scale rhs accordingly. If
- // zero, take the first main
- // diagonal entry we can find, or
- // one if no nonzero main diagonal
- // element exists. Normally, however,
- // the main diagonal entry should
- // not be zero.
- //
- // store the new rhs entry to make
- // the gauss step more efficient
- if(!ignore_zeros)
- matrix.set (dof_number, dof_number,
- first_nonzero_diagonal_entry);
- // if the user wants to have
- // the symmetry of the matrix
- // preserved, and if the
- // sparsity pattern is
- // symmetric, then do a Gauss
- // elimination step with the
- // present row
- if (preserve_symmetry)
- {
- // we have to loop over all
- // rows of the matrix which
- // have a nonzero entry in
- // the column which we work
- // in presently. if the
- // sparsity pattern is
- // symmetric, then we can
- // get the positions of
- // these rows cheaply by
- // looking at the nonzero
- // column numbers of the
- // present row. we need not
- // look at the first entry,
- // since that is the
- // diagonal element and
- // thus the present row
- for (unsigned int j=sparsity_rowstart[dof_number]+1; j<last; ++j)
- {
- const unsigned int row = sparsity_colnums[j];
-
- // find the position of
- // element
- // (row,dof_number)
- const unsigned int *
- p = Utilities::lower_bound(&sparsity_colnums[sparsity_rowstart[row]+1],
- &sparsity_colnums[sparsity_rowstart[row+1]],
- dof_number);
-
- // check whether this line has
- // an entry in the regarding column
- // (check for ==dof_number and
- // != next_row, since if
- // row==dof_number-1, *p is a
- // past-the-end pointer but points
- // to dof_number anyway...)
- //
- // there should be such an entry!
- Assert ((*p == dof_number) &&
- (p != &sparsity_colnums[sparsity_rowstart[row+1]]),
- ExcInternalError());
-
- const unsigned int global_entry
- = (p - &sparsity_colnums[sparsity_rowstart[0]]);
-
- // correct right hand side
- // set matrix entry to zero
- matrix.global_entry(global_entry) = 0.;
- }
- }
+ Assert (*dof < n_dofs, ExcInternalError());
+
+ const unsigned int dof_number = *dof;
+ // for each boundary dof:
+
+ // set entries of this line
+ // to zero except for the diagonal
+ // entry. Note that the diagonal
+ // entry is always the first one
+ // for square matrices, i.e.
+ // we shall not set
+ // matrix.global_entry(
+ // sparsity_rowstart[dof.first])
+ const unsigned int last = sparsity_rowstart[dof_number+1];
+ for (unsigned int j=sparsity_rowstart[dof_number]+1; j<last; ++j)
+ matrix.global_entry(j) = 0.;
+
+
+ // set right hand side to
+ // wanted value: if main diagonal
+ // entry nonzero, don't touch it
+ // and scale rhs accordingly. If
+ // zero, take the first main
+ // diagonal entry we can find, or
+ // one if no nonzero main diagonal
+ // element exists. Normally, however,
+ // the main diagonal entry should
+ // not be zero.
+ //
+ // store the new rhs entry to make
+ // the gauss step more efficient
+ if(!ignore_zeros)
+ matrix.set (dof_number, dof_number,
+ first_nonzero_diagonal_entry);
+ // if the user wants to have
+ // the symmetry of the matrix
+ // preserved, and if the
+ // sparsity pattern is
+ // symmetric, then do a Gauss
+ // elimination step with the
+ // present row
+ if (preserve_symmetry)
+ {
+ // we have to loop over all
+ // rows of the matrix which
+ // have a nonzero entry in
+ // the column which we work
+ // in presently. if the
+ // sparsity pattern is
+ // symmetric, then we can
+ // get the positions of
+ // these rows cheaply by
+ // looking at the nonzero
+ // column numbers of the
+ // present row. we need not
+ // look at the first entry,
+ // since that is the
+ // diagonal element and
+ // thus the present row
+ for (unsigned int j=sparsity_rowstart[dof_number]+1; j<last; ++j)
+ {
+ const unsigned int row = sparsity_colnums[j];
+
+ // find the position of
+ // element
+ // (row,dof_number)
+ const unsigned int *
+ p = Utilities::lower_bound(&sparsity_colnums[sparsity_rowstart[row]+1],
+ &sparsity_colnums[sparsity_rowstart[row+1]],
+ dof_number);
+
+ // check whether this line has
+ // an entry in the regarding column
+ // (check for ==dof_number and
+ // != next_row, since if
+ // row==dof_number-1, *p is a
+ // past-the-end pointer but points
+ // to dof_number anyway...)
+ //
+ // there should be such an entry!
+ Assert ((*p == dof_number) &&
+ (p != &sparsity_colnums[sparsity_rowstart[row+1]]),
+ ExcInternalError());
+
+ const unsigned int global_entry
+ = (p - &sparsity_colnums[sparsity_rowstart[0]]);
+
+ // correct right hand side
+ // set matrix entry to zero
+ matrix.global_entry(global_entry) = 0.;
+ }
+ }
}
}
const unsigned int blocks = matrix.n_block_rows();
Assert (matrix.n_block_rows() == matrix.n_block_cols(),
- ExcNotQuadratic());
+ ExcNotQuadratic());
Assert (matrix.get_sparsity_pattern().get_row_indices() ==
- matrix.get_sparsity_pattern().get_column_indices(),
- ExcNotQuadratic());
+ matrix.get_sparsity_pattern().get_column_indices(),
+ ExcNotQuadratic());
for (unsigned int i=0; i<blocks; ++i)
Assert (matrix.block(i,i).get_sparsity_pattern().optimize_diagonal(),
- SparsityPattern::ExcDiagonalNotOptimized());
+ SparsityPattern::ExcDiagonalNotOptimized());
- // if no boundary values are to be applied
- // simply return
+ // if no boundary values are to be applied
+ // simply return
if (boundary_dofs.size() == 0)
return;
const unsigned int n_dofs = matrix.m();
- // if a diagonal entry is zero
- // later, then we use another
- // number instead. take it to be
- // the first nonzero diagonal
- // element of the matrix, or 1 if
- // there is no such thing
+ // if a diagonal entry is zero
+ // later, then we use another
+ // number instead. take it to be
+ // the first nonzero diagonal
+ // element of the matrix, or 1 if
+ // there is no such thing
number first_nonzero_diagonal_entry = 0;
for (unsigned int diag_block=0; diag_block<blocks; ++diag_block)
{
- for (unsigned int i=0; i<matrix.block(diag_block,diag_block).n(); ++i)
- if (matrix.block(diag_block,diag_block).diag_element(i) != 0)
- {
- first_nonzero_diagonal_entry
- = matrix.block(diag_block,diag_block).diag_element(i);
- break;
- }
- // check whether we have found
- // something in the present
- // block
- if (first_nonzero_diagonal_entry != 0)
- break;
+ for (unsigned int i=0; i<matrix.block(diag_block,diag_block).n(); ++i)
+ if (matrix.block(diag_block,diag_block).diag_element(i) != 0)
+ {
+ first_nonzero_diagonal_entry
+ = matrix.block(diag_block,diag_block).diag_element(i);
+ break;
+ }
+ // check whether we have found
+ // something in the present
+ // block
+ if (first_nonzero_diagonal_entry != 0)
+ break;
}
- // nothing found on all diagonal
- // blocks? if so, use 1.0 instead
+ // nothing found on all diagonal
+ // blocks? if so, use 1.0 instead
if (first_nonzero_diagonal_entry == 0)
first_nonzero_diagonal_entry = 1;
std::set<unsigned int>::const_iterator dof = boundary_dofs.begin(),
- endd = boundary_dofs.end();
+ endd = boundary_dofs.end();
const BlockSparsityPattern &
sparsity_pattern = matrix.get_sparsity_pattern();
- // pointer to the mapping between
- // global and block indices. since
- // the row and column mappings are
- // equal, store a pointer on only
- // one of them
+ // pointer to the mapping between
+ // global and block indices. since
+ // the row and column mappings are
+ // equal, store a pointer on only
+ // one of them
const BlockIndices &
index_mapping = sparsity_pattern.get_column_indices();
- // now loop over all boundary dofs
+ // now loop over all boundary dofs
for (; dof != endd; ++dof)
{
- Assert (*dof < n_dofs, ExcInternalError());
-
- // get global index and index
- // in the block in which this
- // dof is located
- const unsigned int dof_number = *dof;
- const std::pair<unsigned int,unsigned int>
- block_index = index_mapping.global_to_local (dof_number);
-
- // for each boundary dof:
-
- // set entries of this line
- // to zero except for the diagonal
- // entry. Note that the diagonal
- // entry is always the first one
- // for square matrices, i.e.
- // we shall not set
- // matrix.global_entry(
- // sparsity_rowstart[dof.first])
- // of the diagonal block
- for (unsigned int block_col=0; block_col<blocks; ++block_col)
- {
- const SparsityPattern &
- local_sparsity = sparsity_pattern.block(block_index.first,
- block_col);
-
- // find first and last
- // entry in the present row
- // of the present
- // block. exclude the main
- // diagonal element, which
- // is the diagonal element
- // of a diagonal block,
- // which must be a square
- // matrix so the diagonal
- // element is the first of
- // this row.
- const unsigned int
- last = local_sparsity.get_rowstart_indices()[block_index.second+1],
- first = (block_col == block_index.first ?
- local_sparsity.get_rowstart_indices()[block_index.second]+1 :
- local_sparsity.get_rowstart_indices()[block_index.second]);
-
- for (unsigned int j=first; j<last; ++j)
- matrix.block(block_index.first,block_col).global_entry(j) = 0.;
- }
-
- matrix.block(block_index.first, block_index.first)
- .diag_element(block_index.second)
- = first_nonzero_diagonal_entry;
-
- // if the user wants to have
- // the symmetry of the matrix
- // preserved, and if the
- // sparsity pattern is
- // symmetric, then do a Gauss
- // elimination step with the
- // present row. this is a
- // little more complicated for
- // block matrices.
- if (preserve_symmetry)
- {
- // we have to loop over all
- // rows of the matrix which
- // have a nonzero entry in
- // the column which we work
- // in presently. if the
- // sparsity pattern is
- // symmetric, then we can
- // get the positions of
- // these rows cheaply by
- // looking at the nonzero
- // column numbers of the
- // present row.
- //
- // note that if we check
- // whether row @p{row} in
- // block (r,c) is non-zero,
- // then we have to check
- // for the existence of
- // column @p{row} in block
- // (c,r), i.e. of the
- // transpose block
- for (unsigned int block_row=0; block_row<blocks; ++block_row)
- {
- // get pointers to the
- // sparsity patterns of
- // this block and of
- // the transpose one
- const SparsityPattern &this_sparsity
- = sparsity_pattern.block (block_row, block_index.first);
- const SparsityPattern &transpose_sparsity
- = sparsity_pattern.block (block_index.first, block_row);
-
- // traverse the row of
- // the transpose block
- // to find the
- // interesting rows in
- // the present block.
- // don't use the
- // diagonal element of
- // the diagonal block
- const unsigned int
- first = (block_index.first == block_row ?
- transpose_sparsity.get_rowstart_indices()[block_index.second]+1 :
- transpose_sparsity.get_rowstart_indices()[block_index.second]),
- last = transpose_sparsity.get_rowstart_indices()[block_index.second+1];
-
- for (unsigned int j=first; j<last; ++j)
- {
- // get the number
- // of the column in
- // this row in
- // which a nonzero
- // entry is. this
- // is also the row
- // of the transpose
- // block which has
- // an entry in the
- // interesting row
- const unsigned int row = transpose_sparsity.get_column_numbers()[j];
-
- // find the
- // position of
- // element
- // (row,dof_number)
- // in this block
- // (not in the
- // transpose
- // one). note that
- // we have to take
- // care of special
- // cases with
- // square
- // sub-matrices
- const unsigned int *p = 0;
- if (this_sparsity.n_rows() == this_sparsity.n_cols())
- {
- if (this_sparsity.get_column_numbers()
- [this_sparsity.get_rowstart_indices()[row]]
- ==
- block_index.second)
- p = &this_sparsity.get_column_numbers()
- [this_sparsity.get_rowstart_indices()[row]];
- else
- p = Utilities::lower_bound(&this_sparsity.get_column_numbers()
- [this_sparsity.get_rowstart_indices()[row]+1],
- &this_sparsity.get_column_numbers()
- [this_sparsity.get_rowstart_indices()[row+1]],
- block_index.second);
- }
- else
- p = Utilities::lower_bound(&this_sparsity.get_column_numbers()
- [this_sparsity.get_rowstart_indices()[row]],
- &this_sparsity.get_column_numbers()
- [this_sparsity.get_rowstart_indices()[row+1]],
- block_index.second);
-
- // check whether this line has
- // an entry in the regarding column
- // (check for ==dof_number and
- // != next_row, since if
- // row==dof_number-1, *p is a
- // past-the-end pointer but points
- // to dof_number anyway...)
- //
- // there should be
- // such an entry!
- // note, however,
- // that this
- // assertion will
- // fail sometimes
- // if the sparsity
- // pattern is not
- // symmetric!
- Assert ((*p == block_index.second) &&
- (p != &this_sparsity.get_column_numbers()
- [this_sparsity.get_rowstart_indices()[row+1]]),
- ExcInternalError());
-
- const unsigned int global_entry
- = (p
- -
- &this_sparsity.get_column_numbers()
- [this_sparsity.get_rowstart_indices()[0]]);
-
- // set matrix entry to zero
- matrix.block(block_row,block_index.first).global_entry(global_entry) = 0.;
- }
- }
- }
+ Assert (*dof < n_dofs, ExcInternalError());
+
+ // get global index and index
+ // in the block in which this
+ // dof is located
+ const unsigned int dof_number = *dof;
+ const std::pair<unsigned int,unsigned int>
+ block_index = index_mapping.global_to_local (dof_number);
+
+ // for each boundary dof:
+
+ // set entries of this line
+ // to zero except for the diagonal
+ // entry. Note that the diagonal
+ // entry is always the first one
+ // for square matrices, i.e.
+ // we shall not set
+ // matrix.global_entry(
+ // sparsity_rowstart[dof.first])
+ // of the diagonal block
+ for (unsigned int block_col=0; block_col<blocks; ++block_col)
+ {
+ const SparsityPattern &
+ local_sparsity = sparsity_pattern.block(block_index.first,
+ block_col);
+
+ // find first and last
+ // entry in the present row
+ // of the present
+ // block. exclude the main
+ // diagonal element, which
+ // is the diagonal element
+ // of a diagonal block,
+ // which must be a square
+ // matrix so the diagonal
+ // element is the first of
+ // this row.
+ const unsigned int
+ last = local_sparsity.get_rowstart_indices()[block_index.second+1],
+ first = (block_col == block_index.first ?
+ local_sparsity.get_rowstart_indices()[block_index.second]+1 :
+ local_sparsity.get_rowstart_indices()[block_index.second]);
+
+ for (unsigned int j=first; j<last; ++j)
+ matrix.block(block_index.first,block_col).global_entry(j) = 0.;
+ }
+
+ matrix.block(block_index.first, block_index.first)
+ .diag_element(block_index.second)
+ = first_nonzero_diagonal_entry;
+
+ // if the user wants to have
+ // the symmetry of the matrix
+ // preserved, and if the
+ // sparsity pattern is
+ // symmetric, then do a Gauss
+ // elimination step with the
+ // present row. this is a
+ // little more complicated for
+ // block matrices.
+ if (preserve_symmetry)
+ {
+ // we have to loop over all
+ // rows of the matrix which
+ // have a nonzero entry in
+ // the column which we work
+ // in presently. if the
+ // sparsity pattern is
+ // symmetric, then we can
+ // get the positions of
+ // these rows cheaply by
+ // looking at the nonzero
+ // column numbers of the
+ // present row.
+ //
+ // note that if we check
+ // whether row @p{row} in
+ // block (r,c) is non-zero,
+ // then we have to check
+ // for the existence of
+ // column @p{row} in block
+ // (c,r), i.e. of the
+ // transpose block
+ for (unsigned int block_row=0; block_row<blocks; ++block_row)
+ {
+ // get pointers to the
+ // sparsity patterns of
+ // this block and of
+ // the transpose one
+ const SparsityPattern &this_sparsity
+ = sparsity_pattern.block (block_row, block_index.first);
+ const SparsityPattern &transpose_sparsity
+ = sparsity_pattern.block (block_index.first, block_row);
+
+ // traverse the row of
+ // the transpose block
+ // to find the
+ // interesting rows in
+ // the present block.
+ // don't use the
+ // diagonal element of
+ // the diagonal block
+ const unsigned int
+ first = (block_index.first == block_row ?
+ transpose_sparsity.get_rowstart_indices()[block_index.second]+1 :
+ transpose_sparsity.get_rowstart_indices()[block_index.second]),
+ last = transpose_sparsity.get_rowstart_indices()[block_index.second+1];
+
+ for (unsigned int j=first; j<last; ++j)
+ {
+ // get the number
+ // of the column in
+ // this row in
+ // which a nonzero
+ // entry is. this
+ // is also the row
+ // of the transpose
+ // block which has
+ // an entry in the
+ // interesting row
+ const unsigned int row = transpose_sparsity.get_column_numbers()[j];
+
+ // find the
+ // position of
+ // element
+ // (row,dof_number)
+ // in this block
+ // (not in the
+ // transpose
+ // one). note that
+ // we have to take
+ // care of special
+ // cases with
+ // square
+ // sub-matrices
+ const unsigned int *p = 0;
+ if (this_sparsity.n_rows() == this_sparsity.n_cols())
+ {
+ if (this_sparsity.get_column_numbers()
+ [this_sparsity.get_rowstart_indices()[row]]
+ ==
+ block_index.second)
+ p = &this_sparsity.get_column_numbers()
+ [this_sparsity.get_rowstart_indices()[row]];
+ else
+ p = Utilities::lower_bound(&this_sparsity.get_column_numbers()
+ [this_sparsity.get_rowstart_indices()[row]+1],
+ &this_sparsity.get_column_numbers()
+ [this_sparsity.get_rowstart_indices()[row+1]],
+ block_index.second);
+ }
+ else
+ p = Utilities::lower_bound(&this_sparsity.get_column_numbers()
+ [this_sparsity.get_rowstart_indices()[row]],
+ &this_sparsity.get_column_numbers()
+ [this_sparsity.get_rowstart_indices()[row+1]],
+ block_index.second);
+
+ // check whether this line has
+ // an entry in the regarding column
+ // (check for ==dof_number and
+ // != next_row, since if
+ // row==dof_number-1, *p is a
+ // past-the-end pointer but points
+ // to dof_number anyway...)
+ //
+ // there should be
+ // such an entry!
+ // note, however,
+ // that this
+ // assertion will
+ // fail sometimes
+ // if the sparsity
+ // pattern is not
+ // symmetric!
+ Assert ((*p == block_index.second) &&
+ (p != &this_sparsity.get_column_numbers()
+ [this_sparsity.get_rowstart_indices()[row+1]]),
+ ExcInternalError());
+
+ const unsigned int global_entry
+ = (p
+ -
+ &this_sparsity.get_column_numbers()
+ [this_sparsity.get_rowstart_indices()[0]]);
+
+ // set matrix entry to zero
+ matrix.block(block_row,block_index.first).global_entry(global_entry) = 0.;
+ }
+ }
+ }
}
}
}
// $Id$
// Version: $Name$
//
-// Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2010 by the deal.II authors
+// Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2010, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
namespace
{
- /**
- * Adjust vectors on all levels
- * to correct size. The degrees
- * of freedom on each level are
- * counted by block and only the
- * block selected is used.
- */
+ /**
+ * Adjust vectors on all levels
+ * to correct size. The degrees
+ * of freedom on each level are
+ * counted by block and only the
+ * block selected is used.
+ */
template <int dim, typename number, int spacedim>
void
reinit_vector_by_blocks (
std::vector<std::vector<unsigned int> >& ndofs)
{
std::vector<bool> selected=sel;
- // Compute the number of blocks needed
+ // Compute the number of blocks needed
const unsigned int n_selected
= std::accumulate(selected.begin(),
- selected.end(),
- 0U);
+ selected.end(),
+ 0U);
if (ndofs.size() == 0)
{
- std::vector<std::vector<unsigned int> >
- new_dofs(mg_dof.get_tria().n_levels(),
- std::vector<unsigned int>(selected.size()));
- std::swap(ndofs, new_dofs);
- MGTools::count_dofs_per_block (mg_dof, ndofs);
+ std::vector<std::vector<unsigned int> >
+ new_dofs(mg_dof.get_tria().n_levels(),
+ std::vector<unsigned int>(selected.size()));
+ std::swap(ndofs, new_dofs);
+ MGTools::count_dofs_per_block (mg_dof, ndofs);
}
for (unsigned int level=v.get_minlevel();
- level<=v.get_maxlevel();++level)
+ level<=v.get_maxlevel();++level)
{
- v[level].reinit(n_selected, 0);
- unsigned int k=0;
- for (unsigned int i=0;i<selected.size() && (k<v[level].n_blocks());++i)
- {
- if (selected[i])
- {
- v[level].block(k++).reinit(ndofs[level][i]);
- }
- v[level].collect_sizes();
- }
+ v[level].reinit(n_selected, 0);
+ unsigned int k=0;
+ for (unsigned int i=0;i<selected.size() && (k<v[level].n_blocks());++i)
+ {
+ if (selected[i])
+ {
+ v[level].block(k++).reinit(ndofs[level][i]);
+ }
+ v[level].collect_sizes();
+ }
}
}
- /**
- * Adjust block vectors on all
- * levels to correct size. The
- * degrees of freedom on each
- * level are counted by block.
- */
+ /**
+ * Adjust block vectors on all
+ * levels to correct size. The
+ * degrees of freedom on each
+ * level are counted by block.
+ */
template <int dim, typename number, int spacedim>
void
reinit_vector_by_blocks (
if (ndofs.size() == 0)
{
- std::vector<std::vector<unsigned int> >
- new_dofs(mg_dof.get_tria().n_levels(),
- std::vector<unsigned int>(selected.size()));
- std::swap(ndofs, new_dofs);
- MGTools::count_dofs_per_block (mg_dof, ndofs);
+ std::vector<std::vector<unsigned int> >
+ new_dofs(mg_dof.get_tria().n_levels(),
+ std::vector<unsigned int>(selected.size()));
+ std::swap(ndofs, new_dofs);
+ MGTools::count_dofs_per_block (mg_dof, ndofs);
}
for (unsigned int level=v.get_minlevel();
- level<=v.get_maxlevel();++level)
+ level<=v.get_maxlevel();++level)
{
- v[level].reinit(ndofs[level][selected_block]);
+ v[level].reinit(ndofs[level][selected_block]);
}
}
}
const BlockVector<number2> &src) const
{
reinit_vector_by_blocks(mg_dof_handler, dst, selected_block, sizes);
- // For MGTransferBlockSelect, the
- // multilevel block is always the
- // first, since only one block is
- // selected.
+ // For MGTransferBlockSelect, the
+ // multilevel block is always the
+ // first, since only one block is
+ // selected.
bool first = true;
for (unsigned int level=mg_dof_handler.get_tria().n_levels();level != 0;)
{
--level;
for (IT i= copy_indices[selected_block][level].begin();
- i != copy_indices[selected_block][level].end();++i)
- dst[level](i->second) = src.block(selected_block)(i->first);
+ i != copy_indices[selected_block][level].end();++i)
+ dst[level](i->second) = src.block(selected_block)(i->first);
if (!first)
- restrict_and_add (level+1, dst[level], dst[level+1]);
+ restrict_and_add (level+1, dst[level], dst[level+1]);
first = false;
}
}
const Vector<number2> &src) const
{
reinit_vector_by_blocks(mg_dof_handler, dst, selected_block, sizes);
- // For MGTransferBlockSelect, the
- // multilevel block is always the
- // first, since only one block is selected.
+ // For MGTransferBlockSelect, the
+ // multilevel block is always the
+ // first, since only one block is selected.
bool first = true;
for (unsigned int level=mg_dof_handler.get_tria().n_levels();level != 0;)
{
--level;
for (IT i= copy_indices[selected_block][level].begin();
- i != copy_indices[selected_block][level].end();++i)
- dst[level](i->second) = src(i->first);
+ i != copy_indices[selected_block][level].end();++i)
+ dst[level](i->second) = src(i->first);
if (!first)
- restrict_and_add (level+1, dst[level], dst[level+1]);
+ restrict_and_add (level+1, dst[level], dst[level+1]);
first = false;
}
}
{
--level;
for (unsigned int block=0;block<selected.size();++block)
- if (selected[block])
- for (IT i= copy_indices[block][level].begin();
- i != copy_indices[block][level].end();++i)
- dst[level].block(mg_block[block])(i->second) = src.block(block)(i->first);
+ if (selected[block])
+ for (IT i= copy_indices[block][level].begin();
+ i != copy_indices[block][level].end();++i)
+ dst[level].block(mg_block[block])(i->second) = src.block(block)(i->first);
if (!first)
- restrict_and_add (level+1, dst[level], dst[level+1]);
+ restrict_and_add (level+1, dst[level], dst[level+1]);
first = false;
}
}
const unsigned int n_levels = mg_dof.get_tria().n_levels();
Assert (selected.size() == n_blocks,
- ExcDimensionMismatch(selected.size(), n_blocks));
+ ExcDimensionMismatch(selected.size(), n_blocks));
- // Compute the mapping between real
- // blocks and blocks used for
- // multigrid computations.
+ // Compute the mapping between real
+ // blocks and blocks used for
+ // multigrid computations.
mg_block.resize(n_blocks);
n_mg_blocks = 0;
for (unsigned int i=0;i<n_blocks;++i)
else
mg_block[i] = numbers::invalid_unsigned_int;
- // Compute the lengths of all blocks
+ // Compute the lengths of all blocks
sizes.clear ();
sizes.resize(n_levels, std::vector<unsigned int>(fe.n_blocks()));
MGTools::count_dofs_per_block(mg_dof, sizes);
- // Fill some index vectors
- // for later use.
+ // Fill some index vectors
+ // for later use.
mg_block_start = sizes;
- // Compute start indices from sizes
+ // Compute start indices from sizes
for (unsigned int l=0;l<mg_block_start.size();++l)
{
unsigned int k=0;
for (unsigned int i=0;i<mg_block_start[l].size();++i)
- {
- const unsigned int t=mg_block_start[l][i];
- mg_block_start[l][i] = k;
- k += t;
- }
+ {
+ const unsigned int t=mg_block_start[l][i];
+ mg_block_start[l][i] = k;
+ k += t;
+ }
}
block_start.resize(n_blocks);
DoFTools::count_dofs_per_block (static_cast<const DoFHandler<dim,spacedim>&>(mg_dof),
- block_start);
+ block_start);
unsigned int k=0;
for (unsigned int i=0;i<block_start.size();++i)
block_start[i] = k;
k += t;
}
- // Build index vectors for
- // copy_to_mg and
- // copy_from_mg. These vectors must
- // be prebuilt, since the
- // get_dof_indices functions are
- // too slow
+ // Build index vectors for
+ // copy_to_mg and
+ // copy_from_mg. These vectors must
+ // be prebuilt, since the
+ // get_dof_indices functions are
+ // too slow
copy_indices.resize(n_blocks);
for (unsigned int block=0;block<n_blocks;++block)
if (selected[block])
// Building the prolongation matrices starts here!
- // reset the size of the array of
- // matrices. call resize(0) first,
- // in order to delete all elements
- // and clear their memory. then
- // repopulate these arrays
- //
- // note that on resize(0), the
- // shared_ptr class takes care of
- // deleting the object it points to
- // by itself
+ // reset the size of the array of
+ // matrices. call resize(0) first,
+ // in order to delete all elements
+ // and clear their memory. then
+ // repopulate these arrays
+ //
+ // note that on resize(0), the
+ // shared_ptr class takes care of
+ // deleting the object it points to
+ // by itself
prolongation_matrices.resize (0);
prolongation_sparsities.resize (0);
for (unsigned int i=0; i<n_levels-1; ++i)
{
prolongation_sparsities
- .push_back (std_cxx1x::shared_ptr<BlockSparsityPattern> (new BlockSparsityPattern));
+ .push_back (std_cxx1x::shared_ptr<BlockSparsityPattern> (new BlockSparsityPattern));
prolongation_matrices
- .push_back (std_cxx1x::shared_ptr<BlockSparseMatrix<double> > (new BlockSparseMatrix<double>));
+ .push_back (std_cxx1x::shared_ptr<BlockSparseMatrix<double> > (new BlockSparseMatrix<double>));
}
- // two fields which will store the
- // indices of the multigrid dofs
- // for a cell and one of its children
+ // two fields which will store the
+ // indices of the multigrid dofs
+ // for a cell and one of its children
std::vector<unsigned int> dof_indices_parent (dofs_per_cell);
std::vector<unsigned int> dof_indices_child (dofs_per_cell);
- // for each level: first build the
- // sparsity pattern of the matrices
- // and then build the matrices
- // themselves. note that we only
- // need to take care of cells on
- // the coarser level which have
- // children
+ // for each level: first build the
+ // sparsity pattern of the matrices
+ // and then build the matrices
+ // themselves. note that we only
+ // need to take care of cells on
+ // the coarser level which have
+ // children
for (unsigned int level=0; level<n_levels-1; ++level)
{
- // reset the dimension of the
- // structure. note that for
- // the number of entries per
- // row, the number of parent
- // dofs coupling to a child dof
- // is necessary. this, is the
- // number of degrees of freedom
- // per cell
+ // reset the dimension of the
+ // structure. note that for
+ // the number of entries per
+ // row, the number of parent
+ // dofs coupling to a child dof
+ // is necessary. this, is the
+ // number of degrees of freedom
+ // per cell
prolongation_sparsities[level]->reinit (n_blocks, n_blocks);
for (unsigned int i=0; i<n_blocks; ++i)
- for (unsigned int j=0; j<n_blocks; ++j)
- if (i==j)
- prolongation_sparsities[level]->block(i,j)
- .reinit(sizes[level+1][i],
- sizes[level][j],
- dofs_per_cell+1, false);
- else
- prolongation_sparsities[level]->block(i,j)
- .reinit(sizes[level+1][i],
- sizes[level][j],
- 0, false);
+ for (unsigned int j=0; j<n_blocks; ++j)
+ if (i==j)
+ prolongation_sparsities[level]->block(i,j)
+ .reinit(sizes[level+1][i],
+ sizes[level][j],
+ dofs_per_cell+1, false);
+ else
+ prolongation_sparsities[level]->block(i,j)
+ .reinit(sizes[level+1][i],
+ sizes[level][j],
+ 0, false);
prolongation_sparsities[level]->collect_sizes();
for (typename MGDoFHandler<dim,spacedim>::cell_iterator cell=mg_dof.begin(level);
- cell != mg_dof.end(level); ++cell)
- if (cell->has_children())
- {
- cell->get_mg_dof_indices (dof_indices_parent);
-
- Assert(cell->n_children()==GeometryInfo<dim>::max_children_per_cell,
- ExcNotImplemented());
- for (unsigned int child=0; child<cell->n_children(); ++child)
- {
- // set an alias to the
- // prolongation matrix for
- // this child
- const FullMatrix<double> &prolongation
- = mg_dof.get_fe().get_prolongation_matrix (child, cell->refinement_case());
-
- cell->child(child)->get_mg_dof_indices (dof_indices_child);
-
- // now tag the entries in the
- // matrix which will be used
- // for this pair of parent/child
- for (unsigned int i=0; i<dofs_per_cell; ++i)
- for (unsigned int j=0; j<dofs_per_cell; ++j)
- if (prolongation(i,j) != 0)
- {
- const unsigned int icomp
- = fe.system_to_block_index(i).first;
- const unsigned int jcomp
- = fe.system_to_block_index(j).first;
- if ((icomp==jcomp) && selected[icomp])
- prolongation_sparsities[level]->add(dof_indices_child[i],
- dof_indices_parent[j]);
- };
- };
- };
+ cell != mg_dof.end(level); ++cell)
+ if (cell->has_children())
+ {
+ cell->get_mg_dof_indices (dof_indices_parent);
+
+ Assert(cell->n_children()==GeometryInfo<dim>::max_children_per_cell,
+ ExcNotImplemented());
+ for (unsigned int child=0; child<cell->n_children(); ++child)
+ {
+ // set an alias to the
+ // prolongation matrix for
+ // this child
+ const FullMatrix<double> &prolongation
+ = mg_dof.get_fe().get_prolongation_matrix (child, cell->refinement_case());
+
+ cell->child(child)->get_mg_dof_indices (dof_indices_child);
+
+ // now tag the entries in the
+ // matrix which will be used
+ // for this pair of parent/child
+ for (unsigned int i=0; i<dofs_per_cell; ++i)
+ for (unsigned int j=0; j<dofs_per_cell; ++j)
+ if (prolongation(i,j) != 0)
+ {
+ const unsigned int icomp
+ = fe.system_to_block_index(i).first;
+ const unsigned int jcomp
+ = fe.system_to_block_index(j).first;
+ if ((icomp==jcomp) && selected[icomp])
+ prolongation_sparsities[level]->add(dof_indices_child[i],
+ dof_indices_parent[j]);
+ };
+ };
+ };
prolongation_sparsities[level]->compress ();
prolongation_matrices[level]->reinit (*prolongation_sparsities[level]);
- // now actually build the matrices
+ // now actually build the matrices
for (typename MGDoFHandler<dim,spacedim>::cell_iterator cell=mg_dof.begin(level);
- cell != mg_dof.end(level); ++cell)
- if (cell->has_children())
- {
- cell->get_mg_dof_indices (dof_indices_parent);
-
- Assert(cell->n_children()==GeometryInfo<dim>::max_children_per_cell,
- ExcNotImplemented());
- for (unsigned int child=0; child<cell->n_children(); ++child)
- {
- // set an alias to the
- // prolongation matrix for
- // this child
- const FullMatrix<double> &prolongation
- = mg_dof.get_fe().get_prolongation_matrix (child, cell->refinement_case());
-
- cell->child(child)->get_mg_dof_indices (dof_indices_child);
-
- // now set the entries in the
- // matrix
- for (unsigned int i=0; i<dofs_per_cell; ++i)
- for (unsigned int j=0; j<dofs_per_cell; ++j)
- if (prolongation(i,j) != 0)
- {
- const unsigned int icomp = fe.system_to_block_index(i).first;
- const unsigned int jcomp = fe.system_to_block_index(j).first;
- if ((icomp==jcomp) && selected[icomp])
- prolongation_matrices[level]->set(dof_indices_child[i],
- dof_indices_parent[j],
- prolongation(i,j));
- }
- }
- }
+ cell != mg_dof.end(level); ++cell)
+ if (cell->has_children())
+ {
+ cell->get_mg_dof_indices (dof_indices_parent);
+
+ Assert(cell->n_children()==GeometryInfo<dim>::max_children_per_cell,
+ ExcNotImplemented());
+ for (unsigned int child=0; child<cell->n_children(); ++child)
+ {
+ // set an alias to the
+ // prolongation matrix for
+ // this child
+ const FullMatrix<double> &prolongation
+ = mg_dof.get_fe().get_prolongation_matrix (child, cell->refinement_case());
+
+ cell->child(child)->get_mg_dof_indices (dof_indices_child);
+
+ // now set the entries in the
+ // matrix
+ for (unsigned int i=0; i<dofs_per_cell; ++i)
+ for (unsigned int j=0; j<dofs_per_cell; ++j)
+ if (prolongation(i,j) != 0)
+ {
+ const unsigned int icomp = fe.system_to_block_index(i).first;
+ const unsigned int jcomp = fe.system_to_block_index(j).first;
+ if ((icomp==jcomp) && selected[icomp])
+ prolongation_matrices[level]->set(dof_indices_child[i],
+ dof_indices_parent[j],
+ prolongation(i,j));
+ }
+ }
+ }
}
- // impose boundary conditions
- // but only in the column of
- // the prolongation matrix
+ // impose boundary conditions
+ // but only in the column of
+ // the prolongation matrix
if (mg_constrained_dofs != 0)
if (mg_constrained_dofs->set_boundary_values())
{
std::vector<unsigned int> constrain_indices;
std::vector<std::vector<bool> > constraints_per_block (n_blocks);
for (int level=n_levels-2; level>=0; --level)
- {
- if (mg_constrained_dofs->get_boundary_indices()[level].size() == 0)
- continue;
-
- // need to delete all the columns in the
- // matrix that are on the boundary. to achive
- // this, create an array as long as there are
- // matrix columns, and find which columns we
- // need to filter away.
- constrain_indices.resize (0);
- constrain_indices.resize (prolongation_matrices[level]->n(), 0);
- std::set<unsigned int>::const_iterator dof
+ {
+ if (mg_constrained_dofs->get_boundary_indices()[level].size() == 0)
+ continue;
+
+ // need to delete all the columns in the
+ // matrix that are on the boundary. to achive
+ // this, create an array as long as there are
+ // matrix columns, and find which columns we
+ // need to filter away.
+ constrain_indices.resize (0);
+ constrain_indices.resize (prolongation_matrices[level]->n(), 0);
+ std::set<unsigned int>::const_iterator dof
= mg_constrained_dofs->get_boundary_indices()[level].begin(),
- endd = mg_constrained_dofs->get_boundary_indices()[level].end();
- for (; dof != endd; ++dof)
- constrain_indices[*dof] = 1;
+ endd = mg_constrained_dofs->get_boundary_indices()[level].end();
+ for (; dof != endd; ++dof)
+ constrain_indices[*dof] = 1;
unsigned int index = 0;
for(unsigned int block=0; block<n_blocks; ++block)
for (unsigned int i=0; i<n_dofs; ++i, ++index)
constraints_per_block[block][i] = constrain_indices[index] == 1;
- for (unsigned int i=0; i<n_dofs; ++i)
- {
- SparseMatrix<double>::iterator
- start_row = prolongation_matrices[level]->block(block, block).begin(i),
- end_row = prolongation_matrices[level]->block(block, block).end(i);
- for(; start_row != end_row; ++start_row)
- {
- if (constraints_per_block[block][start_row->column()])
- start_row->value() = 0.;
- }
- }
+ for (unsigned int i=0; i<n_dofs; ++i)
+ {
+ SparseMatrix<double>::iterator
+ start_row = prolongation_matrices[level]->block(block, block).begin(i),
+ end_row = prolongation_matrices[level]->block(block, block).end(i);
+ for(; start_row != end_row; ++start_row)
+ {
+ if (constraints_per_block[block][start_row->column()])
+ start_row->value() = 0.;
+ }
+ }
}
- }
+ }
}
}
for (int level=dof.get_tria().n_levels()-1; level>=0; --level)
{
typename MGDoFHandler<dim,spacedim>::active_cell_iterator
- level_cell = mg_dof.begin_active(level);
+ level_cell = mg_dof.begin_active(level);
const typename MGDoFHandler<dim,spacedim>::active_cell_iterator
- level_end = mg_dof.end_active(level);
+ level_end = mg_dof.end_active(level);
temp_copy_indices.resize (0);
temp_copy_indices.resize (sizes[level][selected_block],
- numbers::invalid_unsigned_int);
+ numbers::invalid_unsigned_int);
- // Compute coarse level right hand side
- // by restricting from fine level.
+ // Compute coarse level right hand side
+ // by restricting from fine level.
for (; level_cell!=level_end; ++level_cell)
- {
- DoFAccessor<dim, DoFHandler<dim,spacedim> >& global_cell = *level_cell;
- // get the dof numbers of
- // this cell for the global
- // and the level-wise
- // numbering
- global_cell.get_dof_indices(global_dof_indices);
- level_cell->get_mg_dof_indices (level_dof_indices);
-
- for (unsigned int i=0; i<fe.dofs_per_cell; ++i)
- {
- const unsigned int block = fe.system_to_block_index(i).first;
- if (selected[block])
+ {
+ DoFAccessor<dim, DoFHandler<dim,spacedim> >& global_cell = *level_cell;
+ // get the dof numbers of
+ // this cell for the global
+ // and the level-wise
+ // numbering
+ global_cell.get_dof_indices(global_dof_indices);
+ level_cell->get_mg_dof_indices (level_dof_indices);
+
+ for (unsigned int i=0; i<fe.dofs_per_cell; ++i)
+ {
+ const unsigned int block = fe.system_to_block_index(i).first;
+ if (selected[block])
{
if(mg_constrained_dofs != 0)
{
= global_dof_indices[i] - block_start[block];
}
else
- temp_copy_indices[level_dof_indices[i] - mg_block_start[level][block]]
- = global_dof_indices[i] - block_start[block];
+ temp_copy_indices[level_dof_indices[i] - mg_block_start[level][block]]
+ = global_dof_indices[i] - block_start[block];
}
- }
- }
-
- // now all the active dofs got a valid entry,
- // the other ones have an invalid entry. Count
- // the invalid entries and then resize the
- // copy_indices object. Then, insert the pairs
- // of global index and level index into
- // copy_indices.
+ }
+ }
+
+ // now all the active dofs got a valid entry,
+ // the other ones have an invalid entry. Count
+ // the invalid entries and then resize the
+ // copy_indices object. Then, insert the pairs
+ // of global index and level index into
+ // copy_indices.
const unsigned int n_active_dofs =
- std::count_if (temp_copy_indices.begin(), temp_copy_indices.end(),
- std::bind2nd(std::not_equal_to<unsigned int>(),
- numbers::invalid_unsigned_int));
+ std::count_if (temp_copy_indices.begin(), temp_copy_indices.end(),
+ std::bind2nd(std::not_equal_to<unsigned int>(),
+ numbers::invalid_unsigned_int));
copy_indices[selected_block][level].resize (n_active_dofs);
unsigned int counter = 0;
for (unsigned int i=0; i<temp_copy_indices.size(); ++i)
- if (temp_copy_indices[i] != numbers::invalid_unsigned_int)
- copy_indices[selected_block][level][counter++] =
- std::pair<unsigned int, unsigned int> (temp_copy_indices[i], i);
+ if (temp_copy_indices[i] != numbers::invalid_unsigned_int)
+ copy_indices[selected_block][level][counter++] =
+ std::pair<unsigned int, unsigned int> (temp_copy_indices[i], i);
Assert (counter == n_active_dofs, ExcInternalError());
}
}
if (sel.size() != 0)
{
Assert(sel.size() == n_blocks,
- ExcDimensionMismatch(sel.size(), n_blocks));
+ ExcDimensionMismatch(sel.size(), n_blocks));
selected = sel;
}
if (selected.size() == 0)
for (int level=dof.get_tria().n_levels()-1; level>=0; --level)
{
typename MGDoFHandler<dim,spacedim>::active_cell_iterator
- level_cell = mg_dof.begin_active(level);
+ level_cell = mg_dof.begin_active(level);
const typename MGDoFHandler<dim,spacedim>::active_cell_iterator
- level_end = mg_dof.end_active(level);
+ level_end = mg_dof.end_active(level);
for (unsigned int block=0; block<n_blocks; ++block)
- if (selected[block])
- {
- temp_copy_indices[block].resize (0);
- temp_copy_indices[block].resize (sizes[level][block],
- numbers::invalid_unsigned_int);
- }
-
- // Compute coarse level right hand side
- // by restricting from fine level.
+ if (selected[block])
+ {
+ temp_copy_indices[block].resize (0);
+ temp_copy_indices[block].resize (sizes[level][block],
+ numbers::invalid_unsigned_int);
+ }
+
+ // Compute coarse level right hand side
+ // by restricting from fine level.
for (; level_cell!=level_end; ++level_cell)
- {
- DoFAccessor<dim, DoFHandler<dim,spacedim> >& global_cell = *level_cell;
- // get the dof numbers of
- // this cell for the global
- // and the level-wise
- // numbering
- global_cell.get_dof_indices(global_dof_indices);
- level_cell->get_mg_dof_indices (level_dof_indices);
-
- for (unsigned int i=0; i<fe.dofs_per_cell; ++i)
- {
- const unsigned int block = fe.system_to_block_index(i).first;
- if (selected[block])
- temp_copy_indices[block][level_dof_indices[i] - mg_block_start[level][block]]
- = global_dof_indices[i] - block_start[block];
- }
- }
+ {
+ DoFAccessor<dim, DoFHandler<dim,spacedim> >& global_cell = *level_cell;
+ // get the dof numbers of
+ // this cell for the global
+ // and the level-wise
+ // numbering
+ global_cell.get_dof_indices(global_dof_indices);
+ level_cell->get_mg_dof_indices (level_dof_indices);
+
+ for (unsigned int i=0; i<fe.dofs_per_cell; ++i)
+ {
+ const unsigned int block = fe.system_to_block_index(i).first;
+ if (selected[block])
+ temp_copy_indices[block][level_dof_indices[i] - mg_block_start[level][block]]
+ = global_dof_indices[i] - block_start[block];
+ }
+ }
for (unsigned int block=0; block<n_blocks; ++block)
- if (selected[block])
- {
- const unsigned int n_active_dofs =
- std::count_if (temp_copy_indices[block].begin(),
- temp_copy_indices[block].end(),
- std::bind2nd(std::not_equal_to<unsigned int>(),
- numbers::invalid_unsigned_int));
- copy_indices[block][level].resize (n_active_dofs);
- unsigned int counter = 0;
- for (unsigned int i=0; i<temp_copy_indices[block].size(); ++i)
- if (temp_copy_indices[block][i] != numbers::invalid_unsigned_int)
- copy_indices[block][level][counter++] =
- std::pair<unsigned int, unsigned int>
- (temp_copy_indices[block][i], i);
- Assert (counter == n_active_dofs, ExcInternalError());
- }
+ if (selected[block])
+ {
+ const unsigned int n_active_dofs =
+ std::count_if (temp_copy_indices[block].begin(),
+ temp_copy_indices[block].end(),
+ std::bind2nd(std::not_equal_to<unsigned int>(),
+ numbers::invalid_unsigned_int));
+ copy_indices[block][level].resize (n_active_dofs);
+ unsigned int counter = 0;
+ for (unsigned int i=0; i<temp_copy_indices[block].size(); ++i)
+ if (temp_copy_indices[block][i] != numbers::invalid_unsigned_int)
+ copy_indices[block][level][counter++] =
+ std::pair<unsigned int, unsigned int>
+ (temp_copy_indices[block][i], i);
+ Assert (counter == n_active_dofs, ExcInternalError());
+ }
}
}
// $Id$
// Version: $Name$
//
-// Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 by the deal.II authors
+// Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
namespace
{
- /**
- * Adjust block-vectors on all
- * levels to correct size. Count
- * the numbers of degrees of
- * freedom on each level
- * component-wise. Then, assign
- * each block of @p vector the
- * corresponding size.
- *
- * The boolean field @p selected
- * allows restricting this
- * operation to certain
- * components. In this case, @p
- * vector will only have as many
- * blocks as there are true
- * values in @p selected (no
- * blocks of length zero are
- * padded in). If this argument
- * is omitted, all blocks will be
- * considered.
- *
- * Degrees of freedom must be
- * sorted by component in order
- * to obtain reasonable results
- * from this function.
- *
- * The argument
- * @p target_component allows to
- * re-sort and group components
- * as in
- * DoFRenumbering::component_wise.
- *
- *
- */
+ /**
+ * Adjust block-vectors on all
+ * levels to correct size. Count
+ * the numbers of degrees of
+ * freedom on each level
+ * component-wise. Then, assign
+ * each block of @p vector the
+ * corresponding size.
+ *
+ * The boolean field @p selected
+ * allows restricting this
+ * operation to certain
+ * components. In this case, @p
+ * vector will only have as many
+ * blocks as there are true
+ * values in @p selected (no
+ * blocks of length zero are
+ * padded in). If this argument
+ * is omitted, all blocks will be
+ * considered.
+ *
+ * Degrees of freedom must be
+ * sorted by component in order
+ * to obtain reasonable results
+ * from this function.
+ *
+ * The argument
+ * @p target_component allows to
+ * re-sort and group components
+ * as in
+ * DoFRenumbering::component_wise.
+ *
+ *
+ */
template <int dim, typename number, int spacedim>
void
reinit_vector_by_components (
std::vector<unsigned int> target_component=target_comp;
const unsigned int ncomp = mg_dof.get_fe().n_components();
- // If the selected and
- // target_component have size 0,
- // they must be replaced by default
- // values.
- //
- // Since we already made copies
- // directly after this function was
- // called, we use the arguments
- // directly.
+ // If the selected and
+ // target_component have size 0,
+ // they must be replaced by default
+ // values.
+ //
+ // Since we already made copies
+ // directly after this function was
+ // called, we use the arguments
+ // directly.
if (target_component.size() == 0)
{
- target_component.resize(ncomp);
- for (unsigned int i=0;i<ncomp;++i)
- target_component[i] = i;
+ target_component.resize(ncomp);
+ for (unsigned int i=0;i<ncomp;++i)
+ target_component[i] = i;
}
- // If selected is an empty vector,
- // all components are selected.
+ // If selected is an empty vector,
+ // all components are selected.
if (selected.size() == 0)
{
- selected.resize(target_component.size());
- std::fill_n (selected.begin(), ncomp, false);
- for (unsigned int i=0;i<target_component.size();++i)
- selected[target_component[i]] = true;
+ selected.resize(target_component.size());
+ std::fill_n (selected.begin(), ncomp, false);
+ for (unsigned int i=0;i<target_component.size();++i)
+ selected[target_component[i]] = true;
}
Assert (selected.size() == target_component.size(),
- ExcDimensionMismatch(selected.size(), target_component.size()));
+ ExcDimensionMismatch(selected.size(), target_component.size()));
- // Compute the number of blocks needed
+ // Compute the number of blocks needed
const unsigned int n_selected
= std::accumulate(selected.begin(),
- selected.end(),
- 0U);
+ selected.end(),
+ 0U);
if (ndofs.size() == 0)
{
- std::vector<std::vector<unsigned int> >
- new_dofs(mg_dof.get_tria().n_levels(),
- std::vector<unsigned int>(target_component.size()));
- std::swap(ndofs, new_dofs);
- MGTools::count_dofs_per_block (mg_dof, ndofs, target_component);
+ std::vector<std::vector<unsigned int> >
+ new_dofs(mg_dof.get_tria().n_levels(),
+ std::vector<unsigned int>(target_component.size()));
+ std::swap(ndofs, new_dofs);
+ MGTools::count_dofs_per_block (mg_dof, ndofs, target_component);
}
for (unsigned int level=v.get_minlevel();
- level<=v.get_maxlevel();++level)
+ level<=v.get_maxlevel();++level)
{
- v[level].reinit(n_selected, 0);
- unsigned int k=0;
- for (unsigned int i=0;i<selected.size() && (k<v[level].n_blocks());++i)
- {
- if (selected[i])
- {
- v[level].block(k++).reinit(ndofs[level][i]);
- }
- v[level].collect_sizes();
- }
+ v[level].reinit(n_selected, 0);
+ unsigned int k=0;
+ for (unsigned int i=0;i<selected.size() && (k<v[level].n_blocks());++i)
+ {
+ if (selected[i])
+ {
+ v[level].block(k++).reinit(ndofs[level][i]);
+ }
+ v[level].collect_sizes();
+ }
}
}
- /**
- * Adjust vectors on all levels
- * to correct size. Count the
- * numbers of degrees of freedom
- * on each level component-wise
- * in a single component. Then,
- * assign @p vector the
- * corresponding size.
- *
- * The boolean field @p selected
- * may be nonzero in a single
- * component, indicating the
- * block of a block vector the
- * argument @p v corresponds to.
- *
- * Degrees of freedom must be
- * sorted by component in order
- * to obtain reasonable results
- * from this function.
- *
- * The argument
- * @p target_component allows to
- * re-sort and group components
- * as in
- * DoFRenumbering::component_wise.
- */
+ /**
+ * Adjust vectors on all levels
+ * to correct size. Count the
+ * numbers of degrees of freedom
+ * on each level component-wise
+ * in a single component. Then,
+ * assign @p vector the
+ * corresponding size.
+ *
+ * The boolean field @p selected
+ * may be nonzero in a single
+ * component, indicating the
+ * block of a block vector the
+ * argument @p v corresponds to.
+ *
+ * Degrees of freedom must be
+ * sorted by component in order
+ * to obtain reasonable results
+ * from this function.
+ *
+ * The argument
+ * @p target_component allows to
+ * re-sort and group components
+ * as in
+ * DoFRenumbering::component_wise.
+ */
template <int dim, typename number, int spacedim>
void
reinit_vector_by_components (
std::vector<std::vector<unsigned int> >& ndofs)
{
Assert (selected.size() == target_component.size(),
- ExcDimensionMismatch(selected.size(), target_component.size()));
+ ExcDimensionMismatch(selected.size(), target_component.size()));
- // Compute the number of blocks needed
+ // Compute the number of blocks needed
#ifdef DEBUG
// const unsigned int n_selected
// = std::accumulate(selected.begin(),
-// selected.end(),
-// 0U);
+// selected.end(),
+// 0U);
// Assert(n_selected == 1, ExcDimensionMismatch(n_selected, 1));
#endif
if (ndofs.size() == 0)
{
- std::vector<std::vector<unsigned int> >
- new_dofs(mg_dof.get_tria().n_levels(),
- std::vector<unsigned int>(target_component.size()));
- std::swap(ndofs, new_dofs);
- MGTools::count_dofs_per_block (mg_dof, ndofs,
- target_component);
+ std::vector<std::vector<unsigned int> >
+ new_dofs(mg_dof.get_tria().n_levels(),
+ std::vector<unsigned int>(target_component.size()));
+ std::swap(ndofs, new_dofs);
+ MGTools::count_dofs_per_block (mg_dof, ndofs,
+ target_component);
}
for (unsigned int level=v.get_minlevel();
- level<=v.get_maxlevel();++level)
+ level<=v.get_maxlevel();++level)
{
- v[level].reinit(ndofs[level][selected_block]);
+ v[level].reinit(ndofs[level][selected_block]);
}
}
}
dst=0;
Assert(sizes.size()==mg_dof_handler.get_tria().n_levels(),
- ExcMatricesNotBuilt());
+ ExcMatricesNotBuilt());
reinit_vector_by_components(mg_dof_handler, dst, mg_selected,
- mg_target_component, sizes);
-
- // traverse the grid top-down
- // (i.e. starting with the most
- // refined grid). this way, we can
- // always get that part of one
- // level of the output vector which
- // corresponds to a region which is
- // more refined, by restriction of
- // the respective vector on the
- // next finer level, which we then
- // already have built.
+ mg_target_component, sizes);
+
+ // traverse the grid top-down
+ // (i.e. starting with the most
+ // refined grid). this way, we can
+ // always get that part of one
+ // level of the output vector which
+ // corresponds to a region which is
+ // more refined, by restriction of
+ // the respective vector on the
+ // next finer level, which we then
+ // already have built.
bool first = true;
for (unsigned int level=mg_dof_handler.get_tria().n_levels(); level!=0;)
typedef std::vector<std::pair<unsigned int, unsigned int> >::const_iterator IT;
for (IT i=copy_to_and_from_indices[level].begin();
- i != copy_to_and_from_indices[level].end(); ++i)
- dst[level](i->second) = src(i->first);
- // for that part of the level
- // which is further refined:
- // get the defect by
- // restriction of the defect on
- // one level higher
+ i != copy_to_and_from_indices[level].end(); ++i)
+ dst[level](i->second) = src(i->first);
+ // for that part of the level
+ // which is further refined:
+ // get the defect by
+ // restriction of the defect on
+ // one level higher
if (!first)
- restrict_and_add (level+1, dst[level], dst[level+1]);
+ restrict_and_add (level+1, dst[level], dst[level+1]);
first = false;
}
}
const DoFHandler<dim,spacedim>&,
const MGDoFHandler<dim,spacedim>& mg_dof)
{
- // Fill target component with
- // standard values (identity) if it
- // is empty
+ // Fill target component with
+ // standard values (identity) if it
+ // is empty
if (target_component.size() == 0)
{
target_component.resize(mg_dof.get_fe().n_components());
for (unsigned int i=0;i<target_component.size();++i)
- target_component[i] = i;
+ target_component[i] = i;
} else {
- // otherwise, check it for consistency
+ // otherwise, check it for consistency
Assert (target_component.size() == mg_dof.get_fe().n_components(),
- ExcDimensionMismatch(target_component.size(),
- mg_dof.get_fe().n_components()));
+ ExcDimensionMismatch(target_component.size(),
+ mg_dof.get_fe().n_components()));
for (unsigned int i=0;i<target_component.size();++i)
- {
- Assert(i<target_component.size(),
- ExcIndexRange(i,0,target_component.size()));
- }
+ {
+ Assert(i<target_component.size(),
+ ExcIndexRange(i,0,target_component.size()));
+ }
}
- // Do the same for the multilevel
- // components. These may be
- // different.
+ // Do the same for the multilevel
+ // components. These may be
+ // different.
if (mg_target_component.size() == 0)
{
mg_target_component.resize(mg_dof.get_fe().n_components());
for (unsigned int i=0;i<mg_target_component.size();++i)
- mg_target_component[i] = target_component[i];
+ mg_target_component[i] = target_component[i];
} else {
Assert (mg_target_component.size() == mg_dof.get_fe().n_components(),
- ExcDimensionMismatch(mg_target_component.size(),
- mg_dof.get_fe().n_components()));
+ ExcDimensionMismatch(mg_target_component.size(),
+ mg_dof.get_fe().n_components()));
for (unsigned int i=0;i<mg_target_component.size();++i)
- {
- Assert(i<mg_target_component.size(),
- ExcIndexRange(i,0,mg_target_component.size()));
- }
+ {
+ Assert(i<mg_target_component.size(),
+ ExcIndexRange(i,0,mg_target_component.size()));
+ }
}
const FiniteElement<dim>& fe = mg_dof.get_fe();
- // Effective number of components
- // is the maximum entry in
- // mg_target_component. This
- // assumes that the values in that
- // vector don't have holes.
+ // Effective number of components
+ // is the maximum entry in
+ // mg_target_component. This
+ // assumes that the values in that
+ // vector don't have holes.
const unsigned int n_components =
*std::max_element(mg_target_component.begin(), mg_target_component.end()) + 1;
const unsigned int dofs_per_cell = fe.dofs_per_cell;
const unsigned int n_levels = mg_dof.get_tria().n_levels();
Assert (mg_selected.size() == fe.n_components(),
- ExcDimensionMismatch(mg_selected.size(), fe.n_components()));
+ ExcDimensionMismatch(mg_selected.size(), fe.n_components()));
- // Compute the lengths of all blocks
+ // Compute the lengths of all blocks
sizes.resize(n_levels);
for(unsigned int l=0; l<n_levels; ++l)
sizes[l].resize(n_components);
MGTools::count_dofs_per_block(mg_dof, sizes, mg_target_component);
- // Fill some index vectors
- // for later use.
+ // Fill some index vectors
+ // for later use.
mg_component_start = sizes;
- // Compute start indices from sizes
+ // Compute start indices from sizes
for (unsigned int l=0;l<mg_component_start.size();++l)
{
unsigned int k=0;
for (unsigned int i=0;i<mg_component_start[l].size();++i)
- {
- const unsigned int t=mg_component_start[l][i];
- mg_component_start[l][i] = k;
- k += t;
- }
+ {
+ const unsigned int t=mg_component_start[l][i];
+ mg_component_start[l][i] = k;
+ k += t;
+ }
}
component_start.resize(*std::max_element (target_component.begin(),
- target_component.end()) + 1);
+ target_component.end()) + 1);
DoFTools::
count_dofs_per_block (mg_dof, component_start, target_component);
k += t;
}
- // Build index vectors for
- // copy_to_mg and
- // copy_from_mg. These vectors must
- // be prebuilt, since the
- // get_dof_indices functions are
- // too slow
+ // Build index vectors for
+ // copy_to_mg and
+ // copy_from_mg. These vectors must
+ // be prebuilt, since the
+ // get_dof_indices functions are
+ // too slow
copy_to_and_from_indices.resize(n_levels);
// Building the prolongation matrices starts here!
- // reset the size of the array of
- // matrices. call resize(0) first,
- // in order to delete all elements
- // and clear their memory. then
- // repopulate these arrays
- //
- // note that on resize(0), the
- // shared_ptr class takes care of
- // deleting the object it points to
- // by itself
+ // reset the size of the array of
+ // matrices. call resize(0) first,
+ // in order to delete all elements
+ // and clear their memory. then
+ // repopulate these arrays
+ //
+ // note that on resize(0), the
+ // shared_ptr class takes care of
+ // deleting the object it points to
+ // by itself
prolongation_matrices.resize (0);
prolongation_sparsities.resize (0);
for (unsigned int i=0; i<n_levels-1; ++i)
{
prolongation_sparsities
- .push_back (std_cxx1x::shared_ptr<BlockSparsityPattern> (new BlockSparsityPattern));
+ .push_back (std_cxx1x::shared_ptr<BlockSparsityPattern> (new BlockSparsityPattern));
prolongation_matrices
- .push_back (std_cxx1x::shared_ptr<BlockSparseMatrix<double> > (new BlockSparseMatrix<double>));
+ .push_back (std_cxx1x::shared_ptr<BlockSparseMatrix<double> > (new BlockSparseMatrix<double>));
}
- // two fields which will store the
- // indices of the multigrid dofs
- // for a cell and one of its children
+ // two fields which will store the
+ // indices of the multigrid dofs
+ // for a cell and one of its children
std::vector<unsigned int> dof_indices_parent (dofs_per_cell);
std::vector<unsigned int> dof_indices_child (dofs_per_cell);
- // for each level: first build the
- // sparsity pattern of the matrices
- // and then build the matrices
- // themselves. note that we only
- // need to take care of cells on
- // the coarser level which have
- // children
+ // for each level: first build the
+ // sparsity pattern of the matrices
+ // and then build the matrices
+ // themselves. note that we only
+ // need to take care of cells on
+ // the coarser level which have
+ // children
for (unsigned int level=0; level<n_levels-1; ++level)
{
- // reset the dimension of the
- // structure. note that for
- // the number of entries per
- // row, the number of parent
- // dofs coupling to a child dof
- // is necessary. this, is the
- // number of degrees of freedom
- // per cell
+ // reset the dimension of the
+ // structure. note that for
+ // the number of entries per
+ // row, the number of parent
+ // dofs coupling to a child dof
+ // is necessary. this, is the
+ // number of degrees of freedom
+ // per cell
prolongation_sparsities[level]->reinit (n_components, n_components);
for (unsigned int i=0; i<n_components; ++i)
- for (unsigned int j=0; j<n_components; ++j)
- if (i==j)
- prolongation_sparsities[level]->block(i,j)
- .reinit(sizes[level+1][i],
- sizes[level][j],
- dofs_per_cell+1, false);
- else
- prolongation_sparsities[level]->block(i,j)
- .reinit(sizes[level+1][i],
- sizes[level][j],
- 0, false);
+ for (unsigned int j=0; j<n_components; ++j)
+ if (i==j)
+ prolongation_sparsities[level]->block(i,j)
+ .reinit(sizes[level+1][i],
+ sizes[level][j],
+ dofs_per_cell+1, false);
+ else
+ prolongation_sparsities[level]->block(i,j)
+ .reinit(sizes[level+1][i],
+ sizes[level][j],
+ 0, false);
prolongation_sparsities[level]->collect_sizes();
for (typename MGDoFHandler<dim,spacedim>::cell_iterator cell=mg_dof.begin(level);
- cell != mg_dof.end(level); ++cell)
- if (cell->has_children())
- {
- cell->get_mg_dof_indices (dof_indices_parent);
-
- for (unsigned int child=0; child<cell->n_children(); ++child)
- {
- // set an alias to the
- // prolongation matrix for
- // this child
- const FullMatrix<double> &prolongation
- = mg_dof.get_fe().get_prolongation_matrix (child, cell->refinement_case());
-
- cell->child(child)->get_mg_dof_indices (dof_indices_child);
-
- // now tag the entries in the
- // matrix which will be used
- // for this pair of parent/child
- for (unsigned int i=0; i<dofs_per_cell; ++i)
- for (unsigned int j=0; j<dofs_per_cell; ++j)
- if (prolongation(i,j) != 0)
- {
- const unsigned int icomp
- = fe.system_to_component_index(i).first;
- const unsigned int jcomp
- = fe.system_to_component_index(j).first;
- if ((icomp==jcomp) && mg_selected[icomp])
- prolongation_sparsities[level]->add(dof_indices_child[i],
- dof_indices_parent[j]);
- };
- };
- };
+ cell != mg_dof.end(level); ++cell)
+ if (cell->has_children())
+ {
+ cell->get_mg_dof_indices (dof_indices_parent);
+
+ for (unsigned int child=0; child<cell->n_children(); ++child)
+ {
+ // set an alias to the
+ // prolongation matrix for
+ // this child
+ const FullMatrix<double> &prolongation
+ = mg_dof.get_fe().get_prolongation_matrix (child, cell->refinement_case());
+
+ cell->child(child)->get_mg_dof_indices (dof_indices_child);
+
+ // now tag the entries in the
+ // matrix which will be used
+ // for this pair of parent/child
+ for (unsigned int i=0; i<dofs_per_cell; ++i)
+ for (unsigned int j=0; j<dofs_per_cell; ++j)
+ if (prolongation(i,j) != 0)
+ {
+ const unsigned int icomp
+ = fe.system_to_component_index(i).first;
+ const unsigned int jcomp
+ = fe.system_to_component_index(j).first;
+ if ((icomp==jcomp) && mg_selected[icomp])
+ prolongation_sparsities[level]->add(dof_indices_child[i],
+ dof_indices_parent[j]);
+ };
+ };
+ };
prolongation_sparsities[level]->compress ();
prolongation_matrices[level]->reinit (*prolongation_sparsities[level]);
- // now actually build the matrices
+ // now actually build the matrices
for (typename MGDoFHandler<dim,spacedim>::cell_iterator cell=mg_dof.begin(level);
- cell != mg_dof.end(level); ++cell)
- if (cell->has_children())
- {
- cell->get_mg_dof_indices (dof_indices_parent);
-
- for (unsigned int child=0; child<cell->n_children(); ++child)
- {
- // set an alias to the
- // prolongation matrix for
- // this child
- const FullMatrix<double> &prolongation
- = mg_dof.get_fe().get_prolongation_matrix (child, cell->refinement_case());
-
- cell->child(child)->get_mg_dof_indices (dof_indices_child);
-
- // now set the entries in the
- // matrix
- for (unsigned int i=0; i<dofs_per_cell; ++i)
- for (unsigned int j=0; j<dofs_per_cell; ++j)
- if (prolongation(i,j) != 0)
- {
- const unsigned int icomp = fe.system_to_component_index(i).first;
- const unsigned int jcomp = fe.system_to_component_index(j).first;
- if ((icomp==jcomp) && mg_selected[icomp])
- prolongation_matrices[level]->set(dof_indices_child[i],
- dof_indices_parent[j],
- prolongation(i,j));
- }
- }
- }
+ cell != mg_dof.end(level); ++cell)
+ if (cell->has_children())
+ {
+ cell->get_mg_dof_indices (dof_indices_parent);
+
+ for (unsigned int child=0; child<cell->n_children(); ++child)
+ {
+ // set an alias to the
+ // prolongation matrix for
+ // this child
+ const FullMatrix<double> &prolongation
+ = mg_dof.get_fe().get_prolongation_matrix (child, cell->refinement_case());
+
+ cell->child(child)->get_mg_dof_indices (dof_indices_child);
+
+ // now set the entries in the
+ // matrix
+ for (unsigned int i=0; i<dofs_per_cell; ++i)
+ for (unsigned int j=0; j<dofs_per_cell; ++j)
+ if (prolongation(i,j) != 0)
+ {
+ const unsigned int icomp = fe.system_to_component_index(i).first;
+ const unsigned int jcomp = fe.system_to_component_index(j).first;
+ if ((icomp==jcomp) && mg_selected[icomp])
+ prolongation_matrices[level]->set(dof_indices_child[i],
+ dof_indices_parent[j],
+ prolongation(i,j));
+ }
+ }
+ }
}
// impose boundary conditions
// but only in the column of
for(unsigned int c=0; c<ncomp; ++c)
if(mg_t_component[c] == mg_selected_component)
mg_selected[c] = true;
- // If components are renumbered,
- // find the first original
- // component corresponding to the
- // target component.
+ // If components are renumbered,
+ // find the first original
+ // component corresponding to the
+ // target component.
for (unsigned int i=0;i<target_component.size();++i)
{
if (target_component[i] == select)
- {
- selected_component = i;
- break;
- }
+ {
+ selected_component = i;
+ break;
+ }
}
for (unsigned int i=0;i<mg_target_component.size();++i)
{
if (mg_target_component[i] == mg_select)
- {
- mg_selected_component = i;
- break;
- }
+ {
+ mg_selected_component = i;
+ break;
+ }
}
MGTransferComponentBase::build_matrices (dof, mg_dof);
interface_dofs[l].resize(mg_dof.n_dofs(l));
MGTools::extract_inner_interface_dofs(mg_dof, interface_dofs);
- // use a temporary vector to create the
- // relation between global and level dofs
+ // use a temporary vector to create the
+ // relation between global and level dofs
std::vector<unsigned int> temp_copy_indices;
std::vector<unsigned int> global_dof_indices (fe.dofs_per_cell);
std::vector<unsigned int> level_dof_indices (fe.dofs_per_cell);
{
copy_to_and_from_indices[level].clear();
typename MGDoFHandler<dim,spacedim>::active_cell_iterator
- level_cell = mg_dof.begin_active(level);
+ level_cell = mg_dof.begin_active(level);
const typename MGDoFHandler<dim,spacedim>::active_cell_iterator
- level_end = mg_dof.end_active(level);
+ level_end = mg_dof.end_active(level);
temp_copy_indices.resize (0);
temp_copy_indices.resize (mg_dof.n_dofs(level), numbers::invalid_unsigned_int);
- // Compute coarse level right hand side
- // by restricting from fine level.
+ // Compute coarse level right hand side
+ // by restricting from fine level.
for (; level_cell!=level_end; ++level_cell)
- {
- DoFAccessor<dim, DoFHandler<dim,spacedim> >& global_cell = *level_cell;
- // get the dof numbers of
- // this cell for the global
- // and the level-wise
- // numbering
- global_cell.get_dof_indices(global_dof_indices);
- level_cell->get_mg_dof_indices (level_dof_indices);
-
- for (unsigned int i=0; i<fe.dofs_per_cell; ++i)
- {
- const unsigned int component
+ {
+ DoFAccessor<dim, DoFHandler<dim,spacedim> >& global_cell = *level_cell;
+ // get the dof numbers of
+ // this cell for the global
+ // and the level-wise
+ // numbering
+ global_cell.get_dof_indices(global_dof_indices);
+ level_cell->get_mg_dof_indices (level_dof_indices);
+
+ for (unsigned int i=0; i<fe.dofs_per_cell; ++i)
+ {
+ const unsigned int component
= fe.system_to_component_index(i).first;
- if (selected[component] &&
+ if (selected[component] &&
!interface_dofs[level][level_dof_indices[i]])
- {
- const unsigned int level_start
- = mg_component_start[level][mg_target_component[component]];
- const unsigned int global_start
- = component_start[target_component[component]];
- temp_copy_indices[level_dof_indices[i]-level_start] =
- global_dof_indices[i] - global_start;
- }
- }
- }
-
- // write indices from vector into the map from
- // global to level dofs
+ {
+ const unsigned int level_start
+ = mg_component_start[level][mg_target_component[component]];
+ const unsigned int global_start
+ = component_start[target_component[component]];
+ temp_copy_indices[level_dof_indices[i]-level_start] =
+ global_dof_indices[i] - global_start;
+ }
+ }
+ }
+
+ // write indices from vector into the map from
+ // global to level dofs
const unsigned int n_active_dofs =
- std::count_if (temp_copy_indices.begin(), temp_copy_indices.end(),
- std::bind2nd(std::not_equal_to<unsigned int>(),
- numbers::invalid_unsigned_int));
+ std::count_if (temp_copy_indices.begin(), temp_copy_indices.end(),
+ std::bind2nd(std::not_equal_to<unsigned int>(),
+ numbers::invalid_unsigned_int));
copy_to_and_from_indices[level].resize (n_active_dofs);
unsigned int counter = 0;
for (unsigned int i=0; i<temp_copy_indices.size(); ++i)
- if (temp_copy_indices[i] != numbers::invalid_unsigned_int)
- copy_to_and_from_indices[level][counter++] =
- std::pair<unsigned int, unsigned int> (temp_copy_indices[i], i);
+ if (temp_copy_indices[i] != numbers::invalid_unsigned_int)
+ copy_to_and_from_indices[level][counter++] =
+ std::pair<unsigned int, unsigned int> (temp_copy_indices[i], i);
Assert (counter == n_active_dofs, ExcInternalError());
}
}
//---------------------------------------------------------------------------
// $Id$
//
-// Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 by the deal.II authors
+// Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
for (unsigned int l=0;l<n_levels;++l)
sizes[l] = mg_dof.n_dofs(l);
- // reset the size of the array of
- // matrices. call resize(0) first,
- // in order to delete all elements
- // and clear their memory. then
- // repopulate these arrays
- //
- // note that on resize(0), the
- // shared_ptr class takes care of
- // deleting the object it points to
- // by itself
+ // reset the size of the array of
+ // matrices. call resize(0) first,
+ // in order to delete all elements
+ // and clear their memory. then
+ // repopulate these arrays
+ //
+ // note that on resize(0), the
+ // shared_ptr class takes care of
+ // deleting the object it points to
+ // by itself
prolongation_matrices.resize (0);
prolongation_sparsities.resize (0);
for (unsigned int i=0; i<n_levels-1; ++i)
{
prolongation_sparsities.push_back
- (std_cxx1x::shared_ptr<SparsityPattern> (new SparsityPattern));
+ (std_cxx1x::shared_ptr<SparsityPattern> (new SparsityPattern));
prolongation_matrices.push_back
- (std_cxx1x::shared_ptr<SparseMatrix<double> > (new SparseMatrix<double>));
+ (std_cxx1x::shared_ptr<SparseMatrix<double> > (new SparseMatrix<double>));
}
- // two fields which will store the
- // indices of the multigrid dofs
- // for a cell and one of its children
+ // two fields which will store the
+ // indices of the multigrid dofs
+ // for a cell and one of its children
std::vector<unsigned int> dof_indices_parent (dofs_per_cell);
std::vector<unsigned int> dof_indices_child (dofs_per_cell);
- // for each level: first build the sparsity
- // pattern of the matrices and then build the
- // matrices themselves. note that we only
- // need to take care of cells on the coarser
- // level which have children
+ // for each level: first build the sparsity
+ // pattern of the matrices and then build the
+ // matrices themselves. note that we only
+ // need to take care of cells on the coarser
+ // level which have children
for (unsigned int level=0; level<n_levels-1; ++level)
{
- // reset the dimension of the structure.
- // note that for the number of entries
- // per row, the number of parent dofs
- // coupling to a child dof is
- // necessary. this, of course, is the
- // number of degrees of freedom per
- // cell
- // increment dofs_per_cell
- // since a useless diagonal
- // element will be stored
+ // reset the dimension of the structure.
+ // note that for the number of entries
+ // per row, the number of parent dofs
+ // coupling to a child dof is
+ // necessary. this, of course, is the
+ // number of degrees of freedom per
+ // cell
+ // increment dofs_per_cell
+ // since a useless diagonal
+ // element will be stored
CompressedSimpleSparsityPattern csp (sizes[level+1],
- sizes[level]);
+ sizes[level]);
std::vector<unsigned int> entries (dofs_per_cell);
for (typename MGDoFHandler<dim,spacedim>::cell_iterator cell=mg_dof.begin(level);
- cell != mg_dof.end(level); ++cell)
- if (cell->has_children())
- {
- cell->get_mg_dof_indices (dof_indices_parent);
-
- Assert(cell->n_children()==GeometryInfo<dim>::max_children_per_cell,
- ExcNotImplemented());
- for (unsigned int child=0; child<cell->n_children(); ++child)
- {
- // set an alias to the
- // prolongation matrix for
- // this child
- const FullMatrix<double> &prolongation
- = mg_dof.get_fe().get_prolongation_matrix (child,
- cell->refinement_case());
-
- Assert (prolongation.n() != 0, ExcNoProlongation());
-
- cell->child(child)->get_mg_dof_indices (dof_indices_child);
-
- // now tag the entries in the
- // matrix which will be used
- // for this pair of parent/child
- for (unsigned int i=0; i<dofs_per_cell; ++i)
- {
- entries.resize(0);
- for (unsigned int j=0; j<dofs_per_cell; ++j)
- if (prolongation(i,j) != 0)
- entries.push_back (dof_indices_parent[j]);
- csp.add_entries (dof_indices_child[i],
- entries.begin(), entries.end());
- }
- }
- }
+ cell != mg_dof.end(level); ++cell)
+ if (cell->has_children())
+ {
+ cell->get_mg_dof_indices (dof_indices_parent);
+
+ Assert(cell->n_children()==GeometryInfo<dim>::max_children_per_cell,
+ ExcNotImplemented());
+ for (unsigned int child=0; child<cell->n_children(); ++child)
+ {
+ // set an alias to the
+ // prolongation matrix for
+ // this child
+ const FullMatrix<double> &prolongation
+ = mg_dof.get_fe().get_prolongation_matrix (child,
+ cell->refinement_case());
+
+ Assert (prolongation.n() != 0, ExcNoProlongation());
+
+ cell->child(child)->get_mg_dof_indices (dof_indices_child);
+
+ // now tag the entries in the
+ // matrix which will be used
+ // for this pair of parent/child
+ for (unsigned int i=0; i<dofs_per_cell; ++i)
+ {
+ entries.resize(0);
+ for (unsigned int j=0; j<dofs_per_cell; ++j)
+ if (prolongation(i,j) != 0)
+ entries.push_back (dof_indices_parent[j]);
+ csp.add_entries (dof_indices_child[i],
+ entries.begin(), entries.end());
+ }
+ }
+ }
prolongation_sparsities[level]->copy_from (csp);
csp.reinit(0,0);
prolongation_matrices[level]->reinit (*prolongation_sparsities[level]);
- // now actually build the matrices
+ // now actually build the matrices
for (typename MGDoFHandler<dim,spacedim>::cell_iterator cell=mg_dof.begin(level);
- cell != mg_dof.end(level); ++cell)
- if (cell->has_children())
- {
- cell->get_mg_dof_indices (dof_indices_parent);
-
- Assert(cell->n_children()==GeometryInfo<dim>::max_children_per_cell,
- ExcNotImplemented());
- for (unsigned int child=0; child<cell->n_children(); ++child)
- {
- // set an alias to the
- // prolongation matrix for
- // this child
- const FullMatrix<double> &prolongation
- = mg_dof.get_fe().get_prolongation_matrix (child,
- cell->refinement_case());
-
- cell->child(child)->get_mg_dof_indices (dof_indices_child);
-
- // now set the entries in the
- // matrix
- for (unsigned int i=0; i<dofs_per_cell; ++i)
- prolongation_matrices[level]->set (dof_indices_child[i],
- dofs_per_cell,
- &dof_indices_parent[0],
- &prolongation(i,0),
- true);
- }
- }
+ cell != mg_dof.end(level); ++cell)
+ if (cell->has_children())
+ {
+ cell->get_mg_dof_indices (dof_indices_parent);
+
+ Assert(cell->n_children()==GeometryInfo<dim>::max_children_per_cell,
+ ExcNotImplemented());
+ for (unsigned int child=0; child<cell->n_children(); ++child)
+ {
+ // set an alias to the
+ // prolongation matrix for
+ // this child
+ const FullMatrix<double> &prolongation
+ = mg_dof.get_fe().get_prolongation_matrix (child,
+ cell->refinement_case());
+
+ cell->child(child)->get_mg_dof_indices (dof_indices_child);
+
+ // now set the entries in the
+ // matrix
+ for (unsigned int i=0; i<dofs_per_cell; ++i)
+ prolongation_matrices[level]->set (dof_indices_child[i],
+ dofs_per_cell,
+ &dof_indices_parent[0],
+ &prolongation(i,0),
+ true);
+ }
+ }
}
- // impose boundary conditions
- // but only in the column of
- // the prolongation matrix
+ // impose boundary conditions
+ // but only in the column of
+ // the prolongation matrix
if (mg_constrained_dofs != 0)
if (mg_constrained_dofs->set_boundary_values())
{
std::vector<unsigned int> constrain_indices;
for (int level=n_levels-2; level>=0; --level)
- {
- if (mg_constrained_dofs->get_boundary_indices()[level].size() == 0)
- continue;
-
- // need to delete all the columns in the
- // matrix that are on the boundary. to achive
- // this, create an array as long as there are
- // matrix columns, and find which columns we
- // need to filter away.
- constrain_indices.resize (0);
- constrain_indices.resize (prolongation_matrices[level]->n(), 0);
- std::set<unsigned int>::const_iterator dof
+ {
+ if (mg_constrained_dofs->get_boundary_indices()[level].size() == 0)
+ continue;
+
+ // need to delete all the columns in the
+ // matrix that are on the boundary. to achive
+ // this, create an array as long as there are
+ // matrix columns, and find which columns we
+ // need to filter away.
+ constrain_indices.resize (0);
+ constrain_indices.resize (prolongation_matrices[level]->n(), 0);
+ std::set<unsigned int>::const_iterator dof
= mg_constrained_dofs->get_boundary_indices()[level].begin(),
- endd = mg_constrained_dofs->get_boundary_indices()[level].end();
- for (; dof != endd; ++dof)
- constrain_indices[*dof] = 1;
-
- const unsigned int n_dofs = prolongation_matrices[level]->m();
- for (unsigned int i=0; i<n_dofs; ++i)
- {
- SparseMatrix<double>::iterator
- start_row = prolongation_matrices[level]->begin(i),
- end_row = prolongation_matrices[level]->end(i);
- for(; start_row != end_row; ++start_row)
- {
- if (constrain_indices[start_row->column()] == 1)
- start_row->value() = 0;
- }
- }
- }
+ endd = mg_constrained_dofs->get_boundary_indices()[level].end();
+ for (; dof != endd; ++dof)
+ constrain_indices[*dof] = 1;
+
+ const unsigned int n_dofs = prolongation_matrices[level]->m();
+ for (unsigned int i=0; i<n_dofs; ++i)
+ {
+ SparseMatrix<double>::iterator
+ start_row = prolongation_matrices[level]->begin(i),
+ end_row = prolongation_matrices[level]->end(i);
+ for(; start_row != end_row; ++start_row)
+ {
+ if (constrain_indices[start_row->column()] == 1)
+ start_row->value() = 0;
+ }
+ }
+ }
}
- // to find the indices that describe the
- // relation between global dofs and local
- // numbering on the individual level, first
- // create a temp vector where the ith level
- // entry contains the respective global
- // entry. this gives a neat way to find those
- // indices. in a second step, actually build
- // the std::vector<std::pair<uint,uint> > that
- // only contains the active dofs on the
- // levels.
+ // to find the indices that describe the
+ // relation between global dofs and local
+ // numbering on the individual level, first
+ // create a temp vector where the ith level
+ // entry contains the respective global
+ // entry. this gives a neat way to find those
+ // indices. in a second step, actually build
+ // the std::vector<std::pair<uint,uint> > that
+ // only contains the active dofs on the
+ // levels.
copy_indices.resize(n_levels);
std::vector<unsigned int> temp_copy_indices;
{
copy_indices[level].clear();
typename MGDoFHandler<dim,spacedim>::active_cell_iterator
- level_cell = mg_dof.begin_active(level);
+ level_cell = mg_dof.begin_active(level);
const typename MGDoFHandler<dim,spacedim>::active_cell_iterator
- level_end = mg_dof.end_active(level);
+ level_end = mg_dof.end_active(level);
temp_copy_indices.resize (0);
temp_copy_indices.resize (mg_dof.n_dofs(level), numbers::invalid_unsigned_int);
- // Compute coarse level right hand side
- // by restricting from fine level.
+ // Compute coarse level right hand side
+ // by restricting from fine level.
for (; level_cell!=level_end; ++level_cell)
- {
- DoFAccessor<dim, DoFHandler<dim,spacedim> >& global_cell = *level_cell;
- // get the dof numbers of
- // this cell for the global
- // and the level-wise
- // numbering
- global_cell.get_dof_indices(global_dof_indices);
- level_cell->get_mg_dof_indices (level_dof_indices);
-
- for (unsigned int i=0; i<dofs_per_cell; ++i)
+ {
+ DoFAccessor<dim, DoFHandler<dim,spacedim> >& global_cell = *level_cell;
+ // get the dof numbers of
+ // this cell for the global
+ // and the level-wise
+ // numbering
+ global_cell.get_dof_indices(global_dof_indices);
+ level_cell->get_mg_dof_indices (level_dof_indices);
+
+ for (unsigned int i=0; i<dofs_per_cell; ++i)
{
if(mg_constrained_dofs != 0)
{
- if(!mg_constrained_dofs->at_refinement_edge(level,level_dof_indices[i]))
- temp_copy_indices[level_dof_indices[i]] = global_dof_indices[i];
+ if(!mg_constrained_dofs->at_refinement_edge(level,level_dof_indices[i]))
+ temp_copy_indices[level_dof_indices[i]] = global_dof_indices[i];
}
else
- temp_copy_indices[level_dof_indices[i]] = global_dof_indices[i];
+ temp_copy_indices[level_dof_indices[i]] = global_dof_indices[i];
}
- }
-
- // now all the active dofs got a valid entry,
- // the other ones have an invalid entry. Count
- // the invalid entries and then resize the
- // copy_indices object. Then, insert the pairs
- // of global index and level index into
- // copy_indices.
+ }
+
+ // now all the active dofs got a valid entry,
+ // the other ones have an invalid entry. Count
+ // the invalid entries and then resize the
+ // copy_indices object. Then, insert the pairs
+ // of global index and level index into
+ // copy_indices.
const unsigned int n_active_dofs =
- std::count_if (temp_copy_indices.begin(), temp_copy_indices.end(),
- std::bind2nd(std::not_equal_to<unsigned int>(),
- numbers::invalid_unsigned_int));
+ std::count_if (temp_copy_indices.begin(), temp_copy_indices.end(),
+ std::bind2nd(std::not_equal_to<unsigned int>(),
+ numbers::invalid_unsigned_int));
copy_indices[level].resize (n_active_dofs);
unsigned int counter = 0;
for (unsigned int i=0; i<temp_copy_indices.size(); ++i)
- if (temp_copy_indices[i] != numbers::invalid_unsigned_int)
- copy_indices[level][counter++] =
- std::pair<unsigned int, unsigned int> (temp_copy_indices[i], i);
+ if (temp_copy_indices[i] != numbers::invalid_unsigned_int)
+ copy_indices[level][counter++] =
+ std::pair<unsigned int, unsigned int> (temp_copy_indices[i], i);
Assert (counter == n_active_dofs, ExcInternalError());
}
}
// $Id$
// Version: $Name$
//
-// Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2011 by the deal.II authors
+// Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
template <>
void
Multigrid<Vector<double> >::print_vector (const unsigned int level,
- const Vector<double> &v,
- const char *name) const
+ const Vector<double> &v,
+ const char *name) const
{
if (level!=maxlevel)
return;
const unsigned int dim=deal_II_dimension;
const DoFHandler<dim> *dof = mg_dof_handler;
-
+
Vector<double> out_vector(dof->n_dofs());
out_vector = -10000;
-
+
const unsigned int dofs_per_cell = mg_dof_handler->get_fe().dofs_per_cell;
std::vector<unsigned int> global_dof_indices (dofs_per_cell);
const MGDoFHandler<dim>::cell_iterator
endc = mg_dof_handler->end(level);
- // traverse all cells and copy the
- // data appropriately to the output
- // vector
+ // traverse all cells and copy the
+ // data appropriately to the output
+ // vector
for (; level_cell != endc; ++level_cell, ++global_cell)
{
global_cell->get_dof_indices (global_dof_indices);
level_cell->get_mg_dof_indices(level_dof_indices);
- // copy level-wise data to
- // global vector
+ // copy level-wise data to
+ // global vector
for (unsigned int i=0; i<dofs_per_cell; ++i)
- out_vector(global_dof_indices[i])
- = v(level_dof_indices[i]);
+ out_vector(global_dof_indices[i])
+ = v(level_dof_indices[i]);
}
std::ofstream out_file(name);
template <class VECTOR>
void
Multigrid<VECTOR>::print_vector (const unsigned int level,
- const VECTOR &v,
- const char *name) const
+ const VECTOR &v,
+ const char *name) const
{
Assert(false, ExcNotImplemented());
}
template<class VECTOR>
MGTransferPrebuilt<VECTOR>::MGTransferPrebuilt ()
-{}
+{}
template<class VECTOR>
:
constraints(&c),
mg_constrained_dofs(&mg_c)
-{}
+{}
template <class VECTOR>
-MGTransferPrebuilt<VECTOR>::~MGTransferPrebuilt ()
+MGTransferPrebuilt<VECTOR>::~MGTransferPrebuilt ()
{}
void MGTransferPrebuilt<VECTOR>::prolongate (
const unsigned int to_level,
VECTOR& dst,
- const VECTOR& src) const
+ const VECTOR& src) const
{
Assert ((to_level >= 1) && (to_level<=prolongation_matrices.size()),
- ExcIndexRange (to_level, 1, prolongation_matrices.size()+1));
+ ExcIndexRange (to_level, 1, prolongation_matrices.size()+1));
prolongation_matrices[to_level-1]->vmult (dst, src);
}
void MGTransferPrebuilt<VECTOR>::restrict_and_add (
const unsigned int from_level,
VECTOR &dst,
- const VECTOR &src) const
+ const VECTOR &src) const
{
Assert ((from_level >= 1) && (from_level<=prolongation_matrices.size()),
- ExcIndexRange (from_level, 1, prolongation_matrices.size()+1));
+ ExcIndexRange (from_level, 1, prolongation_matrices.size()+1));
prolongation_matrices[from_level-1]->Tvmult_add (dst, src);
}
template <typename number>
MGTransferBlock<number>::MGTransferBlock ()
- :
- memory(0, typeid(*this).name())
+ :
+ memory(0, typeid(*this).name())
{}
template <typename number>
void
MGTransferBlock<number>::initialize (const std::vector<number>& f,
- VectorMemory<Vector<number> >& mem)
+ VectorMemory<Vector<number> >& mem)
{
factors = f;
memory = &mem;
void MGTransferBlock<number>::prolongate (
const unsigned int to_level,
BlockVector<number> &dst,
- const BlockVector<number> &src) const
+ const BlockVector<number> &src) const
{
Assert ((to_level >= 1) && (to_level<=prolongation_matrices.size()),
- ExcIndexRange (to_level, 1, prolongation_matrices.size()+1));
+ ExcIndexRange (to_level, 1, prolongation_matrices.size()+1));
Assert (src.n_blocks() == this->n_mg_blocks,
- ExcDimensionMismatch(src.n_blocks(), this->n_mg_blocks));
+ ExcDimensionMismatch(src.n_blocks(), this->n_mg_blocks));
Assert (dst.n_blocks() == this->n_mg_blocks,
- ExcDimensionMismatch(dst.n_blocks(), this->n_mg_blocks));
+ ExcDimensionMismatch(dst.n_blocks(), this->n_mg_blocks));
- // Multiplicate with prolongation
- // matrix, but only those blocks
- // selected.
+ // Multiplicate with prolongation
+ // matrix, but only those blocks
+ // selected.
for (unsigned int b=0; b<this->mg_block.size();++b)
{
if (this->selected[b])
- prolongation_matrices[to_level-1]->block(b,b).vmult (
- dst.block(this->mg_block[b]), src.block(this->mg_block[b]));
+ prolongation_matrices[to_level-1]->block(b,b).vmult (
+ dst.block(this->mg_block[b]), src.block(this->mg_block[b]));
}
}
void MGTransferBlock<number>::restrict_and_add (
const unsigned int from_level,
BlockVector<number> &dst,
- const BlockVector<number> &src) const
+ const BlockVector<number> &src) const
{
Assert ((from_level >= 1) && (from_level<=prolongation_matrices.size()),
- ExcIndexRange (from_level, 1, prolongation_matrices.size()+1));
+ ExcIndexRange (from_level, 1, prolongation_matrices.size()+1));
Assert (src.n_blocks() == this->n_mg_blocks,
- ExcDimensionMismatch(src.n_blocks(), this->n_mg_blocks));
+ ExcDimensionMismatch(src.n_blocks(), this->n_mg_blocks));
Assert (dst.n_blocks() == this->n_mg_blocks,
- ExcDimensionMismatch(dst.n_blocks(), this->n_mg_blocks));
-
+ ExcDimensionMismatch(dst.n_blocks(), this->n_mg_blocks));
+
for (unsigned int b=0; b<this->mg_block.size();++b)
{
if (this->selected[b])
- {
- if (factors.size() != 0)
- {
- Assert (memory != 0, ExcNotInitialized());
- Vector<number>* aux = memory->alloc();
- aux->reinit(dst.block(this->mg_block[b]));
- prolongation_matrices[from_level-1]->block(b,b).Tvmult (
- *aux, src.block(this->mg_block[b]));
-
- dst.block(this->mg_block[b]).add(factors[b], *aux);
- memory->free(aux);
- }
- else
- {
- prolongation_matrices[from_level-1]->block(b,b).Tvmult_add (
- dst.block(this->mg_block[b]), src.block(this->mg_block[b]));
- }
- }
+ {
+ if (factors.size() != 0)
+ {
+ Assert (memory != 0, ExcNotInitialized());
+ Vector<number>* aux = memory->alloc();
+ aux->reinit(dst.block(this->mg_block[b]));
+ prolongation_matrices[from_level-1]->block(b,b).Tvmult (
+ *aux, src.block(this->mg_block[b]));
+
+ dst.block(this->mg_block[b]).add(factors[b], *aux);
+ memory->free(aux);
+ }
+ else
+ {
+ prolongation_matrices[from_level-1]->block(b,b).Tvmult_add (
+ dst.block(this->mg_block[b]), src.block(this->mg_block[b]));
+ }
+ }
}
}
{
std::size_t result = sizeof(*this);
result += MemoryConsumption::memory_consumption(selected)
- - sizeof(selected);
+ - sizeof(selected);
result += MemoryConsumption::memory_consumption(target_component)
- - sizeof(mg_target_component);
+ - sizeof(mg_target_component);
result += MemoryConsumption::memory_consumption(sizes)
- - sizeof(sizes);
+ - sizeof(sizes);
result += MemoryConsumption::memory_consumption(component_start)
- - sizeof(component_start);
+ - sizeof(component_start);
result += MemoryConsumption::memory_consumption(mg_component_start)
- - sizeof(mg_component_start);
+ - sizeof(mg_component_start);
result += MemoryConsumption::memory_consumption(prolongation_sparsities)
- - sizeof(prolongation_sparsities);
+ - sizeof(prolongation_sparsities);
result += MemoryConsumption::memory_consumption(prolongation_matrices)
- - sizeof(prolongation_matrices);
+ - sizeof(prolongation_matrices);
//TODO:[GK] Add this.
// result += MemoryConsumption::memory_consumption(copy_to_and_from_indices)
-// - sizeof(copy_to_and_from_indices);
+// - sizeof(copy_to_and_from_indices);
return result;
}
std::size_t result = sizeof(*this);
result += sizeof(unsigned int) * sizes.size();
result += MemoryConsumption::memory_consumption(selected)
- - sizeof(selected);
+ - sizeof(selected);
result += MemoryConsumption::memory_consumption(mg_block)
- - sizeof(mg_block);
+ - sizeof(mg_block);
result += MemoryConsumption::memory_consumption(block_start)
- - sizeof(block_start);
+ - sizeof(block_start);
result += MemoryConsumption::memory_consumption(mg_block_start)
- - sizeof(mg_block_start);
+ - sizeof(mg_block_start);
result += MemoryConsumption::memory_consumption(prolongation_sparsities)
- - sizeof(prolongation_sparsities);
+ - sizeof(prolongation_sparsities);
result += MemoryConsumption::memory_consumption(prolongation_matrices)
- - sizeof(prolongation_matrices);
+ - sizeof(prolongation_matrices);
//TODO:[GK] Add this.
// result += MemoryConsumption::memory_consumption(copy_indices)
-// - sizeof(copy_indices);
+// - sizeof(copy_indices);
return result;
}
template<typename number>
MGTransferSelect<number>::MGTransferSelect ()
-{}
+{}
template<typename number>
MGTransferSelect<number>::MGTransferSelect (const ConstraintMatrix &c)
:
constraints(&c)
-{}
+{}
template <typename number>
-MGTransferSelect<number>::~MGTransferSelect ()
+MGTransferSelect<number>::~MGTransferSelect ()
{}
void MGTransferSelect<number>::prolongate (
const unsigned int to_level,
Vector<number> &dst,
- const Vector<number> &src) const
+ const Vector<number> &src) const
{
Assert ((to_level >= 1) && (to_level<=prolongation_matrices.size()),
- ExcIndexRange (to_level, 1, prolongation_matrices.size()+1));
+ ExcIndexRange (to_level, 1, prolongation_matrices.size()+1));
prolongation_matrices[to_level-1]->block(mg_target_component[mg_selected_component],
- mg_target_component[mg_selected_component])
- .vmult (dst, src);
+ mg_target_component[mg_selected_component])
+ .vmult (dst, src);
}
const Vector<number> &src) const
{
Assert ((from_level >= 1) && (from_level<=prolongation_matrices.size()),
- ExcIndexRange (from_level, 1, prolongation_matrices.size()+1));
+ ExcIndexRange (from_level, 1, prolongation_matrices.size()+1));
prolongation_matrices[from_level-1]->block(mg_target_component[mg_selected_component],
- mg_target_component[mg_selected_component])
+ mg_target_component[mg_selected_component])
.Tvmult_add (dst, src);
}
template <typename number>
MGTransferBlockSelect<number>::MGTransferBlockSelect ()
-{}
+{}
template <typename number>
MGTransferBlockSelect<number>::MGTransferBlockSelect (
const ConstraintMatrix &c, const MGConstrainedDoFs& mg_c)
: MGTransferBlockBase(c, mg_c)
-{}
+{}
template <typename number>
-MGTransferBlockSelect<number>::~MGTransferBlockSelect ()
+MGTransferBlockSelect<number>::~MGTransferBlockSelect ()
{}
void MGTransferBlockSelect<number>::prolongate (
const unsigned int to_level,
Vector<number> &dst,
- const Vector<number> &src) const
+ const Vector<number> &src) const
{
Assert ((to_level >= 1) && (to_level<=prolongation_matrices.size()),
- ExcIndexRange (to_level, 1, prolongation_matrices.size()+1));
+ ExcIndexRange (to_level, 1, prolongation_matrices.size()+1));
prolongation_matrices[to_level-1]->block(selected_block,
- selected_block)
- .vmult (dst, src);
+ selected_block)
+ .vmult (dst, src);
}
const Vector<number> &src) const
{
Assert ((from_level >= 1) && (from_level<=prolongation_matrices.size()),
- ExcIndexRange (from_level, 1, prolongation_matrices.size()+1));
+ ExcIndexRange (from_level, 1, prolongation_matrices.size()+1));
prolongation_matrices[from_level-1]->block(selected_block,
- selected_block)
+ selected_block)
.Tvmult_add (dst, src);
}
template <class FE>
ParallelData<dim,spacedim>::
ParallelData (const Quadrature<dim> &quadrature,
- const unsigned int n_components,
- const unsigned int n_datasets,
- const unsigned int n_subdivisions,
- const std::vector<unsigned int> &n_postprocessor_outputs,
- const Mapping<dim,spacedim> &mapping,
- const std::vector<std::vector<unsigned int> > &cell_to_patch_index_map,
- const FE &finite_elements,
- const UpdateFlags update_flags)
- :
- ParallelDataBase<dim,spacedim> (n_components,
- n_datasets,
- n_subdivisions,
- quadrature.size(),
- n_postprocessor_outputs,
- finite_elements),
- q_collection (quadrature),
- mapping_collection (mapping),
- x_fe_values (this->mapping_collection,
- this->fe_collection,
- q_collection,
- update_flags),
- cell_to_patch_index_map (&cell_to_patch_index_map)
+ const unsigned int n_components,
+ const unsigned int n_datasets,
+ const unsigned int n_subdivisions,
+ const std::vector<unsigned int> &n_postprocessor_outputs,
+ const Mapping<dim,spacedim> &mapping,
+ const std::vector<std::vector<unsigned int> > &cell_to_patch_index_map,
+ const FE &finite_elements,
+ const UpdateFlags update_flags)
+ :
+ ParallelDataBase<dim,spacedim> (n_components,
+ n_datasets,
+ n_subdivisions,
+ quadrature.size(),
+ n_postprocessor_outputs,
+ finite_elements),
+ q_collection (quadrature),
+ mapping_collection (mapping),
+ x_fe_values (this->mapping_collection,
+ this->fe_collection,
+ q_collection,
+ update_flags),
+ cell_to_patch_index_map (&cell_to_patch_index_map)
{}
- /**
- * In a WorkStream context, use
- * this function to append the
- * patch computed by the parallel
- * stage to the array of patches.
- */
+ /**
+ * In a WorkStream context, use
+ * this function to append the
+ * patch computed by the parallel
+ * stage to the array of patches.
+ */
template <int dim, int spacedim>
void
append_patch_to_list (const DataOutBase::Patch<dim,spacedim> &patch,
- std::vector<DataOutBase::Patch<dim,spacedim> > &patches)
+ std::vector<DataOutBase::Patch<dim,spacedim> > &patches)
{
patches.push_back (patch);
patches.back().patch_index = patches.size()-1;
{
template <class DH>
DataEntryBase<DH>::DataEntryBase (const std::vector<std::string> &names_in,
- const std::vector<DataComponentInterpretation::DataComponentInterpretation> &data_component_interpretation)
- :
- names(names_in),
- data_component_interpretation (data_component_interpretation),
- postprocessor(0, typeid(*this).name()),
- n_output_variables(names.size())
+ const std::vector<DataComponentInterpretation::DataComponentInterpretation> &data_component_interpretation)
+ :
+ names(names_in),
+ data_component_interpretation (data_component_interpretation),
+ postprocessor(0, typeid(*this).name()),
+ n_output_variables(names.size())
{
Assert (names.size() == data_component_interpretation.size(),
- ExcDimensionMismatch(data_component_interpretation.size(),
- names.size()));
+ ExcDimensionMismatch(data_component_interpretation.size(),
+ names.size()));
- // check that the names use only allowed
- // characters
- // check names for invalid characters
+ // check that the names use only allowed
+ // characters
+ // check names for invalid characters
for (unsigned int i=0; i<names.size(); ++i)
- Assert (names[i].find_first_not_of("abcdefghijklmnopqrstuvwxyz"
- "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
- "0123456789_<>()") == std::string::npos,
- typename dealii::DataOut<DH::dimension>::
- ExcInvalidCharacter (names[i],
- names[i].find_first_not_of("abcdefghijklmnopqrstuvwxyz"
- "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
- "0123456789_<>()")));
+ Assert (names[i].find_first_not_of("abcdefghijklmnopqrstuvwxyz"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "0123456789_<>()") == std::string::npos,
+ typename dealii::DataOut<DH::dimension>::
+ ExcInvalidCharacter (names[i],
+ names[i].find_first_not_of("abcdefghijklmnopqrstuvwxyz"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "0123456789_<>()")));
}
template <class DH>
DataEntryBase<DH>::DataEntryBase (const DataPostprocessor<DH::space_dimension> *data_postprocessor)
- :
- names(data_postprocessor->get_names()),
- data_component_interpretation (data_postprocessor->get_data_component_interpretation()),
- postprocessor(data_postprocessor, typeid(*this).name()),
- n_output_variables(names.size())
+ :
+ names(data_postprocessor->get_names()),
+ data_component_interpretation (data_postprocessor->get_data_component_interpretation()),
+ postprocessor(data_postprocessor, typeid(*this).name()),
+ n_output_variables(names.size())
{
Assert (data_postprocessor->get_names().size()
- ==
- data_postprocessor->get_data_component_interpretation().size(),
- ExcDimensionMismatch (data_postprocessor->get_names().size(),
- data_postprocessor->get_data_component_interpretation().size()));
+ ==
+ data_postprocessor->get_data_component_interpretation().size(),
+ ExcDimensionMismatch (data_postprocessor->get_names().size(),
+ data_postprocessor->get_data_component_interpretation().size()));
- // check that the names use only allowed
- // characters
+ // check that the names use only allowed
+ // characters
for (unsigned int i=0; i<names.size(); ++i)
- Assert (names[i].find_first_not_of("abcdefghijklmnopqrstuvwxyz"
- "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
- "0123456789_<>()") == std::string::npos,
- typename dealii::DataOut<DH::dimension>::
- ExcInvalidCharacter (names[i],
- names[i].find_first_not_of("abcdefghijklmnopqrstuvwxyz"
- "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
- "0123456789_<>()")));
+ Assert (names[i].find_first_not_of("abcdefghijklmnopqrstuvwxyz"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "0123456789_<>()") == std::string::npos,
+ typename dealii::DataOut<DH::dimension>::
+ ExcInvalidCharacter (names[i],
+ names[i].find_first_not_of("abcdefghijklmnopqrstuvwxyz"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "0123456789_<>()")));
}
class DataEntry : public DataEntryBase<DH>
{
public:
- /**
- * Constructor. Give a list of names
- * for the individual components of
- * the vector and their
- * interpretation as scalar or vector
- * data. This constructor assumes
- * that no postprocessor is going to
- * be used.
- */
- DataEntry (const VectorType *data,
- const std::vector<std::string> &names,
- const std::vector<DataComponentInterpretation::DataComponentInterpretation> &data_component_interpretation);
-
- /**
- * Constructor when a data
- * postprocessor is going to be
- * used. In that case, the names and
- * vector declarations are going to
- * be aquired from the postprocessor.
- */
- DataEntry (const VectorType *data,
- const DataPostprocessor<DH::space_dimension> *data_postprocessor);
+ /**
+ * Constructor. Give a list of names
+ * for the individual components of
+ * the vector and their
+ * interpretation as scalar or vector
+ * data. This constructor assumes
+ * that no postprocessor is going to
+ * be used.
+ */
+ DataEntry (const VectorType *data,
+ const std::vector<std::string> &names,
+ const std::vector<DataComponentInterpretation::DataComponentInterpretation> &data_component_interpretation);
+
+ /**
+ * Constructor when a data
+ * postprocessor is going to be
+ * used. In that case, the names and
+ * vector declarations are going to
+ * be aquired from the postprocessor.
+ */
+ DataEntry (const VectorType *data,
+ const DataPostprocessor<DH::space_dimension> *data_postprocessor);
/**
* Assuming that the stored vector is
virtual
void
get_function_gradients (const FEValuesBase<DH::dimension,DH::space_dimension> &fe_patch_values,
- std::vector<Tensor<1,DH::space_dimension> > &patch_gradients) const;
+ std::vector<Tensor<1,DH::space_dimension> > &patch_gradients) const;
/**
* Given a FEValuesBase object,
virtual
void
get_function_gradients (const FEValuesBase<DH::dimension,DH::space_dimension> &fe_patch_values,
- std::vector<std::vector<Tensor<1,DH::space_dimension> > > &patch_gradients_system) const;
+ std::vector<std::vector<Tensor<1,DH::space_dimension> > > &patch_gradients_system) const;
/**
* Given a FEValuesBase object, extract
virtual
void
get_function_hessians (const FEValuesBase<DH::dimension,DH::space_dimension> &fe_patch_values,
- std::vector<Tensor<2,DH::space_dimension> > &patch_hessians) const;
+ std::vector<Tensor<2,DH::space_dimension> > &patch_hessians) const;
/**
* Given a FEValuesBase object, extract
virtual
void
get_function_hessians (const FEValuesBase<DH::dimension,DH::space_dimension> &fe_patch_values,
- std::vector<std::vector< Tensor<2,DH::space_dimension> > > &patch_hessians_system) const;
+ std::vector<std::vector< Tensor<2,DH::space_dimension> > > &patch_hessians_system) const;
/**
* Clear all references to the
*/
virtual void clear ();
- /**
- * Determine an estimate for
- * the memory consumption (in
- * bytes) of this object.
- */
- virtual std::size_t memory_consumption () const;
+ /**
+ * Determine an estimate for
+ * the memory consumption (in
+ * bytes) of this object.
+ */
+ virtual std::size_t memory_consumption () const;
private:
/**
template <class DH, class VectorType>
DataEntry<DH,VectorType>::
DataEntry (const VectorType *data,
- const std::vector<std::string> &names,
- const std::vector<DataComponentInterpretation::DataComponentInterpretation> &data_component_interpretation)
- :
- DataEntryBase<DH> (names, data_component_interpretation),
- vector (data)
+ const std::vector<std::string> &names,
+ const std::vector<DataComponentInterpretation::DataComponentInterpretation> &data_component_interpretation)
+ :
+ DataEntryBase<DH> (names, data_component_interpretation),
+ vector (data)
{}
template <class DH, class VectorType>
DataEntry<DH,VectorType>::
DataEntry (const VectorType *data,
- const DataPostprocessor<DH::space_dimension> *data_postprocessor)
- :
- DataEntryBase<DH> (data_postprocessor),
- vector (data)
+ const DataPostprocessor<DH::space_dimension> *data_postprocessor)
+ :
+ DataEntryBase<DH> (data_postprocessor),
+ vector (data)
{}
template <class VectorType>
double
get_vector_element (const VectorType &vector,
- const unsigned int cell_number)
+ const unsigned int cell_number)
{
- return vector[cell_number];
+ return vector[cell_number];
}
double
get_vector_element (const IndexSet &is,
- const unsigned int cell_number)
+ const unsigned int cell_number)
{
- return (is.is_element(cell_number) ? 1 : 0);
+ return (is.is_element(cell_number) ? 1 : 0);
}
}
void
DataEntry<DH,VectorType>::
get_function_values (const FEValuesBase<DH::dimension,DH::space_dimension> &fe_patch_values,
- std::vector<dealii::Vector<double> > &patch_values_system) const
+ std::vector<dealii::Vector<double> > &patch_values_system) const
{
fe_patch_values.get_function_values (*vector, patch_values_system);
}
void
DataEntry<DH,VectorType>::
get_function_values (const FEValuesBase<DH::dimension,DH::space_dimension> &fe_patch_values,
- std::vector<double> &patch_values) const
+ std::vector<double> &patch_values) const
{
fe_patch_values.get_function_values (*vector, patch_values);
}
void
DataEntry<DH,VectorType>::
get_function_gradients (const FEValuesBase<DH::dimension,DH::space_dimension> &fe_patch_values,
- std::vector<std::vector<Tensor<1,DH::space_dimension> > > &patch_gradients_system) const
+ std::vector<std::vector<Tensor<1,DH::space_dimension> > > &patch_gradients_system) const
{
fe_patch_values.get_function_grads (*vector, patch_gradients_system);
}
void
DataEntry<DH,VectorType>::
get_function_gradients (const FEValuesBase<DH::dimension,DH::space_dimension> &fe_patch_values,
- std::vector<Tensor<1,DH::space_dimension> > &patch_gradients) const
+ std::vector<Tensor<1,DH::space_dimension> > &patch_gradients) const
{
fe_patch_values.get_function_grads (*vector, patch_gradients);
}
void
DataEntry<DH,VectorType>::
get_function_hessians (const FEValuesBase<DH::dimension,DH::space_dimension> &fe_patch_values,
- std::vector<std::vector<Tensor<2,DH::space_dimension> > > &patch_hessians_system) const
+ std::vector<std::vector<Tensor<2,DH::space_dimension> > > &patch_hessians_system) const
{
fe_patch_values.get_function_2nd_derivatives (*vector, patch_hessians_system);
}
void
DataEntry<DH,VectorType>::
get_function_hessians (const FEValuesBase<DH::dimension,DH::space_dimension> &fe_patch_values,
- std::vector<Tensor<2,DH::space_dimension> > &patch_hessians) const
+ std::vector<Tensor<2,DH::space_dimension> > &patch_hessians) const
{
fe_patch_values.get_function_2nd_derivatives (*vector, patch_hessians);
}
DataEntry<DH,VectorType>::memory_consumption () const
{
return (sizeof (vector) +
- MemoryConsumption::memory_consumption (this->names));
+ MemoryConsumption::memory_consumption (this->names));
}
template <class DH,
- int patch_dim, int patch_space_dim>
+ int patch_dim, int patch_space_dim>
DataOut_DoFData<DH,patch_dim,patch_space_dim>::DataOut_DoFData ()
:
- dofs(0,typeid(*this).name())
+ dofs(0,typeid(*this).name())
{}
template <class DH,
- int patch_dim, int patch_space_dim>
+ int patch_dim, int patch_space_dim>
template <class VECTOR>
void
DataOut_DoFData<DH,patch_dim,patch_space_dim>::
add_data_vector (const VECTOR &vec,
- const std::string &name,
- const DataVectorType type,
- const std::vector<DataComponentInterpretation::DataComponentInterpretation> &data_component_interpretation)
+ const std::string &name,
+ const DataVectorType type,
+ const std::vector<DataComponentInterpretation::DataComponentInterpretation> &data_component_interpretation)
{
Assert (dofs != 0, ExcNoDoFHandlerSelected ());
const unsigned int n_components = dofs->get_fe().n_components ();
std::vector<std::string> names;
- // if only one component or vector
- // is cell vector: we only need one
- // name
+ // if only one component or vector
+ // is cell vector: we only need one
+ // name
if ((n_components == 1) ||
(vec.size() == dofs->get_tria().n_active_cells()))
{
names.resize (1, name);
}
else
- // otherwise append _i to the
- // given name
+ // otherwise append _i to the
+ // given name
{
names.resize (n_components);
for (unsigned int i=0; i<n_components; ++i)
- {
- std::ostringstream namebuf;
- namebuf << '_' << i;
- names[i] = name + namebuf.str();
- }
+ {
+ std::ostringstream namebuf;
+ namebuf << '_' << i;
+ names[i] = name + namebuf.str();
+ }
}
add_data_vector (vec, names, type, data_component_interpretation);
template <class DH,
- int patch_dim, int patch_space_dim>
+ int patch_dim, int patch_space_dim>
template <class VECTOR>
void
DataOut_DoFData<DH,patch_dim,patch_space_dim>::
add_data_vector (const VECTOR &vec,
- const std::vector<std::string> &names,
- const DataVectorType type,
- const std::vector<DataComponentInterpretation::DataComponentInterpretation> &data_component_interpretation_)
+ const std::vector<std::string> &names,
+ const DataVectorType type,
+ const std::vector<DataComponentInterpretation::DataComponentInterpretation> &data_component_interpretation_)
{
Assert (dofs != 0, ExcNoDoFHandlerSelected ());
std::vector<DataComponentInterpretation::DataComponentInterpretation>
(names.size(), DataComponentInterpretation::component_is_scalar));
- // either cell data and one name,
- // or dof data and n_components names
+ // either cell data and one name,
+ // or dof data and n_components names
DataVectorType actual_type = type;
if (type == type_automatic)
{
if (vec.size() == dofs->get_tria().n_active_cells())
- actual_type = type_cell_data;
+ actual_type = type_cell_data;
else
- actual_type = type_dof_data;
+ actual_type = type_dof_data;
}
switch (actual_type)
{
case type_cell_data:
- Assert (vec.size() == dofs->get_tria().n_active_cells(),
- ExcInvalidVectorSize (vec.size(),
- dofs->n_dofs(),
- dofs->get_tria().n_active_cells()));
- Assert (names.size() == 1,
- ExcInvalidNumberOfNames (names.size(), 1));
- break;
+ Assert (vec.size() == dofs->get_tria().n_active_cells(),
+ ExcInvalidVectorSize (vec.size(),
+ dofs->n_dofs(),
+ dofs->get_tria().n_active_cells()));
+ Assert (names.size() == 1,
+ ExcInvalidNumberOfNames (names.size(), 1));
+ break;
case type_dof_data:
- Assert (vec.size() == dofs->n_dofs(),
- ExcInvalidVectorSize (vec.size(),
- dofs->n_dofs(),
- dofs->get_tria().n_active_cells()));
- Assert (names.size() == dofs->get_fe().n_components(),
- ExcInvalidNumberOfNames (names.size(), dofs->get_fe().n_components()));
- break;
+ Assert (vec.size() == dofs->n_dofs(),
+ ExcInvalidVectorSize (vec.size(),
+ dofs->n_dofs(),
+ dofs->get_tria().n_active_cells()));
+ Assert (names.size() == dofs->get_fe().n_components(),
+ ExcInvalidNumberOfNames (names.size(), dofs->get_fe().n_components()));
+ break;
case type_automatic:
- // this case should have
- // been handled above...
- Assert (false, ExcInternalError());
+ // this case should have
+ // been handled above...
+ Assert (false, ExcInternalError());
}
internal::DataOut::DataEntryBase<DH> * new_entry
= new internal::DataOut::DataEntry<DH,VECTOR>(&vec, names,
- data_component_interpretation);
+ data_component_interpretation);
if (actual_type == type_dof_data)
dof_data.push_back (std_cxx1x::shared_ptr<internal::DataOut::DataEntryBase<DH> >(new_entry));
else
template <class DH,
- int patch_dim, int patch_space_dim>
+ int patch_dim, int patch_space_dim>
template <class VECTOR>
void
DataOut_DoFData<DH,patch_dim,patch_space_dim>::
add_data_vector (const VECTOR &vec,
- const DataPostprocessor<DH::space_dimension> &data_postprocessor)
+ const DataPostprocessor<DH::space_dimension> &data_postprocessor)
{
- // this is a specialized version of the
- // other function where we have a
- // postprocessor. if we do, we know that we
- // have type_dof_data, which makes things a
- // bit simpler, we also don't need to deal
- // with some of the other stuff and use a
- // different constructor of DataEntry
+ // this is a specialized version of the
+ // other function where we have a
+ // postprocessor. if we do, we know that we
+ // have type_dof_data, which makes things a
+ // bit simpler, we also don't need to deal
+ // with some of the other stuff and use a
+ // different constructor of DataEntry
Assert (dofs != 0, ExcNoDoFHandlerSelected ());
Assert (vec.size() == dofs->n_dofs(),
- ExcInvalidVectorSize (vec.size(),
- dofs->n_dofs(),
- dofs->get_tria().n_active_cells()));
+ ExcInvalidVectorSize (vec.size(),
+ dofs->n_dofs(),
+ dofs->get_tria().n_active_cells()));
internal::DataOut::DataEntryBase<DH> * new_entry
= new internal::DataOut::DataEntry<DH,VECTOR>(&vec, &data_postprocessor);
template <class DH,
- int patch_dim, int patch_space_dim>
+ int patch_dim, int patch_space_dim>
void DataOut_DoFData<DH,patch_dim,patch_space_dim>::clear_data_vectors ()
{
dof_data.erase (dof_data.begin(), dof_data.end());
cell_data.erase (cell_data.begin(), cell_data.end());
- // delete patches
+ // delete patches
std::vector<Patch> dummy;
patches.swap (dummy);
}
template <class DH,
- int patch_dim, int patch_space_dim>
+ int patch_dim, int patch_space_dim>
void
DataOut_DoFData<DH,patch_dim,patch_space_dim>::
clear_input_data_references ()
if (dofs != 0)
dofs = 0;
- // delete patches
+ // delete patches
std::vector<Patch> dummy;
patches.swap (dummy);
}
template <class DH,
- int patch_dim, int patch_space_dim>
+ int patch_dim, int patch_space_dim>
std::vector<std::string>
DataOut_DoFData<DH,patch_dim,patch_space_dim>::
get_dataset_names () const
{
std::vector<std::string> names;
- // collect the names of dof
- // and cell data
+ // collect the names of dof
+ // and cell data
typedef
typename std::vector<std_cxx1x::shared_ptr<internal::DataOut::DataEntryBase<DH> > >::const_iterator
data_iterator;
template <class DH,
- int patch_dim, int patch_space_dim>
+ int patch_dim, int patch_space_dim>
std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> >
DataOut_DoFData<DH,patch_dim,patch_space_dim>::get_vector_data_ranges () const
{
std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> >
ranges;
- // collect the ranges of dof
- // and cell data
+ // collect the ranges of dof
+ // and cell data
typedef
typename std::vector<std_cxx1x::shared_ptr<internal::DataOut::DataEntryBase<DH> > >::const_iterator
data_iterator;
for (data_iterator d=dof_data.begin();
d!=dof_data.end(); ++d)
for (unsigned int i=0; i<(*d)->n_output_variables;
- ++i, ++output_component)
- // see what kind of data we have
- // here. note that for the purpose of
- // the current function all we care
- // about is vector data
+ ++i, ++output_component)
+ // see what kind of data we have
+ // here. note that for the purpose of
+ // the current function all we care
+ // about is vector data
if ((*d)->data_component_interpretation[i] ==
- DataComponentInterpretation::component_is_part_of_vector)
- {
- // ensure that there is a
- // continuous number of next
- // space_dim components that all
- // deal with vectors
- Assert (i+patch_space_dim <=
- (*d)->n_output_variables,
- ExcInvalidVectorDeclaration (i,
- (*d)->names[i]));
- for (unsigned int dd=1; dd<patch_space_dim; ++dd)
- Assert ((*d)->data_component_interpretation[i+dd]
- ==
- DataComponentInterpretation::component_is_part_of_vector,
- ExcInvalidVectorDeclaration (i,
- (*d)->names[i]));
-
- // all seems alright, so figure out
- // whether there is a common name
- // to these components. if not,
- // leave the name empty and let the
- // output format writer decide what
- // to do here
- std::string name = (*d)->names[i];
- for (unsigned int dd=1; dd<patch_space_dim; ++dd)
- if (name != (*d)->names[i+dd])
- {
- name = "";
- break;
- }
-
- // finally add a corresponding
- // range
- std_cxx1x::tuple<unsigned int, unsigned int, std::string>
- range (output_component,
- output_component+patch_space_dim-1,
- name);
-
- ranges.push_back (range);
-
- // increase the 'component' counter
- // by the appropriate amount, same
- // for 'i', since we have already
- // dealt with all these components
- output_component += patch_space_dim-1;
- i += patch_space_dim-1;
- }
-
- // note that we do not have to traverse the
- // list of cell data here because cell data
- // is one value per (logical) cell and
- // therefore cannot be a vector
-
- // as a final check, the 'component'
- // counter should be at the total number of
- // components added up now
+ DataComponentInterpretation::component_is_part_of_vector)
+ {
+ // ensure that there is a
+ // continuous number of next
+ // space_dim components that all
+ // deal with vectors
+ Assert (i+patch_space_dim <=
+ (*d)->n_output_variables,
+ ExcInvalidVectorDeclaration (i,
+ (*d)->names[i]));
+ for (unsigned int dd=1; dd<patch_space_dim; ++dd)
+ Assert ((*d)->data_component_interpretation[i+dd]
+ ==
+ DataComponentInterpretation::component_is_part_of_vector,
+ ExcInvalidVectorDeclaration (i,
+ (*d)->names[i]));
+
+ // all seems alright, so figure out
+ // whether there is a common name
+ // to these components. if not,
+ // leave the name empty and let the
+ // output format writer decide what
+ // to do here
+ std::string name = (*d)->names[i];
+ for (unsigned int dd=1; dd<patch_space_dim; ++dd)
+ if (name != (*d)->names[i+dd])
+ {
+ name = "";
+ break;
+ }
+
+ // finally add a corresponding
+ // range
+ std_cxx1x::tuple<unsigned int, unsigned int, std::string>
+ range (output_component,
+ output_component+patch_space_dim-1,
+ name);
+
+ ranges.push_back (range);
+
+ // increase the 'component' counter
+ // by the appropriate amount, same
+ // for 'i', since we have already
+ // dealt with all these components
+ output_component += patch_space_dim-1;
+ i += patch_space_dim-1;
+ }
+
+ // note that we do not have to traverse the
+ // list of cell data here because cell data
+ // is one value per (logical) cell and
+ // therefore cannot be a vector
+
+ // as a final check, the 'component'
+ // counter should be at the total number of
+ // components added up now
#ifdef DEBUG
unsigned int n_output_components = 0;
for (data_iterator d=dof_data.begin();
d!=dof_data.end(); ++d)
n_output_components += (*d)->n_output_variables;
Assert (output_component == n_output_components,
- ExcInternalError());
+ ExcInternalError());
#endif
return ranges;
template <class DH,
- int patch_dim, int patch_space_dim>
+ int patch_dim, int patch_space_dim>
const std::vector< dealii::DataOutBase::Patch<patch_dim, patch_space_dim> > &
DataOut_DoFData<DH,patch_dim,patch_space_dim>::get_patches () const
{
template <class DH,
- int patch_dim, int patch_space_dim>
+ int patch_dim, int patch_space_dim>
std::size_t
DataOut_DoFData<DH,patch_dim,patch_space_dim>::memory_consumption () const
{
return (DataOutInterface<patch_dim,patch_space_dim>::memory_consumption () +
- MemoryConsumption::memory_consumption (dofs) +
- MemoryConsumption::memory_consumption (patches));
+ MemoryConsumption::memory_consumption (dofs) +
+ MemoryConsumption::memory_consumption (patches));
}
void
DataOut<dim,DH>::
build_one_patch (const std::pair<cell_iterator, unsigned int> *cell_and_index,
- internal::DataOut::ParallelData<DH::dimension, DH::space_dimension> &data,
- DataOutBase::Patch<DH::dimension, DH::space_dimension> &patch,
- const CurvedCellRegion curved_cell_region)
+ internal::DataOut::ParallelData<DH::dimension, DH::space_dimension> &data,
+ DataOutBase::Patch<DH::dimension, DH::space_dimension> &patch,
+ const CurvedCellRegion curved_cell_region)
{
- // use ucd_to_deal map as patch vertices
- // are in the old, unnatural ordering. if
- // the mapping does not preserve locations
- // (e.g. MappingQEulerian), we need to
- // compute the offset of the vertex for the
- // graphical output. Otherwise, we can just
- // use the vertex info.
+ // use ucd_to_deal map as patch vertices
+ // are in the old, unnatural ordering. if
+ // the mapping does not preserve locations
+ // (e.g. MappingQEulerian), we need to
+ // compute the offset of the vertex for the
+ // graphical output. Otherwise, we can just
+ // use the vertex info.
for (unsigned int vertex=0; vertex<GeometryInfo<DH::dimension>::vertices_per_cell; ++vertex)
if (data.mapping_collection[0].preserves_vertex_locations())
patch.vertices[vertex] = cell_and_index->first->vertex(vertex);
else
patch.vertices[vertex] = data.mapping_collection[0].transform_unit_to_real_cell
- (cell_and_index->first,
- GeometryInfo<DH::dimension>::unit_cell_vertex (vertex));
+ (cell_and_index->first,
+ GeometryInfo<DH::dimension>::unit_cell_vertex (vertex));
if (data.n_datasets > 0)
{
data.x_fe_values.reinit (cell_and_index->first);
const FEValues<DH::dimension,DH::space_dimension> &fe_patch_values
- = data.x_fe_values.get_present_fe_values ();
+ = data.x_fe_values.get_present_fe_values ();
const unsigned int n_q_points = fe_patch_values.n_quadrature_points;
- // depending on the requested output
- // of curved cells, if necessary
- // append the quadrature points to
- // the last rows of the patch.data
- // member. This is the case if we
- // want to produce curved cells at
- // the boundary and this cell
- // actually is at the boundary, or
- // else if we want to produce curved
- // cells everywhere
- //
- // note: a cell is *always* at
- // the boundary if dim<spacedim
+ // depending on the requested output
+ // of curved cells, if necessary
+ // append the quadrature points to
+ // the last rows of the patch.data
+ // member. This is the case if we
+ // want to produce curved cells at
+ // the boundary and this cell
+ // actually is at the boundary, or
+ // else if we want to produce curved
+ // cells everywhere
+ //
+ // note: a cell is *always* at
+ // the boundary if dim<spacedim
if (curved_cell_region==curved_inner_cells
- ||
- (curved_cell_region==curved_boundary
- &&
- (cell_and_index->first->at_boundary()
- ||
- (DH::dimension != DH::space_dimension))))
- {
- Assert(patch.space_dim==DH::space_dimension, ExcInternalError());
- const std::vector<Point<DH::space_dimension> > & q_points=fe_patch_values.get_quadrature_points();
- // resize the patch.data member
- // in order to have enough memory
- // for the quadrature points as
- // well
- patch.data.reinit (data.n_datasets+DH::space_dimension, n_q_points);
- // set the flag indicating that
- // for this cell the points are
- // explicitly given
- patch.points_are_available=true;
- // copy points to patch.data
- for (unsigned int i=0; i<DH::space_dimension; ++i)
- for (unsigned int q=0; q<n_q_points; ++q)
- patch.data(patch.data.size(0)-DH::space_dimension+i,q)=q_points[q][i];
- }
+ ||
+ (curved_cell_region==curved_boundary
+ &&
+ (cell_and_index->first->at_boundary()
+ ||
+ (DH::dimension != DH::space_dimension))))
+ {
+ Assert(patch.space_dim==DH::space_dimension, ExcInternalError());
+ const std::vector<Point<DH::space_dimension> > & q_points=fe_patch_values.get_quadrature_points();
+ // resize the patch.data member
+ // in order to have enough memory
+ // for the quadrature points as
+ // well
+ patch.data.reinit (data.n_datasets+DH::space_dimension, n_q_points);
+ // set the flag indicating that
+ // for this cell the points are
+ // explicitly given
+ patch.points_are_available=true;
+ // copy points to patch.data
+ for (unsigned int i=0; i<DH::space_dimension; ++i)
+ for (unsigned int q=0; q<n_q_points; ++q)
+ patch.data(patch.data.size(0)-DH::space_dimension+i,q)=q_points[q][i];
+ }
else
- {
- patch.data.reinit(data.n_datasets, n_q_points);
- patch.points_are_available = false;
- }
+ {
+ patch.data.reinit(data.n_datasets, n_q_points);
+ patch.points_are_available = false;
+ }
- // counter for data records
+ // counter for data records
unsigned int offset=0;
- // first fill dof_data
+ // first fill dof_data
for (unsigned int dataset=0; dataset<this->dof_data.size(); ++dataset)
- {
- const DataPostprocessor<DH::space_dimension> *postprocessor=this->dof_data[dataset]->postprocessor;
-
- if (postprocessor != 0)
- {
- // we have to postprocess the
- // data, so determine, which
- // fields have to be updated
- const UpdateFlags update_flags=postprocessor->get_needed_update_flags();
- if (data.n_components == 1)
- {
- // at each point there is
- // only one component of
- // value, gradient etc.
- if (update_flags & update_values)
- this->dof_data[dataset]->get_function_values (fe_patch_values,
- data.patch_values);
- if (update_flags & update_gradients)
- this->dof_data[dataset]->get_function_gradients (fe_patch_values,
- data.patch_gradients);
- if (update_flags & update_hessians)
- this->dof_data[dataset]->get_function_hessians (fe_patch_values,
- data.patch_hessians);
-
- if (update_flags & update_quadrature_points)
- data.patch_evaluation_points = fe_patch_values.get_quadrature_points();
-
-
- std::vector<Point<DH::space_dimension> > dummy_normals;
- postprocessor->
- compute_derived_quantities_scalar(data.patch_values,
- data.patch_gradients,
- data.patch_hessians,
- dummy_normals,
- data.patch_evaluation_points,
- data.postprocessed_values[dataset]);
- }
- else
- {
- // at each point there is
- // a vector valued
- // function and its
- // derivative...
- if (update_flags & update_values)
- this->dof_data[dataset]->get_function_values (fe_patch_values,
- data.patch_values_system);
- if (update_flags & update_gradients)
- this->dof_data[dataset]->get_function_gradients (fe_patch_values,
- data.patch_gradients_system);
- if (update_flags & update_hessians)
- this->dof_data[dataset]->get_function_hessians (fe_patch_values,
- data.patch_hessians_system);
-
- if (update_flags & update_quadrature_points)
- data.patch_evaluation_points = fe_patch_values.get_quadrature_points();
-
- std::vector<Point<DH::space_dimension> > dummy_normals;
-
- postprocessor->
- compute_derived_quantities_vector(data.patch_values_system,
- data.patch_gradients_system,
- data.patch_hessians_system,
- dummy_normals,
- data.patch_evaluation_points,
- data.postprocessed_values[dataset]);
- }
-
- for (unsigned int q=0; q<n_q_points; ++q)
- for (unsigned int component=0;
- component<this->dof_data[dataset]->n_output_variables;
- ++component)
- patch.data(offset+component,q)
- = data.postprocessed_values[dataset][q](component);
- }
- else
- // now we use the given data
- // vector without
- // modifications. again, we
- // treat single component
- // functions separately for
- // efficiency reasons.
- if (data.n_components == 1)
- {
- this->dof_data[dataset]->get_function_values (fe_patch_values,
- data.patch_values);
- for (unsigned int q=0; q<n_q_points; ++q)
- patch.data(offset,q) = data.patch_values[q];
- }
- else
- {
- this->dof_data[dataset]->get_function_values (fe_patch_values,
- data.patch_values_system);
- for (unsigned int component=0; component<data.n_components;
- ++component)
- for (unsigned int q=0; q<n_q_points; ++q)
- patch.data(offset+component,q) =
- data.patch_values_system[q](component);
- }
- // increment the counter for the
- // actual data record
- offset+=this->dof_data[dataset]->n_output_variables;
- }
-
- // then do the cell data. only
- // compute the number of a cell if
- // needed; also make sure that we
- // only access cell data if the
- // first_cell/next_cell functions
- // only return active cells
+ {
+ const DataPostprocessor<DH::space_dimension> *postprocessor=this->dof_data[dataset]->postprocessor;
+
+ if (postprocessor != 0)
+ {
+ // we have to postprocess the
+ // data, so determine, which
+ // fields have to be updated
+ const UpdateFlags update_flags=postprocessor->get_needed_update_flags();
+ if (data.n_components == 1)
+ {
+ // at each point there is
+ // only one component of
+ // value, gradient etc.
+ if (update_flags & update_values)
+ this->dof_data[dataset]->get_function_values (fe_patch_values,
+ data.patch_values);
+ if (update_flags & update_gradients)
+ this->dof_data[dataset]->get_function_gradients (fe_patch_values,
+ data.patch_gradients);
+ if (update_flags & update_hessians)
+ this->dof_data[dataset]->get_function_hessians (fe_patch_values,
+ data.patch_hessians);
+
+ if (update_flags & update_quadrature_points)
+ data.patch_evaluation_points = fe_patch_values.get_quadrature_points();
+
+
+ std::vector<Point<DH::space_dimension> > dummy_normals;
+ postprocessor->
+ compute_derived_quantities_scalar(data.patch_values,
+ data.patch_gradients,
+ data.patch_hessians,
+ dummy_normals,
+ data.patch_evaluation_points,
+ data.postprocessed_values[dataset]);
+ }
+ else
+ {
+ // at each point there is
+ // a vector valued
+ // function and its
+ // derivative...
+ if (update_flags & update_values)
+ this->dof_data[dataset]->get_function_values (fe_patch_values,
+ data.patch_values_system);
+ if (update_flags & update_gradients)
+ this->dof_data[dataset]->get_function_gradients (fe_patch_values,
+ data.patch_gradients_system);
+ if (update_flags & update_hessians)
+ this->dof_data[dataset]->get_function_hessians (fe_patch_values,
+ data.patch_hessians_system);
+
+ if (update_flags & update_quadrature_points)
+ data.patch_evaluation_points = fe_patch_values.get_quadrature_points();
+
+ std::vector<Point<DH::space_dimension> > dummy_normals;
+
+ postprocessor->
+ compute_derived_quantities_vector(data.patch_values_system,
+ data.patch_gradients_system,
+ data.patch_hessians_system,
+ dummy_normals,
+ data.patch_evaluation_points,
+ data.postprocessed_values[dataset]);
+ }
+
+ for (unsigned int q=0; q<n_q_points; ++q)
+ for (unsigned int component=0;
+ component<this->dof_data[dataset]->n_output_variables;
+ ++component)
+ patch.data(offset+component,q)
+ = data.postprocessed_values[dataset][q](component);
+ }
+ else
+ // now we use the given data
+ // vector without
+ // modifications. again, we
+ // treat single component
+ // functions separately for
+ // efficiency reasons.
+ if (data.n_components == 1)
+ {
+ this->dof_data[dataset]->get_function_values (fe_patch_values,
+ data.patch_values);
+ for (unsigned int q=0; q<n_q_points; ++q)
+ patch.data(offset,q) = data.patch_values[q];
+ }
+ else
+ {
+ this->dof_data[dataset]->get_function_values (fe_patch_values,
+ data.patch_values_system);
+ for (unsigned int component=0; component<data.n_components;
+ ++component)
+ for (unsigned int q=0; q<n_q_points; ++q)
+ patch.data(offset+component,q) =
+ data.patch_values_system[q](component);
+ }
+ // increment the counter for the
+ // actual data record
+ offset+=this->dof_data[dataset]->n_output_variables;
+ }
+
+ // then do the cell data. only
+ // compute the number of a cell if
+ // needed; also make sure that we
+ // only access cell data if the
+ // first_cell/next_cell functions
+ // only return active cells
if (this->cell_data.size() != 0)
- {
- Assert (!cell_and_index->first->has_children(), ExcNotImplemented());
-
- for (unsigned int dataset=0; dataset<this->cell_data.size(); ++dataset)
- {
- const double value
- = this->cell_data[dataset]->get_cell_data_value (cell_and_index->second);
- for (unsigned int q=0; q<n_q_points; ++q)
- patch.data(offset+dataset,q) = value;
- }
- }
+ {
+ Assert (!cell_and_index->first->has_children(), ExcNotImplemented());
+
+ for (unsigned int dataset=0; dataset<this->cell_data.size(); ++dataset)
+ {
+ const double value
+ = this->cell_data[dataset]->get_cell_data_value (cell_and_index->second);
+ for (unsigned int q=0; q<n_q_points; ++q)
+ patch.data(offset+dataset,q) = value;
+ }
+ }
}
for (unsigned int f=0; f<GeometryInfo<DH::dimension>::faces_per_cell; ++f)
{
- // let's look up whether
- // the neighbor behind that
- // face is noted in the
- // table of cells which we
- // treat. this can only
- // happen if the neighbor
- // exists, and is on the
- // same level as this cell,
- // but it may also happen
- // that the neighbor is not
- // a member of the range of
- // cells over which we
- // loop, in which case the
- // respective entry in the
- // cell_to_patch_index_map
- // will have the value
- // no_neighbor. (note that
- // since we allocated only
- // as much space in this
- // array as the maximum
- // index of the cells we
- // loop over, not every
- // neighbor may have its
- // space in it, so we have
- // to assume that it is
- // extended by values
- // no_neighbor)
+ // let's look up whether
+ // the neighbor behind that
+ // face is noted in the
+ // table of cells which we
+ // treat. this can only
+ // happen if the neighbor
+ // exists, and is on the
+ // same level as this cell,
+ // but it may also happen
+ // that the neighbor is not
+ // a member of the range of
+ // cells over which we
+ // loop, in which case the
+ // respective entry in the
+ // cell_to_patch_index_map
+ // will have the value
+ // no_neighbor. (note that
+ // since we allocated only
+ // as much space in this
+ // array as the maximum
+ // index of the cells we
+ // loop over, not every
+ // neighbor may have its
+ // space in it, so we have
+ // to assume that it is
+ // extended by values
+ // no_neighbor)
if (cell_and_index->first->at_boundary(f)
- ||
- (cell_and_index->first->neighbor(f)->level() != cell_and_index->first->level()))
- {
- patch.neighbors[f] = numbers::invalid_unsigned_int;
- continue;
- }
+ ||
+ (cell_and_index->first->neighbor(f)->level() != cell_and_index->first->level()))
+ {
+ patch.neighbors[f] = numbers::invalid_unsigned_int;
+ continue;
+ }
const cell_iterator neighbor = cell_and_index->first->neighbor(f);
Assert (static_cast<unsigned int>(neighbor->level()) <
- data.cell_to_patch_index_map->size(),
- ExcInternalError());
+ data.cell_to_patch_index_map->size(),
+ ExcInternalError());
if ((static_cast<unsigned int>(neighbor->index()) >=
- (*data.cell_to_patch_index_map)[neighbor->level()].size())
- ||
- ((*data.cell_to_patch_index_map)[neighbor->level()][neighbor->index()]
- ==
- dealii::DataOutBase::Patch<DH::dimension>::no_neighbor))
- {
- patch.neighbors[f] = numbers::invalid_unsigned_int;
- continue;
- }
-
- // now, there is a
- // neighbor, so get its
- // patch number and set it
- // for the neighbor index
+ (*data.cell_to_patch_index_map)[neighbor->level()].size())
+ ||
+ ((*data.cell_to_patch_index_map)[neighbor->level()][neighbor->index()]
+ ==
+ dealii::DataOutBase::Patch<DH::dimension>::no_neighbor))
+ {
+ patch.neighbors[f] = numbers::invalid_unsigned_int;
+ continue;
+ }
+
+ // now, there is a
+ // neighbor, so get its
+ // patch number and set it
+ // for the neighbor index
patch.neighbors[f]
- = (*data.cell_to_patch_index_map)[neighbor->level()][neighbor->index()];
+ = (*data.cell_to_patch_index_map)[neighbor->level()][neighbor->index()];
}
}
void DataOut<dim,DH>::build_patches (const unsigned int n_subdivisions)
{
build_patches (StaticMappingQ1<DH::dimension,DH::space_dimension>::mapping,
- n_subdivisions, no_curved_cells);
+ n_subdivisions, no_curved_cells);
}
template <int dim, class DH>
void DataOut<dim,DH>::build_patches (const Mapping<DH::dimension,DH::space_dimension> &mapping,
- const unsigned int nnnn_subdivisions,
- const CurvedCellRegion curved_region)
+ const unsigned int nnnn_subdivisions,
+ const CurvedCellRegion curved_region)
{
- // Check consistency of redundant
- // template parameter
+ // Check consistency of redundant
+ // template parameter
Assert (dim==DH::dimension, ExcDimensionMismatch(dim, DH::dimension));
typedef DataOut_DoFData<DH, DH::dimension, DH::space_dimension> BaseClass;
Assert (this->dofs != 0, typename BaseClass::ExcNoDoFHandlerSelected());
const unsigned int n_subdivisions = (nnnn_subdivisions != 0)
- ? nnnn_subdivisions
- : this->default_subdivisions;
+ ? nnnn_subdivisions
+ : this->default_subdivisions;
Assert (n_subdivisions >= 1,
- ExcInvalidNumberOfSubdivisions(n_subdivisions));
-
- // first count the cells we want to
- // create patches of. also fill the
- // object that maps the cell
- // indices to the patch numbers, as
- // this will be needed for
- // generation of neighborship
- // information
+ ExcInvalidNumberOfSubdivisions(n_subdivisions));
+
+ // first count the cells we want to
+ // create patches of. also fill the
+ // object that maps the cell
+ // indices to the patch numbers, as
+ // this will be needed for
+ // generation of neighborship
+ // information
std::vector<std::vector<unsigned int> > cell_to_patch_index_map;
cell_to_patch_index_map.resize (this->dofs->get_tria().n_levels());
for (unsigned int l=0; l<this->dofs->get_tria().n_levels(); ++l)
std::vector<std::pair<cell_iterator, unsigned int> > all_cells;
{
- // set the index of the first
- // cell. if
- // first_locally_owned_cell /
- // next_locally_owned_cell
- // returns non-active cells, then
- // the index is not usable
- // anyway, but otherwise we
- // should keep track where we are
+ // set the index of the first
+ // cell. if
+ // first_locally_owned_cell /
+ // next_locally_owned_cell
+ // returns non-active cells, then
+ // the index is not usable
+ // anyway, but otherwise we
+ // should keep track where we are
unsigned int index;
if ((first_locally_owned_cell() == this->dofs->end())
- ||
- (first_locally_owned_cell()->has_children()))
+ ||
+ (first_locally_owned_cell()->has_children()))
index = 0;
else
index = std::distance (this->dofs->begin_active(),
- active_cell_iterator(first_locally_owned_cell()));
+ active_cell_iterator(first_locally_owned_cell()));
for (cell_iterator cell=first_locally_owned_cell(); cell != this->dofs->end();
- cell = next_locally_owned_cell(cell))
+ cell = next_locally_owned_cell(cell))
{
- Assert (static_cast<unsigned int>(cell->level()) <
- cell_to_patch_index_map.size(),
- ExcInternalError());
- Assert (static_cast<unsigned int>(cell->index()) <
- cell_to_patch_index_map[cell->level()].size(),
- ExcInternalError());
-
- cell_to_patch_index_map[cell->level()][cell->index()] = all_cells.size();
-
- all_cells.push_back (std::make_pair(cell, index));
-
- // if both this and the next
- // cell are active, then
- // increment the index that
- // keeps track on which
- // active cell we are sitting
- // correctly. if one of the
- // cells is not active, then
- // this index doesn't mean
- // anything anyway, so just
- // ignore it. same if we are
- // at the end of the range
- if (!cell->has_children() &&
- next_locally_owned_cell(cell) != this->dofs->end() &&
- !next_locally_owned_cell(cell)->has_children())
- index += std::distance (active_cell_iterator(cell),
- active_cell_iterator(next_locally_owned_cell(cell)));
+ Assert (static_cast<unsigned int>(cell->level()) <
+ cell_to_patch_index_map.size(),
+ ExcInternalError());
+ Assert (static_cast<unsigned int>(cell->index()) <
+ cell_to_patch_index_map[cell->level()].size(),
+ ExcInternalError());
+
+ cell_to_patch_index_map[cell->level()][cell->index()] = all_cells.size();
+
+ all_cells.push_back (std::make_pair(cell, index));
+
+ // if both this and the next
+ // cell are active, then
+ // increment the index that
+ // keeps track on which
+ // active cell we are sitting
+ // correctly. if one of the
+ // cells is not active, then
+ // this index doesn't mean
+ // anything anyway, so just
+ // ignore it. same if we are
+ // at the end of the range
+ if (!cell->has_children() &&
+ next_locally_owned_cell(cell) != this->dofs->end() &&
+ !next_locally_owned_cell(cell)->has_children())
+ index += std::distance (active_cell_iterator(cell),
+ active_cell_iterator(next_locally_owned_cell(cell)));
}
}
this->patches.reserve (all_cells.size());
Assert (this->patches.size() == 0, ExcInternalError());
- // now create a default patch and a
- // default object for the
- // WorkStream object to work with
+ // now create a default patch and a
+ // default object for the
+ // WorkStream object to work with
const QTrapez<1> q_trapez;
const QIterated<DH::dimension> patch_points (q_trapez, n_subdivisions);
for (unsigned int i=0; i<this->dof_data.size(); ++i)
if (this->dof_data[i]->postprocessor)
update_flags |= this->dof_data[i]->postprocessor->get_needed_update_flags();
- // perhaps update_normal_vectors is present,
- // which would only be useful on faces, but
- // we may not use it here.
+ // perhaps update_normal_vectors is present,
+ // which would only be useful on faces, but
+ // we may not use it here.
Assert (!(update_flags & update_normal_vectors),
- ExcMessage("The update of normal vectors may not be requested for evaluation of "
- "data on cells via DataPostprocessor."));
+ ExcMessage("The update of normal vectors may not be requested for evaluation of "
+ "data on cells via DataPostprocessor."));
internal::DataOut::ParallelData<DH::dimension, DH::space_dimension>
thread_data (patch_points,
- n_components, n_datasets, n_subdivisions,
- n_postprocessor_outputs,
- mapping,
- cell_to_patch_index_map,
- this->dofs->get_fe(),
- update_flags);
+ n_components, n_datasets, n_subdivisions,
+ n_postprocessor_outputs,
+ mapping,
+ cell_to_patch_index_map,
+ this->dofs->get_fe(),
+ update_flags);
DataOutBase::Patch<DH::dimension, DH::space_dimension> sample_patch;
sample_patch.n_subdivisions = n_subdivisions;
- // now build the patches in parallel
+ // now build the patches in parallel
if (all_cells.size() > 0)
WorkStream::run (&all_cells[0],
- &all_cells[0]+all_cells.size(),
- std_cxx1x::bind(&DataOut<dim,DH>::build_one_patch,
- *this, std_cxx1x::_1, std_cxx1x::_2, std_cxx1x::_3,
- curved_cell_region),
- std_cxx1x::bind(&internal::DataOut::append_patch_to_list<dim,DH::space_dimension>,
- std_cxx1x::_1, std_cxx1x::ref(this->patches)),
- thread_data,
- sample_patch);
+ &all_cells[0]+all_cells.size(),
+ std_cxx1x::bind(&DataOut<dim,DH>::build_one_patch,
+ *this, std_cxx1x::_1, std_cxx1x::_2, std_cxx1x::_3,
+ curved_cell_region),
+ std_cxx1x::bind(&internal::DataOut::append_patch_to_list<dim,DH::space_dimension>,
+ std_cxx1x::_1, std_cxx1x::ref(this->patches)),
+ thread_data,
+ sample_patch);
}
typename DataOut<dim,DH>::cell_iterator
DataOut<dim,DH>::next_cell (const typename DataOut<dim,DH>::cell_iterator &cell)
{
- // convert the iterator to an
- // active_iterator and advance
- // this to the next active cell
+ // convert the iterator to an
+ // active_iterator and advance
+ // this to the next active cell
typename DH::active_cell_iterator active_cell = cell;
++active_cell;
return active_cell;
typename DataOut<dim,DH>::cell_iterator
cell = this->dofs->begin_active ();
- // skip cells if the current one
- // has no children (is active) and
- // is a ghost or artificial cell
+ // skip cells if the current one
+ // has no children (is active) and
+ // is a ghost or artificial cell
while ((cell != this->dofs->end()) &&
- (cell->has_children() == false) &&
- !cell->is_locally_owned())
+ (cell->has_children() == false) &&
+ !cell->is_locally_owned())
cell = next_cell(cell);
return cell;
typename DataOut<dim,DH>::cell_iterator
cell = next_cell(old_cell);
while ((cell != this->dofs->end()) &&
- (cell->has_children() == false) &&
- !cell->is_locally_owned())
+ (cell->has_children() == false) &&
+ !cell->is_locally_owned())
cell = next_cell(cell);
return cell;
}
// $Id$
// Version: $Name$
//
-// Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 by the deal.II authors
+// Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
template <class FE>
ParallelData<dim,spacedim>::
ParallelData (const Quadrature<dim-1> &quadrature,
- const unsigned int n_components,
- const unsigned int n_datasets,
- const unsigned int n_subdivisions,
- const std::vector<unsigned int> &n_postprocessor_outputs,
- const Mapping<dim,spacedim> &mapping,
- const FE &finite_elements,
- const UpdateFlags update_flags)
- :
- internal::DataOut::
- ParallelDataBase<dim,spacedim> (n_components,
- n_datasets,
- n_subdivisions,
- quadrature.size(),
- n_postprocessor_outputs,
- finite_elements),
- q_collection (quadrature),
- mapping_collection (mapping),
- x_fe_values (this->mapping_collection,
- this->fe_collection,
- q_collection,
- update_flags)
+ const unsigned int n_components,
+ const unsigned int n_datasets,
+ const unsigned int n_subdivisions,
+ const std::vector<unsigned int> &n_postprocessor_outputs,
+ const Mapping<dim,spacedim> &mapping,
+ const FE &finite_elements,
+ const UpdateFlags update_flags)
+ :
+ internal::DataOut::
+ ParallelDataBase<dim,spacedim> (n_components,
+ n_datasets,
+ n_subdivisions,
+ quadrature.size(),
+ n_postprocessor_outputs,
+ finite_elements),
+ q_collection (quadrature),
+ mapping_collection (mapping),
+ x_fe_values (this->mapping_collection,
+ this->fe_collection,
+ q_collection,
+ update_flags)
{}
- /**
- * In a WorkStream context, use
- * this function to append the
- * patch computed by the parallel
- * stage to the array of patches.
- */
+ /**
+ * In a WorkStream context, use
+ * this function to append the
+ * patch computed by the parallel
+ * stage to the array of patches.
+ */
template <int dim, int spacedim>
void
append_patch_to_list (const DataOutBase::Patch<dim-1,spacedim> &patch,
- std::vector<DataOutBase::Patch<dim-1,spacedim> > &patches)
+ std::vector<DataOutBase::Patch<dim-1,spacedim> > &patches)
{
patches.push_back (patch);
patches.back().patch_index = patches.size()-1;
template <int dim, class DH>
DataOutFaces<dim,DH>::DataOutFaces(const bool so)
- :
- surface_only(so)
+ :
+ surface_only(so)
{}
void
DataOutFaces<dim,DH>::
build_one_patch (const FaceDescriptor *cell_and_face,
- internal::DataOutFaces::ParallelData<DH::dimension, DH::dimension> &data,
- DataOutBase::Patch<DH::dimension-1,DH::space_dimension> &patch)
+ internal::DataOutFaces::ParallelData<DH::dimension, DH::dimension> &data,
+ DataOutBase::Patch<DH::dimension-1,DH::space_dimension> &patch)
{
Assert (cell_and_face->first->is_locally_owned(),
- ExcNotImplemented());
-
- // we use the mapping to transform the
- // vertices. However, the mapping works on
- // cells, not faces, so transform the face
- // vertex to a cell vertex, that to a unit
- // cell vertex and then, finally, that to
- // the mapped vertex. In most cases this
- // complicated procedure will be the
- // identity.
+ ExcNotImplemented());
+
+ // we use the mapping to transform the
+ // vertices. However, the mapping works on
+ // cells, not faces, so transform the face
+ // vertex to a cell vertex, that to a unit
+ // cell vertex and then, finally, that to
+ // the mapped vertex. In most cases this
+ // complicated procedure will be the
+ // identity.
for (unsigned int vertex=0; vertex<GeometryInfo<DH::dimension-1>::vertices_per_cell; ++vertex)
patch.vertices[vertex] = data.mapping_collection[0].transform_unit_to_real_cell
- (cell_and_face->first,
- GeometryInfo<DH::dimension>::unit_cell_vertex
- (GeometryInfo<dim>::face_to_cell_vertices
- (cell_and_face->second,
- vertex,
- cell_and_face->first->face_orientation(cell_and_face->second),
- cell_and_face->first->face_flip(cell_and_face->second),
- cell_and_face->first->face_rotation(cell_and_face->second))));
+ (cell_and_face->first,
+ GeometryInfo<DH::dimension>::unit_cell_vertex
+ (GeometryInfo<dim>::face_to_cell_vertices
+ (cell_and_face->second,
+ vertex,
+ cell_and_face->first->face_orientation(cell_and_face->second),
+ cell_and_face->first->face_flip(cell_and_face->second),
+ cell_and_face->first->face_rotation(cell_and_face->second))));
if (data.n_datasets > 0)
{
data.x_fe_values.reinit (cell_and_face->first, cell_and_face->second);
const FEFaceValues<DH::dimension> &fe_patch_values
- = data.x_fe_values.get_present_fe_values ();
+ = data.x_fe_values.get_present_fe_values ();
const unsigned int n_q_points = fe_patch_values.n_quadrature_points;
- // store the intermediate points
+ // store the intermediate points
Assert(patch.space_dim==DH::dimension, ExcInternalError());
const std::vector<Point<DH::dimension> > & q_points=fe_patch_values.get_quadrature_points();
- // resize the patch.data member
- // in order to have enough memory
- // for the quadrature points as
- // well
+ // resize the patch.data member
+ // in order to have enough memory
+ // for the quadrature points as
+ // well
patch.data.reinit(data.n_datasets+DH::dimension,
- patch.data.size(1));
- // set the flag indicating that
- // for this cell the points are
- // explicitly given
+ patch.data.size(1));
+ // set the flag indicating that
+ // for this cell the points are
+ // explicitly given
patch.points_are_available=true;
- // copy points to patch.data
+ // copy points to patch.data
for (unsigned int i=0; i<DH::dimension; ++i)
- for (unsigned int q=0; q<n_q_points; ++q)
- patch.data(patch.data.size(0)-DH::dimension+i,q)=q_points[q][i];
+ for (unsigned int q=0; q<n_q_points; ++q)
+ patch.data(patch.data.size(0)-DH::dimension+i,q)=q_points[q][i];
- // counter for data records
+ // counter for data records
unsigned int offset=0;
- // first fill dof_data
+ // first fill dof_data
for (unsigned int dataset=0; dataset<this->dof_data.size(); ++dataset)
- {
- const DataPostprocessor<dim> *postprocessor=this->dof_data[dataset]->postprocessor;
- if (postprocessor != 0)
- {
- // we have to postprocess the
- // data, so determine, which
- // fields have to be updated
- const UpdateFlags update_flags=postprocessor->get_needed_update_flags();
-
- // get normals, if
- // needed. this is a
- // geometrical information
- // and thus does not depend
- // on the number of
- // components of the data
- // vector
- if (update_flags & update_normal_vectors)
- data.patch_normals=fe_patch_values.get_normal_vectors();
-
- if (data.n_components == 1)
- {
- // at each point there is
- // only one component of
- // value, gradient etc.
- if (update_flags & update_values)
- this->dof_data[dataset]->get_function_values (fe_patch_values,
- data.patch_values);
- if (update_flags & update_gradients)
- this->dof_data[dataset]->get_function_gradients (fe_patch_values,
- data.patch_gradients);
- if (update_flags & update_hessians)
- this->dof_data[dataset]->get_function_hessians (fe_patch_values,
- data.patch_hessians);
-
- if (update_flags & update_quadrature_points)
- data.patch_evaluation_points = fe_patch_values.get_quadrature_points();
-
- postprocessor->
- compute_derived_quantities_scalar(data.patch_values,
- data.patch_gradients,
- data.patch_hessians,
- data.patch_normals,
- data.patch_evaluation_points,
- data.postprocessed_values[dataset]);
- }
- else
- {
- // at each point there is
- // a vector valued
- // function and its
- // derivative...
- if (update_flags & update_values)
- this->dof_data[dataset]->get_function_values (fe_patch_values,
- data.patch_values_system);
- if (update_flags & update_gradients)
- this->dof_data[dataset]->get_function_gradients (fe_patch_values,
- data.patch_gradients_system);
- if (update_flags & update_hessians)
- this->dof_data[dataset]->get_function_hessians (fe_patch_values,
- data.patch_hessians_system);
-
- if (update_flags & update_quadrature_points)
- data.patch_evaluation_points = fe_patch_values.get_quadrature_points();
-
- postprocessor->
- compute_derived_quantities_vector(data.patch_values_system,
- data.patch_gradients_system,
- data.patch_hessians_system,
- data.patch_normals,
- data.patch_evaluation_points,
- data.postprocessed_values[dataset]);
- }
-
- for (unsigned int q=0; q<n_q_points; ++q)
- for (unsigned int component=0;
- component<this->dof_data[dataset]->n_output_variables;++component)
- patch.data(offset+component,q)
- = data.postprocessed_values[dataset][q](component);
- }
- else
- // now we use the given data
- // vector without
- // modifications. again, we
- // treat single component
- // functions separately for
- // efficiency reasons.
- if (data.n_components == 1)
- {
- this->dof_data[dataset]->get_function_values (fe_patch_values,
- data.patch_values);
- for (unsigned int q=0; q<n_q_points; ++q)
- patch.data(offset,q) = data.patch_values[q];
- }
- else
- {
- this->dof_data[dataset]->get_function_values (fe_patch_values,
- data.patch_values_system);
- for (unsigned int component=0; component<data.n_components;
- ++component)
- for (unsigned int q=0; q<n_q_points; ++q)
- patch.data(offset+component,q) =
- data.patch_values_system[q](component);
- }
- // increment the counter for the
- // actual data record
- offset+=this->dof_data[dataset]->n_output_variables;
- }
-
- // then do the cell data
+ {
+ const DataPostprocessor<dim> *postprocessor=this->dof_data[dataset]->postprocessor;
+ if (postprocessor != 0)
+ {
+ // we have to postprocess the
+ // data, so determine, which
+ // fields have to be updated
+ const UpdateFlags update_flags=postprocessor->get_needed_update_flags();
+
+ // get normals, if
+ // needed. this is a
+ // geometrical information
+ // and thus does not depend
+ // on the number of
+ // components of the data
+ // vector
+ if (update_flags & update_normal_vectors)
+ data.patch_normals=fe_patch_values.get_normal_vectors();
+
+ if (data.n_components == 1)
+ {
+ // at each point there is
+ // only one component of
+ // value, gradient etc.
+ if (update_flags & update_values)
+ this->dof_data[dataset]->get_function_values (fe_patch_values,
+ data.patch_values);
+ if (update_flags & update_gradients)
+ this->dof_data[dataset]->get_function_gradients (fe_patch_values,
+ data.patch_gradients);
+ if (update_flags & update_hessians)
+ this->dof_data[dataset]->get_function_hessians (fe_patch_values,
+ data.patch_hessians);
+
+ if (update_flags & update_quadrature_points)
+ data.patch_evaluation_points = fe_patch_values.get_quadrature_points();
+
+ postprocessor->
+ compute_derived_quantities_scalar(data.patch_values,
+ data.patch_gradients,
+ data.patch_hessians,
+ data.patch_normals,
+ data.patch_evaluation_points,
+ data.postprocessed_values[dataset]);
+ }
+ else
+ {
+ // at each point there is
+ // a vector valued
+ // function and its
+ // derivative...
+ if (update_flags & update_values)
+ this->dof_data[dataset]->get_function_values (fe_patch_values,
+ data.patch_values_system);
+ if (update_flags & update_gradients)
+ this->dof_data[dataset]->get_function_gradients (fe_patch_values,
+ data.patch_gradients_system);
+ if (update_flags & update_hessians)
+ this->dof_data[dataset]->get_function_hessians (fe_patch_values,
+ data.patch_hessians_system);
+
+ if (update_flags & update_quadrature_points)
+ data.patch_evaluation_points = fe_patch_values.get_quadrature_points();
+
+ postprocessor->
+ compute_derived_quantities_vector(data.patch_values_system,
+ data.patch_gradients_system,
+ data.patch_hessians_system,
+ data.patch_normals,
+ data.patch_evaluation_points,
+ data.postprocessed_values[dataset]);
+ }
+
+ for (unsigned int q=0; q<n_q_points; ++q)
+ for (unsigned int component=0;
+ component<this->dof_data[dataset]->n_output_variables;++component)
+ patch.data(offset+component,q)
+ = data.postprocessed_values[dataset][q](component);
+ }
+ else
+ // now we use the given data
+ // vector without
+ // modifications. again, we
+ // treat single component
+ // functions separately for
+ // efficiency reasons.
+ if (data.n_components == 1)
+ {
+ this->dof_data[dataset]->get_function_values (fe_patch_values,
+ data.patch_values);
+ for (unsigned int q=0; q<n_q_points; ++q)
+ patch.data(offset,q) = data.patch_values[q];
+ }
+ else
+ {
+ this->dof_data[dataset]->get_function_values (fe_patch_values,
+ data.patch_values_system);
+ for (unsigned int component=0; component<data.n_components;
+ ++component)
+ for (unsigned int q=0; q<n_q_points; ++q)
+ patch.data(offset+component,q) =
+ data.patch_values_system[q](component);
+ }
+ // increment the counter for the
+ // actual data record
+ offset+=this->dof_data[dataset]->n_output_variables;
+ }
+
+ // then do the cell data
for (unsigned int dataset=0; dataset<this->cell_data.size(); ++dataset)
- {
- // we need to get at
- // the number of the
- // cell to which this
- // face belongs in
- // order to access the
- // cell data. this is
- // not readily
- // available, so choose
- // the following rather
- // inefficient way:
- Assert (cell_and_face->first->active(), ExcCellNotActiveForCellData());
- const unsigned int cell_number
- = std::distance (this->dofs->begin_active(),
- typename DH::active_cell_iterator(cell_and_face->first));
-
- const double value
- = this->cell_data[dataset]->get_cell_data_value (cell_number);
- for (unsigned int q=0; q<n_q_points; ++q)
- patch.data(dataset+offset,q) = value;
- }
+ {
+ // we need to get at
+ // the number of the
+ // cell to which this
+ // face belongs in
+ // order to access the
+ // cell data. this is
+ // not readily
+ // available, so choose
+ // the following rather
+ // inefficient way:
+ Assert (cell_and_face->first->active(), ExcCellNotActiveForCellData());
+ const unsigned int cell_number
+ = std::distance (this->dofs->begin_active(),
+ typename DH::active_cell_iterator(cell_and_face->first));
+
+ const double value
+ = this->cell_data[dataset]->get_cell_data_value (cell_number);
+ for (unsigned int q=0; q<n_q_points; ++q)
+ patch.data(dataset+offset,q) = value;
+ }
}
}
template <int dim, class DH>
void DataOutFaces<dim,DH>::build_patches (const Mapping<DH::dimension> &mapping,
- const unsigned int n_subdivisions_)
+ const unsigned int n_subdivisions_)
{
- // Check consistency of redundant
- // template parameter
+ // Check consistency of redundant
+ // template parameter
Assert (dim==DH::dimension, ExcDimensionMismatch(dim, DH::dimension));
const unsigned int n_subdivisions = (n_subdivisions_ != 0)
- ? n_subdivisions_
- : this->default_subdivisions;
+ ? n_subdivisions_
+ : this->default_subdivisions;
Assert (n_subdivisions >= 1,
- ExcInvalidNumberOfSubdivisions(n_subdivisions));
+ ExcInvalidNumberOfSubdivisions(n_subdivisions));
typedef DataOut_DoFData<DH,DH::dimension+1> BaseClass;
Assert (this->dofs != 0, typename BaseClass::ExcNoDoFHandlerSelected());
- // before we start the loop:
- // create a quadrature rule that
- // actually has the points on this
- // patch
+ // before we start the loop:
+ // create a quadrature rule that
+ // actually has the points on this
+ // patch
const QTrapez<1> q_trapez;
const QIterated<DH::dimension-1> patch_points (q_trapez, n_subdivisions);
for (unsigned int i=0; i<this->dof_data.size(); ++i)
n_datasets += this->dof_data[i]->n_output_variables;
- // first count the cells we want to
- // create patches of and make sure
- // there is enough memory for that
+ // first count the cells we want to
+ // create patches of and make sure
+ // there is enough memory for that
std::vector<FaceDescriptor> all_faces;
for (FaceDescriptor face=first_face();
face.first != this->dofs->end();
face = next_face(face))
all_faces.push_back (face);
- // clear the patches array and
- // allocate the right number of
- // elements
+ // clear the patches array and
+ // allocate the right number of
+ // elements
this->patches.clear ();
this->patches.reserve (all_faces.size());
Assert (this->patches.size() == 0, ExcInternalError());
internal::DataOutFaces::ParallelData<DH::dimension, DH::dimension>
thread_data (patch_points, n_components, n_datasets,
- n_subdivisions,
- n_postprocessor_outputs,
- mapping,
- this->dofs->get_fe(),
- update_flags);
+ n_subdivisions,
+ n_postprocessor_outputs,
+ mapping,
+ this->dofs->get_fe(),
+ update_flags);
DataOutBase::Patch<DH::dimension-1,DH::space_dimension> sample_patch;
sample_patch.n_subdivisions = n_subdivisions;
sample_patch.data.reinit (n_datasets,
- patch_points.size());
+ patch_points.size());
- // now build the patches in parallel
+ // now build the patches in parallel
WorkStream::run (&all_faces[0],
- &all_faces[0]+all_faces.size(),
- std_cxx1x::bind(&DataOutFaces<dim,DH>::build_one_patch,
- *this, std_cxx1x::_1, std_cxx1x::_2, std_cxx1x::_3),
- std_cxx1x::bind(&internal::DataOutFaces::
- append_patch_to_list<dim,DH::space_dimension>,
- std_cxx1x::_1, std_cxx1x::ref(this->patches)),
- thread_data,
- sample_patch);
+ &all_faces[0]+all_faces.size(),
+ std_cxx1x::bind(&DataOutFaces<dim,DH>::build_one_patch,
+ *this, std_cxx1x::_1, std_cxx1x::_2, std_cxx1x::_3),
+ std_cxx1x::bind(&internal::DataOutFaces::
+ append_patch_to_list<dim,DH::space_dimension>,
+ std_cxx1x::_1, std_cxx1x::ref(this->patches)),
+ thread_data,
+ sample_patch);
}
typename DataOutFaces<dim,DH>::FaceDescriptor
DataOutFaces<dim,DH>::first_face ()
{
- // simply find first active cell
- // with a face on the boundary
+ // simply find first active cell
+ // with a face on the boundary
typename DH::active_cell_iterator cell = this->dofs->begin_active();
for (; cell != this->dofs->end(); ++cell)
for (unsigned int f=0; f<GeometryInfo<DH::dimension>::faces_per_cell; ++f)
if (!surface_only || cell->face(f)->at_boundary())
- return FaceDescriptor(cell, f);
+ return FaceDescriptor(cell, f);
- // ups, triangulation has no
- // boundary? impossible!
+ // ups, triangulation has no
+ // boundary? impossible!
Assert (false, ExcInternalError());
return FaceDescriptor();
{
FaceDescriptor face = old_face;
- // first check whether the present
- // cell has more faces on the
- // boundary
+ // first check whether the present
+ // cell has more faces on the
+ // boundary
for (unsigned int f=face.second+1; f<GeometryInfo<DH::dimension>::faces_per_cell; ++f)
if (!surface_only || face.first->face(f)->at_boundary())
- // yup, that is so, so return it
+ // yup, that is so, so return it
{
- face.second = f;
- return face;
+ face.second = f;
+ return face;
};
- // otherwise find the next active
- // cell that has a face on the
- // boundary
+ // otherwise find the next active
+ // cell that has a face on the
+ // boundary
- // convert the iterator to an
- // active_iterator and advance
- // this to the next active cell
+ // convert the iterator to an
+ // active_iterator and advance
+ // this to the next active cell
typename DH::active_cell_iterator active_cell = face.first;
- // increase face pointer by one
+ // increase face pointer by one
++active_cell;
- // while there are active cells
+ // while there are active cells
while (active_cell != this->dofs->end())
{
- // check all the faces of this
- // active cell
+ // check all the faces of this
+ // active cell
for (unsigned int f=0; f<GeometryInfo<DH::dimension>::faces_per_cell; ++f)
- if (!surface_only || active_cell->face(f)->at_boundary())
- {
- face.first = active_cell;
- face.second = f;
- return face;
- };
- // the present cell had no
- // faces on the boundary, so
- // check next cell
+ if (!surface_only || active_cell->face(f)->at_boundary())
+ {
+ face.first = active_cell;
+ face.second = f;
+ return face;
+ };
+ // the present cell had no
+ // faces on the boundary, so
+ // check next cell
++active_cell;
};
- // we fell off the edge, so return
- // with invalid pointer
+ // we fell off the edge, so return
+ // with invalid pointer
face.first = this->dofs->end();
face.second = 0;
return face;
// $Id$
// Version: $Name$
//
-// Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 by the deal.II authors
+// Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
template <class FE>
ParallelData<dim,spacedim>::
ParallelData (const Quadrature<dim> &quadrature,
- const unsigned int n_components,
- const unsigned int n_datasets,
- const unsigned int n_subdivisions,
- const unsigned int n_patches_per_circle,
- const std::vector<unsigned int> &n_postprocessor_outputs,
- const FE &finite_elements,
- const UpdateFlags update_flags)
- :
- internal::DataOut::
- ParallelDataBase<dim,spacedim> (n_components,
- n_datasets,
- n_subdivisions,
- quadrature.size(),
- n_postprocessor_outputs,
- finite_elements),
- n_patches_per_circle (n_patches_per_circle),
- q_collection (quadrature),
- x_fe_values (this->fe_collection,
- q_collection,
- update_flags)
+ const unsigned int n_components,
+ const unsigned int n_datasets,
+ const unsigned int n_subdivisions,
+ const unsigned int n_patches_per_circle,
+ const std::vector<unsigned int> &n_postprocessor_outputs,
+ const FE &finite_elements,
+ const UpdateFlags update_flags)
+ :
+ internal::DataOut::
+ ParallelDataBase<dim,spacedim> (n_components,
+ n_datasets,
+ n_subdivisions,
+ quadrature.size(),
+ n_postprocessor_outputs,
+ finite_elements),
+ n_patches_per_circle (n_patches_per_circle),
+ q_collection (quadrature),
+ x_fe_values (this->fe_collection,
+ q_collection,
+ update_flags)
{}
- /**
- * In a WorkStream context, use
- * this function to append the
- * patch computed by the parallel
- * stage to the array of patches.
- */
+ /**
+ * In a WorkStream context, use
+ * this function to append the
+ * patch computed by the parallel
+ * stage to the array of patches.
+ */
template <int dim, int spacedim>
void
append_patch_to_list (const std::vector<DataOutBase::Patch<dim+1,spacedim+1> > &new_patches,
- std::vector<DataOutBase::Patch<dim+1,spacedim+1> > &patches)
+ std::vector<DataOutBase::Patch<dim+1,spacedim+1> > &patches)
{
for (unsigned int i=0; i<new_patches.size(); ++i)
- {
- patches.push_back (new_patches[i]);
- patches.back().patch_index = patches.size()-1;
- }
+ {
+ patches.push_back (new_patches[i]);
+ patches.back().patch_index = patches.size()-1;
+ }
}
}
}
void
DataOutRotation<dim,DH>::
build_one_patch (const cell_iterator *cell,
- internal::DataOutRotation::ParallelData<DH::dimension, DH::space_dimension> &data,
- std::vector<DataOutBase::Patch<DH::dimension+1,DH::space_dimension+1> > &patches)
+ internal::DataOutRotation::ParallelData<DH::dimension, DH::space_dimension> &data,
+ std::vector<DataOutBase::Patch<DH::dimension+1,DH::space_dimension+1> > &patches)
{
if (dim == 3)
{
- // would this function make any
- // sense after all? who would want
- // to output/compute in four space
- // dimensions?
+ // would this function make any
+ // sense after all? who would want
+ // to output/compute in four space
+ // dimensions?
Assert (false, ExcNotImplemented());
return;
}
Assert ((*cell)->is_locally_owned(),
- ExcNotImplemented());
+ ExcNotImplemented());
const unsigned int n_patches_per_circle = data.n_patches_per_circle;
- // another abbreviation denoting
- // the number of q_points in each
- // direction
+ // another abbreviation denoting
+ // the number of q_points in each
+ // direction
const unsigned int n_points = data.n_subdivisions+1;
- // set up an array that holds the
- // directions in the plane of
- // rotation in which we will put
- // points in the whole domain (not
- // the rotationally reduced one in
- // which the computation took
- // place. for simplicity add the
- // initial direction at the end
- // again
+ // set up an array that holds the
+ // directions in the plane of
+ // rotation in which we will put
+ // points in the whole domain (not
+ // the rotationally reduced one in
+ // which the computation took
+ // place. for simplicity add the
+ // initial direction at the end
+ // again
std::vector<Point<DH::dimension+1> > angle_directions (n_patches_per_circle+1);
for (unsigned int i=0; i<=n_patches_per_circle; ++i)
{
angle_directions[i][DH::dimension-1] = std::cos(2*numbers::PI *
- i/n_patches_per_circle);
+ i/n_patches_per_circle);
angle_directions[i][DH::dimension] = std::sin(2*numbers::PI *
- i/n_patches_per_circle);
+ i/n_patches_per_circle);
}
for (unsigned int angle=0; angle<n_patches_per_circle; ++angle)
{
- // first compute the
- // vertices of the
- // patch. note that they
- // will have to be computed
- // from the vertices of the
- // cell, which has one
- // dimension less, however.
+ // first compute the
+ // vertices of the
+ // patch. note that they
+ // will have to be computed
+ // from the vertices of the
+ // cell, which has one
+ // dimension less, however.
switch (DH::dimension)
- {
- case 1:
- {
- const double r1 = (*cell)->vertex(0)(0),
- r2 = (*cell)->vertex(1)(0);
- Assert (r1 >= 0, ExcRadialVariableHasNegativeValues(r1));
- Assert (r2 >= 0, ExcRadialVariableHasNegativeValues(r2));
-
- patches[angle].vertices[0] = r1*angle_directions[angle];
- patches[angle].vertices[1] = r2*angle_directions[angle];
- patches[angle].vertices[2] = r1*angle_directions[angle+1];
- patches[angle].vertices[3] = r2*angle_directions[angle+1];
-
- break;
- };
-
- case 2:
- {
- for (unsigned int vertex=0;
- vertex<GeometryInfo<DH::dimension>::vertices_per_cell;
- ++vertex)
- {
- const Point<DH::dimension> v = (*cell)->vertex(vertex);
-
- // make sure that the
- // radial variable does
- // attain negative
- // values
- Assert (v(0) >= 0, ExcRadialVariableHasNegativeValues(v(0)));
-
- // now set the vertices
- // of the patch
- patches[angle].vertices[vertex] = v(0) * angle_directions[angle];
- patches[angle].vertices[vertex][0] = v(1);
-
- patches[angle].vertices[vertex+GeometryInfo<DH::dimension>::vertices_per_cell]
- = v(0) * angle_directions[angle+1];
- patches[angle].vertices[vertex+GeometryInfo<DH::dimension>::vertices_per_cell][0]
- = v(1);
- };
-
- break;
- };
-
- default:
- Assert (false, ExcNotImplemented());
- };
+ {
+ case 1:
+ {
+ const double r1 = (*cell)->vertex(0)(0),
+ r2 = (*cell)->vertex(1)(0);
+ Assert (r1 >= 0, ExcRadialVariableHasNegativeValues(r1));
+ Assert (r2 >= 0, ExcRadialVariableHasNegativeValues(r2));
+
+ patches[angle].vertices[0] = r1*angle_directions[angle];
+ patches[angle].vertices[1] = r2*angle_directions[angle];
+ patches[angle].vertices[2] = r1*angle_directions[angle+1];
+ patches[angle].vertices[3] = r2*angle_directions[angle+1];
+
+ break;
+ };
+
+ case 2:
+ {
+ for (unsigned int vertex=0;
+ vertex<GeometryInfo<DH::dimension>::vertices_per_cell;
+ ++vertex)
+ {
+ const Point<DH::dimension> v = (*cell)->vertex(vertex);
+
+ // make sure that the
+ // radial variable does
+ // attain negative
+ // values
+ Assert (v(0) >= 0, ExcRadialVariableHasNegativeValues(v(0)));
+
+ // now set the vertices
+ // of the patch
+ patches[angle].vertices[vertex] = v(0) * angle_directions[angle];
+ patches[angle].vertices[vertex][0] = v(1);
+
+ patches[angle].vertices[vertex+GeometryInfo<DH::dimension>::vertices_per_cell]
+ = v(0) * angle_directions[angle+1];
+ patches[angle].vertices[vertex+GeometryInfo<DH::dimension>::vertices_per_cell][0]
+ = v(1);
+ };
+
+ break;
+ };
+
+ default:
+ Assert (false, ExcNotImplemented());
+ };
unsigned int offset=0;
- // then fill in data
+ // then fill in data
if (data.n_datasets > 0)
- {
- data.x_fe_values.reinit (*cell);
- const FEValues<DH::dimension> &fe_patch_values
- = data.x_fe_values.get_present_fe_values ();
-
- // first fill dof_data
- for (unsigned int dataset=0; dataset<this->dof_data.size(); ++dataset)
- {
- const DataPostprocessor<dim> *postprocessor=this->dof_data[dataset]->postprocessor;
- if (postprocessor != 0)
- {
- // we have to postprocess the
- // data, so determine, which
- // fields have to be updated
- const UpdateFlags update_flags=postprocessor->get_needed_update_flags();
-
- if (data.n_components == 1)
- {
- // at each point there is
- // only one component of
- // value, gradient etc.
- if (update_flags & update_values)
- this->dof_data[dataset]->get_function_values (fe_patch_values,
- data.patch_values);
- if (update_flags & update_gradients)
- this->dof_data[dataset]->get_function_gradients (fe_patch_values,
- data.patch_gradients);
- if (update_flags & update_hessians)
- this->dof_data[dataset]->get_function_hessians (fe_patch_values,
- data.patch_hessians);
-
- if (update_flags & update_quadrature_points)
- data.patch_evaluation_points = fe_patch_values.get_quadrature_points();
-
- std::vector<Point<DH::space_dimension> > dummy_normals;
- postprocessor->
- compute_derived_quantities_scalar(data.patch_values,
- data.patch_gradients,
- data.patch_hessians,
- dummy_normals,
- data.patch_evaluation_points,
- data.postprocessed_values[dataset]);
- }
- else
- {
- // at each point there is
- // a vector valued
- // function and its
- // derivative...
- if (update_flags & update_values)
- this->dof_data[dataset]->get_function_values (fe_patch_values,
- data.patch_values_system);
- if (update_flags & update_gradients)
- this->dof_data[dataset]->get_function_gradients (fe_patch_values,
- data.patch_gradients_system);
- if (update_flags & update_hessians)
- this->dof_data[dataset]->get_function_hessians (fe_patch_values,
- data.patch_hessians_system);
-
- if (update_flags & update_quadrature_points)
- data.patch_evaluation_points = fe_patch_values.get_quadrature_points();
-
- std::vector<Point<DH::space_dimension> > dummy_normals;
- postprocessor->
- compute_derived_quantities_vector(data.patch_values_system,
- data.patch_gradients_system,
- data.patch_hessians_system,
- dummy_normals,
- data.patch_evaluation_points,
- data.postprocessed_values[dataset]);
- }
-
- for (unsigned int component=0;
- component<this->dof_data[dataset]->n_output_variables;
- ++component)
- {
- switch (DH::dimension)
- {
- case 1:
- for (unsigned int x=0; x<n_points; ++x)
- for (unsigned int y=0; y<n_points; ++y)
- patches[angle].data(offset+component,
- x*n_points + y)
- = data.postprocessed_values[dataset][x](component);
- break;
-
- case 2:
- for (unsigned int x=0; x<n_points; ++x)
- for (unsigned int y=0; y<n_points; ++y)
- for (unsigned int z=0; z<n_points; ++z)
- patches[angle].data(offset+component,
- x*n_points*n_points +
- y*n_points +
- z)
- = data.postprocessed_values[dataset][x*n_points+z](component);
- break;
-
- default:
- Assert (false, ExcNotImplemented());
- }
- }
- }
- else
- if (data.n_components == 1)
- {
- this->dof_data[dataset]->get_function_values (fe_patch_values,
- data.patch_values);
-
- switch (DH::dimension)
- {
- case 1:
- for (unsigned int x=0; x<n_points; ++x)
- for (unsigned int y=0; y<n_points; ++y)
- patches[angle].data(offset,
- x*n_points + y)
- = data.patch_values[x];
- break;
-
- case 2:
- for (unsigned int x=0; x<n_points; ++x)
- for (unsigned int y=0; y<n_points; ++y)
- for (unsigned int z=0; z<n_points; ++z)
- patches[angle].data(offset,
- x*n_points*n_points +
- y +
- z*n_points)
- = data.patch_values[x*n_points+z];
- break;
-
- default:
- Assert (false, ExcNotImplemented());
- }
- }
- else
- // system of components
- {
- this->dof_data[dataset]->get_function_values (fe_patch_values,
- data.patch_values_system);
-
- for (unsigned int component=0; component<data.n_components;
- ++component)
- {
- switch (DH::dimension)
- {
- case 1:
- for (unsigned int x=0; x<n_points; ++x)
- for (unsigned int y=0; y<n_points; ++y)
- patches[angle].data(offset+component,
- x*n_points + y)
- = data.patch_values_system[x](component);
- break;
-
- case 2:
- for (unsigned int x=0; x<n_points; ++x)
- for (unsigned int y=0; y<n_points; ++y)
- for (unsigned int z=0; z<n_points; ++z)
- patches[angle].data(offset+component,
- x*n_points*n_points +
- y*n_points +
- z)
- = data.patch_values_system[x*n_points+z](component);
- break;
-
- default:
- Assert (false, ExcNotImplemented());
- }
- }
- }
- offset+=this->dof_data[dataset]->n_output_variables;
- }
-
- // then do the cell data
- for (unsigned int dataset=0; dataset<this->cell_data.size(); ++dataset)
- {
- // we need to get at
- // the number of the
- // cell to which this
- // face belongs in
- // order to access the
- // cell data. this is
- // not readily
- // available, so choose
- // the following rather
- // inefficient way:
- Assert ((*cell)->active(),
- ExcMessage("Cell must be active for cell data"));
- const unsigned int cell_number
- = std::distance (this->dofs->begin_active(),
- typename DH::active_cell_iterator(*cell));
- const double value
- = this->cell_data[dataset]->get_cell_data_value (cell_number);
- switch (DH::dimension)
- {
- case 1:
- for (unsigned int x=0; x<n_points; ++x)
- for (unsigned int y=0; y<n_points; ++y)
- patches[angle].data(dataset+offset,
- x*n_points +
- y)
- = value;
- break;
-
- case 2:
- for (unsigned int x=0; x<n_points; ++x)
- for (unsigned int y=0; y<n_points; ++y)
- for (unsigned int z=0; z<n_points; ++z)
- patches[angle].data(dataset+offset,
- x*n_points*n_points +
- y*n_points +
- z)
- = value;
- break;
-
- default:
- Assert (false, ExcNotImplemented());
- }
- }
- }
+ {
+ data.x_fe_values.reinit (*cell);
+ const FEValues<DH::dimension> &fe_patch_values
+ = data.x_fe_values.get_present_fe_values ();
+
+ // first fill dof_data
+ for (unsigned int dataset=0; dataset<this->dof_data.size(); ++dataset)
+ {
+ const DataPostprocessor<dim> *postprocessor=this->dof_data[dataset]->postprocessor;
+ if (postprocessor != 0)
+ {
+ // we have to postprocess the
+ // data, so determine, which
+ // fields have to be updated
+ const UpdateFlags update_flags=postprocessor->get_needed_update_flags();
+
+ if (data.n_components == 1)
+ {
+ // at each point there is
+ // only one component of
+ // value, gradient etc.
+ if (update_flags & update_values)
+ this->dof_data[dataset]->get_function_values (fe_patch_values,
+ data.patch_values);
+ if (update_flags & update_gradients)
+ this->dof_data[dataset]->get_function_gradients (fe_patch_values,
+ data.patch_gradients);
+ if (update_flags & update_hessians)
+ this->dof_data[dataset]->get_function_hessians (fe_patch_values,
+ data.patch_hessians);
+
+ if (update_flags & update_quadrature_points)
+ data.patch_evaluation_points = fe_patch_values.get_quadrature_points();
+
+ std::vector<Point<DH::space_dimension> > dummy_normals;
+ postprocessor->
+ compute_derived_quantities_scalar(data.patch_values,
+ data.patch_gradients,
+ data.patch_hessians,
+ dummy_normals,
+ data.patch_evaluation_points,
+ data.postprocessed_values[dataset]);
+ }
+ else
+ {
+ // at each point there is
+ // a vector valued
+ // function and its
+ // derivative...
+ if (update_flags & update_values)
+ this->dof_data[dataset]->get_function_values (fe_patch_values,
+ data.patch_values_system);
+ if (update_flags & update_gradients)
+ this->dof_data[dataset]->get_function_gradients (fe_patch_values,
+ data.patch_gradients_system);
+ if (update_flags & update_hessians)
+ this->dof_data[dataset]->get_function_hessians (fe_patch_values,
+ data.patch_hessians_system);
+
+ if (update_flags & update_quadrature_points)
+ data.patch_evaluation_points = fe_patch_values.get_quadrature_points();
+
+ std::vector<Point<DH::space_dimension> > dummy_normals;
+ postprocessor->
+ compute_derived_quantities_vector(data.patch_values_system,
+ data.patch_gradients_system,
+ data.patch_hessians_system,
+ dummy_normals,
+ data.patch_evaluation_points,
+ data.postprocessed_values[dataset]);
+ }
+
+ for (unsigned int component=0;
+ component<this->dof_data[dataset]->n_output_variables;
+ ++component)
+ {
+ switch (DH::dimension)
+ {
+ case 1:
+ for (unsigned int x=0; x<n_points; ++x)
+ for (unsigned int y=0; y<n_points; ++y)
+ patches[angle].data(offset+component,
+ x*n_points + y)
+ = data.postprocessed_values[dataset][x](component);
+ break;
+
+ case 2:
+ for (unsigned int x=0; x<n_points; ++x)
+ for (unsigned int y=0; y<n_points; ++y)
+ for (unsigned int z=0; z<n_points; ++z)
+ patches[angle].data(offset+component,
+ x*n_points*n_points +
+ y*n_points +
+ z)
+ = data.postprocessed_values[dataset][x*n_points+z](component);
+ break;
+
+ default:
+ Assert (false, ExcNotImplemented());
+ }
+ }
+ }
+ else
+ if (data.n_components == 1)
+ {
+ this->dof_data[dataset]->get_function_values (fe_patch_values,
+ data.patch_values);
+
+ switch (DH::dimension)
+ {
+ case 1:
+ for (unsigned int x=0; x<n_points; ++x)
+ for (unsigned int y=0; y<n_points; ++y)
+ patches[angle].data(offset,
+ x*n_points + y)
+ = data.patch_values[x];
+ break;
+
+ case 2:
+ for (unsigned int x=0; x<n_points; ++x)
+ for (unsigned int y=0; y<n_points; ++y)
+ for (unsigned int z=0; z<n_points; ++z)
+ patches[angle].data(offset,
+ x*n_points*n_points +
+ y +
+ z*n_points)
+ = data.patch_values[x*n_points+z];
+ break;
+
+ default:
+ Assert (false, ExcNotImplemented());
+ }
+ }
+ else
+ // system of components
+ {
+ this->dof_data[dataset]->get_function_values (fe_patch_values,
+ data.patch_values_system);
+
+ for (unsigned int component=0; component<data.n_components;
+ ++component)
+ {
+ switch (DH::dimension)
+ {
+ case 1:
+ for (unsigned int x=0; x<n_points; ++x)
+ for (unsigned int y=0; y<n_points; ++y)
+ patches[angle].data(offset+component,
+ x*n_points + y)
+ = data.patch_values_system[x](component);
+ break;
+
+ case 2:
+ for (unsigned int x=0; x<n_points; ++x)
+ for (unsigned int y=0; y<n_points; ++y)
+ for (unsigned int z=0; z<n_points; ++z)
+ patches[angle].data(offset+component,
+ x*n_points*n_points +
+ y*n_points +
+ z)
+ = data.patch_values_system[x*n_points+z](component);
+ break;
+
+ default:
+ Assert (false, ExcNotImplemented());
+ }
+ }
+ }
+ offset+=this->dof_data[dataset]->n_output_variables;
+ }
+
+ // then do the cell data
+ for (unsigned int dataset=0; dataset<this->cell_data.size(); ++dataset)
+ {
+ // we need to get at
+ // the number of the
+ // cell to which this
+ // face belongs in
+ // order to access the
+ // cell data. this is
+ // not readily
+ // available, so choose
+ // the following rather
+ // inefficient way:
+ Assert ((*cell)->active(),
+ ExcMessage("Cell must be active for cell data"));
+ const unsigned int cell_number
+ = std::distance (this->dofs->begin_active(),
+ typename DH::active_cell_iterator(*cell));
+ const double value
+ = this->cell_data[dataset]->get_cell_data_value (cell_number);
+ switch (DH::dimension)
+ {
+ case 1:
+ for (unsigned int x=0; x<n_points; ++x)
+ for (unsigned int y=0; y<n_points; ++y)
+ patches[angle].data(dataset+offset,
+ x*n_points +
+ y)
+ = value;
+ break;
+
+ case 2:
+ for (unsigned int x=0; x<n_points; ++x)
+ for (unsigned int y=0; y<n_points; ++y)
+ for (unsigned int z=0; z<n_points; ++z)
+ patches[angle].data(dataset+offset,
+ x*n_points*n_points +
+ y*n_points +
+ z)
+ = value;
+ break;
+
+ default:
+ Assert (false, ExcNotImplemented());
+ }
+ }
+ }
}
}
template <int dim, class DH>
void DataOutRotation<dim,DH>::build_patches (const unsigned int n_patches_per_circle,
- const unsigned int nnnn_subdivisions)
+ const unsigned int nnnn_subdivisions)
{
- // Check consistency of redundant
- // template parameter
+ // Check consistency of redundant
+ // template parameter
Assert (dim==DH::dimension, ExcDimensionMismatch(dim, DH::dimension));
typedef DataOut_DoFData<DH,DH::dimension+1> BaseClass;
Assert (this->dofs != 0, typename BaseClass::ExcNoDoFHandlerSelected());
const unsigned int n_subdivisions = (nnnn_subdivisions != 0)
- ? nnnn_subdivisions
- : this->default_subdivisions;
+ ? nnnn_subdivisions
+ : this->default_subdivisions;
Assert (n_subdivisions >= 1,
- ExcInvalidNumberOfSubdivisions(n_subdivisions));
+ ExcInvalidNumberOfSubdivisions(n_subdivisions));
const QTrapez<1> q_trapez;
const QIterated<DH::dimension> patch_points (q_trapez, n_subdivisions);
for (unsigned int i=0; i<this->dof_data.size(); ++i)
if (this->dof_data[i]->postprocessor)
update_flags |= this->dof_data[i]->postprocessor->get_needed_update_flags();
- // perhaps update_normal_vectors is present,
- // which would only be useful on faces, but
- // we may not use it here.
+ // perhaps update_normal_vectors is present,
+ // which would only be useful on faces, but
+ // we may not use it here.
Assert (!(update_flags & update_normal_vectors),
- ExcMessage("The update of normal vectors may not be requested for "
- "evaluation of data on cells via DataPostprocessor."));
+ ExcMessage("The update of normal vectors may not be requested for "
+ "evaluation of data on cells via DataPostprocessor."));
- // first count the cells we want to
- // create patches of and make sure
- // there is enough memory for that
+ // first count the cells we want to
+ // create patches of and make sure
+ // there is enough memory for that
std::vector<cell_iterator> all_cells;
for (cell_iterator cell=first_cell(); cell != this->dofs->end();
cell = next_cell(cell))
all_cells.push_back (cell);
- // then also take into account that
- // we want more than one patch to
- // come out of every cell, as they
- // are repeated around the axis of
- // rotation
+ // then also take into account that
+ // we want more than one patch to
+ // come out of every cell, as they
+ // are repeated around the axis of
+ // rotation
this->patches.clear();
this->patches.reserve (all_cells.size() * n_patches_per_circle);
internal::DataOutRotation::ParallelData<DH::dimension, DH::space_dimension>
thread_data (patch_points, n_components, n_datasets,
- n_subdivisions, n_patches_per_circle,
- n_postprocessor_outputs, this->dofs->get_fe(),
- update_flags);
+ n_subdivisions, n_patches_per_circle,
+ n_postprocessor_outputs, this->dofs->get_fe(),
+ update_flags);
std::vector<DataOutBase::Patch<DH::dimension+1,DH::space_dimension+1> >
new_patches (n_patches_per_circle);
for (unsigned int i=0; i<new_patches.size(); ++i)
{
new_patches[i].n_subdivisions = n_subdivisions;
new_patches[i].data.reinit (n_datasets,
- patch_points.size()
- * (n_subdivisions+1));
+ patch_points.size()
+ * (n_subdivisions+1));
}
- // now build the patches in parallel
+ // now build the patches in parallel
WorkStream::run (&all_cells[0],
- &all_cells[0]+all_cells.size(),
- std_cxx1x::bind(&DataOutRotation<dim,DH>::build_one_patch,
- *this, std_cxx1x::_1, std_cxx1x::_2, std_cxx1x::_3),
- std_cxx1x::bind(&internal::DataOutRotation
- ::append_patch_to_list<dim,DH::space_dimension>,
- std_cxx1x::_1, std_cxx1x::ref(this->patches)),
- thread_data,
- new_patches);
+ &all_cells[0]+all_cells.size(),
+ std_cxx1x::bind(&DataOutRotation<dim,DH>::build_one_patch,
+ *this, std_cxx1x::_1, std_cxx1x::_2, std_cxx1x::_3),
+ std_cxx1x::bind(&internal::DataOutRotation
+ ::append_patch_to_list<dim,DH::space_dimension>,
+ std_cxx1x::_1, std_cxx1x::ref(this->patches)),
+ thread_data,
+ new_patches);
}
typename DataOutRotation<dim,DH>::cell_iterator
DataOutRotation<dim,DH>::next_cell (const cell_iterator &cell)
{
- // convert the iterator to an
- // active_iterator and advance
- // this to the next active cell
+ // convert the iterator to an
+ // active_iterator and advance
+ // this to the next active cell
typename DH::active_cell_iterator active_cell = cell;
++active_cell;
return active_cell;
// $Id$
// Version: $Name$
//
-// Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2010, 2011 by the deal.II authors
+// Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2010, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
DataOutStack<dim,spacedim,DH>::DataVector::memory_consumption () const
{
return (MemoryConsumption::memory_consumption (data) +
- MemoryConsumption::memory_consumption (names));
+ MemoryConsumption::memory_consumption (names));
}
template <int dim, int spacedim, class DH>
void DataOutStack<dim,spacedim,DH>::new_parameter_value (const double p,
- const double dp)
+ const double dp)
{
parameter = p;
parameter_step = dp;
- // check whether the user called @p{finish_...}
- // at the end of the previous parameter step
- //
- // this is to prevent serious waste of
- // memory
+ // check whether the user called @p{finish_...}
+ // at the end of the previous parameter step
+ //
+ // this is to prevent serious waste of
+ // memory
for (typename std::vector<DataVector>::const_iterator i=dof_data.begin();
i!=dof_data.end(); ++i)
Assert (i->data.size() == 0,
- ExcDataNotCleared ());
+ ExcDataNotCleared ());
for (typename std::vector<DataVector>::const_iterator i=cell_data.begin();
i!=cell_data.end(); ++i)
Assert (i->data.size() == 0,
- ExcDataNotCleared ());
+ ExcDataNotCleared ());
}
template <int dim, int spacedim, class DH>
void DataOutStack<dim,spacedim,DH>::attach_dof_handler (const DH& dof)
{
- // Check consistency of redundant
- // template parameter
+ // Check consistency of redundant
+ // template parameter
Assert (dim==DH::dimension, ExcDimensionMismatch(dim, DH::dimension));
dof_handler = &dof;
template <int dim, int spacedim, class DH>
void DataOutStack<dim,spacedim,DH>::declare_data_vector (const std::string &name,
- const VectorType vector_type)
+ const VectorType vector_type)
{
std::vector<std::string> names;
names.push_back (name);
template <int dim, int spacedim, class DH>
void DataOutStack<dim,spacedim,DH>::declare_data_vector (const std::vector<std::string> &names,
- const VectorType vector_type)
+ const VectorType vector_type)
{
- // make sure this function is
- // not called after some parameter
- // values have already been
- // processed
+ // make sure this function is
+ // not called after some parameter
+ // values have already been
+ // processed
Assert (patches.size() == 0, ExcDataAlreadyAdded());
- // also make sure that no name is
- // used twice
+ // also make sure that no name is
+ // used twice
for (std::vector<std::string>::const_iterator name=names.begin(); name!=names.end(); ++name)
{
for (typename std::vector<DataVector>::const_iterator data_set=dof_data.begin();
- data_set!=dof_data.end(); ++data_set)
- for (unsigned int i=0; i<data_set->names.size(); ++i)
- Assert (*name != data_set->names[i], ExcNameAlreadyUsed(*name));
+ data_set!=dof_data.end(); ++data_set)
+ for (unsigned int i=0; i<data_set->names.size(); ++i)
+ Assert (*name != data_set->names[i], ExcNameAlreadyUsed(*name));
for (typename std::vector<DataVector>::const_iterator data_set=cell_data.begin();
- data_set!=cell_data.end(); ++data_set)
- for (unsigned int i=0; i<data_set->names.size(); ++i)
- Assert (*name != data_set->names[i], ExcNameAlreadyUsed(*name));
+ data_set!=cell_data.end(); ++data_set)
+ for (unsigned int i=0; i<data_set->names.size(); ++i)
+ Assert (*name != data_set->names[i], ExcNameAlreadyUsed(*name));
};
switch (vector_type)
{
case dof_vector:
- dof_data.push_back (DataVector());
- dof_data.back().names = names;
- break;
+ dof_data.push_back (DataVector());
+ dof_data.back().names = names;
+ break;
case cell_vector:
- cell_data.push_back (DataVector());
- cell_data.back().names = names;
- break;
+ cell_data.push_back (DataVector());
+ cell_data.back().names = names;
+ break;
};
}
template <int dim, int spacedim, class DH>
template <typename number>
void DataOutStack<dim,spacedim,DH>::add_data_vector (const Vector<number> &vec,
- const std::string &name)
+ const std::string &name)
{
const unsigned int n_components = dof_handler->get_fe().n_components ();
std::vector<std::string> names;
- // if only one component or vector
- // is cell vector: we only need one
- // name
+ // if only one component or vector
+ // is cell vector: we only need one
+ // name
if ((n_components == 1) ||
(vec.size() == dof_handler->get_tria().n_active_cells()))
{
names.resize (1, name);
}
else
- // otherwise append _i to the
- // given name
+ // otherwise append _i to the
+ // given name
{
names.resize (n_components);
for (unsigned int i=0; i<n_components; ++i)
- {
- std::ostringstream namebuf;
- namebuf << '_' << i;
- names[i] = name + namebuf.str();
- }
+ {
+ std::ostringstream namebuf;
+ namebuf << '_' << i;
+ names[i] = name + namebuf.str();
+ }
}
add_data_vector (vec, names);
template <int dim, int spacedim, class DH>
template <typename number>
void DataOutStack<dim,spacedim,DH>::add_data_vector (const Vector<number> &vec,
- const std::vector<std::string> &names)
+ const std::vector<std::string> &names)
{
Assert (dof_handler != 0, ExcNoDoFHandlerSelected ());
- // either cell data and one name,
- // or dof data and n_components names
+ // either cell data and one name,
+ // or dof data and n_components names
Assert (((vec.size() == dof_handler->get_tria().n_active_cells()) &&
- (names.size() == 1))
- ||
- ((vec.size() == dof_handler->n_dofs()) &&
- (names.size() == dof_handler->get_fe().n_components())),
- ExcInvalidNumberOfNames (names.size(), dof_handler->get_fe().n_components()));
+ (names.size() == 1))
+ ||
+ ((vec.size() == dof_handler->n_dofs()) &&
+ (names.size() == dof_handler->get_fe().n_components())),
+ ExcInvalidNumberOfNames (names.size(), dof_handler->get_fe().n_components()));
for (unsigned int i=0; i<names.size(); ++i)
Assert (names[i].find_first_not_of("abcdefghijklmnopqrstuvwxyz"
- "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
- "0123456789_<>()") == std::string::npos,
- ExcInvalidCharacter (names[i],
- names[i].find_first_not_of("abcdefghijklmnopqrstuvwxyz"
- "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
- "0123456789_<>()")));
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "0123456789_<>()") == std::string::npos,
+ ExcInvalidCharacter (names[i],
+ names[i].find_first_not_of("abcdefghijklmnopqrstuvwxyz"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "0123456789_<>()")));
if (vec.size() == dof_handler->n_dofs())
{
typename std::vector<DataVector>::iterator data_vector=dof_data.begin();
for (; data_vector!=dof_data.end(); ++data_vector)
- if (data_vector->names == names)
- {
- data_vector->data.reinit (vec.size());
- std::copy (vec.begin(), vec.end(),
- data_vector->data.begin());
- return;
- };
+ if (data_vector->names == names)
+ {
+ data_vector->data.reinit (vec.size());
+ std::copy (vec.begin(), vec.end(),
+ data_vector->data.begin());
+ return;
+ };
// ok. not found. there is a
// slight chance that
{
typename std::vector<DataVector>::iterator data_vector=cell_data.begin();
for (; data_vector!=cell_data.end(); ++data_vector)
- if (data_vector->names == names)
- {
- data_vector->data.reinit (vec.size());
- std::copy (vec.begin(), vec.end(),
- data_vector->data.begin());
- return;
- };
+ if (data_vector->names == names)
+ {
+ data_vector->data.reinit (vec.size());
+ std::copy (vec.begin(), vec.end(),
+ data_vector->data.begin());
+ return;
+ };
Assert (false, ExcVectorNotDeclared (names[0]));
};
template <int dim, int spacedim, class DH>
void DataOutStack<dim,spacedim,DH>::build_patches (const unsigned int nnnn_subdivisions)
{
- // this is mostly copied from the
- // DataOut class
+ // this is mostly copied from the
+ // DataOut class
unsigned int n_subdivisions = (nnnn_subdivisions != 0)
- ? nnnn_subdivisions
- : this->default_subdivisions;
+ ? nnnn_subdivisions
+ : this->default_subdivisions;
Assert (n_subdivisions >= 1,
- ExcInvalidNumberOfSubdivisions(n_subdivisions));
+ ExcInvalidNumberOfSubdivisions(n_subdivisions));
Assert (dof_handler != 0, ExcNoDoFHandlerSelected());
const unsigned int n_components = dof_handler->get_fe().n_components();
const unsigned int n_datasets = dof_data.size() * n_components +
- cell_data.size();
+ cell_data.size();
- // first count the cells we want to
- // create patches of and make sure
- // there is enough memory for that
+ // first count the cells we want to
+ // create patches of and make sure
+ // there is enough memory for that
unsigned int n_patches = 0;
for (typename DH::active_cell_iterator
- cell=dof_handler->begin_active();
+ cell=dof_handler->begin_active();
cell != dof_handler->end(); ++cell)
++n_patches;
- // before we start the loop:
- // create a quadrature rule that
- // actually has the points on this
- // patch, and an object that
- // extracts the data on each
- // cell to these points
+ // before we start the loop:
+ // create a quadrature rule that
+ // actually has the points on this
+ // patch, and an object that
+ // extracts the data on each
+ // cell to these points
QTrapez<1> q_trapez;
QIterated<dim> patch_points (q_trapez, n_subdivisions);
- // create collection objects from
- // single quadratures,
- // and finite elements. if we have
- // an hp DoFHandler,
- // dof_handler.get_fe() returns a
- // collection of which we do a
- // shallow copy instead
+ // create collection objects from
+ // single quadratures,
+ // and finite elements. if we have
+ // an hp DoFHandler,
+ // dof_handler.get_fe() returns a
+ // collection of which we do a
+ // shallow copy instead
const hp::QCollection<dim> q_collection (patch_points);
const hp::FECollection<dim> fe_collection(dof_handler->get_fe());
const unsigned int n_q_points = patch_points.size();
std::vector<double> patch_values (n_q_points);
std::vector<Vector<double> > patch_values_system (n_q_points,
- Vector<double>(n_components));
+ Vector<double>(n_components));
- // add the required number of
- // patches. first initialize a template
- // patch with n_q_points (in the the plane
- // of the cells) times n_subdivisions+1 (in
- // the time direction) points
+ // add the required number of
+ // patches. first initialize a template
+ // patch with n_q_points (in the the plane
+ // of the cells) times n_subdivisions+1 (in
+ // the time direction) points
dealii::DataOutBase::Patch<dim+1,dim+1> default_patch;
default_patch.n_subdivisions = n_subdivisions;
default_patch.data.reinit (n_datasets, n_q_points*(n_subdivisions+1));
patches.insert (patches.end(), n_patches, default_patch);
- // now loop over all cells and
- // actually create the patches
+ // now loop over all cells and
+ // actually create the patches
typename std::vector< dealii::DataOutBase::Patch<dim+1,dim+1> >::iterator
patch = patches.begin() + (patches.size()-n_patches);
unsigned int cell_number = 0;
cell != dof_handler->end(); ++cell, ++patch, ++cell_number)
{
Assert (cell->is_locally_owned(),
- ExcNotImplemented());
+ ExcNotImplemented());
Assert (patch != patches.end(), ExcInternalError());
- // first fill in the vertices of the patch
+ // first fill in the vertices of the patch
- // Patches are organized such
- // that the parameter direction
- // is the last
- // coordinate. Thus, vertices
- // are two copies of the space
- // patch, one at parameter-step
- // and one at parameter.
+ // Patches are organized such
+ // that the parameter direction
+ // is the last
+ // coordinate. Thus, vertices
+ // are two copies of the space
+ // patch, one at parameter-step
+ // and one at parameter.
switch (dim)
- {
- case 1:
- patch->vertices[0] = Point<dim+1>(cell->vertex(0)(0),
- parameter-parameter_step);
- patch->vertices[1] = Point<dim+1>(cell->vertex(1)(0),
- parameter-parameter_step);
- patch->vertices[2] = Point<dim+1>(cell->vertex(0)(0),
- parameter);
- patch->vertices[3] = Point<dim+1>(cell->vertex(1)(0),
- parameter);
- break;
+ {
+ case 1:
+ patch->vertices[0] = Point<dim+1>(cell->vertex(0)(0),
+ parameter-parameter_step);
+ patch->vertices[1] = Point<dim+1>(cell->vertex(1)(0),
+ parameter-parameter_step);
+ patch->vertices[2] = Point<dim+1>(cell->vertex(0)(0),
+ parameter);
+ patch->vertices[3] = Point<dim+1>(cell->vertex(1)(0),
+ parameter);
+ break;
case 2:
- patch->vertices[0] = Point<dim+1>(cell->vertex(0)(0),
- cell->vertex(0)(1),
- parameter-parameter_step);
- patch->vertices[1] = Point<dim+1>(cell->vertex(1)(0),
- cell->vertex(1)(1),
- parameter-parameter_step);
+ patch->vertices[0] = Point<dim+1>(cell->vertex(0)(0),
+ cell->vertex(0)(1),
+ parameter-parameter_step);
+ patch->vertices[1] = Point<dim+1>(cell->vertex(1)(0),
+ cell->vertex(1)(1),
+ parameter-parameter_step);
patch->vertices[2] = Point<dim+1>(cell->vertex(2)(0),
- cell->vertex(2)(1),
- parameter-parameter_step);
- patch->vertices[3] = Point<dim+1>(cell->vertex(3)(0),
- cell->vertex(3)(1),
- parameter-parameter_step);
- patch->vertices[4] = Point<dim+1>(cell->vertex(0)(0),
- cell->vertex(0)(1),
- parameter);
- patch->vertices[5] = Point<dim+1>(cell->vertex(1)(0),
- cell->vertex(1)(1),
- parameter);
- patch->vertices[6] = Point<dim+1>(cell->vertex(2)(0),
- cell->vertex(2)(1),
- parameter);
- patch->vertices[7] = Point<dim+1>(cell->vertex(3)(0),
- cell->vertex(3)(1),
- parameter);
- break;
-
- default:
- Assert (false, ExcNotImplemented());
- };
-
-
- // now fill in the the data values.
- // note that the required order is
- // with highest coordinate running
- // fastest, we need to enter each
- // value (n_subdivisions+1) times
- // in succession
+ cell->vertex(2)(1),
+ parameter-parameter_step);
+ patch->vertices[3] = Point<dim+1>(cell->vertex(3)(0),
+ cell->vertex(3)(1),
+ parameter-parameter_step);
+ patch->vertices[4] = Point<dim+1>(cell->vertex(0)(0),
+ cell->vertex(0)(1),
+ parameter);
+ patch->vertices[5] = Point<dim+1>(cell->vertex(1)(0),
+ cell->vertex(1)(1),
+ parameter);
+ patch->vertices[6] = Point<dim+1>(cell->vertex(2)(0),
+ cell->vertex(2)(1),
+ parameter);
+ patch->vertices[7] = Point<dim+1>(cell->vertex(3)(0),
+ cell->vertex(3)(1),
+ parameter);
+ break;
+
+ default:
+ Assert (false, ExcNotImplemented());
+ };
+
+
+ // now fill in the the data values.
+ // note that the required order is
+ // with highest coordinate running
+ // fastest, we need to enter each
+ // value (n_subdivisions+1) times
+ // in succession
if (n_datasets > 0)
- {
- x_fe_patch_values.reinit (cell);
+ {
+ x_fe_patch_values.reinit (cell);
const FEValues<dim> &fe_patch_values
= x_fe_patch_values.get_present_fe_values ();
- // first fill dof_data
- for (unsigned int dataset=0; dataset<dof_data.size(); ++dataset)
- {
- if (n_components == 1)
- {
- fe_patch_values.get_function_values (dof_data[dataset].data,
- patch_values);
- for (unsigned int i=0; i<n_subdivisions+1; ++i)
- for (unsigned int q=0; q<n_q_points; ++q)
- patch->data(dataset,q+n_q_points*i) = patch_values[q];
- }
- else
- // system of components
- {
- fe_patch_values.get_function_values (dof_data[dataset].data,
- patch_values_system);
- for (unsigned int component=0; component<n_components; ++component)
- for (unsigned int i=0; i<n_subdivisions+1; ++i)
- for (unsigned int q=0; q<n_q_points; ++q)
- patch->data(dataset*n_components+component,
- q+n_q_points*i)
- = patch_values_system[q](component);
- }
- }
-
- // then do the cell data
- for (unsigned int dataset=0; dataset<cell_data.size(); ++dataset)
- {
- const double value = cell_data[dataset].data(cell_number);
- for (unsigned int q=0; q<n_q_points; ++q)
- for (unsigned int i=0; i<n_subdivisions+1; ++i)
- patch->data(dataset+dof_data.size()*n_components,
- q*(n_subdivisions+1)+i) = value;
- }
- }
+ // first fill dof_data
+ for (unsigned int dataset=0; dataset<dof_data.size(); ++dataset)
+ {
+ if (n_components == 1)
+ {
+ fe_patch_values.get_function_values (dof_data[dataset].data,
+ patch_values);
+ for (unsigned int i=0; i<n_subdivisions+1; ++i)
+ for (unsigned int q=0; q<n_q_points; ++q)
+ patch->data(dataset,q+n_q_points*i) = patch_values[q];
+ }
+ else
+ // system of components
+ {
+ fe_patch_values.get_function_values (dof_data[dataset].data,
+ patch_values_system);
+ for (unsigned int component=0; component<n_components; ++component)
+ for (unsigned int i=0; i<n_subdivisions+1; ++i)
+ for (unsigned int q=0; q<n_q_points; ++q)
+ patch->data(dataset*n_components+component,
+ q+n_q_points*i)
+ = patch_values_system[q](component);
+ }
+ }
+
+ // then do the cell data
+ for (unsigned int dataset=0; dataset<cell_data.size(); ++dataset)
+ {
+ const double value = cell_data[dataset].data(cell_number);
+ for (unsigned int q=0; q<n_q_points; ++q)
+ for (unsigned int i=0; i<n_subdivisions+1; ++i)
+ patch->data(dataset+dof_data.size()*n_components,
+ q*(n_subdivisions+1)+i) = value;
+ }
+ }
}
}
template <int dim, int spacedim, class DH>
void DataOutStack<dim,spacedim,DH>::finish_parameter_value ()
{
- // release lock on dof handler
+ // release lock on dof handler
dof_handler = 0;
for (typename std::vector<DataVector>::iterator i=dof_data.begin();
i!=dof_data.end(); ++i)
DataOutStack<dim,spacedim,DH>::memory_consumption () const
{
return (DataOutInterface<dim+1>::memory_consumption () +
- MemoryConsumption::memory_consumption (parameter) +
- MemoryConsumption::memory_consumption (parameter_step) +
- MemoryConsumption::memory_consumption (dof_handler) +
- MemoryConsumption::memory_consumption (patches) +
- MemoryConsumption::memory_consumption (dof_data) +
- MemoryConsumption::memory_consumption (cell_data));
+ MemoryConsumption::memory_consumption (parameter) +
+ MemoryConsumption::memory_consumption (parameter_step) +
+ MemoryConsumption::memory_consumption (dof_handler) +
+ MemoryConsumption::memory_consumption (patches) +
+ MemoryConsumption::memory_consumption (dof_data) +
+ MemoryConsumption::memory_consumption (cell_data));
}
// $Id$
// Version: $Name$
//
-// Copyright (C) 2007, 2010 by the deal.II authors
+// Copyright (C) 2007, 2010, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
void
DataPostprocessor<dim>::
compute_derived_quantities_scalar (const std::vector<double> &/*uh*/,
- const std::vector<Tensor<1,dim> > &/*duh*/,
- const std::vector<Tensor<2,dim> > &/*dduh*/,
- const std::vector<Point<dim> > &/*normals*/,
- std::vector<Vector<double> > &computed_quantities) const
+ const std::vector<Tensor<1,dim> > &/*duh*/,
+ const std::vector<Tensor<2,dim> > &/*dduh*/,
+ const std::vector<Point<dim> > &/*normals*/,
+ std::vector<Vector<double> > &computed_quantities) const
{
computed_quantities.clear();
AssertThrow(false,ExcPureFunctionCalled());
void
DataPostprocessor<dim>::
compute_derived_quantities_scalar (const std::vector<double> &uh,
- const std::vector<Tensor<1,dim> > &duh,
- const std::vector<Tensor<2,dim> > &dduh,
- const std::vector<Point<dim> > &normals,
- const std::vector<Point<dim> > &/*evaluation_points*/,
- std::vector<Vector<double> > &computed_quantities) const
+ const std::vector<Tensor<1,dim> > &duh,
+ const std::vector<Tensor<2,dim> > &dduh,
+ const std::vector<Point<dim> > &normals,
+ const std::vector<Point<dim> > &/*evaluation_points*/,
+ std::vector<Vector<double> > &computed_quantities) const
{
compute_derived_quantities_scalar(uh, duh, dduh, normals, computed_quantities);
}
void
DataPostprocessor<dim>::
compute_derived_quantities_vector (const std::vector<Vector<double> > &/*uh*/,
- const std::vector<std::vector<Tensor<1,dim> > > &/*duh*/,
- const std::vector<std::vector<Tensor<2,dim> > > &/*dduh*/,
- const std::vector<Point<dim> > &/*normals*/,
- std::vector<Vector<double> > &computed_quantities) const
+ const std::vector<std::vector<Tensor<1,dim> > > &/*duh*/,
+ const std::vector<std::vector<Tensor<2,dim> > > &/*dduh*/,
+ const std::vector<Point<dim> > &/*normals*/,
+ std::vector<Vector<double> > &computed_quantities) const
{
computed_quantities.clear();
AssertThrow(false,ExcPureFunctionCalled());
void
DataPostprocessor<dim>::
compute_derived_quantities_vector (const std::vector<Vector<double> > &uh,
- const std::vector<std::vector<Tensor<1,dim> > > &duh,
- const std::vector<std::vector<Tensor<2,dim> > > &dduh,
- const std::vector<Point<dim> > &normals,
- const std::vector<Point<dim> > &/*evaluation_points*/,
- std::vector<Vector<double> > &computed_quantities) const
+ const std::vector<std::vector<Tensor<1,dim> > > &duh,
+ const std::vector<std::vector<Tensor<2,dim> > > &dduh,
+ const std::vector<Point<dim> > &normals,
+ const std::vector<Point<dim> > &/*evaluation_points*/,
+ std::vector<Vector<double> > &computed_quantities) const
{
compute_derived_quantities_vector(uh, duh, dduh, normals, computed_quantities);
}
std::vector<DataComponentInterpretation::DataComponentInterpretation>
DataPostprocessor<dim>::get_data_component_interpretation () const
{
- // default implementation assumes that all
- // components are independent scalars
+ // default implementation assumes that all
+ // components are independent scalars
return
std::vector<DataComponentInterpretation::DataComponentInterpretation>
(get_names().size(),
template <int dim>
DataPostprocessorScalar<dim>::
DataPostprocessorScalar (const std::string &name,
- const UpdateFlags update_flags)
+ const UpdateFlags update_flags)
:
name (name),
update_flags (update_flags)
{}
-
-
+
+
template <int dim>
-std::vector<std::string>
+std::vector<std::string>
DataPostprocessorScalar<dim>::
get_names () const
{
DataPostprocessorScalar<dim>::
get_data_component_interpretation () const
{
- return
- std::vector<DataComponentInterpretation::DataComponentInterpretation>
+ return
+ std::vector<DataComponentInterpretation::DataComponentInterpretation>
(1, DataComponentInterpretation::component_is_scalar);
}
template <int dim>
-UpdateFlags
+UpdateFlags
DataPostprocessorScalar<dim>::
get_needed_update_flags () const
{
template <int dim>
DataPostprocessorVector<dim>::
DataPostprocessorVector (const std::string &name,
- const UpdateFlags update_flags)
+ const UpdateFlags update_flags)
:
name (name),
update_flags (update_flags)
{}
-
-
+
+
template <int dim>
-std::vector<std::string>
+std::vector<std::string>
DataPostprocessorVector<dim>::
get_names () const
{
DataPostprocessorVector<dim>::
get_data_component_interpretation () const
{
- return
- std::vector<DataComponentInterpretation::DataComponentInterpretation>
+ return
+ std::vector<DataComponentInterpretation::DataComponentInterpretation>
(dim, DataComponentInterpretation::component_is_part_of_vector);
}
template <int dim>
-UpdateFlags
+UpdateFlags
DataPostprocessorVector<dim>::
get_needed_update_flags () const
{
// $Id$
// Version: $Name$
//
-// Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by the deal.II authors
+// Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
typename DerivativeApproximation::Gradient<dim>::ProjectedDerivative
DerivativeApproximation::Gradient<dim>::
get_projected_derivative (const FEValues<dim,spacedim> &fe_values,
- const InputVector &solution,
- const unsigned int component)
+ const InputVector &solution,
+ const unsigned int component)
{
if (fe_values.get_fe().n_components() == 1)
{
else
{
std::vector<Vector<double> > values
- (1, Vector<double>(fe_values.get_fe().n_components()));
+ (1, Vector<double>(fe_values.get_fe().n_components()));
fe_values.get_function_values (solution, values);
return values[0](component);
}
void
DerivativeApproximation::Gradient<dim>::symmetrize (Derivative &)
{
- // nothing to do here
+ // nothing to do here
}
typename DerivativeApproximation::SecondDerivative<dim>::ProjectedDerivative
DerivativeApproximation::SecondDerivative<dim>::
get_projected_derivative (const FEValues<dim,spacedim> &fe_values,
- const InputVector &solution,
- const unsigned int component)
+ const InputVector &solution,
+ const unsigned int component)
{
if (fe_values.get_fe().n_components() == 1)
{
else
{
std::vector<std::vector<ProjectedDerivative> > values
- (1, std::vector<ProjectedDerivative>(fe_values.get_fe().n_components()));
+ (1, std::vector<ProjectedDerivative>(fe_values.get_fe().n_components()));
fe_values.get_function_grads (solution, values);
return values[0][component];
};
DerivativeApproximation::SecondDerivative<2>::
derivative_norm (const Derivative &d)
{
- // note that d should be a
- // symmetric 2x2 tensor, so the
- // eigenvalues are:
- //
- // 1/2(a+b\pm\sqrt((a-b)^2+4c^2))
- //
- // if the d_11=a, d_22=b,
- // d_12=d_21=c
+ // note that d should be a
+ // symmetric 2x2 tensor, so the
+ // eigenvalues are:
+ //
+ // 1/2(a+b\pm\sqrt((a-b)^2+4c^2))
+ //
+ // if the d_11=a, d_22=b,
+ // d_12=d_21=c
const double radicand = dealii::sqr(d[0][0] - d[1][1]) +
- 4*dealii::sqr(d[0][1]);
+ 4*dealii::sqr(d[0][1]);
const double eigenvalues[2]
= { 0.5*(d[0][0] + d[1][1] + std::sqrt(radicand)),
- 0.5*(d[0][0] + d[1][1] - std::sqrt(radicand)) };
+ 0.5*(d[0][0] + d[1][1] - std::sqrt(radicand)) };
return std::max (std::fabs (eigenvalues[0]),
- std::fabs (eigenvalues[1]));
+ std::fabs (eigenvalues[1]));
}
const double am = trace(d) / 3.;
- // s := d - trace(d) I
+ // s := d - trace(d) I
Tensor<2,3> s = d;
for (unsigned int i=0; i<3; ++i)
s[i][i] -= am;
const double ss01 = s[0][1] * s[0][1],
- ss12 = s[1][2] * s[1][2],
- ss02 = s[0][2] * s[0][2];
+ ss12 = s[1][2] * s[1][2],
+ ss02 = s[0][2] * s[0][2];
const double J2 = (s[0][0]*s[0][0] + s[1][1]*s[1][1] + s[2][2]*s[2][2]
- + 2 * (ss01 + ss02 + ss12)) / 2.;
+ + 2 * (ss01 + ss02 + ss12)) / 2.;
const double J3 = (std::pow(s[0][0],3) + std::pow(s[1][1],3) + std::pow(s[2][2],3)
- + 3. * s[0][0] * (ss01 + ss02)
- + 3. * s[1][1] * (ss01 + ss12)
- + 3. * s[2][2] * (ss02 + ss12)
- + 6. * s[0][1] * s[0][2] * s[1][2]) / 3.;
+ + 3. * s[0][0] * (ss01 + ss02)
+ + 3. * s[1][1] * (ss01 + ss12)
+ + 3. * s[2][2] * (ss02 + ss12)
+ + 6. * s[0][1] * s[0][2] * s[1][2]) / 3.;
const double R = std::sqrt (4. * J2 / 3.);
double EE[3] = { 0, 0, 0 };
- // the eigenvalues are away from
- // @p{am} in the order of R. thus,
- // if R<<AM, then we have the
- // degenerate case with three
- // identical eigenvalues. check
- // this first
+ // the eigenvalues are away from
+ // @p{am} in the order of R. thus,
+ // if R<<AM, then we have the
+ // degenerate case with three
+ // identical eigenvalues. check
+ // this first
if (R <= 1e-14*std::fabs(am))
EE[0] = EE[1] = EE[2] = am;
else
{
- // at least two eigenvalues are
- // distinct
+ // at least two eigenvalues are
+ // distinct
const double R3 = R*R*R;
const double XX = 4. * J3 / R3;
const double YY = 1. - std::fabs(XX);
Assert (YY > -1e-14, ExcInternalError());
if (YY < 0)
- {
- // two roots are equal
- const double a = (XX>0 ? -1. : 1.) * R / 2;
- EE[0] = EE[1] = am + a;
- EE[2] = am - 2.*a;
- }
+ {
+ // two roots are equal
+ const double a = (XX>0 ? -1. : 1.) * R / 2;
+ EE[0] = EE[1] = am + a;
+ EE[2] = am - 2.*a;
+ }
else
- {
- const double theta = std::acos(XX) / 3.;
- EE[0] = am + R*std::cos(theta);
- EE[1] = am + R*std::cos(theta + 2./3.*numbers::PI);
- EE[2] = am + R*std::cos(theta + 4./3.*numbers::PI);
- };
+ {
+ const double theta = std::acos(XX) / 3.;
+ EE[0] = am + R*std::cos(theta);
+ EE[1] = am + R*std::cos(theta + 2./3.*numbers::PI);
+ EE[2] = am + R*std::cos(theta + 4./3.*numbers::PI);
+ };
};
return std::max (std::fabs (EE[0]),
- std::max (std::fabs (EE[1]),
- std::fabs (EE[2])));
+ std::max (std::fabs (EE[1]),
+ std::fabs (EE[2])));
}
DerivativeApproximation::SecondDerivative<dim>::
derivative_norm (const Derivative &)
{
- // computing the spectral norm is
- // not so simple in general. it is
- // feasible for dim==3 as shown
- // above, since then there are
- // still closed form expressions of
- // the roots of the characteristic
- // polynomial, and they can easily
- // be computed using
- // maple. however, for higher
- // dimensions, some other method
- // needs to be employed. maybe some
- // steps of the power method would
- // suffice?
+ // computing the spectral norm is
+ // not so simple in general. it is
+ // feasible for dim==3 as shown
+ // above, since then there are
+ // still closed form expressions of
+ // the roots of the characteristic
+ // polynomial, and they can easily
+ // be computed using
+ // maple. however, for higher
+ // dimensions, some other method
+ // needs to be employed. maybe some
+ // steps of the power method would
+ // suffice?
Assert (false, ExcNotImplemented());
return 0;
}
void
DerivativeApproximation::SecondDerivative<dim>::symmetrize (Derivative &d)
{
- // symmetrize non-diagonal entries
+ // symmetrize non-diagonal entries
for (unsigned int i=0; i<dim; ++i)
for (unsigned int j=i+1; j<dim; ++j)
{
- const double s = (d[i][j] + d[j][i]) / 2;
- d[i][j] = d[j][i] = s;
+ const double s = (d[i][j] + d[j][i]) / 2;
+ d[i][j] = d[j][i] = s;
};
}
typename DerivativeApproximation::ThirdDerivative<dim>::ProjectedDerivative
DerivativeApproximation::ThirdDerivative<dim>::
get_projected_derivative (const FEValues<dim,spacedim> &fe_values,
- const InputVector &solution,
- const unsigned int component)
+ const InputVector &solution,
+ const unsigned int component)
{
if (fe_values.get_fe().n_components() == 1)
{
else
{
std::vector<std::vector<ProjectedDerivative> > values
- (1, std::vector<ProjectedDerivative>(fe_values.get_fe().n_components()));
+ (1, std::vector<ProjectedDerivative>(fe_values.get_fe().n_components()));
fe_values.get_function_hessians (solution, values);
return values[0][component];
};
DerivativeApproximation::ThirdDerivative<dim>::
derivative_norm (const Derivative &d)
{
- // return the Frobenius-norm. this is a
- // member function of Tensor<rank_,dim>
+ // return the Frobenius-norm. this is a
+ // member function of Tensor<rank_,dim>
return d.norm();
}
void
DerivativeApproximation::ThirdDerivative<dim>::symmetrize (Derivative &d)
{
- // symmetrize non-diagonal entries
+ // symmetrize non-diagonal entries
- // first do it in the case, that i,j,k are
- // pairwise different (which can onlky happen
- // in dim >= 3)
+ // first do it in the case, that i,j,k are
+ // pairwise different (which can onlky happen
+ // in dim >= 3)
for (unsigned int i=0; i<dim; ++i)
for (unsigned int j=i+1; j<dim; ++j)
for (unsigned int k=j+1; k<dim; ++k)
- {
- const double s = (d[i][j][k] +
- d[i][k][j] +
- d[j][i][k] +
- d[j][k][i] +
- d[k][i][j] +
- d[k][j][i]) / 6;
- d[i][j][k]
- = d[i][k][j]
- = d[j][i][k]
- = d[j][k][i]
- = d[k][i][j]
- = d[k][j][i]
- = s;
- };
- // now do the case, where two indices are
- // equal
+ {
+ const double s = (d[i][j][k] +
+ d[i][k][j] +
+ d[j][i][k] +
+ d[j][k][i] +
+ d[k][i][j] +
+ d[k][j][i]) / 6;
+ d[i][j][k]
+ = d[i][k][j]
+ = d[j][i][k]
+ = d[j][k][i]
+ = d[k][i][j]
+ = d[k][j][i]
+ = s;
+ };
+ // now do the case, where two indices are
+ // equal
for (unsigned int i=0; i<dim; ++i)
for (unsigned int j=i+1; j<dim; ++j)
{
- // case 1: index i (lower one) is
- // double
- const double s = (d[i][i][j] +
- d[i][j][i] +
- d[j][i][i] ) / 3;
- d[i][i][j]
- = d[i][j][i]
- = d[j][i][i]
- = s;
-
- // case 2: index j (higher one) is
- // double
- const double t = (d[i][j][j] +
- d[j][i][j] +
- d[j][j][i] ) / 3;
- d[i][j][j]
- = d[j][i][j]
- = d[j][j][i]
- = t;
+ // case 1: index i (lower one) is
+ // double
+ const double s = (d[i][i][j] +
+ d[i][j][i] +
+ d[j][i][i] ) / 3;
+ d[i][i][j]
+ = d[i][j][i]
+ = d[j][i][i]
+ = s;
+
+ // case 2: index j (higher one) is
+ // double
+ const double t = (d[i][j][j] +
+ d[j][i][j] +
+ d[j][j][i] ) / 3;
+ d[i][j][j]
+ = d[j][i][j]
+ = d[j][j][i]
+ = t;
};
}
void
DerivativeApproximation::
approximate_gradient (const Mapping<dim,spacedim> &mapping,
- const DH<dim,spacedim> &dof_handler,
- const InputVector &solution,
- Vector<float> &derivative_norm,
- const unsigned int component)
+ const DH<dim,spacedim> &dof_handler,
+ const InputVector &solution,
+ Vector<float> &derivative_norm,
+ const unsigned int component)
{
approximate_derivative<Gradient<dim>,dim> (mapping,
dof_handler,
void
DerivativeApproximation::
approximate_gradient (const DH<dim,spacedim> &dof_handler,
- const InputVector &solution,
- Vector<float> &derivative_norm,
- const unsigned int component)
+ const InputVector &solution,
+ Vector<float> &derivative_norm,
+ const unsigned int component)
{
Assert (DEAL_II_COMPAT_MAPPING, ExcCompatibility("mapping"));
approximate_derivative<Gradient<dim>,dim> (StaticMappingQ1<dim>::mapping,
void
DerivativeApproximation::
approximate_second_derivative (const Mapping<dim,spacedim> &mapping,
- const DH<dim,spacedim> &dof_handler,
- const InputVector &solution,
- Vector<float> &derivative_norm,
- const unsigned int component)
+ const DH<dim,spacedim> &dof_handler,
+ const InputVector &solution,
+ Vector<float> &derivative_norm,
+ const unsigned int component)
{
approximate_derivative<SecondDerivative<dim>,dim> (mapping,
- dof_handler,
- solution,
- component,
- derivative_norm);
+ dof_handler,
+ solution,
+ component,
+ derivative_norm);
}
void
DerivativeApproximation::
approximate_second_derivative (const DH<dim,spacedim> &dof_handler,
- const InputVector &solution,
- Vector<float> &derivative_norm,
- const unsigned int component)
+ const InputVector &solution,
+ Vector<float> &derivative_norm,
+ const unsigned int component)
{
Assert (DEAL_II_COMPAT_MAPPING, ExcCompatibility("mapping"));
approximate_derivative<SecondDerivative<dim>,dim> (StaticMappingQ1<dim>::mapping,
- dof_handler,
- solution,
- component,
- derivative_norm);
+ dof_handler,
+ solution,
+ component,
+ derivative_norm);
}
void
DerivativeApproximation::
approximate_derivative_tensor (const Mapping<dim,spacedim> &mapping,
- const DH<dim,spacedim> &dof,
- const InputVector &solution,
- const typename DH<dim,spacedim>::active_cell_iterator &cell,
- Tensor<order,dim> &derivative,
- const unsigned int component)
+ const DH<dim,spacedim> &dof,
+ const InputVector &solution,
+ const typename DH<dim,spacedim>::active_cell_iterator &cell,
+ Tensor<order,dim> &derivative,
+ const unsigned int component)
{
approximate_cell<typename DerivativeSelector<order,dim>::DerivDescr,dim,DH,InputVector>
(mapping,
void
DerivativeApproximation::
approximate_derivative_tensor (const DH<dim,spacedim> &dof,
- const InputVector &solution,
- const typename DH<dim,spacedim>::active_cell_iterator &cell,
- Tensor<order,dim> &derivative,
- const unsigned int component)
+ const InputVector &solution,
+ const typename DH<dim,spacedim>::active_cell_iterator &cell,
+ Tensor<order,dim> &derivative,
+ const unsigned int component)
{
- // just call the respective function with Q1
- // mapping
+ // just call the respective function with Q1
+ // mapping
Assert (DEAL_II_COMPAT_MAPPING, ExcCompatibility("mapping"));
approximate_derivative_tensor (StaticMappingQ1<dim>::mapping,
- dof,
- solution,
- cell,
- derivative,
- component);
+ dof,
+ solution,
+ cell,
+ derivative,
+ component);
}
void
DerivativeApproximation::
approximate_derivative (const Mapping<dim,spacedim> &mapping,
- const DH<dim,spacedim> &dof_handler,
- const InputVector &solution,
- const unsigned int component,
- Vector<float> &derivative_norm)
+ const DH<dim,spacedim> &dof_handler,
+ const InputVector &solution,
+ const unsigned int component,
+ Vector<float> &derivative_norm)
{
Assert (derivative_norm.size() == dof_handler.get_tria().n_active_cells(),
- ExcInvalidVectorLength (derivative_norm.size(),
- dof_handler.get_tria().n_active_cells()));
+ ExcInvalidVectorLength (derivative_norm.size(),
+ dof_handler.get_tria().n_active_cells()));
Assert (component < dof_handler.get_fe().n_components(),
- ExcIndexRange (component, 0, dof_handler.get_fe().n_components()));
+ ExcIndexRange (component, 0, dof_handler.get_fe().n_components()));
const unsigned int n_threads = multithread_info.n_default_threads;
std::vector<IndexInterval> index_intervals
= Threads::split_interval (0, dof_handler.get_tria().n_active_cells(),
- n_threads);
+ n_threads);
typedef void (*FunPtr) (const Mapping<dim,spacedim> &,
const DH<dim,spacedim> &,
const IndexInterval &,
Vector<float> &);
FunPtr fun_ptr = &DerivativeApproximation::
- template approximate<DerivativeDescription,dim,
- DH,InputVector>;
+ template approximate<DerivativeDescription,dim,
+ DH,InputVector>;
//TODO: Use WorkStream here
Threads::TaskGroup<> tasks;
for (unsigned int i=0; i<n_threads; ++i)
tasks += Threads::new_task (fun_ptr,
- mapping, dof_handler,
- solution, component,
- index_intervals[i],
- derivative_norm);
+ mapping, dof_handler,
+ solution, component,
+ index_intervals[i],
+ derivative_norm);
tasks.join_all ();
}
template <int, int> class DH, class InputVector, int spacedim>
void
DerivativeApproximation::approximate (const Mapping<dim,spacedim> &mapping,
- const DH<dim,spacedim> &dof_handler,
- const InputVector &solution,
- const unsigned int component,
- const IndexInterval &index_interval,
- Vector<float> &derivative_norm)
+ const DH<dim,spacedim> &dof_handler,
+ const InputVector &solution,
+ const unsigned int component,
+ const IndexInterval &index_interval,
+ Vector<float> &derivative_norm)
{
- // iterators over all cells and the
- // respective entries in the output
- // vector:
+ // iterators over all cells and the
+ // respective entries in the output
+ // vector:
Vector<float>::iterator
derivative_norm_on_this_cell
= derivative_norm.begin() + index_interval.first;
typename DH<dim,spacedim>::active_cell_iterator cell, endc;
cell = endc = dof_handler.begin_active();
- // (static_cast to avoid warnings
- // about unsigned always >=0)
+ // (static_cast to avoid warnings
+ // about unsigned always >=0)
std::advance (cell, static_cast<int>(index_interval.first));
std::advance (endc, static_cast<int>(index_interval.second));
for (; cell!=endc; ++cell, ++derivative_norm_on_this_cell)
if (cell->is_locally_owned())
{
- typename DerivativeDescription::Derivative derivative;
- // call the function doing the actual
- // work on this cell
- DerivativeApproximation::
- template approximate_cell<DerivativeDescription,dim,DH,InputVector>
- (mapping,
- dof_handler,
- solution,
- component,
- cell,
- derivative);
- // evaluate the norm and fill the vector
- *derivative_norm_on_this_cell
- = DerivativeDescription::derivative_norm (derivative);
+ typename DerivativeDescription::Derivative derivative;
+ // call the function doing the actual
+ // work on this cell
+ DerivativeApproximation::
+ template approximate_cell<DerivativeDescription,dim,DH,InputVector>
+ (mapping,
+ dof_handler,
+ solution,
+ component,
+ cell,
+ derivative);
+ // evaluate the norm and fill the vector
+ *derivative_norm_on_this_cell
+ = DerivativeDescription::derivative_norm (derivative);
}
}
void
DerivativeApproximation::
approximate_cell (const Mapping<dim,spacedim> &mapping,
- const DH<dim,spacedim> &dof_handler,
- const InputVector &solution,
- const unsigned int component,
- const typename DH<dim,spacedim>::active_cell_iterator &cell,
- typename DerivativeDescription::Derivative &derivative)
+ const DH<dim,spacedim> &dof_handler,
+ const InputVector &solution,
+ const unsigned int component,
+ const typename DH<dim,spacedim>::active_cell_iterator &cell,
+ typename DerivativeDescription::Derivative &derivative)
{
QMidpoint<dim> midpoint_rule;
- // create collection objects from
- // single quadratures, mappings,
- // and finite elements. if we have
- // an hp DoFHandler,
- // dof_handler.get_fe() returns a
- // collection of which we do a
- // shallow copy instead
+ // create collection objects from
+ // single quadratures, mappings,
+ // and finite elements. if we have
+ // an hp DoFHandler,
+ // dof_handler.get_fe() returns a
+ // collection of which we do a
+ // shallow copy instead
const hp::QCollection<dim> q_collection (midpoint_rule);
const hp::FECollection<dim> fe_collection(dof_handler.get_fe());
const hp::MappingCollection<dim> mapping_collection (mapping);
hp::FEValues<dim> x_fe_midpoint_value (mapping_collection, fe_collection,
- q_collection,
- DerivativeDescription::update_flags |
- update_quadrature_points);
+ q_collection,
+ DerivativeDescription::update_flags |
+ update_quadrature_points);
- // matrix Y=sum_i y_i y_i^T
+ // matrix Y=sum_i y_i y_i^T
Tensor<2,dim> Y;
- // vector to hold iterators to all
- // active neighbors of a cell
- // reserve the maximal number of
- // active neighbors
+ // vector to hold iterators to all
+ // active neighbors of a cell
+ // reserve the maximal number of
+ // active neighbors
std::vector<typename DH<dim,spacedim>::active_cell_iterator> active_neighbors;
active_neighbors.reserve (GeometryInfo<dim>::faces_per_cell *
- GeometryInfo<dim>::max_children_per_face);
+ GeometryInfo<dim>::max_children_per_face);
- // vector
- // g=sum_i y_i (f(x+y_i)-f(x))/|y_i|
- // or related type for higher
- // derivatives
+ // vector
+ // g=sum_i y_i (f(x+y_i)-f(x))/|y_i|
+ // or related type for higher
+ // derivatives
typename DerivativeDescription::Derivative projected_derivative;
- // reinit fe values object...
+ // reinit fe values object...
x_fe_midpoint_value.reinit (cell);
const FEValues<dim> &fe_midpoint_value
= x_fe_midpoint_value.get_present_fe_values();
- // ...and get the value of the
- // projected derivative...
+ // ...and get the value of the
+ // projected derivative...
const typename DerivativeDescription::ProjectedDerivative
this_midpoint_value
= DerivativeDescription::get_projected_derivative (fe_midpoint_value,
- solution,
- component);
- // ...and the place where it lives
+ solution,
+ component);
+ // ...and the place where it lives
const Point<dim> this_center = fe_midpoint_value.quadrature_point(0);
- // loop over all neighbors and
- // accumulate the difference
- // quotients from them. note
- // that things get a bit more
- // complicated if the neighbor
- // is more refined than the
- // present one
- //
- // to make processing simpler,
- // first collect all neighbor
- // cells in a vector, and then
- // collect the data from them
+ // loop over all neighbors and
+ // accumulate the difference
+ // quotients from them. note
+ // that things get a bit more
+ // complicated if the neighbor
+ // is more refined than the
+ // present one
+ //
+ // to make processing simpler,
+ // first collect all neighbor
+ // cells in a vector, and then
+ // collect the data from them
GridTools::template get_active_neighbors<DH<dim,spacedim> >(cell, active_neighbors);
- // now loop over all active
- // neighbors and collect the
- // data we need
+ // now loop over all active
+ // neighbors and collect the
+ // data we need
typename std::vector<typename DH<dim,spacedim>::active_cell_iterator>::const_iterator
neighbor_ptr = active_neighbors.begin();
for (; neighbor_ptr!=active_neighbors.end(); ++neighbor_ptr)
{
const typename DH<dim,spacedim>::active_cell_iterator
- neighbor = *neighbor_ptr;
+ neighbor = *neighbor_ptr;
- // reinit fe values object...
+ // reinit fe values object...
x_fe_midpoint_value.reinit (neighbor);
const FEValues<dim> &fe_midpoint_value
- = x_fe_midpoint_value.get_present_fe_values();
+ = x_fe_midpoint_value.get_present_fe_values();
- // ...and get the value of the
- // solution...
+ // ...and get the value of the
+ // solution...
const typename DerivativeDescription::ProjectedDerivative
- neighbor_midpoint_value
- = DerivativeDescription::get_projected_derivative (fe_midpoint_value,
- solution, component);
+ neighbor_midpoint_value
+ = DerivativeDescription::get_projected_derivative (fe_midpoint_value,
+ solution, component);
- // ...and the place where it lives
+ // ...and the place where it lives
const Point<dim>
- neighbor_center = fe_midpoint_value.quadrature_point(0);
+ neighbor_center = fe_midpoint_value.quadrature_point(0);
- // vector for the
- // normalized
- // direction between
- // the centers of two
- // cells
+ // vector for the
+ // normalized
+ // direction between
+ // the centers of two
+ // cells
Point<dim> y = neighbor_center - this_center;
const double distance = std::sqrt(y.square());
- // normalize y
+ // normalize y
y /= distance;
- // *** note that unlike in
- // the docs, y denotes the
- // normalized vector
- // connecting the centers
- // of the two cells, rather
- // than the normal
- // difference! ***
-
- // add up the
- // contribution of
- // this cell to Y
+ // *** note that unlike in
+ // the docs, y denotes the
+ // normalized vector
+ // connecting the centers
+ // of the two cells, rather
+ // than the normal
+ // difference! ***
+
+ // add up the
+ // contribution of
+ // this cell to Y
for (unsigned int i=0; i<dim; ++i)
- for (unsigned int j=0; j<dim; ++j)
- Y[i][j] += y[i] * y[j];
+ for (unsigned int j=0; j<dim; ++j)
+ Y[i][j] += y[i] * y[j];
- // then update the sum
- // of difference
- // quotients
+ // then update the sum
+ // of difference
+ // quotients
typename DerivativeDescription::ProjectedDerivative
- projected_finite_difference
- = (neighbor_midpoint_value -
- this_midpoint_value);
+ projected_finite_difference
+ = (neighbor_midpoint_value -
+ this_midpoint_value);
projected_finite_difference /= distance;
typename DerivativeDescription::Derivative projected_derivative_update;
outer_product (projected_derivative_update,
- y,
- projected_finite_difference);
+ y,
+ projected_finite_difference);
projected_derivative += projected_derivative_update;
};
- // can we determine an
- // approximation of the
- // gradient for the present
- // cell? if so, then we need to
- // have passed over vectors y_i
- // which span the whole space,
- // otherwise we would not have
- // all components of the
- // gradient
+ // can we determine an
+ // approximation of the
+ // gradient for the present
+ // cell? if so, then we need to
+ // have passed over vectors y_i
+ // which span the whole space,
+ // otherwise we would not have
+ // all components of the
+ // gradient
AssertThrow (determinant(Y) != 0,
- ExcInsufficientDirections());
+ ExcInsufficientDirections());
// compute Y^-1 g
const Tensor<2,dim> Y_inverse = invert(Y);
contract (derivative, Y_inverse, projected_derivative);
- // finally symmetrize the derivative
+ // finally symmetrize the derivative
DerivativeDescription::symmetrize (derivative);
}
// $Id$
// Version: $Name$
//
-// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 by the deal.II authors
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
template <typename CellIterator>
inline
void advance_by_n (CellIterator &cell,
- const unsigned int n)
+ const unsigned int n)
{
- // store a pointer to the end
- // iterator, since we can't get at
- // it any more once cell is already
- // the end iterator (in that case
- // dereferencing cell-> triggers an
- // assertion)
+ // store a pointer to the end
+ // iterator, since we can't get at
+ // it any more once cell is already
+ // the end iterator (in that case
+ // dereferencing cell-> triggers an
+ // assertion)
const CellIterator endc = cell->get_dof_handler().end();
for (unsigned int t=0; ((t<n) && (cell!=endc)); ++t, ++cell)
;
{
namespace
{
- /**
- * All small temporary data
- * objects that are needed once
- * per thread by the several
- * functions of the error
- * estimator are gathered in this
- * struct. The reason for this
- * structure is mainly that we
- * have a number of functions
- * that operate on cells or faces
- * and need a number of small
- * temporary data objects. Since
- * these functions may run in
- * parallel, we cannot make these
- * objects member variables of
- * the enclosing class. On the
- * other hand, declaring them
- * locally in each of these
- * functions would require their
- * reallocating every time we
- * visit the next cell or face,
- * which we found can take a
- * significant amount of time if
- * it happens often even in the
- * single threaded case (10-20
- * per cent in our measurements);
- * however, most importantly,
- * memory allocation requires
- * synchronisation in
- * multithreaded mode. While that
- * is done by the C++ library and
- * has not to be handcoded, it
- * nevertheless seriously damages
- * the ability to efficiently run
- * the functions of this class in
- * parallel, since they are quite
- * often blocked by these
- * synchronisation points,
- * slowing everything down by a
- * factor of two or three.
- *
- * Thus, every thread gets an
- * instance of this class to work
- * with and needs not allocate
- * memory itself, or synchronise
- * with other threads.
- *
- * The sizes of the arrays are
- * initialized with the maximal number of
- * entries necessary for the hp
- * case. Within the loop over individual
- * cells, we then resize the arrays as
- * necessary. Since for std::vector
- * resizing to a smaller size doesn't
- * imply memory allocation, this is fast.
- */
+ /**
+ * All small temporary data
+ * objects that are needed once
+ * per thread by the several
+ * functions of the error
+ * estimator are gathered in this
+ * struct. The reason for this
+ * structure is mainly that we
+ * have a number of functions
+ * that operate on cells or faces
+ * and need a number of small
+ * temporary data objects. Since
+ * these functions may run in
+ * parallel, we cannot make these
+ * objects member variables of
+ * the enclosing class. On the
+ * other hand, declaring them
+ * locally in each of these
+ * functions would require their
+ * reallocating every time we
+ * visit the next cell or face,
+ * which we found can take a
+ * significant amount of time if
+ * it happens often even in the
+ * single threaded case (10-20
+ * per cent in our measurements);
+ * however, most importantly,
+ * memory allocation requires
+ * synchronisation in
+ * multithreaded mode. While that
+ * is done by the C++ library and
+ * has not to be handcoded, it
+ * nevertheless seriously damages
+ * the ability to efficiently run
+ * the functions of this class in
+ * parallel, since they are quite
+ * often blocked by these
+ * synchronisation points,
+ * slowing everything down by a
+ * factor of two or three.
+ *
+ * Thus, every thread gets an
+ * instance of this class to work
+ * with and needs not allocate
+ * memory itself, or synchronise
+ * with other threads.
+ *
+ * The sizes of the arrays are
+ * initialized with the maximal number of
+ * entries necessary for the hp
+ * case. Within the loop over individual
+ * cells, we then resize the arrays as
+ * necessary. Since for std::vector
+ * resizing to a smaller size doesn't
+ * imply memory allocation, this is fast.
+ */
template <class DH>
struct ParallelData
{
- static const unsigned int dim = DH::dimension;
- static const unsigned int spacedim = DH::space_dimension;
-
- /**
- * The finite element to be used.
- */
- const dealii::hp::FECollection<dim,spacedim> finite_element;
-
- /**
- * The quadrature formulas to be used for
- * the faces.
- */
- const dealii::hp::QCollection<dim-1> face_quadratures;
-
- /**
- * FEFaceValues objects to integrate over
- * the faces of the current and
- * potentially of neighbor cells.
- */
- dealii::hp::FEFaceValues<dim,spacedim> fe_face_values_cell;
- dealii::hp::FEFaceValues<dim,spacedim> fe_face_values_neighbor;
- dealii::hp::FESubfaceValues<dim,spacedim> fe_subface_values;
-
- /**
- * A vector to store the jump
- * of the normal vectors in
- * the quadrature points for
- * each of the solution
- * vectors (i.e. a temporary
- * value). This vector is not
- * allocated inside the
- * functions that use it, but
- * rather globally, since
- * memory allocation is slow,
- * in particular in presence
- * of multiple threads where
- * synchronisation makes
- * things even slower.
- */
- std::vector<std::vector<std::vector<double> > > phi;
-
- /**
- * A vector for the gradients of
- * the finite element function
- * on one cell
- *
- * Let psi be a short name
- * for <tt>a grad u_h</tt>, where
- * the third index be the
- * component of the finite
- * element, and the second
- * index the number of the
- * quadrature point. The
- * first index denotes the
- * index of the solution
- * vector.
- */
- std::vector<std::vector<std::vector<Tensor<1,spacedim> > > > psi;
-
- /**
- * The same vector for a neighbor cell
- */
- std::vector<std::vector<std::vector<Tensor<1,spacedim> > > > neighbor_psi;
-
- /**
- * The normal vectors of the finite
- * element function on one face
- */
- std::vector<Point<spacedim> > normal_vectors;
-
- /**
- * Two arrays needed for the
- * values of coefficients in
- * the jumps, if they are
- * given.
- */
- std::vector<double> coefficient_values1;
- std::vector<dealii::Vector<double> > coefficient_values;
-
- /**
- * Array for the products of
- * Jacobian determinants and
- * weights of quadraturs
- * points.
- */
- std::vector<double> JxW_values;
-
- /**
- * The subdomain id we are to care
- * for.
- */
- const types::subdomain_id_t subdomain_id;
- /**
- * The material id we are to care
- * for.
- */
- const types::material_id_t material_id;
-
- /**
- * Some more references to input data to
- * the KellyErrorEstimator::estimate()
- * function.
- */
- const typename FunctionMap<spacedim>::type *neumann_bc;
- const std::vector<bool> component_mask;
- const Function<spacedim> *coefficients;
-
- /**
- * Constructor.
- */
- template <class FE>
- ParallelData (const FE &fe,
- const dealii::hp::QCollection<DH::dimension-1> &face_quadratures,
- const dealii::hp::MappingCollection<DH::dimension, DH::space_dimension> &mapping,
- const bool need_quadrature_points,
- const unsigned int n_solution_vectors,
- const types::subdomain_id_t subdomain_id,
- const types::material_id_t material_id,
- const typename FunctionMap<spacedim>::type *neumann_bc,
- const std::vector<bool> component_mask,
- const Function<spacedim> *coefficients);
-
- /**
- * Resize the arrays so that they fit the
- * number of quadrature points associated
- * with the given finite element index
- * into the hp collections.
- */
- void resize (const unsigned int active_fe_index);
+ static const unsigned int dim = DH::dimension;
+ static const unsigned int spacedim = DH::space_dimension;
+
+ /**
+ * The finite element to be used.
+ */
+ const dealii::hp::FECollection<dim,spacedim> finite_element;
+
+ /**
+ * The quadrature formulas to be used for
+ * the faces.
+ */
+ const dealii::hp::QCollection<dim-1> face_quadratures;
+
+ /**
+ * FEFaceValues objects to integrate over
+ * the faces of the current and
+ * potentially of neighbor cells.
+ */
+ dealii::hp::FEFaceValues<dim,spacedim> fe_face_values_cell;
+ dealii::hp::FEFaceValues<dim,spacedim> fe_face_values_neighbor;
+ dealii::hp::FESubfaceValues<dim,spacedim> fe_subface_values;
+
+ /**
+ * A vector to store the jump
+ * of the normal vectors in
+ * the quadrature points for
+ * each of the solution
+ * vectors (i.e. a temporary
+ * value). This vector is not
+ * allocated inside the
+ * functions that use it, but
+ * rather globally, since
+ * memory allocation is slow,
+ * in particular in presence
+ * of multiple threads where
+ * synchronisation makes
+ * things even slower.
+ */
+ std::vector<std::vector<std::vector<double> > > phi;
+
+ /**
+ * A vector for the gradients of
+ * the finite element function
+ * on one cell
+ *
+ * Let psi be a short name
+ * for <tt>a grad u_h</tt>, where
+ * the third index be the
+ * component of the finite
+ * element, and the second
+ * index the number of the
+ * quadrature point. The
+ * first index denotes the
+ * index of the solution
+ * vector.
+ */
+ std::vector<std::vector<std::vector<Tensor<1,spacedim> > > > psi;
+
+ /**
+ * The same vector for a neighbor cell
+ */
+ std::vector<std::vector<std::vector<Tensor<1,spacedim> > > > neighbor_psi;
+
+ /**
+ * The normal vectors of the finite
+ * element function on one face
+ */
+ std::vector<Point<spacedim> > normal_vectors;
+
+ /**
+ * Two arrays needed for the
+ * values of coefficients in
+ * the jumps, if they are
+ * given.
+ */
+ std::vector<double> coefficient_values1;
+ std::vector<dealii::Vector<double> > coefficient_values;
+
+ /**
+ * Array for the products of
+ * Jacobian determinants and
+ * weights of quadraturs
+ * points.
+ */
+ std::vector<double> JxW_values;
+
+ /**
+ * The subdomain id we are to care
+ * for.
+ */
+ const types::subdomain_id_t subdomain_id;
+ /**
+ * The material id we are to care
+ * for.
+ */
+ const types::material_id_t material_id;
+
+ /**
+ * Some more references to input data to
+ * the KellyErrorEstimator::estimate()
+ * function.
+ */
+ const typename FunctionMap<spacedim>::type *neumann_bc;
+ const std::vector<bool> component_mask;
+ const Function<spacedim> *coefficients;
+
+ /**
+ * Constructor.
+ */
+ template <class FE>
+ ParallelData (const FE &fe,
+ const dealii::hp::QCollection<DH::dimension-1> &face_quadratures,
+ const dealii::hp::MappingCollection<DH::dimension, DH::space_dimension> &mapping,
+ const bool need_quadrature_points,
+ const unsigned int n_solution_vectors,
+ const types::subdomain_id_t subdomain_id,
+ const types::material_id_t material_id,
+ const typename FunctionMap<spacedim>::type *neumann_bc,
+ const std::vector<bool> component_mask,
+ const Function<spacedim> *coefficients);
+
+ /**
+ * Resize the arrays so that they fit the
+ * number of quadrature points associated
+ * with the given finite element index
+ * into the hp collections.
+ */
+ void resize (const unsigned int active_fe_index);
};
template <class FE>
ParallelData<DH>::
ParallelData (const FE &fe,
- const dealii::hp::QCollection<DH::dimension-1> &face_quadratures,
- const dealii::hp::MappingCollection<DH::dimension, DH::space_dimension> &mapping,
- const bool need_quadrature_points,
- const unsigned int n_solution_vectors,
- const types::subdomain_id_t subdomain_id,
- const types::material_id_t material_id,
- const typename FunctionMap<spacedim>::type *neumann_bc,
- const std::vector<bool> component_mask,
- const Function<spacedim> *coefficients)
- :
- finite_element (fe),
- face_quadratures (face_quadratures),
- fe_face_values_cell (mapping,
- finite_element,
- face_quadratures,
- update_gradients |
- update_JxW_values |
- (need_quadrature_points ?
- update_quadrature_points :
- UpdateFlags()) |
- update_normal_vectors),
- fe_face_values_neighbor (mapping,
- finite_element,
- face_quadratures,
- update_gradients),
- fe_subface_values (mapping,
- finite_element,
- face_quadratures,
- update_gradients),
- phi (n_solution_vectors,
- std::vector<std::vector<double> >
- (face_quadratures.max_n_quadrature_points(),
- std::vector<double> (fe.n_components()))),
- psi (n_solution_vectors,
- std::vector<std::vector<Tensor<1,spacedim> > >
- (face_quadratures.max_n_quadrature_points(),
- std::vector<Tensor<1,spacedim> > (fe.n_components()))),
- neighbor_psi (n_solution_vectors,
- std::vector<std::vector<Tensor<1,spacedim> > >
- (face_quadratures.max_n_quadrature_points(),
- std::vector<Tensor<1,spacedim> > (fe.n_components()))),
- normal_vectors (face_quadratures.max_n_quadrature_points()),
- coefficient_values1 (face_quadratures.max_n_quadrature_points()),
- coefficient_values (face_quadratures.max_n_quadrature_points(),
- dealii::Vector<double> (fe.n_components())),
- JxW_values (face_quadratures.max_n_quadrature_points()),
- subdomain_id (subdomain_id),
- material_id (material_id),
- neumann_bc (neumann_bc),
- component_mask (component_mask),
- coefficients (coefficients)
+ const dealii::hp::QCollection<DH::dimension-1> &face_quadratures,
+ const dealii::hp::MappingCollection<DH::dimension, DH::space_dimension> &mapping,
+ const bool need_quadrature_points,
+ const unsigned int n_solution_vectors,
+ const types::subdomain_id_t subdomain_id,
+ const types::material_id_t material_id,
+ const typename FunctionMap<spacedim>::type *neumann_bc,
+ const std::vector<bool> component_mask,
+ const Function<spacedim> *coefficients)
+ :
+ finite_element (fe),
+ face_quadratures (face_quadratures),
+ fe_face_values_cell (mapping,
+ finite_element,
+ face_quadratures,
+ update_gradients |
+ update_JxW_values |
+ (need_quadrature_points ?
+ update_quadrature_points :
+ UpdateFlags()) |
+ update_normal_vectors),
+ fe_face_values_neighbor (mapping,
+ finite_element,
+ face_quadratures,
+ update_gradients),
+ fe_subface_values (mapping,
+ finite_element,
+ face_quadratures,
+ update_gradients),
+ phi (n_solution_vectors,
+ std::vector<std::vector<double> >
+ (face_quadratures.max_n_quadrature_points(),
+ std::vector<double> (fe.n_components()))),
+ psi (n_solution_vectors,
+ std::vector<std::vector<Tensor<1,spacedim> > >
+ (face_quadratures.max_n_quadrature_points(),
+ std::vector<Tensor<1,spacedim> > (fe.n_components()))),
+ neighbor_psi (n_solution_vectors,
+ std::vector<std::vector<Tensor<1,spacedim> > >
+ (face_quadratures.max_n_quadrature_points(),
+ std::vector<Tensor<1,spacedim> > (fe.n_components()))),
+ normal_vectors (face_quadratures.max_n_quadrature_points()),
+ coefficient_values1 (face_quadratures.max_n_quadrature_points()),
+ coefficient_values (face_quadratures.max_n_quadrature_points(),
+ dealii::Vector<double> (fe.n_components())),
+ JxW_values (face_quadratures.max_n_quadrature_points()),
+ subdomain_id (subdomain_id),
+ material_id (material_id),
+ neumann_bc (neumann_bc),
+ component_mask (component_mask),
+ coefficients (coefficients)
{}
JxW_values.resize(n_q_points);
for (unsigned int i=0; i<phi.size(); ++i)
- {
- phi[i].resize(n_q_points);
- psi[i].resize(n_q_points);
- neighbor_psi[i].resize(n_q_points);
-
- for (unsigned int qp=0;qp<n_q_points;++qp)
- {
- phi[i][qp].resize(n_components);
- psi[i][qp].resize(n_components);
- neighbor_psi[i][qp].resize(n_components);
- }
- }
+ {
+ phi[i].resize(n_q_points);
+ psi[i].resize(n_q_points);
+ neighbor_psi[i].resize(n_q_points);
+
+ for (unsigned int qp=0;qp<n_q_points;++qp)
+ {
+ phi[i][qp].resize(n_components);
+ psi[i][qp].resize(n_components);
+ neighbor_psi[i][qp].resize(n_components);
+ }
+ }
for (unsigned int qp=0; qp<n_q_points; ++qp)
- coefficient_values[qp].reinit(n_components);
+ coefficient_values[qp].reinit(n_components);
}
- /**
- * Copy data from the
- * local_face_integrals map of a single
- * ParallelData object into a global such
- * map. This is the copier stage of a
- * WorkStream pipeline.
- */
+ /**
+ * Copy data from the
+ * local_face_integrals map of a single
+ * ParallelData object into a global such
+ * map. This is the copier stage of a
+ * WorkStream pipeline.
+ */
template <class DH>
void
- copy_local_to_global (const std::map<typename DH::face_iterator,std::vector<double> > &local_face_integrals,
- std::map<typename DH::face_iterator,std::vector<double> > &face_integrals)
+ copy_local_to_global (const std::map<typename DH::face_iterator,std::vector<double> > &local_face_integrals,
+ std::map<typename DH::face_iterator,std::vector<double> > &face_integrals)
{
- // now copy locally computed elements
- // into the global map
+ // now copy locally computed elements
+ // into the global map
for (typename std::map<typename DH::face_iterator,std::vector<double> >::const_iterator
- p=local_face_integrals.begin();
- p!=local_face_integrals.end();
- ++p)
- {
- // double check that the
- // element does not already
- // exists in the global map
- Assert (face_integrals.find (p->first) == face_integrals.end(),
- ExcInternalError());
-
- for (unsigned int i=0; i<p->second.size(); ++i)
- {
- Assert (numbers::is_finite(p->second[i]), ExcInternalError());
- Assert (p->second[i] >= 0, ExcInternalError());
- }
-
- face_integrals[p->first] = p->second;
- }
+ p=local_face_integrals.begin();
+ p!=local_face_integrals.end();
+ ++p)
+ {
+ // double check that the
+ // element does not already
+ // exists in the global map
+ Assert (face_integrals.find (p->first) == face_integrals.end(),
+ ExcInternalError());
+
+ for (unsigned int i=0; i<p->second.size(); ++i)
+ {
+ Assert (numbers::is_finite(p->second[i]), ExcInternalError());
+ Assert (p->second[i] >= 0, ExcInternalError());
+ }
+
+ face_integrals[p->first] = p->second;
+ }
}
- /**
- * Actually do the computation on
- * a face which has no hanging
- * nodes (it is regular), i.e.
- * either on the other side there
- * is nirvana (face is at
- * boundary), or the other side's
- * refinement level is the same
- * as that of this side, then
- * handle the integration of
- * these both cases together.
- */
+ /**
+ * Actually do the computation on
+ * a face which has no hanging
+ * nodes (it is regular), i.e.
+ * either on the other side there
+ * is nirvana (face is at
+ * boundary), or the other side's
+ * refinement level is the same
+ * as that of this side, then
+ * handle the integration of
+ * these both cases together.
+ */
template <typename InputVector, class DH>
void
integrate_over_regular_face (const std::vector<const InputVector*> &solutions,
- ParallelData<DH> ¶llel_data,
- std::map<typename DH::face_iterator,std::vector<double> > &local_face_integrals,
- const typename DH::active_cell_iterator &cell,
- const unsigned int face_no,
- dealii::hp::FEFaceValues<DH::dimension, DH::space_dimension> &fe_face_values_cell,
- dealii::hp::FEFaceValues<DH::dimension, DH::space_dimension> &fe_face_values_neighbor)
+ ParallelData<DH> ¶llel_data,
+ std::map<typename DH::face_iterator,std::vector<double> > &local_face_integrals,
+ const typename DH::active_cell_iterator &cell,
+ const unsigned int face_no,
+ dealii::hp::FEFaceValues<DH::dimension, DH::space_dimension> &fe_face_values_cell,
+ dealii::hp::FEFaceValues<DH::dimension, DH::space_dimension> &fe_face_values_neighbor)
{
const unsigned int dim = DH::dimension;
const typename DH::face_iterator face = cell->face(face_no);
const unsigned int n_q_points = parallel_data.face_quadratures[cell->active_fe_index()].size(),
- n_components = parallel_data.finite_element.n_components(),
- n_solution_vectors = solutions.size();
+ n_components = parallel_data.finite_element.n_components(),
+ n_solution_vectors = solutions.size();
- // initialize data of the restriction
- // of this cell to the present face
+ // initialize data of the restriction
+ // of this cell to the present face
fe_face_values_cell.reinit (cell, face_no,
- cell->active_fe_index());
+ cell->active_fe_index());
- // get gradients of the finite element
- // function on this cell
+ // get gradients of the finite element
+ // function on this cell
for (unsigned int n=0; n<n_solution_vectors; ++n)
- fe_face_values_cell.get_present_fe_values()
- .get_function_grads (*solutions[n], parallel_data.psi[n]);
+ fe_face_values_cell.get_present_fe_values()
+ .get_function_grads (*solutions[n], parallel_data.psi[n]);
- // now compute over the other side of
- // the face
+ // now compute over the other side of
+ // the face
if (face->at_boundary() == false)
- // internal face; integrate jump
- // of gradient across this face
- {
- Assert (cell->neighbor(face_no).state() == IteratorState::valid,
- ExcInternalError());
-
- const typename DH::active_cell_iterator neighbor = cell->neighbor(face_no);
-
- // find which number the
- // current face has relative to
- // the neighboring cell
- const unsigned int neighbor_neighbor
- = cell->neighbor_of_neighbor (face_no);
- Assert (neighbor_neighbor<GeometryInfo<dim>::faces_per_cell,
- ExcInternalError());
-
- // get restriction of finite element
- // function of @p{neighbor} to the
- // common face. in the hp case, use the
- // quadrature formula that matches the
- // one we would use for the present
- // cell
- fe_face_values_neighbor.reinit (neighbor, neighbor_neighbor,
- cell->active_fe_index());
-
- // get gradients on neighbor cell
- for (unsigned int n=0; n<n_solution_vectors; ++n)
- {
- fe_face_values_neighbor.get_present_fe_values()
- .get_function_grads (*solutions[n],
- parallel_data.neighbor_psi[n]);
-
- // compute the jump in the gradients
- for (unsigned int component=0; component<n_components; ++component)
- for (unsigned int p=0; p<n_q_points; ++p)
- parallel_data.psi[n][p][component] -= parallel_data.neighbor_psi[n][p][component];
- }
- }
-
-
- // now psi contains the following:
- // - for an internal face, psi=[grad u]
- // - for a neumann boundary face,
- // psi=grad u
- // each component being the
- // mentioned value at one of the
- // quadrature points
-
- // next we have to multiply this with
- // the normal vector. Since we have
- // taken the difference of gradients
- // for internal faces, we may chose
- // the normal vector of one cell,
- // taking that of the neighbor
- // would only change the sign. We take
- // the outward normal.
+ // internal face; integrate jump
+ // of gradient across this face
+ {
+ Assert (cell->neighbor(face_no).state() == IteratorState::valid,
+ ExcInternalError());
+
+ const typename DH::active_cell_iterator neighbor = cell->neighbor(face_no);
+
+ // find which number the
+ // current face has relative to
+ // the neighboring cell
+ const unsigned int neighbor_neighbor
+ = cell->neighbor_of_neighbor (face_no);
+ Assert (neighbor_neighbor<GeometryInfo<dim>::faces_per_cell,
+ ExcInternalError());
+
+ // get restriction of finite element
+ // function of @p{neighbor} to the
+ // common face. in the hp case, use the
+ // quadrature formula that matches the
+ // one we would use for the present
+ // cell
+ fe_face_values_neighbor.reinit (neighbor, neighbor_neighbor,
+ cell->active_fe_index());
+
+ // get gradients on neighbor cell
+ for (unsigned int n=0; n<n_solution_vectors; ++n)
+ {
+ fe_face_values_neighbor.get_present_fe_values()
+ .get_function_grads (*solutions[n],
+ parallel_data.neighbor_psi[n]);
+
+ // compute the jump in the gradients
+ for (unsigned int component=0; component<n_components; ++component)
+ for (unsigned int p=0; p<n_q_points; ++p)
+ parallel_data.psi[n][p][component] -= parallel_data.neighbor_psi[n][p][component];
+ }
+ }
+
+
+ // now psi contains the following:
+ // - for an internal face, psi=[grad u]
+ // - for a neumann boundary face,
+ // psi=grad u
+ // each component being the
+ // mentioned value at one of the
+ // quadrature points
+
+ // next we have to multiply this with
+ // the normal vector. Since we have
+ // taken the difference of gradients
+ // for internal faces, we may chose
+ // the normal vector of one cell,
+ // taking that of the neighbor
+ // would only change the sign. We take
+ // the outward normal.
parallel_data.normal_vectors =
- fe_face_values_cell.get_present_fe_values().get_normal_vectors();
+ fe_face_values_cell.get_present_fe_values().get_normal_vectors();
for (unsigned int n=0; n<n_solution_vectors; ++n)
- for (unsigned int component=0; component<n_components; ++component)
- for (unsigned int point=0; point<n_q_points; ++point)
- parallel_data.phi[n][point][component]
- = (parallel_data.psi[n][point][component] *
- parallel_data.normal_vectors[point]);
-
- // if a coefficient was given: use that
- // to scale the jump in the gradient
+ for (unsigned int component=0; component<n_components; ++component)
+ for (unsigned int point=0; point<n_q_points; ++point)
+ parallel_data.phi[n][point][component]
+ = (parallel_data.psi[n][point][component] *
+ parallel_data.normal_vectors[point]);
+
+ // if a coefficient was given: use that
+ // to scale the jump in the gradient
if (parallel_data.coefficients != 0)
- {
- // scalar coefficient
- if (parallel_data.coefficients->n_components == 1)
- {
-
- parallel_data.coefficients
- ->value_list (fe_face_values_cell.get_present_fe_values()
- .get_quadrature_points(),
- parallel_data.coefficient_values1);
- for (unsigned int n=0; n<n_solution_vectors; ++n)
- for (unsigned int component=0; component<n_components; ++component)
- for (unsigned int point=0; point<n_q_points; ++point)
- parallel_data.phi[n][point][component] *=
- parallel_data.coefficient_values1[point];
- }
- else
- // vector-valued coefficient
- {
- parallel_data.coefficients
- ->vector_value_list (fe_face_values_cell.get_present_fe_values()
- .get_quadrature_points(),
- parallel_data.coefficient_values);
- for (unsigned int n=0; n<n_solution_vectors; ++n)
- for (unsigned int component=0; component<n_components; ++component)
- for (unsigned int point=0; point<n_q_points; ++point)
- parallel_data.phi[n][point][component] *=
- parallel_data.coefficient_values[point](component);
- }
- }
+ {
+ // scalar coefficient
+ if (parallel_data.coefficients->n_components == 1)
+ {
+
+ parallel_data.coefficients
+ ->value_list (fe_face_values_cell.get_present_fe_values()
+ .get_quadrature_points(),
+ parallel_data.coefficient_values1);
+ for (unsigned int n=0; n<n_solution_vectors; ++n)
+ for (unsigned int component=0; component<n_components; ++component)
+ for (unsigned int point=0; point<n_q_points; ++point)
+ parallel_data.phi[n][point][component] *=
+ parallel_data.coefficient_values1[point];
+ }
+ else
+ // vector-valued coefficient
+ {
+ parallel_data.coefficients
+ ->vector_value_list (fe_face_values_cell.get_present_fe_values()
+ .get_quadrature_points(),
+ parallel_data.coefficient_values);
+ for (unsigned int n=0; n<n_solution_vectors; ++n)
+ for (unsigned int component=0; component<n_components; ++component)
+ for (unsigned int point=0; point<n_q_points; ++point)
+ parallel_data.phi[n][point][component] *=
+ parallel_data.coefficient_values[point](component);
+ }
+ }
if (face->at_boundary() == true)
- // neumann boundary face. compute
- // difference between normal
- // derivative and boundary function
- {
- const types::boundary_id_t boundary_indicator = face->boundary_indicator();
-
- Assert (parallel_data.neumann_bc->find(boundary_indicator) !=
- parallel_data.neumann_bc->end(),
- ExcInternalError ());
- // get the values of the boundary
- // function at the quadrature
- // points
- if (n_components == 1)
- {
- std::vector<double> g(n_q_points);
- parallel_data.neumann_bc->find(boundary_indicator)->second
- ->value_list (fe_face_values_cell.get_present_fe_values()
- .get_quadrature_points(), g);
-
- for (unsigned int n=0; n<n_solution_vectors; ++n)
- for (unsigned int point=0; point<n_q_points; ++point)
- parallel_data.phi[n][point][0] -= g[point];
- }
- else
- {
- std::vector<dealii::Vector<double> >
- g(n_q_points, dealii::Vector<double>(n_components));
- parallel_data.neumann_bc->find(boundary_indicator)->second
- ->vector_value_list (fe_face_values_cell.get_present_fe_values()
- .get_quadrature_points(),
- g);
-
- for (unsigned int n=0; n<n_solution_vectors; ++n)
- for (unsigned int component=0; component<n_components; ++component)
- for (unsigned int point=0; point<n_q_points; ++point)
- parallel_data.phi[n][point][component] -= g[point](component);
- }
- }
-
-
- // now phi contains the following:
- // - for an internal face, phi=[a du/dn]
- // - for a neumann boundary face,
- // phi=a du/dn-g
- // each component being the
- // mentioned value at one of the
- // quadrature points
+ // neumann boundary face. compute
+ // difference between normal
+ // derivative and boundary function
+ {
+ const types::boundary_id_t boundary_indicator = face->boundary_indicator();
+
+ Assert (parallel_data.neumann_bc->find(boundary_indicator) !=
+ parallel_data.neumann_bc->end(),
+ ExcInternalError ());
+ // get the values of the boundary
+ // function at the quadrature
+ // points
+ if (n_components == 1)
+ {
+ std::vector<double> g(n_q_points);
+ parallel_data.neumann_bc->find(boundary_indicator)->second
+ ->value_list (fe_face_values_cell.get_present_fe_values()
+ .get_quadrature_points(), g);
+
+ for (unsigned int n=0; n<n_solution_vectors; ++n)
+ for (unsigned int point=0; point<n_q_points; ++point)
+ parallel_data.phi[n][point][0] -= g[point];
+ }
+ else
+ {
+ std::vector<dealii::Vector<double> >
+ g(n_q_points, dealii::Vector<double>(n_components));
+ parallel_data.neumann_bc->find(boundary_indicator)->second
+ ->vector_value_list (fe_face_values_cell.get_present_fe_values()
+ .get_quadrature_points(),
+ g);
+
+ for (unsigned int n=0; n<n_solution_vectors; ++n)
+ for (unsigned int component=0; component<n_components; ++component)
+ for (unsigned int point=0; point<n_q_points; ++point)
+ parallel_data.phi[n][point][component] -= g[point](component);
+ }
+ }
+
+
+ // now phi contains the following:
+ // - for an internal face, phi=[a du/dn]
+ // - for a neumann boundary face,
+ // phi=a du/dn-g
+ // each component being the
+ // mentioned value at one of the
+ // quadrature points
parallel_data.JxW_values
- = fe_face_values_cell.get_present_fe_values().get_JxW_values();
+ = fe_face_values_cell.get_present_fe_values().get_JxW_values();
- // take the square of the phi[i]
- // for integration, and sum up
+ // take the square of the phi[i]
+ // for integration, and sum up
std::vector<double> face_integral (n_solution_vectors, 0);
for (unsigned int n=0; n<n_solution_vectors; ++n)
- for (unsigned int component=0; component<n_components; ++component)
- if (parallel_data.component_mask[component] == true)
- for (unsigned int p=0; p<n_q_points; ++p)
- face_integral[n] += dealii::sqr(parallel_data.phi[n][p][component]) *
- parallel_data.JxW_values[p];
+ for (unsigned int component=0; component<n_components; ++component)
+ if (parallel_data.component_mask[component] == true)
+ for (unsigned int p=0; p<n_q_points; ++p)
+ face_integral[n] += dealii::sqr(parallel_data.phi[n][p][component]) *
+ parallel_data.JxW_values[p];
local_face_integrals[face] = face_integral;
}
- /**
- * The same applies as for the
- * function above, except that
- * integration is over face
- * @p face_no of @p cell, where
- * the respective neighbor is
- * refined, so that the
- * integration is a bit more
- * complex.
- */
+ /**
+ * The same applies as for the
+ * function above, except that
+ * integration is over face
+ * @p face_no of @p cell, where
+ * the respective neighbor is
+ * refined, so that the
+ * integration is a bit more
+ * complex.
+ */
template <typename InputVector, class DH>
void
integrate_over_irregular_face (const std::vector<const InputVector*> &solutions,
- ParallelData<DH> ¶llel_data,
- std::map<typename DH::face_iterator,std::vector<double> > &local_face_integrals,
- const typename DH::active_cell_iterator &cell,
- const unsigned int face_no,
- dealii::hp::FEFaceValues<DH::dimension,DH::space_dimension> &fe_face_values,
- dealii::hp::FESubfaceValues<DH::dimension, DH::space_dimension> &fe_subface_values)
+ ParallelData<DH> ¶llel_data,
+ std::map<typename DH::face_iterator,std::vector<double> > &local_face_integrals,
+ const typename DH::active_cell_iterator &cell,
+ const unsigned int face_no,
+ dealii::hp::FEFaceValues<DH::dimension,DH::space_dimension> &fe_face_values,
+ dealii::hp::FESubfaceValues<DH::dimension, DH::space_dimension> &fe_subface_values)
{
const unsigned int dim = DH::dimension;
const typename DH::cell_iterator neighbor = cell->neighbor(face_no);
const unsigned int n_q_points = parallel_data.face_quadratures[cell->active_fe_index()].size(),
- n_components = parallel_data.finite_element.n_components(),
- n_solution_vectors = solutions.size();
+ n_components = parallel_data.finite_element.n_components(),
+ n_solution_vectors = solutions.size();
const typename DH::face_iterator
- face=cell->face(face_no);
+ face=cell->face(face_no);
Assert (neighbor.state() == IteratorState::valid, ExcInternalError());
Assert (face->has_children(), ExcInternalError());
- // set up a vector of the gradients
- // of the finite element function
- // on this cell at the quadrature
- // points
- //
- // let psi be a short name for
- // [a grad u_h], where the second
- // index be the component of the
- // finite element, and the first
- // index the number of the
- // quadrature point
-
- // store which number @p{cell} has
- // in the list of neighbors of
- // @p{neighbor}
+ // set up a vector of the gradients
+ // of the finite element function
+ // on this cell at the quadrature
+ // points
+ //
+ // let psi be a short name for
+ // [a grad u_h], where the second
+ // index be the component of the
+ // finite element, and the first
+ // index the number of the
+ // quadrature point
+
+ // store which number @p{cell} has
+ // in the list of neighbors of
+ // @p{neighbor}
const unsigned int neighbor_neighbor
- = cell->neighbor_of_neighbor (face_no);
+ = cell->neighbor_of_neighbor (face_no);
Assert (neighbor_neighbor<GeometryInfo<dim>::faces_per_cell,
- ExcInternalError());
+ ExcInternalError());
- // loop over all subfaces
+ // loop over all subfaces
for (unsigned int subface_no=0; subface_no<face->n_children(); ++subface_no)
- {
- // get an iterator pointing to the
- // cell behind the present subface
- const typename DH::active_cell_iterator neighbor_child
- = cell->neighbor_child_on_subface (face_no, subface_no);
- Assert (!neighbor_child->has_children(),
- ExcInternalError());
-
- // restrict the finite element
- // on the present cell to the
- // subface
- fe_subface_values.reinit (cell, face_no, subface_no,
- cell->active_fe_index());
-
- // restrict the finite element
- // on the neighbor cell to the
- // common @p{subface}.
- fe_face_values.reinit (neighbor_child, neighbor_neighbor,
- cell->active_fe_index());
-
- // store the gradient of the
- // solution in psi
- for (unsigned int n=0; n<n_solution_vectors; ++n)
- fe_subface_values.get_present_fe_values()
- .get_function_grads (*solutions[n], parallel_data.psi[n]);
-
- // store the gradient from the
- // neighbor's side in
- // @p{neighbor_psi}
- for (unsigned int n=0; n<n_solution_vectors; ++n)
- fe_face_values.get_present_fe_values()
- .get_function_grads (*solutions[n], parallel_data.neighbor_psi[n]);
-
- // compute the jump in the gradients
- for (unsigned int n=0; n<n_solution_vectors; ++n)
- for (unsigned int component=0; component<n_components; ++component)
- for (unsigned int p=0; p<n_q_points; ++p)
- parallel_data.psi[n][p][component] -=
- parallel_data.neighbor_psi[n][p][component];
-
- // note that unlike for the
- // case of regular faces
- // (treated in the other
- // function of this class), we
- // have not to take care of
- // boundary faces here, since
- // they always are regular.
-
- // next we have to multiply this with
- // the normal vector. Since we have
- // taken the difference of gradients
- // for internal faces, we may chose
- // the normal vector of one cell,
- // taking that of the neighbor
- // would only change the sign. We take
- // the outward normal.
- //
- // let phi be the name of the integrand
-
- parallel_data.normal_vectors
- = fe_face_values.get_present_fe_values().get_normal_vectors();
-
-
- for (unsigned int n=0; n<n_solution_vectors; ++n)
- for (unsigned int component=0; component<n_components; ++component)
- for (unsigned int point=0; point<n_q_points; ++point)
- parallel_data.phi[n][point][component] = (parallel_data.psi[n][point][component]*
- parallel_data.normal_vectors[point]);
-
- // if a coefficient was given: use that
- // to scale the jump in the gradient
- if (parallel_data.coefficients != 0)
- {
- // scalar coefficient
- if (parallel_data.coefficients->n_components == 1)
- {
- parallel_data.coefficients
- ->value_list (fe_face_values.get_present_fe_values()
- .get_quadrature_points(),
- parallel_data.coefficient_values1);
- for (unsigned int n=0; n<n_solution_vectors; ++n)
- for (unsigned int component=0; component<n_components; ++component)
- for (unsigned int point=0; point<n_q_points; ++point)
- parallel_data.phi[n][point][component] *=
- parallel_data.coefficient_values1[point];
- }
- else
- // vector-valued coefficient
- {
- parallel_data.coefficients
- ->vector_value_list (fe_face_values.get_present_fe_values()
- .get_quadrature_points(),
- parallel_data.coefficient_values);
- for (unsigned int n=0; n<n_solution_vectors; ++n)
- for (unsigned int component=0; component<n_components; ++component)
- for (unsigned int point=0; point<n_q_points; ++point)
- parallel_data.phi[n][point][component] *=
- parallel_data.coefficient_values[point](component);
- }
- }
-
- // get the weights for the
- // integration. note that it
- // does not matter whether we
- // take the JxW values from the
- // fe_face_values or the
- // fe_subface_values, as the
- // first is on the small
- // neighbor cell, while the
- // latter is on the refined
- // face of the big cell here
- parallel_data.JxW_values
- = fe_face_values.get_present_fe_values().get_JxW_values();
-
- // take the square of the phi[i]
- // for integration, and sum up
- std::vector<double> face_integral (n_solution_vectors, 0);
- for (unsigned int n=0; n<n_solution_vectors; ++n)
- for (unsigned int component=0; component<n_components; ++component)
- if (parallel_data.component_mask[component] == true)
- for (unsigned int p=0; p<n_q_points; ++p)
- face_integral[n] += dealii::sqr(parallel_data.phi[n][p][component]) *
- parallel_data.JxW_values[p];
-
- local_face_integrals[neighbor_child->face(neighbor_neighbor)]
- = face_integral;
- }
-
-
- // finally loop over all subfaces to
- // collect the contributions of the
- // subfaces and store them with the
- // mother face
+ {
+ // get an iterator pointing to the
+ // cell behind the present subface
+ const typename DH::active_cell_iterator neighbor_child
+ = cell->neighbor_child_on_subface (face_no, subface_no);
+ Assert (!neighbor_child->has_children(),
+ ExcInternalError());
+
+ // restrict the finite element
+ // on the present cell to the
+ // subface
+ fe_subface_values.reinit (cell, face_no, subface_no,
+ cell->active_fe_index());
+
+ // restrict the finite element
+ // on the neighbor cell to the
+ // common @p{subface}.
+ fe_face_values.reinit (neighbor_child, neighbor_neighbor,
+ cell->active_fe_index());
+
+ // store the gradient of the
+ // solution in psi
+ for (unsigned int n=0; n<n_solution_vectors; ++n)
+ fe_subface_values.get_present_fe_values()
+ .get_function_grads (*solutions[n], parallel_data.psi[n]);
+
+ // store the gradient from the
+ // neighbor's side in
+ // @p{neighbor_psi}
+ for (unsigned int n=0; n<n_solution_vectors; ++n)
+ fe_face_values.get_present_fe_values()
+ .get_function_grads (*solutions[n], parallel_data.neighbor_psi[n]);
+
+ // compute the jump in the gradients
+ for (unsigned int n=0; n<n_solution_vectors; ++n)
+ for (unsigned int component=0; component<n_components; ++component)
+ for (unsigned int p=0; p<n_q_points; ++p)
+ parallel_data.psi[n][p][component] -=
+ parallel_data.neighbor_psi[n][p][component];
+
+ // note that unlike for the
+ // case of regular faces
+ // (treated in the other
+ // function of this class), we
+ // have not to take care of
+ // boundary faces here, since
+ // they always are regular.
+
+ // next we have to multiply this with
+ // the normal vector. Since we have
+ // taken the difference of gradients
+ // for internal faces, we may chose
+ // the normal vector of one cell,
+ // taking that of the neighbor
+ // would only change the sign. We take
+ // the outward normal.
+ //
+ // let phi be the name of the integrand
+
+ parallel_data.normal_vectors
+ = fe_face_values.get_present_fe_values().get_normal_vectors();
+
+
+ for (unsigned int n=0; n<n_solution_vectors; ++n)
+ for (unsigned int component=0; component<n_components; ++component)
+ for (unsigned int point=0; point<n_q_points; ++point)
+ parallel_data.phi[n][point][component] = (parallel_data.psi[n][point][component]*
+ parallel_data.normal_vectors[point]);
+
+ // if a coefficient was given: use that
+ // to scale the jump in the gradient
+ if (parallel_data.coefficients != 0)
+ {
+ // scalar coefficient
+ if (parallel_data.coefficients->n_components == 1)
+ {
+ parallel_data.coefficients
+ ->value_list (fe_face_values.get_present_fe_values()
+ .get_quadrature_points(),
+ parallel_data.coefficient_values1);
+ for (unsigned int n=0; n<n_solution_vectors; ++n)
+ for (unsigned int component=0; component<n_components; ++component)
+ for (unsigned int point=0; point<n_q_points; ++point)
+ parallel_data.phi[n][point][component] *=
+ parallel_data.coefficient_values1[point];
+ }
+ else
+ // vector-valued coefficient
+ {
+ parallel_data.coefficients
+ ->vector_value_list (fe_face_values.get_present_fe_values()
+ .get_quadrature_points(),
+ parallel_data.coefficient_values);
+ for (unsigned int n=0; n<n_solution_vectors; ++n)
+ for (unsigned int component=0; component<n_components; ++component)
+ for (unsigned int point=0; point<n_q_points; ++point)
+ parallel_data.phi[n][point][component] *=
+ parallel_data.coefficient_values[point](component);
+ }
+ }
+
+ // get the weights for the
+ // integration. note that it
+ // does not matter whether we
+ // take the JxW values from the
+ // fe_face_values or the
+ // fe_subface_values, as the
+ // first is on the small
+ // neighbor cell, while the
+ // latter is on the refined
+ // face of the big cell here
+ parallel_data.JxW_values
+ = fe_face_values.get_present_fe_values().get_JxW_values();
+
+ // take the square of the phi[i]
+ // for integration, and sum up
+ std::vector<double> face_integral (n_solution_vectors, 0);
+ for (unsigned int n=0; n<n_solution_vectors; ++n)
+ for (unsigned int component=0; component<n_components; ++component)
+ if (parallel_data.component_mask[component] == true)
+ for (unsigned int p=0; p<n_q_points; ++p)
+ face_integral[n] += dealii::sqr(parallel_data.phi[n][p][component]) *
+ parallel_data.JxW_values[p];
+
+ local_face_integrals[neighbor_child->face(neighbor_neighbor)]
+ = face_integral;
+ }
+
+
+ // finally loop over all subfaces to
+ // collect the contributions of the
+ // subfaces and store them with the
+ // mother face
std::vector<double> sum (n_solution_vectors, 0);
for (unsigned int subface_no=0; subface_no<face->n_children(); ++subface_no)
- {
- Assert (local_face_integrals.find(face->child(subface_no)) !=
- local_face_integrals.end(),
- ExcInternalError());
- Assert (local_face_integrals[face->child(subface_no)][0] >= 0,
- ExcInternalError());
+ {
+ Assert (local_face_integrals.find(face->child(subface_no)) !=
+ local_face_integrals.end(),
+ ExcInternalError());
+ Assert (local_face_integrals[face->child(subface_no)][0] >= 0,
+ ExcInternalError());
- for (unsigned int n=0; n<n_solution_vectors; ++n)
- sum[n] += local_face_integrals[face->child(subface_no)][n];
- }
+ for (unsigned int n=0; n<n_solution_vectors; ++n)
+ sum[n] += local_face_integrals[face->child(subface_no)][n];
+ }
local_face_integrals[face] = sum;
}
- /**
- * Computate the error on the faces of a
- * single cell.
- *
- * This function is only needed
- * in two or three dimensions.
- * The error estimator in one
- * dimension is implemented
- * seperatly.
- */
+ /**
+ * Computate the error on the faces of a
+ * single cell.
+ *
+ * This function is only needed
+ * in two or three dimensions.
+ * The error estimator in one
+ * dimension is implemented
+ * seperatly.
+ */
template <int dim, int spacedim, typename InputVector, class DH>
void
estimate_one_cell (const typename DH::active_cell_iterator &cell,
- ParallelData<DH> ¶llel_data,
- std::map<typename DH::face_iterator,std::vector<double> > &local_face_integrals,
- const std::vector<const InputVector*> &solutions)
+ ParallelData<DH> ¶llel_data,
+ std::map<typename DH::face_iterator,std::vector<double> > &local_face_integrals,
+ const std::vector<const InputVector*> &solutions)
{
const unsigned int n_solution_vectors = solutions.size();
const types::subdomain_id_t subdomain_id = parallel_data.subdomain_id;
const unsigned int material_id = parallel_data.material_id;
- // empty our own copy of the local face
- // integrals
+ // empty our own copy of the local face
+ // integrals
local_face_integrals.clear();
- // loop over all faces of this cell
+ // loop over all faces of this cell
for (unsigned int face_no=0;
- face_no<GeometryInfo<dim>::faces_per_cell; ++face_no)
- {
- const typename DH::face_iterator
- face=cell->face(face_no);
-
- // make sure we do work
- // only once: this face
- // may either be regular
- // or irregular. if it is
- // regular and has a
- // neighbor, then we
- // visit the face twice,
- // once from every
- // side. let the one with
- // the lower index do the
- // work. if it is at the
- // boundary, or if the
- // face is irregular,
- // then do the work below
- if ((face->has_children() == false) &&
- !cell->at_boundary(face_no) &&
- (!cell->neighbor_is_coarser(face_no) &&
- (cell->neighbor(face_no)->index() < cell->index() ||
- (cell->neighbor(face_no)->index() == cell->index() &&
- cell->neighbor(face_no)->level() < cell->level()))))
- continue;
-
- // if the neighboring cell is less
- // refined than the present one,
- // then do nothing since we
- // integrate over the subfaces when
- // we visit the coarse cells.
- if (face->at_boundary() == false)
- if (cell->neighbor_is_coarser(face_no))
- continue;
-
- // if this face is part of the
- // boundary but not of the neumann
- // boundary -> nothing to
- // do. However, to make things
- // easier when summing up the
- // contributions of the faces of
- // cells, we enter this face into
- // the list of faces with
- // contribution zero.
- if (face->at_boundary()
- &&
- (parallel_data.neumann_bc->find(face->boundary_indicator()) ==
- parallel_data.neumann_bc->end()))
- {
- local_face_integrals[face]
- = std::vector<double> (n_solution_vectors, 0.);
- continue;
- }
-
- // finally: note that we only have
- // to do something if either the
- // present cell is on the subdomain
- // we care for (and the same for
- // material_id), or if one of the
- // neighbors behind the face is on
- // the subdomain we care for
- if ( ! ( ((subdomain_id == types::invalid_subdomain_id)
- ||
- (cell->subdomain_id() == subdomain_id))
- &&
- ((material_id == types::invalid_material_id)
- ||
- (cell->material_id() == material_id))) )
- {
- // ok, cell is unwanted, but
- // maybe its neighbor behind
- // the face we presently work
- // on? oh is there a face at
- // all?
- if (face->at_boundary())
- continue;
-
- bool care_for_cell = false;
- if (face->has_children() == false)
- care_for_cell |= ((cell->neighbor(face_no)->subdomain_id()
- == subdomain_id) ||
- (subdomain_id == types::invalid_subdomain_id))
- &&
- ((cell->neighbor(face_no)->material_id()
- == material_id) ||
- (material_id == types::invalid_material_id));
- else
- {
- for (unsigned int sf=0; sf<face->n_children(); ++sf)
- if (((cell->neighbor_child_on_subface(face_no,sf)
- ->subdomain_id() == subdomain_id)
- &&
- (material_id ==
- types::invalid_material_id))
- ||
- ((cell->neighbor_child_on_subface(face_no,sf)
- ->material_id() == material_id)
- &&
- (subdomain_id ==
- types::invalid_subdomain_id)))
- {
- care_for_cell = true;
- break;
- }
- }
-
- // so if none of the neighbors
- // cares for this subdomain or
- // material either, then try
- // next face
- if (care_for_cell == false)
- continue;
- }
-
- // so now we know that we care for
- // this face, let's do something
- // about it. first re-size the
- // arrays we may use to the correct
- // size:
- parallel_data.resize (cell->active_fe_index());
-
-
- // then do the actual integration
- if (face->has_children() == false)
- // if the face is a regular one,
- // i.e. either on the other side
- // there is nirvana (face is at
- // boundary), or the other side's
- // refinement level is the same
- // as that of this side, then
- // handle the integration of
- // these both cases together
- integrate_over_regular_face (solutions,
- parallel_data,
- local_face_integrals,
- cell, face_no,
- parallel_data.fe_face_values_cell,
- parallel_data.fe_face_values_neighbor);
-
- else
- // otherwise we need to do some
- // special computations which do
- // not fit into the framework of
- // the above function
- integrate_over_irregular_face (solutions,
- parallel_data,
- local_face_integrals,
- cell, face_no,
- parallel_data.fe_face_values_cell,
- parallel_data.fe_subface_values);
- }
+ face_no<GeometryInfo<dim>::faces_per_cell; ++face_no)
+ {
+ const typename DH::face_iterator
+ face=cell->face(face_no);
+
+ // make sure we do work
+ // only once: this face
+ // may either be regular
+ // or irregular. if it is
+ // regular and has a
+ // neighbor, then we
+ // visit the face twice,
+ // once from every
+ // side. let the one with
+ // the lower index do the
+ // work. if it is at the
+ // boundary, or if the
+ // face is irregular,
+ // then do the work below
+ if ((face->has_children() == false) &&
+ !cell->at_boundary(face_no) &&
+ (!cell->neighbor_is_coarser(face_no) &&
+ (cell->neighbor(face_no)->index() < cell->index() ||
+ (cell->neighbor(face_no)->index() == cell->index() &&
+ cell->neighbor(face_no)->level() < cell->level()))))
+ continue;
+
+ // if the neighboring cell is less
+ // refined than the present one,
+ // then do nothing since we
+ // integrate over the subfaces when
+ // we visit the coarse cells.
+ if (face->at_boundary() == false)
+ if (cell->neighbor_is_coarser(face_no))
+ continue;
+
+ // if this face is part of the
+ // boundary but not of the neumann
+ // boundary -> nothing to
+ // do. However, to make things
+ // easier when summing up the
+ // contributions of the faces of
+ // cells, we enter this face into
+ // the list of faces with
+ // contribution zero.
+ if (face->at_boundary()
+ &&
+ (parallel_data.neumann_bc->find(face->boundary_indicator()) ==
+ parallel_data.neumann_bc->end()))
+ {
+ local_face_integrals[face]
+ = std::vector<double> (n_solution_vectors, 0.);
+ continue;
+ }
+
+ // finally: note that we only have
+ // to do something if either the
+ // present cell is on the subdomain
+ // we care for (and the same for
+ // material_id), or if one of the
+ // neighbors behind the face is on
+ // the subdomain we care for
+ if ( ! ( ((subdomain_id == types::invalid_subdomain_id)
+ ||
+ (cell->subdomain_id() == subdomain_id))
+ &&
+ ((material_id == types::invalid_material_id)
+ ||
+ (cell->material_id() == material_id))) )
+ {
+ // ok, cell is unwanted, but
+ // maybe its neighbor behind
+ // the face we presently work
+ // on? oh is there a face at
+ // all?
+ if (face->at_boundary())
+ continue;
+
+ bool care_for_cell = false;
+ if (face->has_children() == false)
+ care_for_cell |= ((cell->neighbor(face_no)->subdomain_id()
+ == subdomain_id) ||
+ (subdomain_id == types::invalid_subdomain_id))
+ &&
+ ((cell->neighbor(face_no)->material_id()
+ == material_id) ||
+ (material_id == types::invalid_material_id));
+ else
+ {
+ for (unsigned int sf=0; sf<face->n_children(); ++sf)
+ if (((cell->neighbor_child_on_subface(face_no,sf)
+ ->subdomain_id() == subdomain_id)
+ &&
+ (material_id ==
+ types::invalid_material_id))
+ ||
+ ((cell->neighbor_child_on_subface(face_no,sf)
+ ->material_id() == material_id)
+ &&
+ (subdomain_id ==
+ types::invalid_subdomain_id)))
+ {
+ care_for_cell = true;
+ break;
+ }
+ }
+
+ // so if none of the neighbors
+ // cares for this subdomain or
+ // material either, then try
+ // next face
+ if (care_for_cell == false)
+ continue;
+ }
+
+ // so now we know that we care for
+ // this face, let's do something
+ // about it. first re-size the
+ // arrays we may use to the correct
+ // size:
+ parallel_data.resize (cell->active_fe_index());
+
+
+ // then do the actual integration
+ if (face->has_children() == false)
+ // if the face is a regular one,
+ // i.e. either on the other side
+ // there is nirvana (face is at
+ // boundary), or the other side's
+ // refinement level is the same
+ // as that of this side, then
+ // handle the integration of
+ // these both cases together
+ integrate_over_regular_face (solutions,
+ parallel_data,
+ local_face_integrals,
+ cell, face_no,
+ parallel_data.fe_face_values_cell,
+ parallel_data.fe_face_values_neighbor);
+
+ else
+ // otherwise we need to do some
+ // special computations which do
+ // not fit into the framework of
+ // the above function
+ integrate_over_irregular_face (solutions,
+ parallel_data,
+ local_face_integrals,
+ cell, face_no,
+ parallel_data.fe_face_values_cell,
+ parallel_data.fe_subface_values);
+ }
}
}
}
const types::subdomain_id_t subdomain_id,
const types::material_id_t material_id)
{
- // just pass on to the other function
+ // just pass on to the other function
const std::vector<const InputVector *> solutions (1, &solution);
std::vector<Vector<float>*> errors (1, &error);
estimate (mapping, dof_handler, quadrature, neumann_bc, solutions, errors,
- component_mask, coefficients, n_threads, subdomain_id, material_id);
+ component_mask, coefficients, n_threads, subdomain_id, material_id);
}
{
Assert (DEAL_II_COMPAT_MAPPING, ExcCompatibility("mapping"));
estimate(StaticMappingQ1<1,spacedim>::mapping, dof_handler, quadrature, neumann_bc, solution,
- error, component_mask, coefficients, n_threads, subdomain_id, material_id);
+ error, component_mask, coefficients, n_threads, subdomain_id, material_id);
}
{
Assert (DEAL_II_COMPAT_MAPPING, ExcCompatibility("mapping"));
estimate(StaticMappingQ1<1,spacedim>::mapping, dof_handler, quadrature, neumann_bc, solutions,
- errors, component_mask, coefficients, n_threads, subdomain_id, material_id);
+ errors, component_mask, coefficients, n_threads, subdomain_id, material_id);
}
const types::subdomain_id_t subdomain_id,
const types::material_id_t material_id)
{
- // just pass on to the other function
+ // just pass on to the other function
const std::vector<const InputVector *> solutions (1, &solution);
std::vector<Vector<float>*> errors (1, &error);
estimate (mapping, dof_handler, quadrature, neumann_bc, solutions, errors,
- component_mask, coefficients, n_threads, subdomain_id, material_id);
+ component_mask, coefficients, n_threads, subdomain_id, material_id);
}
{
Assert (DEAL_II_COMPAT_MAPPING, ExcCompatibility("mapping"));
estimate(StaticMappingQ1<1,spacedim>::mapping, dof_handler, quadrature, neumann_bc, solution,
- error, component_mask, coefficients, n_threads, subdomain_id, material_id);
+ error, component_mask, coefficients, n_threads, subdomain_id, material_id);
}
{
Assert (DEAL_II_COMPAT_MAPPING, ExcCompatibility("mapping"));
estimate(StaticMappingQ1<1,spacedim>::mapping, dof_handler, quadrature, neumann_bc, solutions,
- errors, component_mask, coefficients, n_threads, subdomain_id, material_id);
+ errors, component_mask, coefficients, n_threads, subdomain_id, material_id);
}
(&dof_handler.get_tria())
!= 0)
Assert ((subdomain_id_ == types::invalid_subdomain_id)
- ||
- (subdomain_id_ ==
- dynamic_cast<const parallel::distributed::Triangulation<1,spacedim>&>
- (dof_handler.get_tria()).locally_owned_subdomain()),
- ExcMessage ("For parallel distributed triangulations, the only "
- "valid subdomain_id that can be passed here is the "
- "one that corresponds to the locally owned subdomain id."));
+ ||
+ (subdomain_id_ ==
+ dynamic_cast<const parallel::distributed::Triangulation<1,spacedim>&>
+ (dof_handler.get_tria()).locally_owned_subdomain()),
+ ExcMessage ("For parallel distributed triangulations, the only "
+ "valid subdomain_id that can be passed here is the "
+ "one that corresponds to the locally owned subdomain id."));
const types::subdomain_id_t subdomain_id
= ((dynamic_cast<const parallel::distributed::Triangulation<1,spacedim>*>
- (&dof_handler.get_tria())
- != 0)
+ (&dof_handler.get_tria())
+ != 0)
?
dynamic_cast<const parallel::distributed::Triangulation<1,spacedim>&>
(dof_handler.get_tria()).locally_owned_subdomain()
const unsigned int n_components = dof_handler.get_fe().n_components();
const unsigned int n_solution_vectors = solutions.size();
- // sanity checks
+ // sanity checks
Assert (neumann_bc.find(types::internal_face_boundary_id) == neumann_bc.end(),
- ExcInvalidBoundaryIndicator());
+ ExcInvalidBoundaryIndicator());
for (typename FunctionMap<spacedim>::type::const_iterator i=neumann_bc.begin();
i!=neumann_bc.end(); ++i)
Assert ((component_mask_.size() == 0) ||
(std::count(component_mask_.begin(), component_mask_.end(),
true) > 0),
- ExcInvalidComponentMask());
+ ExcInvalidComponentMask());
Assert ((coefficient == 0) ||
- (coefficient->n_components == n_components) ||
- (coefficient->n_components == 1),
- ExcInvalidCoefficient());
+ (coefficient->n_components == n_components) ||
+ (coefficient->n_components == 1),
+ ExcInvalidCoefficient());
Assert (solutions.size() > 0,
- ExcNoSolutions());
+ ExcNoSolutions());
Assert (solutions.size() == errors.size(),
- ExcIncompatibleNumberOfElements(solutions.size(), errors.size()));
+ ExcIncompatibleNumberOfElements(solutions.size(), errors.size()));
for (unsigned int n=0; n<solutions.size(); ++n)
Assert (solutions[n]->size() == dof_handler.n_dofs(),
- ExcInvalidSolutionVector());
+ ExcInvalidSolutionVector());
- // if no mask given: treat all components
+ // if no mask given: treat all components
std::vector<bool> component_mask ((component_mask_.size() == 0) ?
- std::vector<bool>(n_components, true) :
- component_mask_);
+ std::vector<bool>(n_components, true) :
+ component_mask_);
Assert (component_mask.size() == n_components, ExcInvalidComponentMask());
Assert (std::count(component_mask.begin(), component_mask.end(), true) > 0,
- ExcInvalidComponentMask());
+ ExcInvalidComponentMask());
Assert ((coefficient == 0) ||
- (coefficient->n_components == n_components) ||
- (coefficient->n_components == 1),
- ExcInvalidCoefficient());
+ (coefficient->n_components == n_components) ||
+ (coefficient->n_components == 1),
+ ExcInvalidCoefficient());
for (typename FunctionMap<spacedim>::type::const_iterator i=neumann_bc.begin();
i!=neumann_bc.end(); ++i)
Assert (i->second->n_components == n_components,
ExcInvalidBoundaryFunction());
- // reserve one slot for each cell and set
- // it to zero
+ // reserve one slot for each cell and set
+ // it to zero
for (unsigned int n=0; n<n_solution_vectors; ++n)
(*errors[n]).reinit (dof_handler.get_tria().n_active_cells());
- // fields to get the gradients on
- // the present and the neighbor cell.
- //
- // for the neighbor gradient, we
- // need several auxiliary fields,
- // depending on the way we get it
- // (see below)
+ // fields to get the gradients on
+ // the present and the neighbor cell.
+ //
+ // for the neighbor gradient, we
+ // need several auxiliary fields,
+ // depending on the way we get it
+ // (see below)
std::vector<std::vector<std::vector<Tensor<1,spacedim> > > >
gradients_here (n_solution_vectors,
- std::vector<std::vector<Tensor<1,spacedim> > >(2, std::vector<Tensor<1,spacedim> >(n_components)));
+ std::vector<std::vector<Tensor<1,spacedim> > >(2, std::vector<Tensor<1,spacedim> >(n_components)));
std::vector<std::vector<std::vector<Tensor<1,spacedim> > > >
gradients_neighbor (gradients_here);
std::vector<Vector<double> >
grad_neighbor (n_solution_vectors, Vector<double>(n_components));
- // reserve some space for
- // coefficient values at one point.
- // if there is no coefficient, then
- // we fill it by unity once and for
- // all and don't set it any more
+ // reserve some space for
+ // coefficient values at one point.
+ // if there is no coefficient, then
+ // we fill it by unity once and for
+ // all and don't set it any more
Vector<double> coefficient_values (n_components);
if (coefficient == 0)
for (unsigned int c=0; c<n_components; ++c)
mapping_collection.push_back (mapping);
hp::FEValues<1,spacedim> fe_values (mapping_collection, fe, q_collection,
- update_gradients);
+ update_gradients);
- // loop over all cells and do something on
- // the cells which we're told to work
- // on. note that the error indicator is
- // only a sum over the two contributions
- // from the two vertices of each cell.
+ // loop over all cells and do something on
+ // the cells which we're told to work
+ // on. note that the error indicator is
+ // only a sum over the two contributions
+ // from the two vertices of each cell.
typename DH::active_cell_iterator cell = dof_handler.begin_active();
for (unsigned int cell_index=0; cell != dof_handler.end();
++cell, ++cell_index)
for (unsigned int s=0; s<n_solution_vectors; ++s)
fe_values.get_present_fe_values()
- .get_function_grads (*solutions[s], gradients_here[s]);
+ .get_function_grads (*solutions[s], gradients_here[s]);
if (neighbor.state() == IteratorState::valid)
{
for (unsigned int s=0; s<n_solution_vectors; ++s)
fe_values.get_present_fe_values()
- .get_function_grads (*solutions[s],
- gradients_neighbor[s]);
+ .get_function_grads (*solutions[s],
+ gradients_neighbor[s]);
// extract the
// gradients of all the
const types::subdomain_id_t subdomain_id,
const types::material_id_t material_id)
{
- // just pass on to the other function
+ // just pass on to the other function
const std::vector<const InputVector *> solutions (1, &solution);
std::vector<Vector<float>*> errors (1, &error);
estimate (mapping, dof_handler, quadrature, neumann_bc, solutions, errors,
- component_mask, coefficients, n_threads, subdomain_id, material_id);
+ component_mask, coefficients, n_threads, subdomain_id, material_id);
}
{
Assert (DEAL_II_COMPAT_MAPPING, ExcCompatibility("mapping"));
estimate(StaticMappingQ1<dim,spacedim>::mapping, dof_handler, quadrature, neumann_bc, solution,
- error, component_mask, coefficients, n_threads,
+ error, component_mask, coefficients, n_threads,
subdomain_id, material_id);
}
const types::subdomain_id_t subdomain_id,
const types::material_id_t material_id)
{
- // just pass on to the other function
+ // just pass on to the other function
const std::vector<const InputVector *> solutions (1, &solution);
std::vector<Vector<float>*> errors (1, &error);
estimate (mapping, dof_handler, quadrature, neumann_bc, solutions, errors,
- component_mask, coefficients, n_threads, subdomain_id, material_id);
+ component_mask, coefficients, n_threads, subdomain_id, material_id);
}
{
Assert (DEAL_II_COMPAT_MAPPING, ExcCompatibility("mapping"));
estimate(StaticMappingQ1<dim, spacedim>::mapping, dof_handler, quadrature, neumann_bc, solution,
- error, component_mask, coefficients, n_threads,
+ error, component_mask, coefficients, n_threads,
subdomain_id, material_id);
}
(&dof_handler.get_tria())
!= 0)
Assert ((subdomain_id_ == types::invalid_subdomain_id)
- ||
- (subdomain_id_ ==
- dynamic_cast<const parallel::distributed::Triangulation<dim,spacedim>&>
- (dof_handler.get_tria()).locally_owned_subdomain()),
- ExcMessage ("For parallel distributed triangulations, the only "
- "valid subdomain_id that can be passed here is the "
- "one that corresponds to the locally owned subdomain id."));
+ ||
+ (subdomain_id_ ==
+ dynamic_cast<const parallel::distributed::Triangulation<dim,spacedim>&>
+ (dof_handler.get_tria()).locally_owned_subdomain()),
+ ExcMessage ("For parallel distributed triangulations, the only "
+ "valid subdomain_id that can be passed here is the "
+ "one that corresponds to the locally owned subdomain id."));
const types::subdomain_id_t subdomain_id
= ((dynamic_cast<const parallel::distributed::Triangulation<dim,spacedim>*>
- (&dof_handler.get_tria())
- != 0)
+ (&dof_handler.get_tria())
+ != 0)
?
dynamic_cast<const parallel::distributed::Triangulation<dim,spacedim>&>
(dof_handler.get_tria()).locally_owned_subdomain()
const unsigned int n_components = dof_handler.get_fe().n_components();
- // sanity checks
+ // sanity checks
Assert (solutions.size() > 0,
- ExcNoSolutions());
+ ExcNoSolutions());
Assert (solutions.size() == errors.size(),
- ExcIncompatibleNumberOfElements(solutions.size(), errors.size()));
+ ExcIncompatibleNumberOfElements(solutions.size(), errors.size()));
for (typename FunctionMap<spacedim>::type::const_iterator i=neumann_bc.begin();
i!=neumann_bc.end(); ++i)
Assert ((component_mask_.size() == 0) ||
(std::count(component_mask_.begin(), component_mask_.end(),
true) > 0),
- ExcInvalidComponentMask());
+ ExcInvalidComponentMask());
Assert ((coefficients == 0) ||
- (coefficients->n_components == n_components) ||
- (coefficients->n_components == 1),
- ExcInvalidCoefficient());
+ (coefficients->n_components == n_components) ||
+ (coefficients->n_components == 1),
+ ExcInvalidCoefficient());
for (unsigned int n=0; n<solutions.size(); ++n)
Assert (solutions[n]->size() == dof_handler.n_dofs(),
- ExcInvalidSolutionVector());
+ ExcInvalidSolutionVector());
- // if no mask given: treat all components
+ // if no mask given: treat all components
std::vector<bool> component_mask ((component_mask_.size() == 0) ?
- std::vector<bool>(n_components, true) :
- component_mask_);
+ std::vector<bool>(n_components, true) :
+ component_mask_);
Assert (component_mask.size() == n_components, ExcInvalidComponentMask());
Assert (std::count(component_mask.begin(), component_mask.end(), true) > 0,
- ExcInvalidComponentMask());
+ ExcInvalidComponentMask());
const unsigned int n_solution_vectors = solutions.size();
- // Map of integrals indexed by
- // the corresponding face. In this map
- // we store the integrated jump of the
- // gradient for each face.
- // At the end of the function, we again
- // loop over the cells and collect the
- // contributions of the different faces
- // of the cell.
+ // Map of integrals indexed by
+ // the corresponding face. In this map
+ // we store the integrated jump of the
+ // gradient for each face.
+ // At the end of the function, we again
+ // loop over the cells and collect the
+ // contributions of the different faces
+ // of the cell.
std::map<typename DH::face_iterator,std::vector<double> > face_integrals;
- // all the data needed in the error
- // estimator by each of the threads
- // is gathered in the following
- // stuctures
+ // all the data needed in the error
+ // estimator by each of the threads
+ // is gathered in the following
+ // stuctures
const hp::MappingCollection<dim,spacedim> mapping_collection(mapping);
const internal::ParallelData<DH>
parallel_data (dof_handler.get_fe(),
- face_quadratures,
- mapping_collection,
- (!neumann_bc.empty() || (coefficients != 0)),
- solutions.size(),
- subdomain_id,
- material_id,
- &neumann_bc,
- component_mask,
- coefficients);
+ face_quadratures,
+ mapping_collection,
+ (!neumann_bc.empty() || (coefficients != 0)),
+ solutions.size(),
+ subdomain_id,
+ material_id,
+ &neumann_bc,
+ component_mask,
+ coefficients);
std::map<typename DH::face_iterator,std::vector<double> > sample_local_face_integrals;
- // now let's work on all those cells:
+ // now let's work on all those cells:
WorkStream::run (dof_handler.begin_active(),
- static_cast<typename DH::active_cell_iterator>(dof_handler.end()),
- std_cxx1x::bind (&internal::estimate_one_cell<dim,spacedim,InputVector,DH>,
- std_cxx1x::_1, std_cxx1x::_2, std_cxx1x::_3, std_cxx1x::ref(solutions)),
- std_cxx1x::bind (&internal::copy_local_to_global<DH>,
- std_cxx1x::_1, std_cxx1x::ref(face_integrals)),
- parallel_data,
- sample_local_face_integrals);
-
- // finally add up the contributions of the
- // faces for each cell
-
- // reserve one slot for each cell and set
- // it to zero
+ static_cast<typename DH::active_cell_iterator>(dof_handler.end()),
+ std_cxx1x::bind (&internal::estimate_one_cell<dim,spacedim,InputVector,DH>,
+ std_cxx1x::_1, std_cxx1x::_2, std_cxx1x::_3, std_cxx1x::ref(solutions)),
+ std_cxx1x::bind (&internal::copy_local_to_global<DH>,
+ std_cxx1x::_1, std_cxx1x::ref(face_integrals)),
+ parallel_data,
+ sample_local_face_integrals);
+
+ // finally add up the contributions of the
+ // faces for each cell
+
+ // reserve one slot for each cell and set
+ // it to zero
for (unsigned int n=0; n<n_solution_vectors; ++n)
{
(*errors[n]).reinit (dof_handler.get_tria().n_active_cells());
for (unsigned int i=0; i<dof_handler.get_tria().n_active_cells(); ++i)
- (*errors[n])(i)=0;
+ (*errors[n])(i)=0;
}
// now walk over all cells and collect
const types::subdomain_id_t subdomain_id,
const types::material_id_t material_id)
{
- // forward to the function with the QCollection
+ // forward to the function with the QCollection
estimate (mapping, dof_handler,
- hp::QCollection<dim-1>(quadrature),
- neumann_bc, solutions,
- errors, component_mask, coefficients,
- n_threads, subdomain_id, material_id);
+ hp::QCollection<dim-1>(quadrature),
+ neumann_bc, solutions,
+ errors, component_mask, coefficients,
+ n_threads, subdomain_id, material_id);
}
template <int dim, int spacedim>
template <typename InputVector, class DH>
void KellyErrorEstimator<dim, spacedim>::estimate (const DH &dof_handler,
- const Quadrature<dim-1> &quadrature,
- const typename FunctionMap<spacedim>::type &neumann_bc,
- const std::vector<const InputVector *> &solutions,
- std::vector<Vector<float>*> &errors,
- const std::vector<bool> &component_mask,
- const Function<spacedim> *coefficients,
- const unsigned int n_threads,
+ const Quadrature<dim-1> &quadrature,
+ const typename FunctionMap<spacedim>::type &neumann_bc,
+ const std::vector<const InputVector *> &solutions,
+ std::vector<Vector<float>*> &errors,
+ const std::vector<bool> &component_mask,
+ const Function<spacedim> *coefficients,
+ const unsigned int n_threads,
const types::subdomain_id_t subdomain_id,
const types::material_id_t material_id)
{
Assert (DEAL_II_COMPAT_MAPPING, ExcCompatibility("mapping"));
estimate(StaticMappingQ1<dim, spacedim>::mapping, dof_handler, quadrature, neumann_bc, solutions,
- errors, component_mask, coefficients, n_threads,
+ errors, component_mask, coefficients, n_threads,
subdomain_id, material_id);
}
template <int dim, int spacedim>
template <typename InputVector, class DH>
void KellyErrorEstimator<dim, spacedim>::estimate (const DH &dof_handler,
- const hp::QCollection<dim-1> &quadrature,
- const typename FunctionMap<spacedim>::type &neumann_bc,
- const std::vector<const InputVector *> &solutions,
- std::vector<Vector<float>*> &errors,
- const std::vector<bool> &component_mask,
- const Function<spacedim> *coefficients,
- const unsigned int n_threads,
+ const hp::QCollection<dim-1> &quadrature,
+ const typename FunctionMap<spacedim>::type &neumann_bc,
+ const std::vector<const InputVector *> &solutions,
+ std::vector<Vector<float>*> &errors,
+ const std::vector<bool> &component_mask,
+ const Function<spacedim> *coefficients,
+ const unsigned int n_threads,
const types::subdomain_id_t subdomain_id,
const types::material_id_t material_id)
{
Assert (DEAL_II_COMPAT_MAPPING, ExcCompatibility("mapping"));
estimate(StaticMappingQ1<dim, spacedim>::mapping, dof_handler, quadrature, neumann_bc, solutions,
- errors, component_mask, coefficients, n_threads,
+ errors, component_mask, coefficients, n_threads,
subdomain_id, material_id);
}
// $Id$
// Version: $Name$
//
-// Copyright (C) 2007, 2008 by the deal.II authors
+// Copyright (C) 2007, 2008, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
namespace Functions
{
-# include "fe_field_function.inst"
+# include "fe_field_function.inst"
}
DEAL_II_NAMESPACE_CLOSE
// $Id$
// Version: $Name$
//
-// Copyright (C) 1999, 2000, 2001, 2002, 2003, 2005, 2006, 2010, 2011 by the deal.II authors
+// Copyright (C) 1999, 2000, 2001, 2002, 2003, 2005, 2006, 2010, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
template <typename number>
inline
bool Histogram::logarithmic_less (const number n1,
- const number n2)
+ const number n2)
{
return (((n1<n2) && (n1>0)) ||
- ((n1<n2) && (n2<=0)) ||
- ((n2<n1) && (n1>0) && (n2<=0)));
+ ((n1<n2) && (n2<=0)) ||
+ ((n2<n1) && (n1>0) && (n2<=0)));
}
Histogram::Interval::Interval (const double left_point,
- const double right_point) :
- left_point (left_point),
- right_point (right_point),
- content (0)
+ const double right_point) :
+ left_point (left_point),
+ right_point (right_point),
+ content (0)
{}
template <typename number>
void Histogram::evaluate (const std::vector<Vector<number> > &values,
- const std::vector<double> &y_values_,
- const unsigned int n_intervals,
- const IntervalSpacing interval_spacing)
+ const std::vector<double> &y_values_,
+ const unsigned int n_intervals,
+ const IntervalSpacing interval_spacing)
{
Assert (values.size() > 0, ExcEmptyData());
Assert (n_intervals > 0, ExcInvalidIntervals());
for (unsigned int i=0; i<values.size(); ++i)
Assert (values[i].size() > 0, ExcEmptyData());
Assert (values.size() == y_values_.size(),
- ExcIncompatibleArraySize(values.size(), y_values_.size()));
+ ExcIncompatibleArraySize(values.size(), y_values_.size()));
- // store y_values
+ // store y_values
y_values = y_values_;
- // first find minimum and maximum value
- // in the indicators
+ // first find minimum and maximum value
+ // in the indicators
number min_value=0, max_value=0;
switch (interval_spacing)
{
case linear:
{
- min_value = *std::min_element(values[0].begin(),
- values[0].end());
- max_value = *std::max_element(values[0].begin(),
- values[0].end());
-
- for (unsigned int i=1; i<values.size(); ++i)
- {
- min_value = std::min (min_value,
- *std::min_element(values[i].begin(),
- values[i].end()));
- max_value = std::max (max_value,
- *std::max_element(values[i].begin(),
- values[i].end()));
- };
-
- break;
+ min_value = *std::min_element(values[0].begin(),
+ values[0].end());
+ max_value = *std::max_element(values[0].begin(),
+ values[0].end());
+
+ for (unsigned int i=1; i<values.size(); ++i)
+ {
+ min_value = std::min (min_value,
+ *std::min_element(values[i].begin(),
+ values[i].end()));
+ max_value = std::max (max_value,
+ *std::max_element(values[i].begin(),
+ values[i].end()));
+ };
+
+ break;
};
case logarithmic:
{
- typedef bool (*comparator) (const number, const number);
- const comparator logarithmic_less_function
- = &Histogram::template logarithmic_less<number>;
-
- min_value = *std::min_element(values[0].begin(),
- values[0].end(),
- logarithmic_less_function);
-
- max_value = *std::max_element(values[0].begin(),
- values[0].end(),
- logarithmic_less_function);
-
- for (unsigned int i=1; i<values.size(); ++i)
- {
- min_value = std::min (min_value,
- *std::min_element(values[i].begin(),
- values[i].end(),
- logarithmic_less_function),
- logarithmic_less_function);
-
- max_value = std::max (max_value,
- *std::max_element(values[i].begin(),
- values[i].end(),
- logarithmic_less_function),
- logarithmic_less_function);
- };
-
- break;
+ typedef bool (*comparator) (const number, const number);
+ const comparator logarithmic_less_function
+ = &Histogram::template logarithmic_less<number>;
+
+ min_value = *std::min_element(values[0].begin(),
+ values[0].end(),
+ logarithmic_less_function);
+
+ max_value = *std::max_element(values[0].begin(),
+ values[0].end(),
+ logarithmic_less_function);
+
+ for (unsigned int i=1; i<values.size(); ++i)
+ {
+ min_value = std::min (min_value,
+ *std::min_element(values[i].begin(),
+ values[i].end(),
+ logarithmic_less_function),
+ logarithmic_less_function);
+
+ max_value = std::max (max_value,
+ *std::max_element(values[i].begin(),
+ values[i].end(),
+ logarithmic_less_function),
+ logarithmic_less_function);
+ };
+
+ break;
};
default:
- Assert (false, ExcInternalError());
+ Assert (false, ExcInternalError());
};
- // move right bound arbitrarily if
- // necessary. sometimes in logarithmic
- // mode, max_value may be larger than
- // min_value, but only up to rounding
- // precision.
+ // move right bound arbitrarily if
+ // necessary. sometimes in logarithmic
+ // mode, max_value may be larger than
+ // min_value, but only up to rounding
+ // precision.
if (max_value <= min_value)
max_value = min_value+1;
- // now set up the intervals based on
- // the min and max values
+ // now set up the intervals based on
+ // the min and max values
intervals.clear ();
- // set up one list of intervals
- // for the first data vector. we will
- // then produce all the other lists
- // for the other data vectors by
- // copying
+ // set up one list of intervals
+ // for the first data vector. we will
+ // then produce all the other lists
+ // for the other data vectors by
+ // copying
intervals.push_back (std::vector<Interval>());
switch (interval_spacing)
{
case linear:
{
- const float delta = (max_value-min_value)/n_intervals;
+ const float delta = (max_value-min_value)/n_intervals;
- for (unsigned int n=0; n<n_intervals; ++n)
- intervals[0].push_back (Interval(min_value+n*delta,
- min_value+(n+1)*delta));
+ for (unsigned int n=0; n<n_intervals; ++n)
+ intervals[0].push_back (Interval(min_value+n*delta,
+ min_value+(n+1)*delta));
- break;
+ break;
};
case logarithmic:
{
- const float delta = (std::log(max_value)-std::log(min_value))/n_intervals;
+ const float delta = (std::log(max_value)-std::log(min_value))/n_intervals;
- for (unsigned int n=0; n<n_intervals; ++n)
- intervals[0].push_back (Interval(std::exp(std::log(min_value)+n*delta),
- std::exp(std::log(min_value)+(n+1)*delta)));
+ for (unsigned int n=0; n<n_intervals; ++n)
+ intervals[0].push_back (Interval(std::exp(std::log(min_value)+n*delta),
+ std::exp(std::log(min_value)+(n+1)*delta)));
- break;
+ break;
};
default:
- Assert (false, ExcInternalError());
+ Assert (false, ExcInternalError());
};
- // fill the other lists of intervals
+ // fill the other lists of intervals
for (unsigned int i=1; i<values.size(); ++i)
intervals.push_back (intervals[0]);
- // finally fill the intervals
+ // finally fill the intervals
for (unsigned int i=0; i<values.size(); ++i)
for (typename Vector<number>::const_iterator p=values[i].begin();
- p < values[i].end(); ++p)
+ p < values[i].end(); ++p)
{
- // find the right place for *p in
- // intervals[i]. use regular
- // operator< here instead of
- // the logarithmic one to
- // map negative or zero value
- // to the leftmost interval always
- for (unsigned int n=0; n<n_intervals; ++n)
- if (*p <= intervals[i][n].right_point)
- {
- ++intervals[i][n].content;
- break;
- };
+ // find the right place for *p in
+ // intervals[i]. use regular
+ // operator< here instead of
+ // the logarithmic one to
+ // map negative or zero value
+ // to the leftmost interval always
+ for (unsigned int n=0; n<n_intervals; ++n)
+ if (*p <= intervals[i][n].right_point)
+ {
+ ++intervals[i][n].content;
+ break;
+ };
};
}
template <typename number>
void Histogram::evaluate (const Vector<number> &values,
- const unsigned int n_intervals,
- const IntervalSpacing interval_spacing)
+ const unsigned int n_intervals,
+ const IntervalSpacing interval_spacing)
{
std::vector<Vector<number> > values_list (1,
- values);
+ values);
evaluate (values_list, std::vector<double>(1,0.), n_intervals, interval_spacing);
}
AssertThrow (out, ExcIO());
Assert (!intervals.empty(), ExcEmptyData());
- // do a simple 2d plot, if only
- // one data set is available
+ // do a simple 2d plot, if only
+ // one data set is available
if (intervals.size()==1)
{
for (unsigned int n=0; n<intervals[0].size(); ++n)
- out << intervals[0][n].left_point
- << ' '
- << intervals[0][n].content
- << std::endl
- << intervals[0][n].right_point
- << ' '
- << intervals[0][n].content
- << std::endl;
+ out << intervals[0][n].left_point
+ << ' '
+ << intervals[0][n].content
+ << std::endl
+ << intervals[0][n].right_point
+ << ' '
+ << intervals[0][n].content
+ << std::endl;
}
else
- // otherwise create a whole 3d plot
- // for the data. use th patch method
- // of gnuplot for this
- //
- // run this loop backwards since otherwise
- // gnuplot thinks the upper side is the
- // lower side and draws the diagram in
- // strange colors
+ // otherwise create a whole 3d plot
+ // for the data. use th patch method
+ // of gnuplot for this
+ //
+ // run this loop backwards since otherwise
+ // gnuplot thinks the upper side is the
+ // lower side and draws the diagram in
+ // strange colors
for (int i=intervals.size()-1; i>=0; --i)
{
- for (unsigned int n=0; n<intervals[i].size(); ++n)
- out << intervals[i][n].left_point
- << ' '
- << (i<static_cast<int>(intervals.size())-1 ?
- y_values[i+1] :
- y_values[i] + (y_values[i]-y_values[i-1]))
- << ' '
- << intervals[i][n].content
- << std::endl
- << intervals[i][n].right_point
- << ' '
- << (i<static_cast<int>(intervals.size())-1 ?
- y_values[i+1] :
- y_values[i] + (y_values[i]-y_values[i-1]))
- << ' '
- << intervals[i][n].content
- << std::endl;
-
- out << std::endl;
- for (unsigned int n=0; n<intervals[i].size(); ++n)
- out << intervals[i][n].left_point
- << ' '
- << y_values[i]
- << ' '
- << intervals[i][n].content
- << std::endl
- << intervals[i][n].right_point
- << ' '
- << y_values[i]
- << ' '
- << intervals[i][n].content
- << std::endl;
-
- out << std::endl;
+ for (unsigned int n=0; n<intervals[i].size(); ++n)
+ out << intervals[i][n].left_point
+ << ' '
+ << (i<static_cast<int>(intervals.size())-1 ?
+ y_values[i+1] :
+ y_values[i] + (y_values[i]-y_values[i-1]))
+ << ' '
+ << intervals[i][n].content
+ << std::endl
+ << intervals[i][n].right_point
+ << ' '
+ << (i<static_cast<int>(intervals.size())-1 ?
+ y_values[i+1] :
+ y_values[i] + (y_values[i]-y_values[i-1]))
+ << ' '
+ << intervals[i][n].content
+ << std::endl;
+
+ out << std::endl;
+ for (unsigned int n=0; n<intervals[i].size(); ++n)
+ out << intervals[i][n].left_point
+ << ' '
+ << y_values[i]
+ << ' '
+ << intervals[i][n].content
+ << std::endl
+ << intervals[i][n].right_point
+ << ' '
+ << y_values[i]
+ << ' '
+ << intervals[i][n].content
+ << std::endl;
+
+ out << std::endl;
};
return logarithmic;
else
{
- AssertThrow (false, ExcInvalidName(name));
+ AssertThrow (false, ExcInvalidName(name));
- return linear;
+ return linear;
};
}
Histogram::memory_consumption () const
{
return (MemoryConsumption::memory_consumption (intervals) +
- MemoryConsumption::memory_consumption (y_values));
+ MemoryConsumption::memory_consumption (y_values));
}
// explicit instantiations for float
template
void Histogram::evaluate<float> (const std::vector<Vector<float> > &values,
- const std::vector<double> &y_values,
- const unsigned int n_intervals,
- const IntervalSpacing interval_spacing);
+ const std::vector<double> &y_values,
+ const unsigned int n_intervals,
+ const IntervalSpacing interval_spacing);
template
void Histogram::evaluate<float> (const Vector<float> &values,
- const unsigned int n_intervals,
- const IntervalSpacing interval_spacing);
+ const unsigned int n_intervals,
+ const IntervalSpacing interval_spacing);
// explicit instantiations for double
template
void Histogram::evaluate<double> (const std::vector<Vector<double> > &values,
- const std::vector<double> &y_values,
- const unsigned int n_intervals,
- const IntervalSpacing interval_spacing);
+ const std::vector<double> &y_values,
+ const unsigned int n_intervals,
+ const IntervalSpacing interval_spacing);
template
void Histogram::evaluate<double> (const Vector<double> &values,
- const unsigned int n_intervals,
- const IntervalSpacing interval_spacing);
+ const unsigned int n_intervals,
+ const IntervalSpacing interval_spacing);
DEAL_II_NAMESPACE_CLOSE
// $Id$
// Version: $Name$
//
-// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 by the deal.II authors
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
{
namespace internal
{
- /**
- * Convenience abbreviation for
- * pairs of DoF handler cell
- * iterators. This type works
- * just like a
- * <tt>std::pair<iterator,iterator></tt>
- * but is templatized on the
- * dof handler that shouls be used.
- */
+ /**
+ * Convenience abbreviation for
+ * pairs of DoF handler cell
+ * iterators. This type works
+ * just like a
+ * <tt>std::pair<iterator,iterator></tt>
+ * but is templatized on the
+ * dof handler that shouls be used.
+ */
template <typename DH>
struct IteratorRange
{
- /**
- * Typedef for the iterator type.
- */
- typedef typename DH::active_cell_iterator active_cell_iterator;
-
- /**
- * Abbreviation for a pair of
- * iterators.
- */
- typedef std::pair<active_cell_iterator,active_cell_iterator> iterator_pair;
-
- /**
- * Constructor. Initialize
- * the two values by the
- * given values.
- */
- IteratorRange (const active_cell_iterator &first,
- const active_cell_iterator &second);
-
- /**
- * Constructor taking a pair
- * of values for
- * initialization.
- */
- IteratorRange (const iterator_pair &ip);
-
- /**
- * Pair of iterators denoting
- * a half-open range.
- */
- active_cell_iterator first, second;
+ /**
+ * Typedef for the iterator type.
+ */
+ typedef typename DH::active_cell_iterator active_cell_iterator;
+
+ /**
+ * Abbreviation for a pair of
+ * iterators.
+ */
+ typedef std::pair<active_cell_iterator,active_cell_iterator> iterator_pair;
+
+ /**
+ * Constructor. Initialize
+ * the two values by the
+ * given values.
+ */
+ IteratorRange (const active_cell_iterator &first,
+ const active_cell_iterator &second);
+
+ /**
+ * Constructor taking a pair
+ * of values for
+ * initialization.
+ */
+ IteratorRange (const iterator_pair &ip);
+
+ /**
+ * Pair of iterators denoting
+ * a half-open range.
+ */
+ active_cell_iterator first, second;
};
inline
IteratorRange<DH>::
IteratorRange (const active_cell_iterator &first,
- const active_cell_iterator &second)
- :
- first (first),
- second (second)
+ const active_cell_iterator &second)
+ :
+ first (first),
+ second (second)
{}
template <typename DH>
inline
IteratorRange<DH>::IteratorRange (const iterator_pair &ip)
- :
- first (ip.first),
- second (ip.second)
+ :
+ first (ip.first),
+ second (ip.second)
{}
namespace AssemblerData
{
template <int dim,
- int spacedim>
+ int spacedim>
struct Scratch
{
- Scratch (const ::dealii::hp::FECollection<dim,spacedim> &fe,
- const UpdateFlags update_flags,
- const Function<spacedim> *coefficient,
- const Function<spacedim> *rhs_function,
- const ::dealii::hp::QCollection<dim> &quadrature,
- const ::dealii::hp::MappingCollection<dim,spacedim> &mapping)
- :
- fe_collection (fe),
- quadrature_collection (quadrature),
- mapping_collection (mapping),
- x_fe_values (mapping_collection,
- fe_collection,
- quadrature_collection,
- update_flags),
- coefficient_values(quadrature_collection.max_n_quadrature_points()),
- coefficient_vector_values (quadrature_collection.max_n_quadrature_points(),
- dealii::Vector<double> (fe_collection.n_components())),
- rhs_values(quadrature_collection.max_n_quadrature_points()),
- rhs_vector_values(quadrature_collection.max_n_quadrature_points(),
- dealii::Vector<double> (fe_collection.n_components())),
- coefficient (coefficient),
- rhs_function (rhs_function),
- update_flags (update_flags)
- {}
-
- Scratch (const Scratch &data)
- :
- fe_collection (data.fe_collection),
- quadrature_collection (data.quadrature_collection),
- mapping_collection (data.mapping_collection),
- x_fe_values (mapping_collection,
- fe_collection,
- quadrature_collection,
- data.update_flags),
- coefficient_values (data.coefficient_values),
- coefficient_vector_values (data.coefficient_vector_values),
- rhs_values (data.rhs_values),
- rhs_vector_values (data.rhs_vector_values),
- coefficient (data.coefficient),
- rhs_function (data.rhs_function),
- update_flags (data.update_flags)
- {}
-
- const ::dealii::hp::FECollection<dim,spacedim> &fe_collection;
- const ::dealii::hp::QCollection<dim> &quadrature_collection;
- const ::dealii::hp::MappingCollection<dim,spacedim> &mapping_collection;
-
- ::dealii::hp::FEValues<dim,spacedim> x_fe_values;
-
- std::vector<double> coefficient_values;
- std::vector<dealii::Vector<double> > coefficient_vector_values;
- std::vector<double> rhs_values;
- std::vector<dealii::Vector<double> > rhs_vector_values;
-
- std::vector<double> old_JxW;
-
- const Function<spacedim> *coefficient;
- const Function<spacedim> *rhs_function;
-
- const UpdateFlags update_flags;
+ Scratch (const ::dealii::hp::FECollection<dim,spacedim> &fe,
+ const UpdateFlags update_flags,
+ const Function<spacedim> *coefficient,
+ const Function<spacedim> *rhs_function,
+ const ::dealii::hp::QCollection<dim> &quadrature,
+ const ::dealii::hp::MappingCollection<dim,spacedim> &mapping)
+ :
+ fe_collection (fe),
+ quadrature_collection (quadrature),
+ mapping_collection (mapping),
+ x_fe_values (mapping_collection,
+ fe_collection,
+ quadrature_collection,
+ update_flags),
+ coefficient_values(quadrature_collection.max_n_quadrature_points()),
+ coefficient_vector_values (quadrature_collection.max_n_quadrature_points(),
+ dealii::Vector<double> (fe_collection.n_components())),
+ rhs_values(quadrature_collection.max_n_quadrature_points()),
+ rhs_vector_values(quadrature_collection.max_n_quadrature_points(),
+ dealii::Vector<double> (fe_collection.n_components())),
+ coefficient (coefficient),
+ rhs_function (rhs_function),
+ update_flags (update_flags)
+ {}
+
+ Scratch (const Scratch &data)
+ :
+ fe_collection (data.fe_collection),
+ quadrature_collection (data.quadrature_collection),
+ mapping_collection (data.mapping_collection),
+ x_fe_values (mapping_collection,
+ fe_collection,
+ quadrature_collection,
+ data.update_flags),
+ coefficient_values (data.coefficient_values),
+ coefficient_vector_values (data.coefficient_vector_values),
+ rhs_values (data.rhs_values),
+ rhs_vector_values (data.rhs_vector_values),
+ coefficient (data.coefficient),
+ rhs_function (data.rhs_function),
+ update_flags (data.update_flags)
+ {}
+
+ const ::dealii::hp::FECollection<dim,spacedim> &fe_collection;
+ const ::dealii::hp::QCollection<dim> &quadrature_collection;
+ const ::dealii::hp::MappingCollection<dim,spacedim> &mapping_collection;
+
+ ::dealii::hp::FEValues<dim,spacedim> x_fe_values;
+
+ std::vector<double> coefficient_values;
+ std::vector<dealii::Vector<double> > coefficient_vector_values;
+ std::vector<double> rhs_values;
+ std::vector<dealii::Vector<double> > rhs_vector_values;
+
+ std::vector<double> old_JxW;
+
+ const Function<spacedim> *coefficient;
+ const Function<spacedim> *rhs_function;
+
+ const UpdateFlags update_flags;
};
struct CopyData
{
- std::vector<unsigned int> dof_indices;
- FullMatrix<double> cell_matrix;
- dealii::Vector<double> cell_rhs;
+ std::vector<unsigned int> dof_indices;
+ FullMatrix<double> cell_matrix;
+ dealii::Vector<double> cell_rhs;
};
}
template <int dim,
- int spacedim,
- typename CellIterator>
+ int spacedim,
+ typename CellIterator>
void mass_assembler (const CellIterator &cell,
- MatrixCreator::internal::AssemblerData::Scratch<dim,spacedim> &data,
- MatrixCreator::internal::AssemblerData::CopyData ©_data)
+ MatrixCreator::internal::AssemblerData::Scratch<dim,spacedim> &data,
+ MatrixCreator::internal::AssemblerData::CopyData ©_data)
{
data.x_fe_values.reinit (cell);
const FEValues<dim,spacedim> &fe_values = data.x_fe_values.get_present_fe_values ();
const unsigned int dofs_per_cell = fe_values.dofs_per_cell,
- n_q_points = fe_values.n_quadrature_points;
+ n_q_points = fe_values.n_quadrature_points;
const FiniteElement<dim,spacedim> &fe = fe_values.get_fe();
const unsigned int n_components = fe.n_components();
Assert(data.rhs_function == 0 ||
- data.rhs_function->n_components==1 ||
- data.rhs_function->n_components==n_components,
- ::dealii::MatrixCreator::ExcComponentMismatch());
+ data.rhs_function->n_components==1 ||
+ data.rhs_function->n_components==n_components,
+ ::dealii::MatrixCreator::ExcComponentMismatch());
Assert(data.coefficient == 0 ||
- data.coefficient->n_components==1 ||
- data.coefficient->n_components==n_components,
- ::dealii::MatrixCreator::ExcComponentMismatch());
+ data.coefficient->n_components==1 ||
+ data.coefficient->n_components==n_components,
+ ::dealii::MatrixCreator::ExcComponentMismatch());
copy_data.cell_matrix.reinit (dofs_per_cell, dofs_per_cell);
copy_data.cell_rhs.reinit (dofs_per_cell);
const bool use_rhs_function = data.rhs_function != 0;
if (use_rhs_function)
- {
- if (data.rhs_function->n_components==1)
- {
- data.rhs_values.resize (n_q_points);
- data.rhs_function->value_list (fe_values.get_quadrature_points(),
- data.rhs_values);
- }
- else
- {
- data.rhs_vector_values.resize (n_q_points,
- dealii::Vector<double>(n_components));
- data.rhs_function->vector_value_list (fe_values.get_quadrature_points(),
- data.rhs_vector_values);
- }
- }
+ {
+ if (data.rhs_function->n_components==1)
+ {
+ data.rhs_values.resize (n_q_points);
+ data.rhs_function->value_list (fe_values.get_quadrature_points(),
+ data.rhs_values);
+ }
+ else
+ {
+ data.rhs_vector_values.resize (n_q_points,
+ dealii::Vector<double>(n_components));
+ data.rhs_function->vector_value_list (fe_values.get_quadrature_points(),
+ data.rhs_vector_values);
+ }
+ }
const bool use_coefficient = data.coefficient != 0;
if (use_coefficient)
- {
- if (data.coefficient->n_components==1)
- {
- data.coefficient_values.resize (n_q_points);
- data.coefficient->value_list (fe_values.get_quadrature_points(),
- data.coefficient_values);
- }
- else
- {
- data.coefficient_vector_values.resize (n_q_points,
- dealii::Vector<double>(n_components));
- data.coefficient->vector_value_list (fe_values.get_quadrature_points(),
- data.coefficient_vector_values);
- }
- }
+ {
+ if (data.coefficient->n_components==1)
+ {
+ data.coefficient_values.resize (n_q_points);
+ data.coefficient->value_list (fe_values.get_quadrature_points(),
+ data.coefficient_values);
+ }
+ else
+ {
+ data.coefficient_vector_values.resize (n_q_points,
+ dealii::Vector<double>(n_components));
+ data.coefficient->vector_value_list (fe_values.get_quadrature_points(),
+ data.coefficient_vector_values);
+ }
+ }
double add_data;
const std::vector<double> & JxW = fe_values.get_JxW_values();
for (unsigned int i=0; i<dofs_per_cell; ++i)
- if (fe.is_primitive ())
- {
- const unsigned int component_i =
- fe.system_to_component_index(i).first;
- const double * phi_i = &fe_values.shape_value(i,0);
- add_data = 0;
-
- // use symmetry in the mass matrix here:
- // just need to calculate the diagonal
- // and half of the elements above the
- // diagonal
- for (unsigned int j=i; j<dofs_per_cell; ++j)
- if ((n_components==1) ||
- (fe.system_to_component_index(j).first ==
- component_i))
- {
- const double * phi_j = &fe_values.shape_value(j,0);
- add_data = 0;
- if (use_coefficient)
- {
- if (data.coefficient->n_components==1)
- for (unsigned int point=0; point<n_q_points; ++point)
- add_data += (phi_i[point] * phi_j[point] * JxW[point] *
- data.coefficient_values[point]);
- else
- for (unsigned int point=0; point<n_q_points; ++point)
- add_data += (phi_i[point] * phi_j[point] * JxW[point] *
- data.coefficient_vector_values[point](component_i));
- }
- else
- for (unsigned int point=0; point<n_q_points; ++point)
- add_data += phi_i[point] * phi_j[point] * JxW[point];
-
- // this is even ok for i==j, since then
- // we just write the same value twice.
- copy_data.cell_matrix(i,j) = add_data;
- copy_data.cell_matrix(j,i) = add_data;
- }
-
- if (use_rhs_function)
- {
- add_data = 0;
- if (data.rhs_function->n_components==1)
- for (unsigned int point=0; point<n_q_points; ++point)
- add_data += phi_i[point] * JxW[point] *
- data.rhs_values[point];
- else
- for (unsigned int point=0; point<n_q_points; ++point)
- add_data += phi_i[point] * JxW[point] *
- data.rhs_vector_values[point](component_i);
- copy_data.cell_rhs(i) = add_data;
- }
- }
- else
- {
- // non-primitive vector-valued FE, using
- // symmetry again
- for (unsigned int j=i; j<dofs_per_cell; ++j)
- {
- add_data = 0;
- for (unsigned int comp_i = 0; comp_i < n_components; ++comp_i)
- if (fe.get_nonzero_components(i)[comp_i] &&
- fe.get_nonzero_components(j)[comp_i])
- {
- if (use_coefficient)
- {
- if (data.coefficient->n_components==1)
- for (unsigned int point=0; point<n_q_points; ++point)
- add_data += (fe_values.shape_value_component(i,point,comp_i) *
- fe_values.shape_value_component(j,point,comp_i) *
- JxW[point] *
- data.coefficient_values[point]);
- else
- for (unsigned int point=0; point<n_q_points; ++point)
- add_data += (fe_values.shape_value_component(i,point,comp_i) *
- fe_values.shape_value_component(j,point,comp_i) *
- JxW[point] *
- data.coefficient_vector_values[point](comp_i));
- }
- else
- for (unsigned int point=0; point<n_q_points; ++point)
- add_data += fe_values.shape_value_component(i,point,comp_i) *
- fe_values.shape_value_component(j,point,comp_i) * JxW[point];
- }
-
- copy_data.cell_matrix(i,j) = add_data;
- copy_data.cell_matrix(j,i) = add_data;
- }
-
- if (use_rhs_function)
- {
- add_data = 0;
- for (unsigned int comp_i = 0; comp_i < n_components; ++comp_i)
- if (fe.get_nonzero_components(i)[comp_i])
- {
- if (data.rhs_function->n_components==1)
- for (unsigned int point=0; point<n_q_points; ++point)
- add_data += fe_values.shape_value_component(i,point,comp_i) *
- JxW[point] * data.rhs_values[point];
- else
- for (unsigned int point=0; point<n_q_points; ++point)
- add_data += fe_values.shape_value_component(i,point,comp_i) *
- JxW[point] * data.rhs_vector_values[point](comp_i);
- }
- copy_data.cell_rhs(i) = add_data;
- }
- }
+ if (fe.is_primitive ())
+ {
+ const unsigned int component_i =
+ fe.system_to_component_index(i).first;
+ const double * phi_i = &fe_values.shape_value(i,0);
+ add_data = 0;
+
+ // use symmetry in the mass matrix here:
+ // just need to calculate the diagonal
+ // and half of the elements above the
+ // diagonal
+ for (unsigned int j=i; j<dofs_per_cell; ++j)
+ if ((n_components==1) ||
+ (fe.system_to_component_index(j).first ==
+ component_i))
+ {
+ const double * phi_j = &fe_values.shape_value(j,0);
+ add_data = 0;
+ if (use_coefficient)
+ {
+ if (data.coefficient->n_components==1)
+ for (unsigned int point=0; point<n_q_points; ++point)
+ add_data += (phi_i[point] * phi_j[point] * JxW[point] *
+ data.coefficient_values[point]);
+ else
+ for (unsigned int point=0; point<n_q_points; ++point)
+ add_data += (phi_i[point] * phi_j[point] * JxW[point] *
+ data.coefficient_vector_values[point](component_i));
+ }
+ else
+ for (unsigned int point=0; point<n_q_points; ++point)
+ add_data += phi_i[point] * phi_j[point] * JxW[point];
+
+ // this is even ok for i==j, since then
+ // we just write the same value twice.
+ copy_data.cell_matrix(i,j) = add_data;
+ copy_data.cell_matrix(j,i) = add_data;
+ }
+
+ if (use_rhs_function)
+ {
+ add_data = 0;
+ if (data.rhs_function->n_components==1)
+ for (unsigned int point=0; point<n_q_points; ++point)
+ add_data += phi_i[point] * JxW[point] *
+ data.rhs_values[point];
+ else
+ for (unsigned int point=0; point<n_q_points; ++point)
+ add_data += phi_i[point] * JxW[point] *
+ data.rhs_vector_values[point](component_i);
+ copy_data.cell_rhs(i) = add_data;
+ }
+ }
+ else
+ {
+ // non-primitive vector-valued FE, using
+ // symmetry again
+ for (unsigned int j=i; j<dofs_per_cell; ++j)
+ {
+ add_data = 0;
+ for (unsigned int comp_i = 0; comp_i < n_components; ++comp_i)
+ if (fe.get_nonzero_components(i)[comp_i] &&
+ fe.get_nonzero_components(j)[comp_i])
+ {
+ if (use_coefficient)
+ {
+ if (data.coefficient->n_components==1)
+ for (unsigned int point=0; point<n_q_points; ++point)
+ add_data += (fe_values.shape_value_component(i,point,comp_i) *
+ fe_values.shape_value_component(j,point,comp_i) *
+ JxW[point] *
+ data.coefficient_values[point]);
+ else
+ for (unsigned int point=0; point<n_q_points; ++point)
+ add_data += (fe_values.shape_value_component(i,point,comp_i) *
+ fe_values.shape_value_component(j,point,comp_i) *
+ JxW[point] *
+ data.coefficient_vector_values[point](comp_i));
+ }
+ else
+ for (unsigned int point=0; point<n_q_points; ++point)
+ add_data += fe_values.shape_value_component(i,point,comp_i) *
+ fe_values.shape_value_component(j,point,comp_i) * JxW[point];
+ }
+
+ copy_data.cell_matrix(i,j) = add_data;
+ copy_data.cell_matrix(j,i) = add_data;
+ }
+
+ if (use_rhs_function)
+ {
+ add_data = 0;
+ for (unsigned int comp_i = 0; comp_i < n_components; ++comp_i)
+ if (fe.get_nonzero_components(i)[comp_i])
+ {
+ if (data.rhs_function->n_components==1)
+ for (unsigned int point=0; point<n_q_points; ++point)
+ add_data += fe_values.shape_value_component(i,point,comp_i) *
+ JxW[point] * data.rhs_values[point];
+ else
+ for (unsigned int point=0; point<n_q_points; ++point)
+ add_data += fe_values.shape_value_component(i,point,comp_i) *
+ JxW[point] * data.rhs_vector_values[point](comp_i);
+ }
+ copy_data.cell_rhs(i) = add_data;
+ }
+ }
}
template <int dim,
- int spacedim,
- typename CellIterator>
+ int spacedim,
+ typename CellIterator>
void laplace_assembler (const CellIterator &cell,
- MatrixCreator::internal::AssemblerData::Scratch<dim,spacedim> &data,
- MatrixCreator::internal::AssemblerData::CopyData ©_data)
+ MatrixCreator::internal::AssemblerData::Scratch<dim,spacedim> &data,
+ MatrixCreator::internal::AssemblerData::CopyData ©_data)
{
data.x_fe_values.reinit (cell);
const FEValues<dim,spacedim> &fe_values = data.x_fe_values.get_present_fe_values ();
const unsigned int dofs_per_cell = fe_values.dofs_per_cell,
- n_q_points = fe_values.n_quadrature_points;
+ n_q_points = fe_values.n_quadrature_points;
const FiniteElement<dim,spacedim> &fe = fe_values.get_fe();
const unsigned int n_components = fe.n_components();
Assert(data.rhs_function == 0 ||
- data.rhs_function->n_components==1 ||
- data.rhs_function->n_components==n_components,
- ::dealii::MatrixCreator::ExcComponentMismatch());
+ data.rhs_function->n_components==1 ||
+ data.rhs_function->n_components==n_components,
+ ::dealii::MatrixCreator::ExcComponentMismatch());
Assert(data.coefficient == 0 ||
- data.coefficient->n_components==1 ||
- data.coefficient->n_components==n_components,
- ::dealii::MatrixCreator::ExcComponentMismatch());
+ data.coefficient->n_components==1 ||
+ data.coefficient->n_components==n_components,
+ ::dealii::MatrixCreator::ExcComponentMismatch());
copy_data.cell_matrix.reinit (dofs_per_cell, dofs_per_cell);
copy_data.cell_rhs.reinit (dofs_per_cell);
const bool use_rhs_function = data.rhs_function != 0;
if (use_rhs_function)
- {
- if (data.rhs_function->n_components==1)
- {
- data.rhs_values.resize (n_q_points);
- data.rhs_function->value_list (fe_values.get_quadrature_points(),
- data.rhs_values);
- }
- else
- {
- data.rhs_vector_values.resize (n_q_points,
- dealii::Vector<double>(n_components));
- data.rhs_function->vector_value_list (fe_values.get_quadrature_points(),
- data.rhs_vector_values);
- }
- }
+ {
+ if (data.rhs_function->n_components==1)
+ {
+ data.rhs_values.resize (n_q_points);
+ data.rhs_function->value_list (fe_values.get_quadrature_points(),
+ data.rhs_values);
+ }
+ else
+ {
+ data.rhs_vector_values.resize (n_q_points,
+ dealii::Vector<double>(n_components));
+ data.rhs_function->vector_value_list (fe_values.get_quadrature_points(),
+ data.rhs_vector_values);
+ }
+ }
const bool use_coefficient = data.coefficient != 0;
if (use_coefficient)
- {
- if (data.coefficient->n_components==1)
- {
- data.coefficient_values.resize (n_q_points);
- data.coefficient->value_list (fe_values.get_quadrature_points(),
- data.coefficient_values);
- }
- else
- {
- data.coefficient_vector_values.resize (n_q_points,
- dealii::Vector<double>(n_components));
- data.coefficient->vector_value_list (fe_values.get_quadrature_points(),
- data.coefficient_vector_values);
- }
- }
+ {
+ if (data.coefficient->n_components==1)
+ {
+ data.coefficient_values.resize (n_q_points);
+ data.coefficient->value_list (fe_values.get_quadrature_points(),
+ data.coefficient_values);
+ }
+ else
+ {
+ data.coefficient_vector_values.resize (n_q_points,
+ dealii::Vector<double>(n_components));
+ data.coefficient->vector_value_list (fe_values.get_quadrature_points(),
+ data.coefficient_vector_values);
+ }
+ }
const std::vector<double> & JxW = fe_values.get_JxW_values();
double add_data;
for (unsigned int i=0; i<dofs_per_cell; ++i)
- if (fe.is_primitive ())
- {
- const unsigned int component_i =
- fe.system_to_component_index(i).first;
- const Tensor<1,spacedim> * grad_phi_i =
- &fe_values.shape_grad(i,0);
-
- // can use symmetry
- for (unsigned int j=i; j<dofs_per_cell; ++j)
- if ((n_components==1) ||
- (fe.system_to_component_index(j).first ==
- component_i))
- {
- const Tensor<1,spacedim> * grad_phi_j =
- & fe_values.shape_grad(j,0);
- add_data = 0;
- if (use_coefficient)
- {
- if (data.coefficient->n_components==1)
- for (unsigned int point=0; point<n_q_points; ++point)
- add_data += ((grad_phi_i[point]*grad_phi_j[point]) *
- JxW[point] *
- data.coefficient_values[point]);
- else
- for (unsigned int point=0; point<n_q_points; ++point)
- add_data += ((grad_phi_i[point]*grad_phi_j[point]) *
- JxW[point] *
- data.coefficient_vector_values[point](component_i));
- }
- else
- for (unsigned int point=0; point<n_q_points; ++point)
- add_data += (grad_phi_i[point]*grad_phi_j[point]) *
- JxW[point];
-
- copy_data.cell_matrix(i,j) = add_data;
- copy_data.cell_matrix(j,i) = add_data;
- }
-
- if (use_rhs_function)
- {
- const double * phi_i = &fe_values.shape_value(i,0);
- add_data = 0;
- if (data.rhs_function->n_components==1)
- for (unsigned int point=0; point<n_q_points; ++point)
- add_data += phi_i[point] * JxW[point] *
- data.rhs_values[point];
- else
- for (unsigned int point=0; point<n_q_points; ++point)
- add_data += phi_i[point] * JxW[point] *
- data.rhs_vector_values[point](component_i);
- copy_data.cell_rhs(i) = add_data;
- }
- }
- else
- {
- // non-primitive vector-valued FE
- for (unsigned int j=i; j<dofs_per_cell; ++j)
- {
- add_data = 0;
- for (unsigned int comp_i = 0; comp_i < n_components; ++comp_i)
- if (fe.get_nonzero_components(i)[comp_i] &&
- fe.get_nonzero_components(j)[comp_i])
- {
- if (use_coefficient)
- {
- if (data.coefficient->n_components==1)
- for (unsigned int point=0; point<n_q_points; ++point)
- add_data += ((fe_values.shape_grad_component(i,point,comp_i) *
- fe_values.shape_grad_component(j,point,comp_i)) *
- JxW[point] *
- data.coefficient_values[point]);
- else
- for (unsigned int point=0; point<n_q_points; ++point)
- add_data += ((fe_values.shape_grad_component(i,point,comp_i) *
- fe_values.shape_grad_component(j,point,comp_i)) *
- JxW[point] *
- data.coefficient_vector_values[point](comp_i));
- }
- else
- for (unsigned int point=0; point<n_q_points; ++point)
- add_data += (fe_values.shape_grad_component(i,point,comp_i) *
- fe_values.shape_grad_component(j,point,comp_i)) *
- JxW[point];
- }
-
- copy_data.cell_matrix(i,j) = add_data;
- copy_data.cell_matrix(j,i) = add_data;
- }
-
- if (use_rhs_function)
- {
- add_data = 0;
- for (unsigned int comp_i = 0; comp_i < n_components; ++comp_i)
- if (fe.get_nonzero_components(i)[comp_i])
- {
- if (data.rhs_function->n_components==1)
- for (unsigned int point=0; point<n_q_points; ++point)
- add_data += fe_values.shape_value_component(i,point,comp_i) *
- JxW[point] * data.rhs_values[point];
- else
- for (unsigned int point=0; point<n_q_points; ++point)
- add_data += fe_values.shape_value_component(i,point,comp_i) *
- JxW[point] * data.rhs_vector_values[point](comp_i);
- }
- copy_data.cell_rhs(i) = add_data;
- }
- }
+ if (fe.is_primitive ())
+ {
+ const unsigned int component_i =
+ fe.system_to_component_index(i).first;
+ const Tensor<1,spacedim> * grad_phi_i =
+ &fe_values.shape_grad(i,0);
+
+ // can use symmetry
+ for (unsigned int j=i; j<dofs_per_cell; ++j)
+ if ((n_components==1) ||
+ (fe.system_to_component_index(j).first ==
+ component_i))
+ {
+ const Tensor<1,spacedim> * grad_phi_j =
+ & fe_values.shape_grad(j,0);
+ add_data = 0;
+ if (use_coefficient)
+ {
+ if (data.coefficient->n_components==1)
+ for (unsigned int point=0; point<n_q_points; ++point)
+ add_data += ((grad_phi_i[point]*grad_phi_j[point]) *
+ JxW[point] *
+ data.coefficient_values[point]);
+ else
+ for (unsigned int point=0; point<n_q_points; ++point)
+ add_data += ((grad_phi_i[point]*grad_phi_j[point]) *
+ JxW[point] *
+ data.coefficient_vector_values[point](component_i));
+ }
+ else
+ for (unsigned int point=0; point<n_q_points; ++point)
+ add_data += (grad_phi_i[point]*grad_phi_j[point]) *
+ JxW[point];
+
+ copy_data.cell_matrix(i,j) = add_data;
+ copy_data.cell_matrix(j,i) = add_data;
+ }
+
+ if (use_rhs_function)
+ {
+ const double * phi_i = &fe_values.shape_value(i,0);
+ add_data = 0;
+ if (data.rhs_function->n_components==1)
+ for (unsigned int point=0; point<n_q_points; ++point)
+ add_data += phi_i[point] * JxW[point] *
+ data.rhs_values[point];
+ else
+ for (unsigned int point=0; point<n_q_points; ++point)
+ add_data += phi_i[point] * JxW[point] *
+ data.rhs_vector_values[point](component_i);
+ copy_data.cell_rhs(i) = add_data;
+ }
+ }
+ else
+ {
+ // non-primitive vector-valued FE
+ for (unsigned int j=i; j<dofs_per_cell; ++j)
+ {
+ add_data = 0;
+ for (unsigned int comp_i = 0; comp_i < n_components; ++comp_i)
+ if (fe.get_nonzero_components(i)[comp_i] &&
+ fe.get_nonzero_components(j)[comp_i])
+ {
+ if (use_coefficient)
+ {
+ if (data.coefficient->n_components==1)
+ for (unsigned int point=0; point<n_q_points; ++point)
+ add_data += ((fe_values.shape_grad_component(i,point,comp_i) *
+ fe_values.shape_grad_component(j,point,comp_i)) *
+ JxW[point] *
+ data.coefficient_values[point]);
+ else
+ for (unsigned int point=0; point<n_q_points; ++point)
+ add_data += ((fe_values.shape_grad_component(i,point,comp_i) *
+ fe_values.shape_grad_component(j,point,comp_i)) *
+ JxW[point] *
+ data.coefficient_vector_values[point](comp_i));
+ }
+ else
+ for (unsigned int point=0; point<n_q_points; ++point)
+ add_data += (fe_values.shape_grad_component(i,point,comp_i) *
+ fe_values.shape_grad_component(j,point,comp_i)) *
+ JxW[point];
+ }
+
+ copy_data.cell_matrix(i,j) = add_data;
+ copy_data.cell_matrix(j,i) = add_data;
+ }
+
+ if (use_rhs_function)
+ {
+ add_data = 0;
+ for (unsigned int comp_i = 0; comp_i < n_components; ++comp_i)
+ if (fe.get_nonzero_components(i)[comp_i])
+ {
+ if (data.rhs_function->n_components==1)
+ for (unsigned int point=0; point<n_q_points; ++point)
+ add_data += fe_values.shape_value_component(i,point,comp_i) *
+ JxW[point] * data.rhs_values[point];
+ else
+ for (unsigned int point=0; point<n_q_points; ++point)
+ add_data += fe_values.shape_value_component(i,point,comp_i) *
+ JxW[point] * data.rhs_vector_values[point](comp_i);
+ }
+ copy_data.cell_rhs(i) = add_data;
+ }
+ }
}
template <typename MatrixType,
- typename VectorType>
+ typename VectorType>
void copy_local_to_global (const AssemblerData::CopyData &data,
- MatrixType *matrix,
- VectorType *right_hand_side)
+ MatrixType *matrix,
+ VectorType *right_hand_side)
{
const unsigned int dofs_per_cell = data.dof_indices.size();
Assert (data.cell_matrix.m() == dofs_per_cell,
- ExcInternalError());
+ ExcInternalError());
Assert (data.cell_matrix.n() == dofs_per_cell,
- ExcInternalError());
+ ExcInternalError());
Assert ((right_hand_side == 0)
- ||
- (data.cell_rhs.size() == dofs_per_cell),
- ExcInternalError());
+ ||
+ (data.cell_rhs.size() == dofs_per_cell),
+ ExcInternalError());
matrix->add(data.dof_indices, data.cell_matrix);
if (right_hand_side != 0)
- for (unsigned int i=0; i<dofs_per_cell; ++i)
- (*right_hand_side)(data.dof_indices[i]) += data.cell_rhs(i);
+ for (unsigned int i=0; i<dofs_per_cell; ++i)
+ (*right_hand_side)(data.dof_indices[i]) += data.cell_rhs(i);
}
}
}
template <int dim, typename number, int spacedim>
void create_mass_matrix (const Mapping<dim,spacedim> &mapping,
- const DoFHandler<dim,spacedim> &dof,
- const Quadrature<dim> &q,
- SparseMatrix<number> &matrix,
- const Function<spacedim> * const coefficient)
+ const DoFHandler<dim,spacedim> &dof,
+ const Quadrature<dim> &q,
+ SparseMatrix<number> &matrix,
+ const Function<spacedim> * const coefficient)
{
Assert (matrix.m() == dof.n_dofs(),
- ExcDimensionMismatch (matrix.m(), dof.n_dofs()));
+ ExcDimensionMismatch (matrix.m(), dof.n_dofs()));
Assert (matrix.n() == dof.n_dofs(),
- ExcDimensionMismatch (matrix.n(), dof.n_dofs()));
+ ExcDimensionMismatch (matrix.n(), dof.n_dofs()));
hp::FECollection<dim,spacedim> fe_collection (dof.get_fe());
hp::QCollection<dim> q_collection (q);
hp::MappingCollection<dim,spacedim> mapping_collection (mapping);
MatrixCreator::internal::AssemblerData::Scratch<dim, spacedim>
assembler_data (fe_collection,
- update_values | update_JxW_values |
- (coefficient != 0 ? update_quadrature_points : UpdateFlags(0)),
- coefficient, /*rhs_function=*/0,
- q_collection, mapping_collection);
+ update_values | update_JxW_values |
+ (coefficient != 0 ? update_quadrature_points : UpdateFlags(0)),
+ coefficient, /*rhs_function=*/0,
+ q_collection, mapping_collection);
MatrixCreator::internal::AssemblerData::CopyData copy_data;
copy_data.cell_matrix.reinit (assembler_data.fe_collection.max_dofs_per_cell(),
- assembler_data.fe_collection.max_dofs_per_cell());
+ assembler_data.fe_collection.max_dofs_per_cell());
copy_data.cell_rhs.reinit (assembler_data.fe_collection.max_dofs_per_cell());
copy_data.dof_indices.resize (assembler_data.fe_collection.max_dofs_per_cell());
WorkStream::run (dof.begin_active(),
- static_cast<typename DoFHandler<dim,spacedim>::active_cell_iterator>(dof.end()),
- &MatrixCreator::internal::mass_assembler<dim, spacedim, typename DoFHandler<dim,spacedim>::active_cell_iterator>,
- std_cxx1x::bind (&MatrixCreator::internal::
- copy_local_to_global<SparseMatrix<number>, Vector<double> >,
- std_cxx1x::_1, &matrix, (Vector<double>*)0),
- assembler_data,
- copy_data);
+ static_cast<typename DoFHandler<dim,spacedim>::active_cell_iterator>(dof.end()),
+ &MatrixCreator::internal::mass_assembler<dim, spacedim, typename DoFHandler<dim,spacedim>::active_cell_iterator>,
+ std_cxx1x::bind (&MatrixCreator::internal::
+ copy_local_to_global<SparseMatrix<number>, Vector<double> >,
+ std_cxx1x::_1, &matrix, (Vector<double>*)0),
+ assembler_data,
+ copy_data);
}
template <int dim, typename number, int spacedim>
void create_mass_matrix (const DoFHandler<dim,spacedim> &dof,
- const Quadrature<dim> &q,
- SparseMatrix<number> &matrix,
- const Function<spacedim> * const coefficient)
+ const Quadrature<dim> &q,
+ SparseMatrix<number> &matrix,
+ const Function<spacedim> * const coefficient)
{
Assert (DEAL_II_COMPAT_MAPPING, ExcCompatibility("mapping"));
create_mass_matrix(StaticMappingQ1<dim,spacedim>::mapping, dof,
- q, matrix, coefficient);
+ q, matrix, coefficient);
}
template <int dim, typename number, int spacedim>
void create_mass_matrix (const Mapping<dim,spacedim> &mapping,
- const DoFHandler<dim,spacedim> &dof,
- const Quadrature<dim> &q,
- SparseMatrix<number> &matrix,
- const Function<spacedim> &rhs,
- Vector<double> &rhs_vector,
- const Function<spacedim> * const coefficient)
+ const DoFHandler<dim,spacedim> &dof,
+ const Quadrature<dim> &q,
+ SparseMatrix<number> &matrix,
+ const Function<spacedim> &rhs,
+ Vector<double> &rhs_vector,
+ const Function<spacedim> * const coefficient)
{
Assert (matrix.m() == dof.n_dofs(),
- ExcDimensionMismatch (matrix.m(), dof.n_dofs()));
+ ExcDimensionMismatch (matrix.m(), dof.n_dofs()));
Assert (matrix.n() == dof.n_dofs(),
- ExcDimensionMismatch (matrix.n(), dof.n_dofs()));
+ ExcDimensionMismatch (matrix.n(), dof.n_dofs()));
hp::FECollection<dim,spacedim> fe_collection (dof.get_fe());
hp::QCollection<dim> q_collection (q);
hp::MappingCollection<dim,spacedim> mapping_collection (mapping);
MatrixCreator::internal::AssemblerData::Scratch<dim, spacedim>
assembler_data (fe_collection,
- update_values |
- update_JxW_values | update_quadrature_points,
- coefficient, &rhs,
- q_collection, mapping_collection);
+ update_values |
+ update_JxW_values | update_quadrature_points,
+ coefficient, &rhs,
+ q_collection, mapping_collection);
MatrixCreator::internal::AssemblerData::CopyData copy_data;
copy_data.cell_matrix.reinit (assembler_data.fe_collection.max_dofs_per_cell(),
- assembler_data.fe_collection.max_dofs_per_cell());
+ assembler_data.fe_collection.max_dofs_per_cell());
copy_data.cell_rhs.reinit (assembler_data.fe_collection.max_dofs_per_cell());
copy_data.dof_indices.resize (assembler_data.fe_collection.max_dofs_per_cell());
WorkStream::run (dof.begin_active(),
- static_cast<typename DoFHandler<dim,spacedim>::active_cell_iterator>(dof.end()),
- &MatrixCreator::internal::mass_assembler<dim, spacedim, typename DoFHandler<dim,spacedim>::active_cell_iterator>,
- std_cxx1x::bind(&MatrixCreator::internal::
- copy_local_to_global<SparseMatrix<number>, Vector<double> >,
- std_cxx1x::_1, &matrix, &rhs_vector),
- assembler_data,
- copy_data);
+ static_cast<typename DoFHandler<dim,spacedim>::active_cell_iterator>(dof.end()),
+ &MatrixCreator::internal::mass_assembler<dim, spacedim, typename DoFHandler<dim,spacedim>::active_cell_iterator>,
+ std_cxx1x::bind(&MatrixCreator::internal::
+ copy_local_to_global<SparseMatrix<number>, Vector<double> >,
+ std_cxx1x::_1, &matrix, &rhs_vector),
+ assembler_data,
+ copy_data);
}
template <int dim, typename number, int spacedim>
void create_mass_matrix (const DoFHandler<dim,spacedim> &dof,
- const Quadrature<dim> &q,
- SparseMatrix<number> &matrix,
- const Function<spacedim> &rhs,
- Vector<double> &rhs_vector,
- const Function<spacedim> * const coefficient)
+ const Quadrature<dim> &q,
+ SparseMatrix<number> &matrix,
+ const Function<spacedim> &rhs,
+ Vector<double> &rhs_vector,
+ const Function<spacedim> * const coefficient)
{
Assert (DEAL_II_COMPAT_MAPPING, ExcCompatibility("mapping"));
create_mass_matrix(StaticMappingQ1<dim,spacedim>::mapping,
- dof, q, matrix, rhs, rhs_vector, coefficient);
+ dof, q, matrix, rhs, rhs_vector, coefficient);
}
template <int dim, typename number, int spacedim>
void create_mass_matrix (const hp::MappingCollection<dim,spacedim> &mapping,
- const hp::DoFHandler<dim,spacedim> &dof,
- const hp::QCollection<dim> &q,
- SparseMatrix<number> &matrix,
- const Function<spacedim> * const coefficient)
+ const hp::DoFHandler<dim,spacedim> &dof,
+ const hp::QCollection<dim> &q,
+ SparseMatrix<number> &matrix,
+ const Function<spacedim> * const coefficient)
{
Assert (matrix.m() == dof.n_dofs(),
- ExcDimensionMismatch (matrix.m(), dof.n_dofs()));
+ ExcDimensionMismatch (matrix.m(), dof.n_dofs()));
Assert (matrix.n() == dof.n_dofs(),
- ExcDimensionMismatch (matrix.n(), dof.n_dofs()));
+ ExcDimensionMismatch (matrix.n(), dof.n_dofs()));
MatrixCreator::internal::AssemblerData::Scratch<dim, spacedim>
assembler_data (dof.get_fe(),
- update_values | update_JxW_values |
- (coefficient != 0 ? update_quadrature_points : UpdateFlags(0)),
- coefficient, /*rhs_function=*/0,
- q, mapping);
+ update_values | update_JxW_values |
+ (coefficient != 0 ? update_quadrature_points : UpdateFlags(0)),
+ coefficient, /*rhs_function=*/0,
+ q, mapping);
MatrixCreator::internal::AssemblerData::CopyData copy_data;
copy_data.cell_matrix.reinit (assembler_data.fe_collection.max_dofs_per_cell(),
- assembler_data.fe_collection.max_dofs_per_cell());
+ assembler_data.fe_collection.max_dofs_per_cell());
copy_data.cell_rhs.reinit (assembler_data.fe_collection.max_dofs_per_cell());
copy_data.dof_indices.resize (assembler_data.fe_collection.max_dofs_per_cell());
WorkStream::run (dof.begin_active(),
- static_cast<typename hp::DoFHandler<dim,spacedim>::active_cell_iterator>(dof.end()),
- &MatrixCreator::internal::mass_assembler<dim, spacedim, typename hp::DoFHandler<dim,spacedim>::active_cell_iterator>,
- std_cxx1x::bind (&MatrixCreator::internal::
- copy_local_to_global<SparseMatrix<number>, Vector<double> >,
- std_cxx1x::_1, &matrix, (Vector<double>*)0),
- assembler_data,
- copy_data);
+ static_cast<typename hp::DoFHandler<dim,spacedim>::active_cell_iterator>(dof.end()),
+ &MatrixCreator::internal::mass_assembler<dim, spacedim, typename hp::DoFHandler<dim,spacedim>::active_cell_iterator>,
+ std_cxx1x::bind (&MatrixCreator::internal::
+ copy_local_to_global<SparseMatrix<number>, Vector<double> >,
+ std_cxx1x::_1, &matrix, (Vector<double>*)0),
+ assembler_data,
+ copy_data);
}
template <int dim, typename number, int spacedim>
void create_mass_matrix (const hp::DoFHandler<dim,spacedim> &dof,
- const hp::QCollection<dim> &q,
- SparseMatrix<number> &matrix,
- const Function<spacedim> * const coefficient)
+ const hp::QCollection<dim> &q,
+ SparseMatrix<number> &matrix,
+ const Function<spacedim> * const coefficient)
{
Assert (DEAL_II_COMPAT_MAPPING, ExcCompatibility("mapping"));
create_mass_matrix(hp::StaticMappingQ1<dim,spacedim>::mapping_collection, dof, q, matrix, coefficient);
template <int dim, typename number, int spacedim>
void create_mass_matrix (const hp::MappingCollection<dim,spacedim> &mapping,
- const hp::DoFHandler<dim,spacedim> &dof,
- const hp::QCollection<dim> &q,
- SparseMatrix<number> &matrix,
- const Function<spacedim> &rhs,
- Vector<double> &rhs_vector,
- const Function<spacedim> * const coefficient)
+ const hp::DoFHandler<dim,spacedim> &dof,
+ const hp::QCollection<dim> &q,
+ SparseMatrix<number> &matrix,
+ const Function<spacedim> &rhs,
+ Vector<double> &rhs_vector,
+ const Function<spacedim> * const coefficient)
{
Assert (matrix.m() == dof.n_dofs(),
- ExcDimensionMismatch (matrix.m(), dof.n_dofs()));
+ ExcDimensionMismatch (matrix.m(), dof.n_dofs()));
Assert (matrix.n() == dof.n_dofs(),
- ExcDimensionMismatch (matrix.n(), dof.n_dofs()));
+ ExcDimensionMismatch (matrix.n(), dof.n_dofs()));
MatrixCreator::internal::AssemblerData::Scratch<dim, spacedim>
assembler_data (dof.get_fe(),
- update_values |
- update_JxW_values | update_quadrature_points,
- coefficient, &rhs,
- q, mapping);
+ update_values |
+ update_JxW_values | update_quadrature_points,
+ coefficient, &rhs,
+ q, mapping);
MatrixCreator::internal::AssemblerData::CopyData copy_data;
copy_data.cell_matrix.reinit (assembler_data.fe_collection.max_dofs_per_cell(),
- assembler_data.fe_collection.max_dofs_per_cell());
+ assembler_data.fe_collection.max_dofs_per_cell());
copy_data.cell_rhs.reinit (assembler_data.fe_collection.max_dofs_per_cell());
copy_data.dof_indices.resize (assembler_data.fe_collection.max_dofs_per_cell());
WorkStream::run (dof.begin_active(),
- static_cast<typename hp::DoFHandler<dim,spacedim>::active_cell_iterator>(dof.end()),
- &MatrixCreator::internal::mass_assembler<dim, spacedim, typename hp::DoFHandler<dim,spacedim>::active_cell_iterator>,
- std_cxx1x::bind (&MatrixCreator::internal::
- copy_local_to_global<SparseMatrix<number>, Vector<double> >,
- std_cxx1x::_1, &matrix, &rhs_vector),
- assembler_data,
- copy_data);
+ static_cast<typename hp::DoFHandler<dim,spacedim>::active_cell_iterator>(dof.end()),
+ &MatrixCreator::internal::mass_assembler<dim, spacedim, typename hp::DoFHandler<dim,spacedim>::active_cell_iterator>,
+ std_cxx1x::bind (&MatrixCreator::internal::
+ copy_local_to_global<SparseMatrix<number>, Vector<double> >,
+ std_cxx1x::_1, &matrix, &rhs_vector),
+ assembler_data,
+ copy_data);
}
template <int dim, typename number, int spacedim>
void create_mass_matrix (const hp::DoFHandler<dim,spacedim> &dof,
- const hp::QCollection<dim> &q,
- SparseMatrix<number> &matrix,
- const Function<spacedim> &rhs,
- Vector<double> &rhs_vector,
- const Function<spacedim> * const coefficient)
+ const hp::QCollection<dim> &q,
+ SparseMatrix<number> &matrix,
+ const Function<spacedim> &rhs,
+ Vector<double> &rhs_vector,
+ const Function<spacedim> * const coefficient)
{
Assert (DEAL_II_COMPAT_MAPPING, ExcCompatibility("mapping"));
create_mass_matrix(hp::StaticMappingQ1<dim,spacedim>::mapping_collection, dof, q,
- matrix, rhs, rhs_vector, coefficient);
+ matrix, rhs, rhs_vector, coefficient);
}
template <int dim, int spacedim>
void
create_boundary_mass_matrix_1 (std_cxx1x::tuple<const Mapping<dim, spacedim> &,
- const DoFHandler<dim,spacedim> &,
- const Quadrature<dim-1> & > commons,
- SparseMatrix<double> &matrix,
- const typename FunctionMap<spacedim>::type &boundary_functions,
- Vector<double> &rhs_vector,
- std::vector<unsigned int> &dof_to_boundary_mapping,
- const Function<spacedim> * const coefficient,
- const std::vector<unsigned int>& component_mapping,
- const MatrixCreator::internal::IteratorRange<DoFHandler<dim,spacedim> > range,
- Threads::ThreadMutex &mutex)
+ const DoFHandler<dim,spacedim> &,
+ const Quadrature<dim-1> & > commons,
+ SparseMatrix<double> &matrix,
+ const typename FunctionMap<spacedim>::type &boundary_functions,
+ Vector<double> &rhs_vector,
+ std::vector<unsigned int> &dof_to_boundary_mapping,
+ const Function<spacedim> * const coefficient,
+ const std::vector<unsigned int>& component_mapping,
+ const MatrixCreator::internal::IteratorRange<DoFHandler<dim,spacedim> > range,
+ Threads::ThreadMutex &mutex)
{
- // All assertions for this function
- // are in the calling function
- // before creating threads.
+ // All assertions for this function
+ // are in the calling function
+ // before creating threads.
const Mapping<dim,spacedim>& mapping = std_cxx1x::get<0>(commons);
const DoFHandler<dim,spacedim>& dof = std_cxx1x::get<1>(commons);
const Quadrature<dim-1>& q = std_cxx1x::get<2>(commons);
const bool fe_is_primitive = fe.is_primitive();
const unsigned int dofs_per_cell = fe.dofs_per_cell,
- dofs_per_face = fe.dofs_per_face;
+ dofs_per_face = fe.dofs_per_face;
FullMatrix<double> cell_matrix(dofs_per_cell, dofs_per_cell);
Vector<double> cell_vector(dofs_per_cell);
UpdateFlags update_flags = UpdateFlags (update_values |
- update_JxW_values |
- update_normal_vectors |
- update_quadrature_points);
+ update_JxW_values |
+ update_normal_vectors |
+ update_quadrature_points);
FEFaceValues<dim,spacedim> fe_values (mapping, fe, q, update_flags);
- // two variables for the coefficient,
- // one for the two cases indicated in
- // the name
+ // two variables for the coefficient,
+ // one for the two cases indicated in
+ // the name
std::vector<double> coefficient_values (fe_values.n_quadrature_points, 1.);
std::vector<Vector<double> > coefficient_vector_values (fe_values.n_quadrature_points,
- Vector<double>(n_components));
+ Vector<double>(n_components));
const bool coefficient_is_vector = (coefficient != 0 && coefficient->n_components != 1)
- ? true : false;
+ ? true : false;
std::vector<double> rhs_values_scalar (fe_values.n_quadrature_points);
std::vector<Vector<double> > rhs_values_system (fe_values.n_quadrature_points,
- Vector<double>(n_function_components));
+ Vector<double>(n_function_components));
std::vector<unsigned int> dofs (dofs_per_cell);
std::vector<unsigned int> dofs_on_face_vector (dofs_per_face);
- // for each dof on the cell, have a
- // flag whether it is on the face
+ // for each dof on the cell, have a
+ // flag whether it is on the face
std::vector<bool> dof_is_on_face(dofs_per_cell);
typename DoFHandler<dim,spacedim>::active_cell_iterator cell = range.first;
for (; cell!=range.second; ++cell)
- for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
- // check if this face is on that part of
- // the boundary we are interested in
- if (boundary_functions.find(cell->face(face)->boundary_indicator()) !=
- boundary_functions.end())
- {
- cell_matrix = 0;
- cell_vector = 0;
-
- fe_values.reinit (cell, face);
-
- if (fe_is_system)
- // FE has several components
- {
- boundary_functions.find(cell->face(face)->boundary_indicator())
- ->second->vector_value_list (fe_values.get_quadrature_points(),
- rhs_values_system);
-
- if (coefficient_is_vector)
- // If coefficient is
- // vector valued, fill
- // all components
- coefficient->vector_value_list (fe_values.get_quadrature_points(),
- coefficient_vector_values);
- else
- {
- // If a scalar
- // function is
- // geiven, update
- // the values, if
- // not, use the
- // default one set
- // in the
- // constructor above
- if (coefficient != 0)
- coefficient->value_list (fe_values.get_quadrature_points(),
- coefficient_values);
- // Copy scalar
- // values into vector
- for (unsigned int point=0; point<fe_values.n_quadrature_points; ++point)
- coefficient_vector_values[point] = coefficient_values[point];
- }
-
- // Special treatment
- // for Hdiv and Hcurl
- // elements, where only
- // the normal or
- // tangential component
- // should be projected.
- std::vector<std::vector<double> > normal_adjustment(fe_values.n_quadrature_points,
- std::vector<double>(n_components, 1.));
-
- for (unsigned int comp = 0;comp<n_components;++comp)
- {
- const FiniteElement<dim,spacedim>& base = fe.base_element(fe.component_to_base_index(comp).first);
- const unsigned int bcomp = fe.component_to_base_index(comp).second;
-
- if (!base.conforms(FiniteElementData<dim>::H1) &&
- base.conforms(FiniteElementData<dim>::Hdiv))
- for (unsigned int point=0; point<fe_values.n_quadrature_points; ++point)
- normal_adjustment[point][comp] = fe_values.normal_vector(point)(bcomp)
- * fe_values.normal_vector(point)(bcomp);
- }
-
- for (unsigned int point=0; point<fe_values.n_quadrature_points; ++point)
- {
- const double weight = fe_values.JxW(point);
- for (unsigned int i=0; i<fe_values.dofs_per_cell; ++i)
- if (fe_is_primitive)
- {
- for (unsigned int j=0; j<fe_values.dofs_per_cell; ++j)
- {
- if (fe.system_to_component_index(j).first
- == fe.system_to_component_index(i).first)
- {
- cell_matrix(i,j)
- += weight
- * fe_values.shape_value(j,point)
- * fe_values.shape_value(i,point)
- * coefficient_vector_values[point](fe.system_to_component_index(i).first);
- }
- }
- cell_vector(i) += fe_values.shape_value(i,point)
- * rhs_values_system[point](component_mapping[fe.system_to_component_index(i).first])
- * weight;
- }
- else
- {
- for (unsigned int comp=0;comp<n_components;++comp)
- {
- for (unsigned int j=0; j<fe_values.dofs_per_cell; ++j)
- cell_matrix(i,j)
- += fe_values.shape_value_component(j,point,comp)
- * fe_values.shape_value_component(i,point,comp)
- * normal_adjustment[point][comp]
- * weight * coefficient_vector_values[point](comp);
- cell_vector(i) += fe_values.shape_value_component(i,point,comp) *
- rhs_values_system[point](component_mapping[comp])
- * normal_adjustment[point][comp]
- * weight;
- }
- }
- }
- }
- else
- // FE is a scalar one
- {
- boundary_functions.find(cell->face(face)->boundary_indicator())
- ->second->value_list (fe_values.get_quadrature_points(), rhs_values_scalar);
-
- if (coefficient != 0)
- coefficient->value_list (fe_values.get_quadrature_points(),
- coefficient_values);
- for (unsigned int point=0; point<fe_values.n_quadrature_points; ++point)
- {
- const double weight = fe_values.JxW(point);
- for (unsigned int i=0; i<fe_values.dofs_per_cell; ++i)
- {
- const double v = fe_values.shape_value(i,point);
- for (unsigned int j=0; j<fe_values.dofs_per_cell; ++j)
- {
- const double u = fe_values.shape_value(j,point);
- cell_matrix(i,j) += (u * v * weight * coefficient_values[point]);
- }
- cell_vector(i) += v * rhs_values_scalar[point] *weight;
- }
- }
- }
- // now transfer cell matrix and vector
- // to the whole boundary matrix
- //
- // in the following: dof[i] holds the
- // global index of the i-th degree of
- // freedom on the present cell. If it
- // is also a dof on the boundary, it
- // must be a nonzero entry in the
- // dof_to_boundary_mapping and then
- // the boundary index of this dof is
- // dof_to_boundary_mapping[dof[i]].
- //
- // if dof[i] is not on the boundary,
- // it should be zero on the boundary
- // therefore on all quadrature
- // points and finally all of its
- // entries in the cell matrix and
- // vector should be zero. If not, we
- // throw an error (note: because of
- // the evaluation of the shape
- // functions only up to machine
- // precision, the term "must be zero"
- // really should mean: "should be
- // very small". since this is only an
- // assertion and not part of the
- // code, we may choose "very small"
- // quite arbitrarily)
- //
- // the main problem here is that the
- // matrix or vector entry should also
- // be zero if the degree of freedom
- // dof[i] is on the boundary, but not
- // on the present face, i.e. on
- // another face of the same cell also
- // on the boundary. We can therefore
- // not rely on the
- // dof_to_boundary_mapping[dof[i]]
- // being !=-1, we really have to
- // determine whether dof[i] is a
- // dof on the present face. We do so
- // by getting the dofs on the
- // face into @p{dofs_on_face_vector},
- // a vector as always. Usually,
- // searching in a vector is
- // inefficient, so we copy the dofs
- // into a set, which enables binary
- // searches.
- cell->get_dof_indices (dofs);
- cell->face(face)->get_dof_indices (dofs_on_face_vector);
- for (unsigned int i=0; i<dofs_per_cell; ++i)
- dof_is_on_face[i] = (std::find(dofs_on_face_vector.begin(),
- dofs_on_face_vector.end(),
- dofs[i])
- !=
- dofs_on_face_vector.end());
-
- // lock the matrix
- Threads::ThreadMutex::ScopedLock lock (mutex);
- for (unsigned int i=0; i<dofs_per_cell; ++i)
- {
- if (dof_is_on_face[i] && dof_to_boundary_mapping[dofs[i]] != numbers::invalid_unsigned_int)
- {
- for (unsigned int j=0; j<dofs_per_cell; ++j)
- if (dof_is_on_face[j] && dof_to_boundary_mapping[dofs[j]] != numbers::invalid_unsigned_int)
- {
- Assert(numbers::is_finite(cell_matrix(i,j)), ExcNumberNotFinite());
- matrix.add(dof_to_boundary_mapping[dofs[i]],
- dof_to_boundary_mapping[dofs[j]],
- cell_matrix(i,j));
- }
- Assert(numbers::is_finite(cell_vector(i)), ExcNumberNotFinite());
- rhs_vector(dof_to_boundary_mapping[dofs[i]]) += cell_vector(i);
- }
- }
- }
+ for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
+ // check if this face is on that part of
+ // the boundary we are interested in
+ if (boundary_functions.find(cell->face(face)->boundary_indicator()) !=
+ boundary_functions.end())
+ {
+ cell_matrix = 0;
+ cell_vector = 0;
+
+ fe_values.reinit (cell, face);
+
+ if (fe_is_system)
+ // FE has several components
+ {
+ boundary_functions.find(cell->face(face)->boundary_indicator())
+ ->second->vector_value_list (fe_values.get_quadrature_points(),
+ rhs_values_system);
+
+ if (coefficient_is_vector)
+ // If coefficient is
+ // vector valued, fill
+ // all components
+ coefficient->vector_value_list (fe_values.get_quadrature_points(),
+ coefficient_vector_values);
+ else
+ {
+ // If a scalar
+ // function is
+ // geiven, update
+ // the values, if
+ // not, use the
+ // default one set
+ // in the
+ // constructor above
+ if (coefficient != 0)
+ coefficient->value_list (fe_values.get_quadrature_points(),
+ coefficient_values);
+ // Copy scalar
+ // values into vector
+ for (unsigned int point=0; point<fe_values.n_quadrature_points; ++point)
+ coefficient_vector_values[point] = coefficient_values[point];
+ }
+
+ // Special treatment
+ // for Hdiv and Hcurl
+ // elements, where only
+ // the normal or
+ // tangential component
+ // should be projected.
+ std::vector<std::vector<double> > normal_adjustment(fe_values.n_quadrature_points,
+ std::vector<double>(n_components, 1.));
+
+ for (unsigned int comp = 0;comp<n_components;++comp)
+ {
+ const FiniteElement<dim,spacedim>& base = fe.base_element(fe.component_to_base_index(comp).first);
+ const unsigned int bcomp = fe.component_to_base_index(comp).second;
+
+ if (!base.conforms(FiniteElementData<dim>::H1) &&
+ base.conforms(FiniteElementData<dim>::Hdiv))
+ for (unsigned int point=0; point<fe_values.n_quadrature_points; ++point)
+ normal_adjustment[point][comp] = fe_values.normal_vector(point)(bcomp)
+ * fe_values.normal_vector(point)(bcomp);
+ }
+
+ for (unsigned int point=0; point<fe_values.n_quadrature_points; ++point)
+ {
+ const double weight = fe_values.JxW(point);
+ for (unsigned int i=0; i<fe_values.dofs_per_cell; ++i)
+ if (fe_is_primitive)
+ {
+ for (unsigned int j=0; j<fe_values.dofs_per_cell; ++j)
+ {
+ if (fe.system_to_component_index(j).first
+ == fe.system_to_component_index(i).first)
+ {
+ cell_matrix(i,j)
+ += weight
+ * fe_values.shape_value(j,point)
+ * fe_values.shape_value(i,point)
+ * coefficient_vector_values[point](fe.system_to_component_index(i).first);
+ }
+ }
+ cell_vector(i) += fe_values.shape_value(i,point)
+ * rhs_values_system[point](component_mapping[fe.system_to_component_index(i).first])
+ * weight;
+ }
+ else
+ {
+ for (unsigned int comp=0;comp<n_components;++comp)
+ {
+ for (unsigned int j=0; j<fe_values.dofs_per_cell; ++j)
+ cell_matrix(i,j)
+ += fe_values.shape_value_component(j,point,comp)
+ * fe_values.shape_value_component(i,point,comp)
+ * normal_adjustment[point][comp]
+ * weight * coefficient_vector_values[point](comp);
+ cell_vector(i) += fe_values.shape_value_component(i,point,comp) *
+ rhs_values_system[point](component_mapping[comp])
+ * normal_adjustment[point][comp]
+ * weight;
+ }
+ }
+ }
+ }
+ else
+ // FE is a scalar one
+ {
+ boundary_functions.find(cell->face(face)->boundary_indicator())
+ ->second->value_list (fe_values.get_quadrature_points(), rhs_values_scalar);
+
+ if (coefficient != 0)
+ coefficient->value_list (fe_values.get_quadrature_points(),
+ coefficient_values);
+ for (unsigned int point=0; point<fe_values.n_quadrature_points; ++point)
+ {
+ const double weight = fe_values.JxW(point);
+ for (unsigned int i=0; i<fe_values.dofs_per_cell; ++i)
+ {
+ const double v = fe_values.shape_value(i,point);
+ for (unsigned int j=0; j<fe_values.dofs_per_cell; ++j)
+ {
+ const double u = fe_values.shape_value(j,point);
+ cell_matrix(i,j) += (u * v * weight * coefficient_values[point]);
+ }
+ cell_vector(i) += v * rhs_values_scalar[point] *weight;
+ }
+ }
+ }
+ // now transfer cell matrix and vector
+ // to the whole boundary matrix
+ //
+ // in the following: dof[i] holds the
+ // global index of the i-th degree of
+ // freedom on the present cell. If it
+ // is also a dof on the boundary, it
+ // must be a nonzero entry in the
+ // dof_to_boundary_mapping and then
+ // the boundary index of this dof is
+ // dof_to_boundary_mapping[dof[i]].
+ //
+ // if dof[i] is not on the boundary,
+ // it should be zero on the boundary
+ // therefore on all quadrature
+ // points and finally all of its
+ // entries in the cell matrix and
+ // vector should be zero. If not, we
+ // throw an error (note: because of
+ // the evaluation of the shape
+ // functions only up to machine
+ // precision, the term "must be zero"
+ // really should mean: "should be
+ // very small". since this is only an
+ // assertion and not part of the
+ // code, we may choose "very small"
+ // quite arbitrarily)
+ //
+ // the main problem here is that the
+ // matrix or vector entry should also
+ // be zero if the degree of freedom
+ // dof[i] is on the boundary, but not
+ // on the present face, i.e. on
+ // another face of the same cell also
+ // on the boundary. We can therefore
+ // not rely on the
+ // dof_to_boundary_mapping[dof[i]]
+ // being !=-1, we really have to
+ // determine whether dof[i] is a
+ // dof on the present face. We do so
+ // by getting the dofs on the
+ // face into @p{dofs_on_face_vector},
+ // a vector as always. Usually,
+ // searching in a vector is
+ // inefficient, so we copy the dofs
+ // into a set, which enables binary
+ // searches.
+ cell->get_dof_indices (dofs);
+ cell->face(face)->get_dof_indices (dofs_on_face_vector);
+ for (unsigned int i=0; i<dofs_per_cell; ++i)
+ dof_is_on_face[i] = (std::find(dofs_on_face_vector.begin(),
+ dofs_on_face_vector.end(),
+ dofs[i])
+ !=
+ dofs_on_face_vector.end());
+
+ // lock the matrix
+ Threads::ThreadMutex::ScopedLock lock (mutex);
+ for (unsigned int i=0; i<dofs_per_cell; ++i)
+ {
+ if (dof_is_on_face[i] && dof_to_boundary_mapping[dofs[i]] != numbers::invalid_unsigned_int)
+ {
+ for (unsigned int j=0; j<dofs_per_cell; ++j)
+ if (dof_is_on_face[j] && dof_to_boundary_mapping[dofs[j]] != numbers::invalid_unsigned_int)
+ {
+ Assert(numbers::is_finite(cell_matrix(i,j)), ExcNumberNotFinite());
+ matrix.add(dof_to_boundary_mapping[dofs[i]],
+ dof_to_boundary_mapping[dofs[j]],
+ cell_matrix(i,j));
+ }
+ Assert(numbers::is_finite(cell_vector(i)), ExcNumberNotFinite());
+ rhs_vector(dof_to_boundary_mapping[dofs[i]]) += cell_vector(i);
+ }
+ }
+ }
}
template <>
void
create_boundary_mass_matrix_1<2,3> (std_cxx1x::tuple<const Mapping<2,3> &,
- const DoFHandler<2,3> &,
- const Quadrature<1> & > ,
- SparseMatrix<double> &,
- const FunctionMap<3>::type &,
- Vector<double> &,
- std::vector<unsigned int> &,
- const Function<3> * const ,
- const std::vector<unsigned int> &,
- const MatrixCreator::internal::IteratorRange<DoFHandler<2,3> > ,
- Threads::ThreadMutex &)
+ const DoFHandler<2,3> &,
+ const Quadrature<1> & > ,
+ SparseMatrix<double> &,
+ const FunctionMap<3>::type &,
+ Vector<double> &,
+ std::vector<unsigned int> &,
+ const Function<3> * const ,
+ const std::vector<unsigned int> &,
+ const MatrixCreator::internal::IteratorRange<DoFHandler<2,3> > ,
+ Threads::ThreadMutex &)
{
Assert(false,ExcNotImplemented());
}
-
+
template <>
void
create_boundary_mass_matrix_1<1,3> (std_cxx1x::tuple<const Mapping<1,3> &,
- const DoFHandler<1,3> &,
- const Quadrature<0> & > ,
- SparseMatrix<double> &,
- const FunctionMap<3>::type &,
- Vector<double> &,
- std::vector<unsigned int> &,
- const Function<3> * const ,
- const std::vector<unsigned int> &,
- const MatrixCreator::internal::IteratorRange<DoFHandler<1,3> > ,
- Threads::ThreadMutex &)
+ const DoFHandler<1,3> &,
+ const Quadrature<0> & > ,
+ SparseMatrix<double> &,
+ const FunctionMap<3>::type &,
+ Vector<double> &,
+ std::vector<unsigned int> &,
+ const Function<3> * const ,
+ const std::vector<unsigned int> &,
+ const MatrixCreator::internal::IteratorRange<DoFHandler<1,3> > ,
+ Threads::ThreadMutex &)
{
Assert(false,ExcNotImplemented());
}
}
-
+
template <int dim, int spacedim>
void
create_boundary_mass_matrix (const Mapping<dim, spacedim> &mapping,
- const DoFHandler<dim,spacedim> &dof,
- const Quadrature<dim-1> &q,
- SparseMatrix<double> &matrix,
- const typename FunctionMap<spacedim>::type &boundary_functions,
- Vector<double> &rhs_vector,
- std::vector<unsigned int> &dof_to_boundary_mapping,
- const Function<spacedim> * const coefficient,
- std::vector<unsigned int> component_mapping)
+ const DoFHandler<dim,spacedim> &dof,
+ const Quadrature<dim-1> &q,
+ SparseMatrix<double> &matrix,
+ const typename FunctionMap<spacedim>::type &boundary_functions,
+ Vector<double> &rhs_vector,
+ std::vector<unsigned int> &dof_to_boundary_mapping,
+ const Function<spacedim> * const coefficient,
+ std::vector<unsigned int> component_mapping)
{
- // what would that be in 1d? the
- // identity matrix on the boundary
- // dofs?
+ // what would that be in 1d? the
+ // identity matrix on the boundary
+ // dofs?
if (dim == 1)
{
- Assert (false, ExcNotImplemented());
- return;
+ Assert (false, ExcNotImplemented());
+ return;
}
const FiniteElement<dim,spacedim> &fe = dof.get_fe();
const unsigned int n_components = fe.n_components();
Assert (matrix.n() == dof.n_boundary_dofs(boundary_functions),
- ExcInternalError());
+ ExcInternalError());
Assert (matrix.n() == matrix.m(), ExcInternalError());
Assert (matrix.n() == rhs_vector.size(), ExcInternalError());
Assert (boundary_functions.size() != 0, ExcInternalError());
Assert (dof_to_boundary_mapping.size() == dof.n_dofs(),
- ExcInternalError());
+ ExcInternalError());
Assert (coefficient ==0 ||
- coefficient->n_components==1 ||
- coefficient->n_components==n_components, ExcComponentMismatch());
+ coefficient->n_components==1 ||
+ coefficient->n_components==n_components, ExcComponentMismatch());
if (component_mapping.size() == 0)
{
- AssertDimension (n_components, boundary_functions.begin()->second->n_components);
- for (unsigned int i=0;i<n_components;++i)
- component_mapping.push_back(i);
+ AssertDimension (n_components, boundary_functions.begin()->second->n_components);
+ for (unsigned int i=0;i<n_components;++i)
+ component_mapping.push_back(i);
}
else
AssertDimension (n_components, component_mapping.size());
const unsigned int n_threads = multithread_info.n_default_threads;
Threads::ThreadGroup<> threads;
- // define starting and end point
- // for each thread
+ // define starting and end point
+ // for each thread
typedef typename DoFHandler<dim,spacedim>::active_cell_iterator active_cell_iterator;
std::vector<std::pair<active_cell_iterator,active_cell_iterator> > thread_ranges
= Threads::split_range<active_cell_iterator> (dof.begin_active(),
- dof.end(), n_threads);
+ dof.end(), n_threads);
- // mutex to synchronise access to
- // the matrix
+ // mutex to synchronise access to
+ // the matrix
Threads::ThreadMutex mutex;
typedef std_cxx1x::tuple<const Mapping<dim,spacedim>&,
- const DoFHandler<dim,spacedim>&,
- const Quadrature<dim-1>&> Commons;
+ const DoFHandler<dim,spacedim>&,
+ const Quadrature<dim-1>&> Commons;
- // then assemble in parallel
+ // then assemble in parallel
typedef void (*create_boundary_mass_matrix_1_t)
(Commons,
SparseMatrix<double> &matrix,
//TODO: Use WorkStream here
for (unsigned int thread=0; thread<n_threads; ++thread)
threads += Threads::new_thread (p,
- Commons(mapping, dof, q), matrix,
- boundary_functions, rhs_vector,
- dof_to_boundary_mapping, coefficient,
- component_mapping,
- thread_ranges[thread], mutex);
+ Commons(mapping, dof, q), matrix,
+ boundary_functions, rhs_vector,
+ dof_to_boundary_mapping, coefficient,
+ component_mapping,
+ thread_ranges[thread], mutex);
threads.join_all ();
}
template <int dim, int spacedim>
void
create_boundary_mass_matrix_1 (std_cxx1x::tuple<const hp::MappingCollection<dim,spacedim> &,
- const hp::DoFHandler<dim,spacedim> &,
- const hp::QCollection<dim-1> &> commons,
- SparseMatrix<double> &matrix,
- const typename FunctionMap<spacedim>::type &boundary_functions,
- Vector<double> &rhs_vector,
- std::vector<unsigned int> &dof_to_boundary_mapping,
- const Function<spacedim> * const coefficient,
- const std::vector<unsigned int>& component_mapping,
+ const hp::DoFHandler<dim,spacedim> &,
+ const hp::QCollection<dim-1> &> commons,
+ SparseMatrix<double> &matrix,
+ const typename FunctionMap<spacedim>::type &boundary_functions,
+ Vector<double> &rhs_vector,
+ std::vector<unsigned int> &dof_to_boundary_mapping,
+ const Function<spacedim> * const coefficient,
+ const std::vector<unsigned int>& component_mapping,
const MatrixCreator::internal::IteratorRange<hp::DoFHandler<dim,spacedim> > range,
- Threads::ThreadMutex &mutex)
+ Threads::ThreadMutex &mutex)
{
const hp::MappingCollection<dim,spacedim>& mapping = std_cxx1x::get<0>(commons);
const hp::DoFHandler<dim,spacedim>& dof = std_cxx1x::get<1>(commons);
const bool fe_is_system = (n_components != 1);
#ifdef DEBUG
if (true)
- {
- unsigned int max_element = 0;
- for (std::vector<unsigned int>::const_iterator i=dof_to_boundary_mapping.begin();
- i!=dof_to_boundary_mapping.end(); ++i)
- if ((*i != hp::DoFHandler<dim,spacedim>::invalid_dof_index) &&
- (*i > max_element))
- max_element = *i;
- Assert (max_element == matrix.n()-1, ExcInternalError());
- };
+ {
+ unsigned int max_element = 0;
+ for (std::vector<unsigned int>::const_iterator i=dof_to_boundary_mapping.begin();
+ i!=dof_to_boundary_mapping.end(); ++i)
+ if ((*i != hp::DoFHandler<dim,spacedim>::invalid_dof_index) &&
+ (*i > max_element))
+ max_element = *i;
+ Assert (max_element == matrix.n()-1, ExcInternalError());
+ };
#endif
const unsigned int max_dofs_per_cell = fe_collection.max_dofs_per_cell(),
- max_dofs_per_face = fe_collection.max_dofs_per_face();
+ max_dofs_per_face = fe_collection.max_dofs_per_face();
FullMatrix<double> cell_matrix(max_dofs_per_cell, max_dofs_per_cell);
Vector<double> cell_vector(max_dofs_per_cell);
UpdateFlags update_flags = UpdateFlags (update_values |
- update_JxW_values |
- update_quadrature_points);
+ update_JxW_values |
+ update_quadrature_points);
hp::FEFaceValues<dim> x_fe_values (mapping, fe_collection, q, update_flags);
- // two variables for the coefficient,
- // one for the two cases indicated in
- // the name
+ // two variables for the coefficient,
+ // one for the two cases indicated in
+ // the name
std::vector<double> coefficient_values;
std::vector<Vector<double> > coefficient_vector_values;
std::vector<unsigned int> dofs (max_dofs_per_cell);
std::vector<unsigned int> dofs_on_face_vector (max_dofs_per_face);
- // for each dof on the cell, have a
- // flag whether it is on the face
+ // for each dof on the cell, have a
+ // flag whether it is on the face
std::vector<bool> dof_is_on_face(max_dofs_per_cell);
typename hp::DoFHandler<dim,spacedim>::active_cell_iterator cell = range.first;
for (; cell!=range.second; ++cell)
- for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
- // check if this face is on that part of
- // the boundary we are interested in
- if (boundary_functions.find(cell->face(face)->boundary_indicator()) !=
- boundary_functions.end())
- {
- x_fe_values.reinit (cell, face);
-
- const FEFaceValues<dim,spacedim> &fe_values = x_fe_values.get_present_fe_values ();
-
- const FiniteElement<dim,spacedim> &fe = cell->get_fe();
- const unsigned int dofs_per_cell = fe.dofs_per_cell;
- const unsigned int dofs_per_face = fe.dofs_per_face;
-
- cell_matrix.reinit (dofs_per_cell, dofs_per_cell);
- cell_vector.reinit (dofs_per_cell);
- cell_matrix = 0;
- cell_vector = 0;
-
- if (fe_is_system)
- // FE has several components
- {
- rhs_values_system.resize (fe_values.n_quadrature_points,
- Vector<double>(n_function_components));
- boundary_functions.find(cell->face(face)->boundary_indicator())
- ->second->vector_value_list (fe_values.get_quadrature_points(),
- rhs_values_system);
-
- if (coefficient != 0)
- {
- if (coefficient->n_components==1)
- {
- coefficient_values.resize (fe_values.n_quadrature_points);
- coefficient->value_list (fe_values.get_quadrature_points(),
- coefficient_values);
- for (unsigned int point=0; point<fe_values.n_quadrature_points; ++point)
- {
- const double weight = fe_values.JxW(point);
- for (unsigned int i=0; i<fe_values.dofs_per_cell; ++i)
- {
- const double v = fe_values.shape_value(i,point);
- for (unsigned int j=0; j<fe_values.dofs_per_cell; ++j)
- if (fe.system_to_component_index(i).first ==
- fe.system_to_component_index(j).first)
- {
- const double u = fe_values.shape_value(j,point);
- cell_matrix(i,j)
- += (u * v * weight * coefficient_values[point]);
- }
-
- cell_vector(i) += v *
- rhs_values_system[point](
- component_mapping[fe.system_to_component_index(i).first]) * weight;
- }
- }
- }
- else
- {
- coefficient_vector_values.resize (fe_values.n_quadrature_points,
- Vector<double>(n_components));
- coefficient->vector_value_list (fe_values.get_quadrature_points(),
- coefficient_vector_values);
- for (unsigned int point=0; point<fe_values.n_quadrature_points; ++point)
- {
- const double weight = fe_values.JxW(point);
- for (unsigned int i=0; i<fe_values.dofs_per_cell; ++i)
- {
- const double v = fe_values.shape_value(i,point);
- const unsigned int component_i=
- fe.system_to_component_index(i).first;
- for (unsigned int j=0; j<fe_values.dofs_per_cell; ++j)
- if (fe.system_to_component_index(j).first ==
- component_i)
- {
- const double u = fe_values.shape_value(j,point);
- cell_matrix(i,j) +=
- (u * v * weight * coefficient_vector_values[point](component_i));
- }
- cell_vector(i) += v * rhs_values_system[point](component_mapping[component_i]) * weight;
- }
- }
- }
- }
- else // if (coefficient == 0)
- for (unsigned int point=0; point<fe_values.n_quadrature_points; ++point)
- {
- const double weight = fe_values.JxW(point);
- for (unsigned int i=0; i<fe_values.dofs_per_cell; ++i)
- {
- const double v = fe_values.shape_value(i,point);
- for (unsigned int j=0; j<fe_values.dofs_per_cell; ++j)
- if (fe.system_to_component_index(i).first ==
- fe.system_to_component_index(j).first)
- {
- const double u = fe_values.shape_value(j,point);
- cell_matrix(i,j) += (u * v * weight);
- }
- cell_vector(i) += v *
- rhs_values_system[point](
- fe.system_to_component_index(i).first) *
- weight;
- }
- }
- }
- else
- // FE is a scalar one
- {
- rhs_values_scalar.resize (fe_values.n_quadrature_points);
- boundary_functions.find(cell->face(face)->boundary_indicator())
- ->second->value_list (fe_values.get_quadrature_points(), rhs_values_scalar);
-
- if (coefficient != 0)
- {
- coefficient_values.resize (fe_values.n_quadrature_points);
- coefficient->value_list (fe_values.get_quadrature_points(),
- coefficient_values);
- for (unsigned int point=0; point<fe_values.n_quadrature_points; ++point)
- {
- const double weight = fe_values.JxW(point);
- for (unsigned int i=0; i<fe_values.dofs_per_cell; ++i)
- {
- const double v = fe_values.shape_value(i,point);
- for (unsigned int j=0; j<fe_values.dofs_per_cell; ++j)
- {
- const double u = fe_values.shape_value(j,point);
- cell_matrix(i,j) += (u * v * weight * coefficient_values[point]);
- }
- cell_vector(i) += v * rhs_values_scalar[point] *weight;
- }
- }
- }
- else
- for (unsigned int point=0; point<fe_values.n_quadrature_points; ++point)
- {
- const double weight = fe_values.JxW(point);
- for (unsigned int i=0; i<fe_values.dofs_per_cell; ++i)
- {
- const double v = fe_values.shape_value(i,point);
- for (unsigned int j=0; j<fe_values.dofs_per_cell; ++j)
- {
- const double u = fe_values.shape_value(j,point);
- cell_matrix(i,j) += (u * v * weight);
- }
- cell_vector(i) += v * rhs_values_scalar[point] * weight;
- }
- }
- }
-
- // now transfer cell matrix and vector
- // to the whole boundary matrix
- //
- // in the following: dof[i] holds the
- // global index of the i-th degree of
- // freedom on the present cell. If it
- // is also a dof on the boundary, it
- // must be a nonzero entry in the
- // dof_to_boundary_mapping and then
- // the boundary index of this dof is
- // dof_to_boundary_mapping[dof[i]].
- //
- // if dof[i] is not on the boundary,
- // it should be zero on the boundary
- // therefore on all quadrature
- // points and finally all of its
- // entries in the cell matrix and
- // vector should be zero. If not, we
- // throw an error (note: because of
- // the evaluation of the shape
- // functions only up to machine
- // precision, the term "must be zero"
- // really should mean: "should be
- // very small". since this is only an
- // assertion and not part of the
- // code, we may choose "very small"
- // quite arbitrarily)
- //
- // the main problem here is that the
- // matrix or vector entry should also
- // be zero if the degree of freedom
- // dof[i] is on the boundary, but not
- // on the present face, i.e. on
- // another face of the same cell also
- // on the boundary. We can therefore
- // not rely on the
- // dof_to_boundary_mapping[dof[i]]
- // being !=-1, we really have to
- // determine whether dof[i] is a
- // dof on the present face. We do so
- // by getting the dofs on the
- // face into @p{dofs_on_face_vector},
- // a vector as always. Usually,
- // searching in a vector is
- // inefficient, so we copy the dofs
- // into a set, which enables binary
- // searches.
- dofs.resize (dofs_per_cell);
- dofs_on_face_vector.resize (dofs_per_face);
- dof_is_on_face.resize (dofs_per_cell);
-
- cell->get_dof_indices (dofs);
- cell->face(face)->get_dof_indices (dofs_on_face_vector,
- cell->active_fe_index());
-
- // check for each of the
- // dofs on this cell
- // whether it is on the
- // face
- for (unsigned int i=0; i<dofs_per_cell; ++i)
- dof_is_on_face[i] = (std::find(dofs_on_face_vector.begin(),
- dofs_on_face_vector.end(),
- dofs[i])
- !=
- dofs_on_face_vector.end());
-
- // in debug mode: compute an element
- // in the matrix which is
- // guaranteed to belong to a boundary
- // dof. We do this to check that the
- // entries in the cell matrix are
- // guaranteed to be zero if the
- // respective dof is not on the
- // boundary. Since because of
- // round-off, the actual
- // value of the matrix entry may be
- // only close to zero, we assert that
- // it is small relative to an element
- // which is guaranteed to be nonzero.
- // (absolute smallness does not
- // suffice since the size of the
- // domain scales in here)
- //
- // for this purpose we seek the
- // diagonal of the matrix, where there
- // must be an element belonging to
- // the boundary. we take the maximum
- // diagonal entry.
+ for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
+ // check if this face is on that part of
+ // the boundary we are interested in
+ if (boundary_functions.find(cell->face(face)->boundary_indicator()) !=
+ boundary_functions.end())
+ {
+ x_fe_values.reinit (cell, face);
+
+ const FEFaceValues<dim,spacedim> &fe_values = x_fe_values.get_present_fe_values ();
+
+ const FiniteElement<dim,spacedim> &fe = cell->get_fe();
+ const unsigned int dofs_per_cell = fe.dofs_per_cell;
+ const unsigned int dofs_per_face = fe.dofs_per_face;
+
+ cell_matrix.reinit (dofs_per_cell, dofs_per_cell);
+ cell_vector.reinit (dofs_per_cell);
+ cell_matrix = 0;
+ cell_vector = 0;
+
+ if (fe_is_system)
+ // FE has several components
+ {
+ rhs_values_system.resize (fe_values.n_quadrature_points,
+ Vector<double>(n_function_components));
+ boundary_functions.find(cell->face(face)->boundary_indicator())
+ ->second->vector_value_list (fe_values.get_quadrature_points(),
+ rhs_values_system);
+
+ if (coefficient != 0)
+ {
+ if (coefficient->n_components==1)
+ {
+ coefficient_values.resize (fe_values.n_quadrature_points);
+ coefficient->value_list (fe_values.get_quadrature_points(),
+ coefficient_values);
+ for (unsigned int point=0; point<fe_values.n_quadrature_points; ++point)
+ {
+ const double weight = fe_values.JxW(point);
+ for (unsigned int i=0; i<fe_values.dofs_per_cell; ++i)
+ {
+ const double v = fe_values.shape_value(i,point);
+ for (unsigned int j=0; j<fe_values.dofs_per_cell; ++j)
+ if (fe.system_to_component_index(i).first ==
+ fe.system_to_component_index(j).first)
+ {
+ const double u = fe_values.shape_value(j,point);
+ cell_matrix(i,j)
+ += (u * v * weight * coefficient_values[point]);
+ }
+
+ cell_vector(i) += v *
+ rhs_values_system[point](
+ component_mapping[fe.system_to_component_index(i).first]) * weight;
+ }
+ }
+ }
+ else
+ {
+ coefficient_vector_values.resize (fe_values.n_quadrature_points,
+ Vector<double>(n_components));
+ coefficient->vector_value_list (fe_values.get_quadrature_points(),
+ coefficient_vector_values);
+ for (unsigned int point=0; point<fe_values.n_quadrature_points; ++point)
+ {
+ const double weight = fe_values.JxW(point);
+ for (unsigned int i=0; i<fe_values.dofs_per_cell; ++i)
+ {
+ const double v = fe_values.shape_value(i,point);
+ const unsigned int component_i=
+ fe.system_to_component_index(i).first;
+ for (unsigned int j=0; j<fe_values.dofs_per_cell; ++j)
+ if (fe.system_to_component_index(j).first ==
+ component_i)
+ {
+ const double u = fe_values.shape_value(j,point);
+ cell_matrix(i,j) +=
+ (u * v * weight * coefficient_vector_values[point](component_i));
+ }
+ cell_vector(i) += v * rhs_values_system[point](component_mapping[component_i]) * weight;
+ }
+ }
+ }
+ }
+ else // if (coefficient == 0)
+ for (unsigned int point=0; point<fe_values.n_quadrature_points; ++point)
+ {
+ const double weight = fe_values.JxW(point);
+ for (unsigned int i=0; i<fe_values.dofs_per_cell; ++i)
+ {
+ const double v = fe_values.shape_value(i,point);
+ for (unsigned int j=0; j<fe_values.dofs_per_cell; ++j)
+ if (fe.system_to_component_index(i).first ==
+ fe.system_to_component_index(j).first)
+ {
+ const double u = fe_values.shape_value(j,point);
+ cell_matrix(i,j) += (u * v * weight);
+ }
+ cell_vector(i) += v *
+ rhs_values_system[point](
+ fe.system_to_component_index(i).first) *
+ weight;
+ }
+ }
+ }
+ else
+ // FE is a scalar one
+ {
+ rhs_values_scalar.resize (fe_values.n_quadrature_points);
+ boundary_functions.find(cell->face(face)->boundary_indicator())
+ ->second->value_list (fe_values.get_quadrature_points(), rhs_values_scalar);
+
+ if (coefficient != 0)
+ {
+ coefficient_values.resize (fe_values.n_quadrature_points);
+ coefficient->value_list (fe_values.get_quadrature_points(),
+ coefficient_values);
+ for (unsigned int point=0; point<fe_values.n_quadrature_points; ++point)
+ {
+ const double weight = fe_values.JxW(point);
+ for (unsigned int i=0; i<fe_values.dofs_per_cell; ++i)
+ {
+ const double v = fe_values.shape_value(i,point);
+ for (unsigned int j=0; j<fe_values.dofs_per_cell; ++j)
+ {
+ const double u = fe_values.shape_value(j,point);
+ cell_matrix(i,j) += (u * v * weight * coefficient_values[point]);
+ }
+ cell_vector(i) += v * rhs_values_scalar[point] *weight;
+ }
+ }
+ }
+ else
+ for (unsigned int point=0; point<fe_values.n_quadrature_points; ++point)
+ {
+ const double weight = fe_values.JxW(point);
+ for (unsigned int i=0; i<fe_values.dofs_per_cell; ++i)
+ {
+ const double v = fe_values.shape_value(i,point);
+ for (unsigned int j=0; j<fe_values.dofs_per_cell; ++j)
+ {
+ const double u = fe_values.shape_value(j,point);
+ cell_matrix(i,j) += (u * v * weight);
+ }
+ cell_vector(i) += v * rhs_values_scalar[point] * weight;
+ }
+ }
+ }
+
+ // now transfer cell matrix and vector
+ // to the whole boundary matrix
+ //
+ // in the following: dof[i] holds the
+ // global index of the i-th degree of
+ // freedom on the present cell. If it
+ // is also a dof on the boundary, it
+ // must be a nonzero entry in the
+ // dof_to_boundary_mapping and then
+ // the boundary index of this dof is
+ // dof_to_boundary_mapping[dof[i]].
+ //
+ // if dof[i] is not on the boundary,
+ // it should be zero on the boundary
+ // therefore on all quadrature
+ // points and finally all of its
+ // entries in the cell matrix and
+ // vector should be zero. If not, we
+ // throw an error (note: because of
+ // the evaluation of the shape
+ // functions only up to machine
+ // precision, the term "must be zero"
+ // really should mean: "should be
+ // very small". since this is only an
+ // assertion and not part of the
+ // code, we may choose "very small"
+ // quite arbitrarily)
+ //
+ // the main problem here is that the
+ // matrix or vector entry should also
+ // be zero if the degree of freedom
+ // dof[i] is on the boundary, but not
+ // on the present face, i.e. on
+ // another face of the same cell also
+ // on the boundary. We can therefore
+ // not rely on the
+ // dof_to_boundary_mapping[dof[i]]
+ // being !=-1, we really have to
+ // determine whether dof[i] is a
+ // dof on the present face. We do so
+ // by getting the dofs on the
+ // face into @p{dofs_on_face_vector},
+ // a vector as always. Usually,
+ // searching in a vector is
+ // inefficient, so we copy the dofs
+ // into a set, which enables binary
+ // searches.
+ dofs.resize (dofs_per_cell);
+ dofs_on_face_vector.resize (dofs_per_face);
+ dof_is_on_face.resize (dofs_per_cell);
+
+ cell->get_dof_indices (dofs);
+ cell->face(face)->get_dof_indices (dofs_on_face_vector,
+ cell->active_fe_index());
+
+ // check for each of the
+ // dofs on this cell
+ // whether it is on the
+ // face
+ for (unsigned int i=0; i<dofs_per_cell; ++i)
+ dof_is_on_face[i] = (std::find(dofs_on_face_vector.begin(),
+ dofs_on_face_vector.end(),
+ dofs[i])
+ !=
+ dofs_on_face_vector.end());
+
+ // in debug mode: compute an element
+ // in the matrix which is
+ // guaranteed to belong to a boundary
+ // dof. We do this to check that the
+ // entries in the cell matrix are
+ // guaranteed to be zero if the
+ // respective dof is not on the
+ // boundary. Since because of
+ // round-off, the actual
+ // value of the matrix entry may be
+ // only close to zero, we assert that
+ // it is small relative to an element
+ // which is guaranteed to be nonzero.
+ // (absolute smallness does not
+ // suffice since the size of the
+ // domain scales in here)
+ //
+ // for this purpose we seek the
+ // diagonal of the matrix, where there
+ // must be an element belonging to
+ // the boundary. we take the maximum
+ // diagonal entry.
#ifdef DEBUG
- double max_diag_entry = 0;
- for (unsigned int i=0; i<dofs_per_cell; ++i)
- if (std::fabs(cell_matrix(i,i)) > max_diag_entry)
- max_diag_entry = std::fabs(cell_matrix(i,i));
+ double max_diag_entry = 0;
+ for (unsigned int i=0; i<dofs_per_cell; ++i)
+ if (std::fabs(cell_matrix(i,i)) > max_diag_entry)
+ max_diag_entry = std::fabs(cell_matrix(i,i));
#endif
- // lock the matrix
- Threads::ThreadMutex::ScopedLock lock (mutex);
- for (unsigned int i=0; i<dofs_per_cell; ++i)
- for (unsigned int j=0; j<dofs_per_cell; ++j)
- if (dof_is_on_face[i] && dof_is_on_face[j])
- matrix.add(dof_to_boundary_mapping[dofs[i]],
- dof_to_boundary_mapping[dofs[j]],
- cell_matrix(i,j));
- else
- {
- // assume that all
- // shape functions
- // that are nonzero
- // on the boundary
- // are also listed
- // in the
- // @p{dof_to_boundary}
- // mapping. if that
- // is not the case,
- // then the
- // boundary mass
- // matrix does not
- // make that much
- // sense anyway, as
- // it only contains
- // entries for
- // parts of the
- // functions living
- // on the boundary
- //
- // these, we may
- // compare here for
- // relative
- // smallness of all
- // entries in the
- // local matrix
- // which are not
- // taken over to
- // the global one
- Assert (std::fabs(cell_matrix(i,j)) <= 1e-10 * max_diag_entry,
- ExcInternalError ());
- };
-
- for (unsigned int j=0; j<dofs_per_cell; ++j)
- if (dof_is_on_face[j])
- rhs_vector(dof_to_boundary_mapping[dofs[j]]) += cell_vector(j);
- else
- {
- // compare here for relative
- // smallness
- Assert (std::fabs(cell_vector(j)) <= 1e-10 * max_diag_entry,
- ExcInternalError());
- }
- }
+ // lock the matrix
+ Threads::ThreadMutex::ScopedLock lock (mutex);
+ for (unsigned int i=0; i<dofs_per_cell; ++i)
+ for (unsigned int j=0; j<dofs_per_cell; ++j)
+ if (dof_is_on_face[i] && dof_is_on_face[j])
+ matrix.add(dof_to_boundary_mapping[dofs[i]],
+ dof_to_boundary_mapping[dofs[j]],
+ cell_matrix(i,j));
+ else
+ {
+ // assume that all
+ // shape functions
+ // that are nonzero
+ // on the boundary
+ // are also listed
+ // in the
+ // @p{dof_to_boundary}
+ // mapping. if that
+ // is not the case,
+ // then the
+ // boundary mass
+ // matrix does not
+ // make that much
+ // sense anyway, as
+ // it only contains
+ // entries for
+ // parts of the
+ // functions living
+ // on the boundary
+ //
+ // these, we may
+ // compare here for
+ // relative
+ // smallness of all
+ // entries in the
+ // local matrix
+ // which are not
+ // taken over to
+ // the global one
+ Assert (std::fabs(cell_matrix(i,j)) <= 1e-10 * max_diag_entry,
+ ExcInternalError ());
+ };
+
+ for (unsigned int j=0; j<dofs_per_cell; ++j)
+ if (dof_is_on_face[j])
+ rhs_vector(dof_to_boundary_mapping[dofs[j]]) += cell_vector(j);
+ else
+ {
+ // compare here for relative
+ // smallness
+ Assert (std::fabs(cell_vector(j)) <= 1e-10 * max_diag_entry,
+ ExcInternalError());
+ }
+ }
}
}
template <int dim, int spacedim>
void create_boundary_mass_matrix (const DoFHandler<dim,spacedim> &dof,
- const Quadrature<dim-1> &q,
- SparseMatrix<double> &matrix,
- const typename FunctionMap<spacedim>::type &rhs,
- Vector<double> &rhs_vector,
- std::vector<unsigned int> &dof_to_boundary_mapping,
- const Function<spacedim> * const a,
- std::vector<unsigned int> component_mapping)
+ const Quadrature<dim-1> &q,
+ SparseMatrix<double> &matrix,
+ const typename FunctionMap<spacedim>::type &rhs,
+ Vector<double> &rhs_vector,
+ std::vector<unsigned int> &dof_to_boundary_mapping,
+ const Function<spacedim> * const a,
+ std::vector<unsigned int> component_mapping)
{
Assert (DEAL_II_COMPAT_MAPPING, ExcCompatibility("mapping"));
create_boundary_mass_matrix(StaticMappingQ1<dim,spacedim>::mapping, dof, q,
- matrix,rhs, rhs_vector, dof_to_boundary_mapping, a, component_mapping);
+ matrix,rhs, rhs_vector, dof_to_boundary_mapping, a, component_mapping);
}
template <int dim, int spacedim>
void
create_boundary_mass_matrix (const hp::MappingCollection<dim,spacedim> &mapping,
- const hp::DoFHandler<dim,spacedim> &dof,
- const hp::QCollection<dim-1> &q,
- SparseMatrix<double> &matrix,
- const typename FunctionMap<spacedim>::type &boundary_functions,
- Vector<double> &rhs_vector,
- std::vector<unsigned int> &dof_to_boundary_mapping,
- const Function<spacedim> * const coefficient,
- std::vector<unsigned int> component_mapping)
+ const hp::DoFHandler<dim,spacedim> &dof,
+ const hp::QCollection<dim-1> &q,
+ SparseMatrix<double> &matrix,
+ const typename FunctionMap<spacedim>::type &boundary_functions,
+ Vector<double> &rhs_vector,
+ std::vector<unsigned int> &dof_to_boundary_mapping,
+ const Function<spacedim> * const coefficient,
+ std::vector<unsigned int> component_mapping)
{
- // what would that be in 1d? the
- // identity matrix on the boundary
- // dofs?
+ // what would that be in 1d? the
+ // identity matrix on the boundary
+ // dofs?
if (dim == 1)
{
- Assert (false, ExcNotImplemented());
- return;
+ Assert (false, ExcNotImplemented());
+ return;
}
const hp::FECollection<dim,spacedim> &fe_collection = dof.get_fe();
const unsigned int n_components = fe_collection.n_components();
Assert (matrix.n() == dof.n_boundary_dofs(boundary_functions),
- ExcInternalError());
+ ExcInternalError());
Assert (matrix.n() == matrix.m(), ExcInternalError());
Assert (matrix.n() == rhs_vector.size(), ExcInternalError());
Assert (boundary_functions.size() != 0, ExcInternalError());
Assert (dof_to_boundary_mapping.size() == dof.n_dofs(),
- ExcInternalError());
+ ExcInternalError());
Assert (coefficient ==0 ||
- coefficient->n_components==1 ||
- coefficient->n_components==n_components, ExcComponentMismatch());
+ coefficient->n_components==1 ||
+ coefficient->n_components==n_components, ExcComponentMismatch());
if (component_mapping.size() == 0)
{
- AssertDimension (n_components, boundary_functions.begin()->second->n_components);
- for (unsigned int i=0;i<n_components;++i)
- component_mapping.push_back(i);
+ AssertDimension (n_components, boundary_functions.begin()->second->n_components);
+ for (unsigned int i=0;i<n_components;++i)
+ component_mapping.push_back(i);
}
else
AssertDimension (n_components, component_mapping.size());
const unsigned int n_threads = multithread_info.n_default_threads;
Threads::ThreadGroup<> threads;
- // define starting and end point
- // for each thread
+ // define starting and end point
+ // for each thread
typedef typename hp::DoFHandler<dim,spacedim>::active_cell_iterator active_cell_iterator;
std::vector<std::pair<active_cell_iterator,active_cell_iterator> > thread_ranges
= Threads::split_range<active_cell_iterator> (dof.begin_active(),
- dof.end(), n_threads);
+ dof.end(), n_threads);
typedef std_cxx1x::tuple<const hp::MappingCollection<dim,spacedim>&,
- const hp::DoFHandler<dim,spacedim>&,
- const hp::QCollection<dim-1>&> Commons;
+ const hp::DoFHandler<dim,spacedim>&,
+ const hp::QCollection<dim-1>&> Commons;
- // mutex to synchronise access to
- // the matrix
+ // mutex to synchronise access to
+ // the matrix
Threads::ThreadMutex mutex;
- // then assemble in parallel
+ // then assemble in parallel
typedef void (*create_boundary_mass_matrix_1_t)
(Commons,
SparseMatrix<double> &matrix,
//TODO: Use WorkStream here
for (unsigned int thread=0; thread<n_threads; ++thread)
threads += Threads::new_thread (p,
- Commons(mapping, dof, q), matrix,
- boundary_functions, rhs_vector,
- dof_to_boundary_mapping, coefficient,
- component_mapping,
- thread_ranges[thread], mutex);
+ Commons(mapping, dof, q), matrix,
+ boundary_functions, rhs_vector,
+ dof_to_boundary_mapping, coefficient,
+ component_mapping,
+ thread_ranges[thread], mutex);
threads.join_all ();
}
template <int dim, int spacedim>
void create_boundary_mass_matrix (const hp::DoFHandler<dim,spacedim> &dof,
- const hp::QCollection<dim-1> &q,
- SparseMatrix<double> &matrix,
- const typename FunctionMap<spacedim>::type &rhs,
- Vector<double> &rhs_vector,
- std::vector<unsigned int> &dof_to_boundary_mapping,
- const Function<spacedim> * const a,
- std::vector<unsigned int> component_mapping)
+ const hp::QCollection<dim-1> &q,
+ SparseMatrix<double> &matrix,
+ const typename FunctionMap<spacedim>::type &rhs,
+ Vector<double> &rhs_vector,
+ std::vector<unsigned int> &dof_to_boundary_mapping,
+ const Function<spacedim> * const a,
+ std::vector<unsigned int> component_mapping)
{
Assert (DEAL_II_COMPAT_MAPPING, ExcCompatibility("mapping"));
create_boundary_mass_matrix(hp::StaticMappingQ1<dim,spacedim>::mapping_collection, dof, q,
- matrix,rhs, rhs_vector, dof_to_boundary_mapping, a, component_mapping);
+ matrix,rhs, rhs_vector, dof_to_boundary_mapping, a, component_mapping);
}
template <int dim, int spacedim>
void create_laplace_matrix (const Mapping<dim, spacedim> &mapping,
- const DoFHandler<dim,spacedim> &dof,
- const Quadrature<dim> &q,
- SparseMatrix<double> &matrix,
- const Function<spacedim> * const coefficient)
+ const DoFHandler<dim,spacedim> &dof,
+ const Quadrature<dim> &q,
+ SparseMatrix<double> &matrix,
+ const Function<spacedim> * const coefficient)
{
Assert (matrix.m() == dof.n_dofs(),
- ExcDimensionMismatch (matrix.m(), dof.n_dofs()));
+ ExcDimensionMismatch (matrix.m(), dof.n_dofs()));
Assert (matrix.n() == dof.n_dofs(),
- ExcDimensionMismatch (matrix.n(), dof.n_dofs()));
+ ExcDimensionMismatch (matrix.n(), dof.n_dofs()));
hp::FECollection<dim,spacedim> fe_collection (dof.get_fe());
hp::QCollection<dim> q_collection (q);
hp::MappingCollection<dim,spacedim> mapping_collection (mapping);
MatrixCreator::internal::AssemblerData::Scratch<dim, spacedim>
assembler_data (fe_collection,
- update_gradients | update_JxW_values |
- (coefficient != 0 ? update_quadrature_points : UpdateFlags(0)),
- coefficient, /*rhs_function=*/0,
- q_collection, mapping_collection);
+ update_gradients | update_JxW_values |
+ (coefficient != 0 ? update_quadrature_points : UpdateFlags(0)),
+ coefficient, /*rhs_function=*/0,
+ q_collection, mapping_collection);
MatrixCreator::internal::AssemblerData::CopyData copy_data;
copy_data.cell_matrix.reinit (assembler_data.fe_collection.max_dofs_per_cell(),
- assembler_data.fe_collection.max_dofs_per_cell());
+ assembler_data.fe_collection.max_dofs_per_cell());
copy_data.cell_rhs.reinit (assembler_data.fe_collection.max_dofs_per_cell());
copy_data.dof_indices.resize (assembler_data.fe_collection.max_dofs_per_cell());
void (*copy_local_to_global) (const MatrixCreator::internal::AssemblerData::CopyData &,
- SparseMatrix<double> *,
- Vector<double> *)
+ SparseMatrix<double> *,
+ Vector<double> *)
= &MatrixCreator::internal::
copy_local_to_global<SparseMatrix<double>, Vector<double> >;
WorkStream::run (dof.begin_active(),
- static_cast<typename DoFHandler<dim,spacedim>::active_cell_iterator>(dof.end()),
- &MatrixCreator::internal::laplace_assembler<dim, spacedim, typename DoFHandler<dim,spacedim>::active_cell_iterator>,
- std_cxx1x::bind (copy_local_to_global,
- std_cxx1x::_1, &matrix, (Vector<double>*)0),
- assembler_data,
- copy_data);
+ static_cast<typename DoFHandler<dim,spacedim>::active_cell_iterator>(dof.end()),
+ &MatrixCreator::internal::laplace_assembler<dim, spacedim, typename DoFHandler<dim,spacedim>::active_cell_iterator>,
+ std_cxx1x::bind (copy_local_to_global,
+ std_cxx1x::_1, &matrix, (Vector<double>*)0),
+ assembler_data,
+ copy_data);
}
template <int dim, int spacedim>
void create_laplace_matrix (const DoFHandler<dim,spacedim> &dof,
- const Quadrature<dim> &q,
- SparseMatrix<double> &matrix,
- const Function<spacedim> * const coefficient)
+ const Quadrature<dim> &q,
+ SparseMatrix<double> &matrix,
+ const Function<spacedim> * const coefficient)
{
Assert (DEAL_II_COMPAT_MAPPING, ExcCompatibility("mapping"));
create_laplace_matrix(StaticMappingQ1<dim,spacedim>::mapping, dof, q, matrix, coefficient);
template <int dim, int spacedim>
void create_laplace_matrix (const Mapping<dim, spacedim> &mapping,
- const DoFHandler<dim,spacedim> &dof,
- const Quadrature<dim> &q,
- SparseMatrix<double> &matrix,
- const Function<spacedim> &rhs,
- Vector<double> &rhs_vector,
- const Function<spacedim> * const coefficient)
+ const DoFHandler<dim,spacedim> &dof,
+ const Quadrature<dim> &q,
+ SparseMatrix<double> &matrix,
+ const Function<spacedim> &rhs,
+ Vector<double> &rhs_vector,
+ const Function<spacedim> * const coefficient)
{
Assert (matrix.m() == dof.n_dofs(),
- ExcDimensionMismatch (matrix.m(), dof.n_dofs()));
+ ExcDimensionMismatch (matrix.m(), dof.n_dofs()));
Assert (matrix.n() == dof.n_dofs(),
- ExcDimensionMismatch (matrix.n(), dof.n_dofs()));
+ ExcDimensionMismatch (matrix.n(), dof.n_dofs()));
hp::FECollection<dim,spacedim> fe_collection (dof.get_fe());
hp::QCollection<dim> q_collection (q);
hp::MappingCollection<dim,spacedim> mapping_collection (mapping);
MatrixCreator::internal::AssemblerData::Scratch<dim, spacedim>
assembler_data (fe_collection,
- update_gradients | update_values |
- update_JxW_values | update_quadrature_points,
- coefficient, &rhs,
- q_collection, mapping_collection);
+ update_gradients | update_values |
+ update_JxW_values | update_quadrature_points,
+ coefficient, &rhs,
+ q_collection, mapping_collection);
MatrixCreator::internal::AssemblerData::CopyData copy_data;
copy_data.cell_matrix.reinit (assembler_data.fe_collection.max_dofs_per_cell(),
- assembler_data.fe_collection.max_dofs_per_cell());
+ assembler_data.fe_collection.max_dofs_per_cell());
copy_data.cell_rhs.reinit (assembler_data.fe_collection.max_dofs_per_cell());
copy_data.dof_indices.resize (assembler_data.fe_collection.max_dofs_per_cell());
void (*copy_local_to_global) (const MatrixCreator::internal::AssemblerData::CopyData &,
- SparseMatrix<double> *,
- Vector<double> *)
+ SparseMatrix<double> *,
+ Vector<double> *)
= &MatrixCreator::internal::
copy_local_to_global<SparseMatrix<double>, Vector<double> >;
WorkStream::run (dof.begin_active(),
- static_cast<typename DoFHandler<dim,spacedim>::active_cell_iterator>(dof.end()),
- &MatrixCreator::internal::laplace_assembler<dim, spacedim, typename DoFHandler<dim,spacedim>::active_cell_iterator>,
- std_cxx1x::bind (copy_local_to_global,
- std_cxx1x::_1, &matrix, &rhs_vector),
- assembler_data,
- copy_data);
+ static_cast<typename DoFHandler<dim,spacedim>::active_cell_iterator>(dof.end()),
+ &MatrixCreator::internal::laplace_assembler<dim, spacedim, typename DoFHandler<dim,spacedim>::active_cell_iterator>,
+ std_cxx1x::bind (copy_local_to_global,
+ std_cxx1x::_1, &matrix, &rhs_vector),
+ assembler_data,
+ copy_data);
}
template <int dim, int spacedim>
void create_laplace_matrix (const DoFHandler<dim,spacedim> &dof,
- const Quadrature<dim> &q,
- SparseMatrix<double> &matrix,
- const Function<spacedim> &rhs,
- Vector<double> &rhs_vector,
- const Function<spacedim> * const coefficient)
+ const Quadrature<dim> &q,
+ SparseMatrix<double> &matrix,
+ const Function<spacedim> &rhs,
+ Vector<double> &rhs_vector,
+ const Function<spacedim> * const coefficient)
{
Assert (DEAL_II_COMPAT_MAPPING, ExcCompatibility("mapping"));
create_laplace_matrix(StaticMappingQ1<dim,spacedim>::mapping, dof, q,
- matrix, rhs, rhs_vector, coefficient);
+ matrix, rhs, rhs_vector, coefficient);
}
template <int dim, int spacedim>
void create_laplace_matrix (const hp::MappingCollection<dim,spacedim> &mapping,
- const hp::DoFHandler<dim,spacedim> &dof,
- const hp::QCollection<dim> &q,
- SparseMatrix<double> &matrix,
- const Function<spacedim> * const coefficient)
+ const hp::DoFHandler<dim,spacedim> &dof,
+ const hp::QCollection<dim> &q,
+ SparseMatrix<double> &matrix,
+ const Function<spacedim> * const coefficient)
{
Assert (matrix.m() == dof.n_dofs(),
- ExcDimensionMismatch (matrix.m(), dof.n_dofs()));
+ ExcDimensionMismatch (matrix.m(), dof.n_dofs()));
Assert (matrix.n() == dof.n_dofs(),
- ExcDimensionMismatch (matrix.n(), dof.n_dofs()));
+ ExcDimensionMismatch (matrix.n(), dof.n_dofs()));
MatrixCreator::internal::AssemblerData::Scratch<dim, spacedim>
assembler_data (dof.get_fe(),
- update_gradients | update_JxW_values |
- (coefficient != 0 ? update_quadrature_points : UpdateFlags(0)),
- coefficient, /*rhs_function=*/0,
- q, mapping);
+ update_gradients | update_JxW_values |
+ (coefficient != 0 ? update_quadrature_points : UpdateFlags(0)),
+ coefficient, /*rhs_function=*/0,
+ q, mapping);
MatrixCreator::internal::AssemblerData::CopyData copy_data;
copy_data.cell_matrix.reinit (assembler_data.fe_collection.max_dofs_per_cell(),
- assembler_data.fe_collection.max_dofs_per_cell());
+ assembler_data.fe_collection.max_dofs_per_cell());
copy_data.cell_rhs.reinit (assembler_data.fe_collection.max_dofs_per_cell());
copy_data.dof_indices.resize (assembler_data.fe_collection.max_dofs_per_cell());
void (*copy_local_to_global) (const MatrixCreator::internal::AssemblerData::CopyData &,
- SparseMatrix<double> *,
- Vector<double> *)
+ SparseMatrix<double> *,
+ Vector<double> *)
= &MatrixCreator::internal::
copy_local_to_global<SparseMatrix<double>, Vector<double> >;
WorkStream::run (dof.begin_active(),
- static_cast<typename hp::DoFHandler<dim,spacedim>::active_cell_iterator>(dof.end()),
- &MatrixCreator::internal::laplace_assembler<dim, spacedim, typename hp::DoFHandler<dim,spacedim>::active_cell_iterator>,
- std_cxx1x::bind (copy_local_to_global,
- std_cxx1x::_1, &matrix, (Vector<double>*)0),
- assembler_data,
- copy_data);
+ static_cast<typename hp::DoFHandler<dim,spacedim>::active_cell_iterator>(dof.end()),
+ &MatrixCreator::internal::laplace_assembler<dim, spacedim, typename hp::DoFHandler<dim,spacedim>::active_cell_iterator>,
+ std_cxx1x::bind (copy_local_to_global,
+ std_cxx1x::_1, &matrix, (Vector<double>*)0),
+ assembler_data,
+ copy_data);
}
template <int dim, int spacedim>
void create_laplace_matrix (const hp::DoFHandler<dim,spacedim> &dof,
- const hp::QCollection<dim> &q,
- SparseMatrix<double> &matrix,
- const Function<spacedim> * const coefficient)
+ const hp::QCollection<dim> &q,
+ SparseMatrix<double> &matrix,
+ const Function<spacedim> * const coefficient)
{
Assert (DEAL_II_COMPAT_MAPPING, ExcCompatibility("mapping"));
create_laplace_matrix(hp::StaticMappingQ1<dim,spacedim>::mapping_collection, dof, q, matrix, coefficient);
template <int dim, int spacedim>
void create_laplace_matrix (const hp::MappingCollection<dim,spacedim> &mapping,
- const hp::DoFHandler<dim,spacedim> &dof,
- const hp::QCollection<dim> &q,
- SparseMatrix<double> &matrix,
- const Function<spacedim> &rhs,
- Vector<double> &rhs_vector,
- const Function<spacedim> * const coefficient)
+ const hp::DoFHandler<dim,spacedim> &dof,
+ const hp::QCollection<dim> &q,
+ SparseMatrix<double> &matrix,
+ const Function<spacedim> &rhs,
+ Vector<double> &rhs_vector,
+ const Function<spacedim> * const coefficient)
{
Assert (matrix.m() == dof.n_dofs(),
- ExcDimensionMismatch (matrix.m(), dof.n_dofs()));
+ ExcDimensionMismatch (matrix.m(), dof.n_dofs()));
Assert (matrix.n() == dof.n_dofs(),
- ExcDimensionMismatch (matrix.n(), dof.n_dofs()));
+ ExcDimensionMismatch (matrix.n(), dof.n_dofs()));
MatrixCreator::internal::AssemblerData::Scratch<dim, spacedim>
assembler_data (dof.get_fe(),
- update_gradients | update_values |
- update_JxW_values | update_quadrature_points,
- coefficient, &rhs,
- q, mapping);
+ update_gradients | update_values |
+ update_JxW_values | update_quadrature_points,
+ coefficient, &rhs,
+ q, mapping);
MatrixCreator::internal::AssemblerData::CopyData copy_data;
copy_data.cell_matrix.reinit (assembler_data.fe_collection.max_dofs_per_cell(),
- assembler_data.fe_collection.max_dofs_per_cell());
+ assembler_data.fe_collection.max_dofs_per_cell());
copy_data.cell_rhs.reinit (assembler_data.fe_collection.max_dofs_per_cell());
copy_data.dof_indices.resize (assembler_data.fe_collection.max_dofs_per_cell());
void (*copy_local_to_global) (const MatrixCreator::internal::AssemblerData::CopyData &,
- SparseMatrix<double> *,
- Vector<double> *)
+ SparseMatrix<double> *,
+ Vector<double> *)
= &MatrixCreator::internal::
copy_local_to_global<SparseMatrix<double>, Vector<double> >;
WorkStream::run (dof.begin_active(),
- static_cast<typename hp::DoFHandler<dim,spacedim>::active_cell_iterator>(dof.end()),
- &MatrixCreator::internal::laplace_assembler<dim, spacedim, typename hp::DoFHandler<dim,spacedim>::active_cell_iterator>,
- std_cxx1x::bind (copy_local_to_global,
- std_cxx1x::_1, &matrix, &rhs_vector),
- assembler_data,
- copy_data);
+ static_cast<typename hp::DoFHandler<dim,spacedim>::active_cell_iterator>(dof.end()),
+ &MatrixCreator::internal::laplace_assembler<dim, spacedim, typename hp::DoFHandler<dim,spacedim>::active_cell_iterator>,
+ std_cxx1x::bind (copy_local_to_global,
+ std_cxx1x::_1, &matrix, &rhs_vector),
+ assembler_data,
+ copy_data);
}
template <int dim, int spacedim>
void create_laplace_matrix (const hp::DoFHandler<dim,spacedim> &dof,
- const hp::QCollection<dim> &q,
- SparseMatrix<double> &matrix,
- const Function<spacedim> &rhs,
- Vector<double> &rhs_vector,
- const Function<spacedim> * const coefficient)
+ const hp::QCollection<dim> &q,
+ SparseMatrix<double> &matrix,
+ const Function<spacedim> &rhs,
+ Vector<double> &rhs_vector,
+ const Function<spacedim> * const coefficient)
{
Assert (DEAL_II_COMPAT_MAPPING, ExcCompatibility("mapping"));
create_laplace_matrix(hp::StaticMappingQ1<dim,spacedim>::mapping_collection, dof, q,
- matrix, rhs, rhs_vector, coefficient);
+ matrix, rhs, rhs_vector, coefficient);
}
} // namespace MatrixCreator
template <typename number>
void
apply_boundary_values (const std::map<unsigned int,double> &boundary_values,
- SparseMatrix<number> &matrix,
- Vector<number> &solution,
- Vector<number> &right_hand_side,
- const bool eliminate_columns)
+ SparseMatrix<number> &matrix,
+ Vector<number> &solution,
+ Vector<number> &right_hand_side,
+ const bool eliminate_columns)
{
- // Require that diagonals are first
- // in each row
+ // Require that diagonals are first
+ // in each row
Assert (matrix.get_sparsity_pattern().optimize_diagonal(),
- typename SparsityPattern::ExcDiagonalNotOptimized());
+ typename SparsityPattern::ExcDiagonalNotOptimized());
Assert (matrix.n() == right_hand_side.size(),
- ExcDimensionMismatch(matrix.n(), right_hand_side.size()));
+ ExcDimensionMismatch(matrix.n(), right_hand_side.size()));
Assert (matrix.n() == solution.size(),
- ExcDimensionMismatch(matrix.n(), solution.size()));
- // if no boundary values are to be applied
- // simply return
+ ExcDimensionMismatch(matrix.n(), solution.size()));
+ // if no boundary values are to be applied
+ // simply return
if (boundary_values.size() == 0)
return;
const unsigned int n_dofs = matrix.m();
- // if a diagonal entry is zero
- // later, then we use another
- // number instead. take it to be
- // the first nonzero diagonal
- // element of the matrix, or 1 if
- // there is no such thing
+ // if a diagonal entry is zero
+ // later, then we use another
+ // number instead. take it to be
+ // the first nonzero diagonal
+ // element of the matrix, or 1 if
+ // there is no such thing
number first_nonzero_diagonal_entry = 1;
for (unsigned int i=0; i<n_dofs; ++i)
if (matrix.diag_element(i) != 0)
- {
- first_nonzero_diagonal_entry = matrix.diag_element(i);
- break;
- }
+ {
+ first_nonzero_diagonal_entry = matrix.diag_element(i);
+ break;
+ }
std::map<unsigned int,double>::const_iterator dof = boundary_values.begin(),
- endd = boundary_values.end();
+ endd = boundary_values.end();
const SparsityPattern &sparsity = matrix.get_sparsity_pattern();
const std::size_t *sparsity_rowstart = sparsity.get_rowstart_indices();
const unsigned int *sparsity_colnums = sparsity.get_column_numbers();
for (; dof != endd; ++dof)
{
- Assert (dof->first < n_dofs, ExcInternalError());
-
- const unsigned int dof_number = dof->first;
- // for each boundary dof:
-
- // set entries of this line
- // to zero except for the diagonal
- // entry. Note that the diagonal
- // entry is always the first one
- // for square matrices, i.e.
- // we shall not set
- // matrix.global_entry(
- // sparsity_rowstart[dof.first])
- const unsigned int last = sparsity_rowstart[dof_number+1];
- for (unsigned int j=sparsity_rowstart[dof_number]+1; j<last; ++j)
- matrix.global_entry(j) = 0.;
-
-
- // set right hand side to
- // wanted value: if main diagonal
- // entry nonzero, don't touch it
- // and scale rhs accordingly. If
- // zero, take the first main
- // diagonal entry we can find, or
- // one if no nonzero main diagonal
- // element exists. Normally, however,
- // the main diagonal entry should
- // not be zero.
- //
- // store the new rhs entry to make
- // the gauss step more efficient
- number new_rhs;
- if (matrix.diag_element(dof_number) != 0.0)
- {
- new_rhs = dof->second * matrix.diag_element(dof_number);
- right_hand_side(dof_number) = new_rhs;
- }
- else
- {
- matrix.set (dof_number, dof_number,
- first_nonzero_diagonal_entry);
- new_rhs = dof->second * first_nonzero_diagonal_entry;
- right_hand_side(dof_number) = new_rhs;
- }
-
-
- // if the user wants to have
- // the symmetry of the matrix
- // preserved, and if the
- // sparsity pattern is
- // symmetric, then do a Gauss
- // elimination step with the
- // present row
- if (eliminate_columns)
- {
- // store the only nonzero entry
- // of this line for the Gauss
- // elimination step
- const number diagonal_entry = matrix.diag_element(dof_number);
-
- // we have to loop over all
- // rows of the matrix which
- // have a nonzero entry in
- // the column which we work
- // in presently. if the
- // sparsity pattern is
- // symmetric, then we can
- // get the positions of
- // these rows cheaply by
- // looking at the nonzero
- // column numbers of the
- // present row. we need not
- // look at the first entry,
- // since that is the
- // diagonal element and
- // thus the present row
- for (unsigned int j=sparsity_rowstart[dof_number]+1; j<last; ++j)
- {
- const unsigned int row = sparsity_colnums[j];
-
- // find the position of
- // element
- // (row,dof_number)
- const unsigned int *
- p = Utilities::lower_bound(&sparsity_colnums[sparsity_rowstart[row]+1],
- &sparsity_colnums[sparsity_rowstart[row+1]],
- dof_number);
-
- // check whether this line has
- // an entry in the regarding column
- // (check for ==dof_number and
- // != next_row, since if
- // row==dof_number-1, *p is a
- // past-the-end pointer but points
- // to dof_number anyway...)
- //
- // there should be such an entry!
- Assert ((*p == dof_number) &&
- (p != &sparsity_colnums[sparsity_rowstart[row+1]]),
- ExcInternalError());
-
- const unsigned int global_entry
- = (p - &sparsity_colnums[sparsity_rowstart[0]]);
-
- // correct right hand side
- right_hand_side(row) -= matrix.global_entry(global_entry) /
- diagonal_entry * new_rhs;
-
- // set matrix entry to zero
- matrix.global_entry(global_entry) = 0.;
- }
- }
-
- // preset solution vector
- solution(dof_number) = dof->second;
+ Assert (dof->first < n_dofs, ExcInternalError());
+
+ const unsigned int dof_number = dof->first;
+ // for each boundary dof:
+
+ // set entries of this line
+ // to zero except for the diagonal
+ // entry. Note that the diagonal
+ // entry is always the first one
+ // for square matrices, i.e.
+ // we shall not set
+ // matrix.global_entry(
+ // sparsity_rowstart[dof.first])
+ const unsigned int last = sparsity_rowstart[dof_number+1];
+ for (unsigned int j=sparsity_rowstart[dof_number]+1; j<last; ++j)
+ matrix.global_entry(j) = 0.;
+
+
+ // set right hand side to
+ // wanted value: if main diagonal
+ // entry nonzero, don't touch it
+ // and scale rhs accordingly. If
+ // zero, take the first main
+ // diagonal entry we can find, or
+ // one if no nonzero main diagonal
+ // element exists. Normally, however,
+ // the main diagonal entry should
+ // not be zero.
+ //
+ // store the new rhs entry to make
+ // the gauss step more efficient
+ number new_rhs;
+ if (matrix.diag_element(dof_number) != 0.0)
+ {
+ new_rhs = dof->second * matrix.diag_element(dof_number);
+ right_hand_side(dof_number) = new_rhs;
+ }
+ else
+ {
+ matrix.set (dof_number, dof_number,
+ first_nonzero_diagonal_entry);
+ new_rhs = dof->second * first_nonzero_diagonal_entry;
+ right_hand_side(dof_number) = new_rhs;
+ }
+
+
+ // if the user wants to have
+ // the symmetry of the matrix
+ // preserved, and if the
+ // sparsity pattern is
+ // symmetric, then do a Gauss
+ // elimination step with the
+ // present row
+ if (eliminate_columns)
+ {
+ // store the only nonzero entry
+ // of this line for the Gauss
+ // elimination step
+ const number diagonal_entry = matrix.diag_element(dof_number);
+
+ // we have to loop over all
+ // rows of the matrix which
+ // have a nonzero entry in
+ // the column which we work
+ // in presently. if the
+ // sparsity pattern is
+ // symmetric, then we can
+ // get the positions of
+ // these rows cheaply by
+ // looking at the nonzero
+ // column numbers of the
+ // present row. we need not
+ // look at the first entry,
+ // since that is the
+ // diagonal element and
+ // thus the present row
+ for (unsigned int j=sparsity_rowstart[dof_number]+1; j<last; ++j)
+ {
+ const unsigned int row = sparsity_colnums[j];
+
+ // find the position of
+ // element
+ // (row,dof_number)
+ const unsigned int *
+ p = Utilities::lower_bound(&sparsity_colnums[sparsity_rowstart[row]+1],
+ &sparsity_colnums[sparsity_rowstart[row+1]],
+ dof_number);
+
+ // check whether this line has
+ // an entry in the regarding column
+ // (check for ==dof_number and
+ // != next_row, since if
+ // row==dof_number-1, *p is a
+ // past-the-end pointer but points
+ // to dof_number anyway...)
+ //
+ // there should be such an entry!
+ Assert ((*p == dof_number) &&
+ (p != &sparsity_colnums[sparsity_rowstart[row+1]]),
+ ExcInternalError());
+
+ const unsigned int global_entry
+ = (p - &sparsity_colnums[sparsity_rowstart[0]]);
+
+ // correct right hand side
+ right_hand_side(row) -= matrix.global_entry(global_entry) /
+ diagonal_entry * new_rhs;
+
+ // set matrix entry to zero
+ matrix.global_entry(global_entry) = 0.;
+ }
+ }
+
+ // preset solution vector
+ solution(dof_number) = dof->second;
}
}
template <typename number>
void
apply_boundary_values (const std::map<unsigned int,double> &boundary_values,
- BlockSparseMatrix<number> &matrix,
- BlockVector<number> &solution,
- BlockVector<number> &right_hand_side,
- const bool eliminate_columns)
+ BlockSparseMatrix<number> &matrix,
+ BlockVector<number> &solution,
+ BlockVector<number> &right_hand_side,
+ const bool eliminate_columns)
{
const unsigned int blocks = matrix.n_block_rows();
Assert (matrix.n() == right_hand_side.size(),
- ExcDimensionMismatch(matrix.n(), right_hand_side.size()));
+ ExcDimensionMismatch(matrix.n(), right_hand_side.size()));
Assert (matrix.n() == solution.size(),
- ExcDimensionMismatch(matrix.n(), solution.size()));
+ ExcDimensionMismatch(matrix.n(), solution.size()));
Assert (matrix.n_block_rows() == matrix.n_block_cols(),
- ExcNotQuadratic());
+ ExcNotQuadratic());
Assert (matrix.get_sparsity_pattern().get_row_indices() ==
- matrix.get_sparsity_pattern().get_column_indices(),
- ExcNotQuadratic());
+ matrix.get_sparsity_pattern().get_column_indices(),
+ ExcNotQuadratic());
Assert (matrix.get_sparsity_pattern().get_column_indices() ==
- solution.get_block_indices (),
- ExcBlocksDontMatch ());
+ solution.get_block_indices (),
+ ExcBlocksDontMatch ());
Assert (matrix.get_sparsity_pattern().get_row_indices() ==
- right_hand_side.get_block_indices (),
- ExcBlocksDontMatch ());
+ right_hand_side.get_block_indices (),
+ ExcBlocksDontMatch ());
for (unsigned int i=0; i<blocks; ++i)
Assert (matrix.block(i,i).get_sparsity_pattern().optimize_diagonal(),
- SparsityPattern::ExcDiagonalNotOptimized());
+ SparsityPattern::ExcDiagonalNotOptimized());
- // if no boundary values are to be applied
- // simply return
+ // if no boundary values are to be applied
+ // simply return
if (boundary_values.size() == 0)
return;
const unsigned int n_dofs = matrix.m();
- // if a diagonal entry is zero
- // later, then we use another
- // number instead. take it to be
- // the first nonzero diagonal
- // element of the matrix, or 1 if
- // there is no such thing
+ // if a diagonal entry is zero
+ // later, then we use another
+ // number instead. take it to be
+ // the first nonzero diagonal
+ // element of the matrix, or 1 if
+ // there is no such thing
number first_nonzero_diagonal_entry = 0;
for (unsigned int diag_block=0; diag_block<blocks; ++diag_block)
{
- for (unsigned int i=0; i<matrix.block(diag_block,diag_block).n(); ++i)
- if (matrix.block(diag_block,diag_block).diag_element(i) != 0)
- {
- first_nonzero_diagonal_entry
- = matrix.block(diag_block,diag_block).diag_element(i);
- break;
- }
- // check whether we have found
- // something in the present
- // block
- if (first_nonzero_diagonal_entry != 0)
- break;
+ for (unsigned int i=0; i<matrix.block(diag_block,diag_block).n(); ++i)
+ if (matrix.block(diag_block,diag_block).diag_element(i) != 0)
+ {
+ first_nonzero_diagonal_entry
+ = matrix.block(diag_block,diag_block).diag_element(i);
+ break;
+ }
+ // check whether we have found
+ // something in the present
+ // block
+ if (first_nonzero_diagonal_entry != 0)
+ break;
}
- // nothing found on all diagonal
- // blocks? if so, use 1.0 instead
+ // nothing found on all diagonal
+ // blocks? if so, use 1.0 instead
if (first_nonzero_diagonal_entry == 0)
first_nonzero_diagonal_entry = 1;
std::map<unsigned int,double>::const_iterator dof = boundary_values.begin(),
- endd = boundary_values.end();
+ endd = boundary_values.end();
const BlockSparsityPattern &
sparsity_pattern = matrix.get_sparsity_pattern();
- // pointer to the mapping between
- // global and block indices. since
- // the row and column mappings are
- // equal, store a pointer on only
- // one of them
+ // pointer to the mapping between
+ // global and block indices. since
+ // the row and column mappings are
+ // equal, store a pointer on only
+ // one of them
const BlockIndices &
index_mapping = sparsity_pattern.get_column_indices();
- // now loop over all boundary dofs
+ // now loop over all boundary dofs
for (; dof != endd; ++dof)
{
- Assert (dof->first < n_dofs, ExcInternalError());
-
- // get global index and index
- // in the block in which this
- // dof is located
- const unsigned int dof_number = dof->first;
- const std::pair<unsigned int,unsigned int>
- block_index = index_mapping.global_to_local (dof_number);
-
- // for each boundary dof:
-
- // set entries of this line
- // to zero except for the diagonal
- // entry. Note that the diagonal
- // entry is always the first one
- // for square matrices, i.e.
- // we shall not set
- // matrix.global_entry(
- // sparsity_rowstart[dof.first])
- // of the diagonal block
- for (unsigned int block_col=0; block_col<blocks; ++block_col)
- {
- const SparsityPattern &
- local_sparsity = sparsity_pattern.block(block_index.first,
- block_col);
-
- // find first and last
- // entry in the present row
- // of the present
- // block. exclude the main
- // diagonal element, which
- // is the diagonal element
- // of a diagonal block,
- // which must be a square
- // matrix so the diagonal
- // element is the first of
- // this row.
- const unsigned int
- last = local_sparsity.get_rowstart_indices()[block_index.second+1],
- first = (block_col == block_index.first ?
- local_sparsity.get_rowstart_indices()[block_index.second]+1 :
- local_sparsity.get_rowstart_indices()[block_index.second]);
-
- for (unsigned int j=first; j<last; ++j)
- matrix.block(block_index.first,block_col).global_entry(j) = 0.;
- }
-
-
- // set right hand side to
- // wanted value: if main diagonal
- // entry nonzero, don't touch it
- // and scale rhs accordingly. If
- // zero, take the first main
- // diagonal entry we can find, or
- // one if no nonzero main diagonal
- // element exists. Normally, however,
- // the main diagonal entry should
- // not be zero.
- //
- // store the new rhs entry to make
- // the gauss step more efficient
- number new_rhs;
- if (matrix.block(block_index.first, block_index.first)
- .diag_element(block_index.second) != 0.0)
- new_rhs = dof->second *
- matrix.block(block_index.first, block_index.first)
- .diag_element(block_index.second);
- else
- {
- matrix.block(block_index.first, block_index.first)
- .diag_element(block_index.second)
- = first_nonzero_diagonal_entry;
- new_rhs = dof->second * first_nonzero_diagonal_entry;
- }
- right_hand_side.block(block_index.first)(block_index.second)
- = new_rhs;
-
-
- // if the user wants to have
- // the symmetry of the matrix
- // preserved, and if the
- // sparsity pattern is
- // symmetric, then do a Gauss
- // elimination step with the
- // present row. this is a
- // little more complicated for
- // block matrices.
- if (eliminate_columns)
- {
- // store the only nonzero entry
- // of this line for the Gauss
- // elimination step
- const number diagonal_entry
- = matrix.block(block_index.first,block_index.first)
- .diag_element(block_index.second);
-
- // we have to loop over all
- // rows of the matrix which
- // have a nonzero entry in
- // the column which we work
- // in presently. if the
- // sparsity pattern is
- // symmetric, then we can
- // get the positions of
- // these rows cheaply by
- // looking at the nonzero
- // column numbers of the
- // present row.
- //
- // note that if we check
- // whether row @p{row} in
- // block (r,c) is non-zero,
- // then we have to check
- // for the existence of
- // column @p{row} in block
- // (c,r), i.e. of the
- // transpose block
- for (unsigned int block_row=0; block_row<blocks; ++block_row)
- {
- // get pointers to the
- // sparsity patterns of
- // this block and of
- // the transpose one
- const SparsityPattern &this_sparsity
- = sparsity_pattern.block (block_row, block_index.first);
- const SparsityPattern &transpose_sparsity
- = sparsity_pattern.block (block_index.first, block_row);
-
- // traverse the row of
- // the transpose block
- // to find the
- // interesting rows in
- // the present block.
- // don't use the
- // diagonal element of
- // the diagonal block
- const unsigned int
- first = (block_index.first == block_row ?
- transpose_sparsity.get_rowstart_indices()[block_index.second]+1 :
- transpose_sparsity.get_rowstart_indices()[block_index.second]),
- last = transpose_sparsity.get_rowstart_indices()[block_index.second+1];
-
- for (unsigned int j=first; j<last; ++j)
- {
- // get the number
- // of the column in
- // this row in
- // which a nonzero
- // entry is. this
- // is also the row
- // of the transpose
- // block which has
- // an entry in the
- // interesting row
- const unsigned int row = transpose_sparsity.get_column_numbers()[j];
-
- // find the
- // position of
- // element
- // (row,dof_number)
- // in this block
- // (not in the
- // transpose
- // one). note that
- // we have to take
- // care of special
- // cases with
- // square
- // sub-matrices
- const unsigned int *p = 0;
- if (this_sparsity.n_rows() == this_sparsity.n_cols())
- {
- if (this_sparsity.get_column_numbers()
- [this_sparsity.get_rowstart_indices()[row]]
- ==
- block_index.second)
- p = &this_sparsity.get_column_numbers()
- [this_sparsity.get_rowstart_indices()[row]];
- else
- p = Utilities::lower_bound(&this_sparsity.get_column_numbers()
- [this_sparsity.get_rowstart_indices()[row]+1],
- &this_sparsity.get_column_numbers()
- [this_sparsity.get_rowstart_indices()[row+1]],
- block_index.second);
- }
- else
- p = Utilities::lower_bound(&this_sparsity.get_column_numbers()
- [this_sparsity.get_rowstart_indices()[row]],
- &this_sparsity.get_column_numbers()
- [this_sparsity.get_rowstart_indices()[row+1]],
- block_index.second);
-
- // check whether this line has
- // an entry in the regarding column
- // (check for ==dof_number and
- // != next_row, since if
- // row==dof_number-1, *p is a
- // past-the-end pointer but points
- // to dof_number anyway...)
- //
- // there should be
- // such an entry!
- // note, however,
- // that this
- // assertion will
- // fail sometimes
- // if the sparsity
- // pattern is not
- // symmetric!
- Assert ((*p == block_index.second) &&
- (p != &this_sparsity.get_column_numbers()
- [this_sparsity.get_rowstart_indices()[row+1]]),
- ExcInternalError());
-
- const unsigned int global_entry
- = (p
- -
- &this_sparsity.get_column_numbers()
- [this_sparsity.get_rowstart_indices()[0]]);
-
- // correct right hand side
- right_hand_side.block(block_row)(row)
- -= matrix.block(block_row,block_index.first).global_entry(global_entry) /
- diagonal_entry * new_rhs;
-
- // set matrix entry to zero
- matrix.block(block_row,block_index.first).global_entry(global_entry) = 0.;
- }
- }
- }
-
- // preset solution vector
- solution.block(block_index.first)(block_index.second) = dof->second;
+ Assert (dof->first < n_dofs, ExcInternalError());
+
+ // get global index and index
+ // in the block in which this
+ // dof is located
+ const unsigned int dof_number = dof->first;
+ const std::pair<unsigned int,unsigned int>
+ block_index = index_mapping.global_to_local (dof_number);
+
+ // for each boundary dof:
+
+ // set entries of this line
+ // to zero except for the diagonal
+ // entry. Note that the diagonal
+ // entry is always the first one
+ // for square matrices, i.e.
+ // we shall not set
+ // matrix.global_entry(
+ // sparsity_rowstart[dof.first])
+ // of the diagonal block
+ for (unsigned int block_col=0; block_col<blocks; ++block_col)
+ {
+ const SparsityPattern &
+ local_sparsity = sparsity_pattern.block(block_index.first,
+ block_col);
+
+ // find first and last
+ // entry in the present row
+ // of the present
+ // block. exclude the main
+ // diagonal element, which
+ // is the diagonal element
+ // of a diagonal block,
+ // which must be a square
+ // matrix so the diagonal
+ // element is the first of
+ // this row.
+ const unsigned int
+ last = local_sparsity.get_rowstart_indices()[block_index.second+1],
+ first = (block_col == block_index.first ?
+ local_sparsity.get_rowstart_indices()[block_index.second]+1 :
+ local_sparsity.get_rowstart_indices()[block_index.second]);
+
+ for (unsigned int j=first; j<last; ++j)
+ matrix.block(block_index.first,block_col).global_entry(j) = 0.;
+ }
+
+
+ // set right hand side to
+ // wanted value: if main diagonal
+ // entry nonzero, don't touch it
+ // and scale rhs accordingly. If
+ // zero, take the first main
+ // diagonal entry we can find, or
+ // one if no nonzero main diagonal
+ // element exists. Normally, however,
+ // the main diagonal entry should
+ // not be zero.
+ //
+ // store the new rhs entry to make
+ // the gauss step more efficient
+ number new_rhs;
+ if (matrix.block(block_index.first, block_index.first)
+ .diag_element(block_index.second) != 0.0)
+ new_rhs = dof->second *
+ matrix.block(block_index.first, block_index.first)
+ .diag_element(block_index.second);
+ else
+ {
+ matrix.block(block_index.first, block_index.first)
+ .diag_element(block_index.second)
+ = first_nonzero_diagonal_entry;
+ new_rhs = dof->second * first_nonzero_diagonal_entry;
+ }
+ right_hand_side.block(block_index.first)(block_index.second)
+ = new_rhs;
+
+
+ // if the user wants to have
+ // the symmetry of the matrix
+ // preserved, and if the
+ // sparsity pattern is
+ // symmetric, then do a Gauss
+ // elimination step with the
+ // present row. this is a
+ // little more complicated for
+ // block matrices.
+ if (eliminate_columns)
+ {
+ // store the only nonzero entry
+ // of this line for the Gauss
+ // elimination step
+ const number diagonal_entry
+ = matrix.block(block_index.first,block_index.first)
+ .diag_element(block_index.second);
+
+ // we have to loop over all
+ // rows of the matrix which
+ // have a nonzero entry in
+ // the column which we work
+ // in presently. if the
+ // sparsity pattern is
+ // symmetric, then we can
+ // get the positions of
+ // these rows cheaply by
+ // looking at the nonzero
+ // column numbers of the
+ // present row.
+ //
+ // note that if we check
+ // whether row @p{row} in
+ // block (r,c) is non-zero,
+ // then we have to check
+ // for the existence of
+ // column @p{row} in block
+ // (c,r), i.e. of the
+ // transpose block
+ for (unsigned int block_row=0; block_row<blocks; ++block_row)
+ {
+ // get pointers to the
+ // sparsity patterns of
+ // this block and of
+ // the transpose one
+ const SparsityPattern &this_sparsity
+ = sparsity_pattern.block (block_row, block_index.first);
+ const SparsityPattern &transpose_sparsity
+ = sparsity_pattern.block (block_index.first, block_row);
+
+ // traverse the row of
+ // the transpose block
+ // to find the
+ // interesting rows in
+ // the present block.
+ // don't use the
+ // diagonal element of
+ // the diagonal block
+ const unsigned int
+ first = (block_index.first == block_row ?
+ transpose_sparsity.get_rowstart_indices()[block_index.second]+1 :
+ transpose_sparsity.get_rowstart_indices()[block_index.second]),
+ last = transpose_sparsity.get_rowstart_indices()[block_index.second+1];
+
+ for (unsigned int j=first; j<last; ++j)
+ {
+ // get the number
+ // of the column in
+ // this row in
+ // which a nonzero
+ // entry is. this
+ // is also the row
+ // of the transpose
+ // block which has
+ // an entry in the
+ // interesting row
+ const unsigned int row = transpose_sparsity.get_column_numbers()[j];
+
+ // find the
+ // position of
+ // element
+ // (row,dof_number)
+ // in this block
+ // (not in the
+ // transpose
+ // one). note that
+ // we have to take
+ // care of special
+ // cases with
+ // square
+ // sub-matrices
+ const unsigned int *p = 0;
+ if (this_sparsity.n_rows() == this_sparsity.n_cols())
+ {
+ if (this_sparsity.get_column_numbers()
+ [this_sparsity.get_rowstart_indices()[row]]
+ ==
+ block_index.second)
+ p = &this_sparsity.get_column_numbers()
+ [this_sparsity.get_rowstart_indices()[row]];
+ else
+ p = Utilities::lower_bound(&this_sparsity.get_column_numbers()
+ [this_sparsity.get_rowstart_indices()[row]+1],
+ &this_sparsity.get_column_numbers()
+ [this_sparsity.get_rowstart_indices()[row+1]],
+ block_index.second);
+ }
+ else
+ p = Utilities::lower_bound(&this_sparsity.get_column_numbers()
+ [this_sparsity.get_rowstart_indices()[row]],
+ &this_sparsity.get_column_numbers()
+ [this_sparsity.get_rowstart_indices()[row+1]],
+ block_index.second);
+
+ // check whether this line has
+ // an entry in the regarding column
+ // (check for ==dof_number and
+ // != next_row, since if
+ // row==dof_number-1, *p is a
+ // past-the-end pointer but points
+ // to dof_number anyway...)
+ //
+ // there should be
+ // such an entry!
+ // note, however,
+ // that this
+ // assertion will
+ // fail sometimes
+ // if the sparsity
+ // pattern is not
+ // symmetric!
+ Assert ((*p == block_index.second) &&
+ (p != &this_sparsity.get_column_numbers()
+ [this_sparsity.get_rowstart_indices()[row+1]]),
+ ExcInternalError());
+
+ const unsigned int global_entry
+ = (p
+ -
+ &this_sparsity.get_column_numbers()
+ [this_sparsity.get_rowstart_indices()[0]]);
+
+ // correct right hand side
+ right_hand_side.block(block_row)(row)
+ -= matrix.block(block_row,block_index.first).global_entry(global_entry) /
+ diagonal_entry * new_rhs;
+
+ // set matrix entry to zero
+ matrix.block(block_row,block_index.first).global_entry(global_entry) = 0.;
+ }
+ }
+ }
+
+ // preset solution vector
+ solution.block(block_index.first)(block_index.second) = dof->second;
}
}
template <typename PETScMatrix, typename PETScVector>
void
apply_boundary_values (const std::map<unsigned int,double> &boundary_values,
- PETScMatrix &matrix,
- PETScVector &solution,
- PETScVector &right_hand_side,
- const bool eliminate_columns)
+ PETScMatrix &matrix,
+ PETScVector &solution,
+ PETScVector &right_hand_side,
+ const bool eliminate_columns)
{
- Assert (eliminate_columns == false, ExcNotImplemented());
-
- Assert (matrix.n() == right_hand_side.size(),
- ExcDimensionMismatch(matrix.n(), right_hand_side.size()));
- Assert (matrix.n() == solution.size(),
- ExcDimensionMismatch(matrix.n(), solution.size()));
-
- // if no boundary values are to be applied
- // simply return
- if (boundary_values.size() == 0)
- return;
-
- const std::pair<unsigned int, unsigned int> local_range
- = matrix.local_range();
- Assert (local_range == right_hand_side.local_range(),
- ExcInternalError());
- Assert (local_range == solution.local_range(),
- ExcInternalError());
-
-
- // we have to read and write from this
- // matrix (in this order). this will only
- // work if we compress the matrix first,
- // done here
- matrix.compress ();
-
- // determine the first nonzero diagonal
- // entry from within the part of the
- // matrix that we can see. if we can't
- // find such an entry, take one
- PetscScalar average_nonzero_diagonal_entry = 1;
- for (unsigned int i=local_range.first; i<local_range.second; ++i)
- if (matrix.diag_element(i) != 0)
- {
- average_nonzero_diagonal_entry = std::fabs(matrix.diag_element(i));
- break;
- }
-
- // figure out which rows of the matrix we
- // have to eliminate on this processor
- std::vector<unsigned int> constrained_rows;
- for (std::map<unsigned int,double>::const_iterator
- dof = boundary_values.begin();
- dof != boundary_values.end();
- ++dof)
- if ((dof->first >= local_range.first) &&
- (dof->first < local_range.second))
- constrained_rows.push_back (dof->first);
-
- // then eliminate these rows and set
- // their diagonal entry to what we have
- // determined above. note that for petsc
- // matrices interleaving read with write
- // operations is very expensive. thus, we
- // here always replace the diagonal
- // element, rather than first checking
- // whether it is nonzero and in that case
- // preserving it. this is different from
- // the case of deal.II sparse matrices
- // treated in the other functions.
- matrix.clear_rows (constrained_rows, average_nonzero_diagonal_entry);
-
- // the next thing is to set right hand
- // side to the wanted value. there's one
- // drawback: if we write to individual
- // vector elements, then we have to do
- // that on all processors. however, some
- // processors may not need to set
- // anything because their chunk of
- // matrix/rhs do not contain any boundary
- // nodes. therefore, rather than using
- // individual calls, we use one call for
- // all elements, thereby making sure that
- // all processors call this function,
- // even if some only have an empty set of
- // elements to set
- right_hand_side.compress ();
- solution.compress ();
-
- std::vector<unsigned int> indices;
- std::vector<PetscScalar> solution_values;
- for (std::map<unsigned int,double>::const_iterator
- dof = boundary_values.begin();
- dof != boundary_values.end();
- ++dof)
- if ((dof->first >= local_range.first) &&
- (dof->first < local_range.second))
- {
- indices.push_back (dof->first);
- solution_values.push_back (dof->second);
- }
- solution.set (indices, solution_values);
-
- // now also set appropriate values for
- // the rhs
- for (unsigned int i=0; i<solution_values.size(); ++i)
- solution_values[i] *= average_nonzero_diagonal_entry;
-
- right_hand_side.set (indices, solution_values);
-
- // clean up
- matrix.compress ();
- solution.compress ();
- right_hand_side.compress ();
+ Assert (eliminate_columns == false, ExcNotImplemented());
+
+ Assert (matrix.n() == right_hand_side.size(),
+ ExcDimensionMismatch(matrix.n(), right_hand_side.size()));
+ Assert (matrix.n() == solution.size(),
+ ExcDimensionMismatch(matrix.n(), solution.size()));
+
+ // if no boundary values are to be applied
+ // simply return
+ if (boundary_values.size() == 0)
+ return;
+
+ const std::pair<unsigned int, unsigned int> local_range
+ = matrix.local_range();
+ Assert (local_range == right_hand_side.local_range(),
+ ExcInternalError());
+ Assert (local_range == solution.local_range(),
+ ExcInternalError());
+
+
+ // we have to read and write from this
+ // matrix (in this order). this will only
+ // work if we compress the matrix first,
+ // done here
+ matrix.compress ();
+
+ // determine the first nonzero diagonal
+ // entry from within the part of the
+ // matrix that we can see. if we can't
+ // find such an entry, take one
+ PetscScalar average_nonzero_diagonal_entry = 1;
+ for (unsigned int i=local_range.first; i<local_range.second; ++i)
+ if (matrix.diag_element(i) != 0)
+ {
+ average_nonzero_diagonal_entry = std::fabs(matrix.diag_element(i));
+ break;
+ }
+
+ // figure out which rows of the matrix we
+ // have to eliminate on this processor
+ std::vector<unsigned int> constrained_rows;
+ for (std::map<unsigned int,double>::const_iterator
+ dof = boundary_values.begin();
+ dof != boundary_values.end();
+ ++dof)
+ if ((dof->first >= local_range.first) &&
+ (dof->first < local_range.second))
+ constrained_rows.push_back (dof->first);
+
+ // then eliminate these rows and set
+ // their diagonal entry to what we have
+ // determined above. note that for petsc
+ // matrices interleaving read with write
+ // operations is very expensive. thus, we
+ // here always replace the diagonal
+ // element, rather than first checking
+ // whether it is nonzero and in that case
+ // preserving it. this is different from
+ // the case of deal.II sparse matrices
+ // treated in the other functions.
+ matrix.clear_rows (constrained_rows, average_nonzero_diagonal_entry);
+
+ // the next thing is to set right hand
+ // side to the wanted value. there's one
+ // drawback: if we write to individual
+ // vector elements, then we have to do
+ // that on all processors. however, some
+ // processors may not need to set
+ // anything because their chunk of
+ // matrix/rhs do not contain any boundary
+ // nodes. therefore, rather than using
+ // individual calls, we use one call for
+ // all elements, thereby making sure that
+ // all processors call this function,
+ // even if some only have an empty set of
+ // elements to set
+ right_hand_side.compress ();
+ solution.compress ();
+
+ std::vector<unsigned int> indices;
+ std::vector<PetscScalar> solution_values;
+ for (std::map<unsigned int,double>::const_iterator
+ dof = boundary_values.begin();
+ dof != boundary_values.end();
+ ++dof)
+ if ((dof->first >= local_range.first) &&
+ (dof->first < local_range.second))
+ {
+ indices.push_back (dof->first);
+ solution_values.push_back (dof->second);
+ }
+ solution.set (indices, solution_values);
+
+ // now also set appropriate values for
+ // the rhs
+ for (unsigned int i=0; i<solution_values.size(); ++i)
+ solution_values[i] *= average_nonzero_diagonal_entry;
+
+ right_hand_side.set (indices, solution_values);
+
+ // clean up
+ matrix.compress ();
+ solution.compress ();
+ right_hand_side.compress ();
}
}
}
void
apply_boundary_values (const std::map<unsigned int,double> &boundary_values,
- PETScWrappers::SparseMatrix &matrix,
- PETScWrappers::Vector &solution,
- PETScWrappers::Vector &right_hand_side,
- const bool eliminate_columns)
+ PETScWrappers::SparseMatrix &matrix,
+ PETScWrappers::Vector &solution,
+ PETScWrappers::Vector &right_hand_side,
+ const bool eliminate_columns)
{
- // simply redirect to the generic function
- // used for both petsc matrix types
+ // simply redirect to the generic function
+ // used for both petsc matrix types
internal::PETScWrappers::apply_boundary_values (boundary_values, matrix, solution,
- right_hand_side, eliminate_columns);
+ right_hand_side, eliminate_columns);
}
void
apply_boundary_values (const std::map<unsigned int,double> &boundary_values,
- PETScWrappers::MPI::SparseMatrix &matrix,
- PETScWrappers::MPI::Vector &solution,
- PETScWrappers::MPI::Vector &right_hand_side,
- const bool eliminate_columns)
+ PETScWrappers::MPI::SparseMatrix &matrix,
+ PETScWrappers::MPI::Vector &solution,
+ PETScWrappers::MPI::Vector &right_hand_side,
+ const bool eliminate_columns)
{
- // simply redirect to the generic function
- // used for both petsc matrix types
+ // simply redirect to the generic function
+ // used for both petsc matrix types
internal::PETScWrappers::apply_boundary_values (boundary_values, matrix, solution,
- right_hand_side, eliminate_columns);
+ right_hand_side, eliminate_columns);
- // compress the matrix once we're done
+ // compress the matrix once we're done
matrix.compress ();
}
void
apply_boundary_values (const std::map<unsigned int,double> &boundary_values,
- PETScWrappers::MPI::BlockSparseMatrix &matrix,
- PETScWrappers::MPI::BlockVector &solution,
- PETScWrappers::MPI::BlockVector &right_hand_side,
- const bool eliminate_columns)
+ PETScWrappers::MPI::BlockSparseMatrix &matrix,
+ PETScWrappers::MPI::BlockVector &solution,
+ PETScWrappers::MPI::BlockVector &right_hand_side,
+ const bool eliminate_columns)
{
Assert (matrix.n() == right_hand_side.size(),
- ExcDimensionMismatch(matrix.n(), right_hand_side.size()));
+ ExcDimensionMismatch(matrix.n(), right_hand_side.size()));
Assert (matrix.n() == solution.size(),
- ExcDimensionMismatch(matrix.n(), solution.size()));
+ ExcDimensionMismatch(matrix.n(), solution.size()));
Assert (matrix.n_block_rows() == matrix.n_block_cols(),
- ExcNotQuadratic());
+ ExcNotQuadratic());
const unsigned int n_blocks = matrix.n_block_rows();
matrix.compress();
- // We need to find the subdivision
- // into blocks for the boundary values.
- // To this end, generate a vector of
- // maps with the respective indices.
+ // We need to find the subdivision
+ // into blocks for the boundary values.
+ // To this end, generate a vector of
+ // maps with the respective indices.
std::vector<std::map<unsigned int,double> > block_boundary_values(n_blocks);
{
int offset = 0, block=0;
for (std::map<unsigned int,double>::const_iterator
- dof = boundary_values.begin();
- dof != boundary_values.end();
- ++dof)
- {
- if (dof->first >= matrix.block(block,0).m() + offset)
- {
- offset += matrix.block(block,0).m();
- block++;
- }
- const unsigned int index = dof->first - offset;
- block_boundary_values[block].insert(std::pair<unsigned int, double> (index,dof->second));
- }
+ dof = boundary_values.begin();
+ dof != boundary_values.end();
+ ++dof)
+ {
+ if (dof->first >= matrix.block(block,0).m() + offset)
+ {
+ offset += matrix.block(block,0).m();
+ block++;
+ }
+ const unsigned int index = dof->first - offset;
+ block_boundary_values[block].insert(std::pair<unsigned int, double> (index,dof->second));
+ }
}
- // Now call the non-block variants on
- // the diagonal subblocks and the
- // solution/rhs.
+ // Now call the non-block variants on
+ // the diagonal subblocks and the
+ // solution/rhs.
for (unsigned int block=0; block<n_blocks; ++block)
internal::PETScWrappers::apply_boundary_values(block_boundary_values[block],
- matrix.block(block,block),
- solution.block(block),
- right_hand_side.block(block),
- eliminate_columns);
-
- // Finally, we need to do something
- // about the off-diagonal matrices. This
- // is luckily not difficult. Just clear
- // the whole row.
+ matrix.block(block,block),
+ solution.block(block),
+ right_hand_side.block(block),
+ eliminate_columns);
+
+ // Finally, we need to do something
+ // about the off-diagonal matrices. This
+ // is luckily not difficult. Just clear
+ // the whole row.
for (unsigned int block_m=0; block_m<n_blocks; ++block_m)
{
- const std::pair<unsigned int, unsigned int> local_range
- = matrix.block(block_m,0).local_range();
-
- std::vector<unsigned int> constrained_rows;
- for (std::map<unsigned int,double>::const_iterator
- dof = block_boundary_values[block_m].begin();
- dof != block_boundary_values[block_m].end();
- ++dof)
- if ((dof->first >= local_range.first) &&
- (dof->first < local_range.second))
- constrained_rows.push_back (dof->first);
-
- for (unsigned int block_n=0; block_n<n_blocks; ++block_n)
- if (block_m != block_n)
- matrix.block(block_m,block_n).clear_rows(constrained_rows);
+ const std::pair<unsigned int, unsigned int> local_range
+ = matrix.block(block_m,0).local_range();
+
+ std::vector<unsigned int> constrained_rows;
+ for (std::map<unsigned int,double>::const_iterator
+ dof = block_boundary_values[block_m].begin();
+ dof != block_boundary_values[block_m].end();
+ ++dof)
+ if ((dof->first >= local_range.first) &&
+ (dof->first < local_range.second))
+ constrained_rows.push_back (dof->first);
+
+ for (unsigned int block_n=0; block_n<n_blocks; ++block_n)
+ if (block_m != block_n)
+ matrix.block(block_m,block_n).clear_rows(constrained_rows);
}
}
template <typename TrilinosMatrix, typename TrilinosVector>
void
apply_boundary_values (const std::map<unsigned int,double> &boundary_values,
- TrilinosMatrix &matrix,
- TrilinosVector &solution,
- TrilinosVector &right_hand_side,
- const bool eliminate_columns)
+ TrilinosMatrix &matrix,
+ TrilinosVector &solution,
+ TrilinosVector &right_hand_side,
+ const bool eliminate_columns)
{
- Assert (eliminate_columns == false, ExcNotImplemented());
-
- Assert (matrix.n() == right_hand_side.size(),
- ExcDimensionMismatch(matrix.n(), right_hand_side.size()));
- Assert (matrix.n() == solution.size(),
- ExcDimensionMismatch(matrix.m(), solution.size()));
-
- // if no boundary values are to be applied
- // simply return
- if (boundary_values.size() == 0)
- return;
-
- const std::pair<unsigned int, unsigned int> local_range
- = matrix.local_range();
- Assert (local_range == right_hand_side.local_range(),
- ExcInternalError());
- Assert (local_range == solution.local_range(),
- ExcInternalError());
-
- // we have to read and write from this
- // matrix (in this order). this will only
- // work if we compress the matrix first,
- // done here
- matrix.compress ();
-
- // determine the first nonzero diagonal
- // entry from within the part of the
- // matrix that we can see. if we can't
- // find such an entry, take one
- TrilinosScalar average_nonzero_diagonal_entry = 1;
- for (unsigned int i=local_range.first; i<local_range.second; ++i)
- if (matrix.diag_element(i) != 0)
- {
- average_nonzero_diagonal_entry = std::fabs(matrix.diag_element(i));
- break;
- }
-
- // figure out which rows of the matrix we
- // have to eliminate on this processor
- std::vector<unsigned int> constrained_rows;
- for (std::map<unsigned int,double>::const_iterator
- dof = boundary_values.begin();
- dof != boundary_values.end();
- ++dof)
- if ((dof->first >= local_range.first) &&
- (dof->first < local_range.second))
- constrained_rows.push_back (dof->first);
-
- // then eliminate these rows and
- // set their diagonal entry to
- // what we have determined
- // above. if the value already is
- // nonzero, it will be preserved,
- // in accordance with the basic
- // matrix classes in deal.II.
- matrix.clear_rows (constrained_rows, average_nonzero_diagonal_entry);
-
- // the next thing is to set right
- // hand side to the wanted
- // value. there's one drawback:
- // if we write to individual
- // vector elements, then we have
- // to do that on all
- // processors. however, some
- // processors may not need to set
- // anything because their chunk
- // of matrix/rhs do not contain
- // any boundary nodes. therefore,
- // rather than using individual
- // calls, we use one call for all
- // elements, thereby making sure
- // that all processors call this
- // function, even if some only
- // have an empty set of elements
- // to set
- right_hand_side.compress ();
- solution.compress ();
-
- std::vector<unsigned int> indices;
- std::vector<TrilinosScalar> solution_values;
- for (std::map<unsigned int,double>::const_iterator
- dof = boundary_values.begin();
- dof != boundary_values.end();
- ++dof)
- if ((dof->first >= local_range.first) &&
- (dof->first < local_range.second))
- {
- indices.push_back (dof->first);
- solution_values.push_back (dof->second);
- }
- solution.set (indices, solution_values);
-
- // now also set appropriate
- // values for the rhs
- for (unsigned int i=0; i<solution_values.size(); ++i)
- solution_values[i] *= matrix.diag_element(indices[i]);
-
- right_hand_side.set (indices, solution_values);
-
- // clean up
- matrix.compress ();
- solution.compress ();
- right_hand_side.compress ();
+ Assert (eliminate_columns == false, ExcNotImplemented());
+
+ Assert (matrix.n() == right_hand_side.size(),
+ ExcDimensionMismatch(matrix.n(), right_hand_side.size()));
+ Assert (matrix.n() == solution.size(),
+ ExcDimensionMismatch(matrix.m(), solution.size()));
+
+ // if no boundary values are to be applied
+ // simply return
+ if (boundary_values.size() == 0)
+ return;
+
+ const std::pair<unsigned int, unsigned int> local_range
+ = matrix.local_range();
+ Assert (local_range == right_hand_side.local_range(),
+ ExcInternalError());
+ Assert (local_range == solution.local_range(),
+ ExcInternalError());
+
+ // we have to read and write from this
+ // matrix (in this order). this will only
+ // work if we compress the matrix first,
+ // done here
+ matrix.compress ();
+
+ // determine the first nonzero diagonal
+ // entry from within the part of the
+ // matrix that we can see. if we can't
+ // find such an entry, take one
+ TrilinosScalar average_nonzero_diagonal_entry = 1;
+ for (unsigned int i=local_range.first; i<local_range.second; ++i)
+ if (matrix.diag_element(i) != 0)
+ {
+ average_nonzero_diagonal_entry = std::fabs(matrix.diag_element(i));
+ break;
+ }
+
+ // figure out which rows of the matrix we
+ // have to eliminate on this processor
+ std::vector<unsigned int> constrained_rows;
+ for (std::map<unsigned int,double>::const_iterator
+ dof = boundary_values.begin();
+ dof != boundary_values.end();
+ ++dof)
+ if ((dof->first >= local_range.first) &&
+ (dof->first < local_range.second))
+ constrained_rows.push_back (dof->first);
+
+ // then eliminate these rows and
+ // set their diagonal entry to
+ // what we have determined
+ // above. if the value already is
+ // nonzero, it will be preserved,
+ // in accordance with the basic
+ // matrix classes in deal.II.
+ matrix.clear_rows (constrained_rows, average_nonzero_diagonal_entry);
+
+ // the next thing is to set right
+ // hand side to the wanted
+ // value. there's one drawback:
+ // if we write to individual
+ // vector elements, then we have
+ // to do that on all
+ // processors. however, some
+ // processors may not need to set
+ // anything because their chunk
+ // of matrix/rhs do not contain
+ // any boundary nodes. therefore,
+ // rather than using individual
+ // calls, we use one call for all
+ // elements, thereby making sure
+ // that all processors call this
+ // function, even if some only
+ // have an empty set of elements
+ // to set
+ right_hand_side.compress ();
+ solution.compress ();
+
+ std::vector<unsigned int> indices;
+ std::vector<TrilinosScalar> solution_values;
+ for (std::map<unsigned int,double>::const_iterator
+ dof = boundary_values.begin();
+ dof != boundary_values.end();
+ ++dof)
+ if ((dof->first >= local_range.first) &&
+ (dof->first < local_range.second))
+ {
+ indices.push_back (dof->first);
+ solution_values.push_back (dof->second);
+ }
+ solution.set (indices, solution_values);
+
+ // now also set appropriate
+ // values for the rhs
+ for (unsigned int i=0; i<solution_values.size(); ++i)
+ solution_values[i] *= matrix.diag_element(indices[i]);
+
+ right_hand_side.set (indices, solution_values);
+
+ // clean up
+ matrix.compress ();
+ solution.compress ();
+ right_hand_side.compress ();
}
template <typename TrilinosMatrix, typename TrilinosBlockVector>
void
apply_block_boundary_values (const std::map<unsigned int,double> &boundary_values,
- TrilinosMatrix &matrix,
- TrilinosBlockVector &solution,
- TrilinosBlockVector &right_hand_side,
- const bool eliminate_columns)
+ TrilinosMatrix &matrix,
+ TrilinosBlockVector &solution,
+ TrilinosBlockVector &right_hand_side,
+ const bool eliminate_columns)
{
- Assert (eliminate_columns == false, ExcNotImplemented());
-
- Assert (matrix.n() == right_hand_side.size(),
- ExcDimensionMismatch(matrix.n(), right_hand_side.size()));
- Assert (matrix.n() == solution.size(),
- ExcDimensionMismatch(matrix.n(), solution.size()));
- Assert (matrix.n_block_rows() == matrix.n_block_cols(),
- ExcNotQuadratic());
-
- const unsigned int n_blocks = matrix.n_block_rows();
-
- matrix.compress();
-
- // We need to find the subdivision
- // into blocks for the boundary values.
- // To this end, generate a vector of
- // maps with the respective indices.
- std::vector<std::map<unsigned int,double> > block_boundary_values(n_blocks);
- {
- int offset = 0, block=0;
- for (std::map<unsigned int,double>::const_iterator
- dof = boundary_values.begin();
- dof != boundary_values.end();
- ++dof)
- {
- if (dof->first >= matrix.block(block,0).m() + offset)
- {
- offset += matrix.block(block,0).m();
- block++;
- }
- const unsigned int index = dof->first - offset;
- block_boundary_values[block].insert(
- std::pair<unsigned int, double> (index,dof->second));
- }
- }
-
- // Now call the non-block variants on
- // the diagonal subblocks and the
- // solution/rhs.
- for (unsigned int block=0; block<n_blocks; ++block)
- TrilinosWrappers::apply_boundary_values(block_boundary_values[block],
- matrix.block(block,block),
- solution.block(block),
- right_hand_side.block(block),
- eliminate_columns);
-
- // Finally, we need to do something
- // about the off-diagonal matrices. This
- // is luckily not difficult. Just clear
- // the whole row.
- for (unsigned int block_m=0; block_m<n_blocks; ++block_m)
- {
- const std::pair<unsigned int, unsigned int> local_range
- = matrix.block(block_m,0).local_range();
-
- std::vector<unsigned int> constrained_rows;
- for (std::map<unsigned int,double>::const_iterator
- dof = block_boundary_values[block_m].begin();
- dof != block_boundary_values[block_m].end();
- ++dof)
- if ((dof->first >= local_range.first) &&
- (dof->first < local_range.second))
- constrained_rows.push_back (dof->first);
-
- for (unsigned int block_n=0; block_n<n_blocks; ++block_n)
- if (block_m != block_n)
- matrix.block(block_m,block_n).clear_rows(constrained_rows);
- }
+ Assert (eliminate_columns == false, ExcNotImplemented());
+
+ Assert (matrix.n() == right_hand_side.size(),
+ ExcDimensionMismatch(matrix.n(), right_hand_side.size()));
+ Assert (matrix.n() == solution.size(),
+ ExcDimensionMismatch(matrix.n(), solution.size()));
+ Assert (matrix.n_block_rows() == matrix.n_block_cols(),
+ ExcNotQuadratic());
+
+ const unsigned int n_blocks = matrix.n_block_rows();
+
+ matrix.compress();
+
+ // We need to find the subdivision
+ // into blocks for the boundary values.
+ // To this end, generate a vector of
+ // maps with the respective indices.
+ std::vector<std::map<unsigned int,double> > block_boundary_values(n_blocks);
+ {
+ int offset = 0, block=0;
+ for (std::map<unsigned int,double>::const_iterator
+ dof = boundary_values.begin();
+ dof != boundary_values.end();
+ ++dof)
+ {
+ if (dof->first >= matrix.block(block,0).m() + offset)
+ {
+ offset += matrix.block(block,0).m();
+ block++;
+ }
+ const unsigned int index = dof->first - offset;
+ block_boundary_values[block].insert(
+ std::pair<unsigned int, double> (index,dof->second));
+ }
+ }
+
+ // Now call the non-block variants on
+ // the diagonal subblocks and the
+ // solution/rhs.
+ for (unsigned int block=0; block<n_blocks; ++block)
+ TrilinosWrappers::apply_boundary_values(block_boundary_values[block],
+ matrix.block(block,block),
+ solution.block(block),
+ right_hand_side.block(block),
+ eliminate_columns);
+
+ // Finally, we need to do something
+ // about the off-diagonal matrices. This
+ // is luckily not difficult. Just clear
+ // the whole row.
+ for (unsigned int block_m=0; block_m<n_blocks; ++block_m)
+ {
+ const std::pair<unsigned int, unsigned int> local_range
+ = matrix.block(block_m,0).local_range();
+
+ std::vector<unsigned int> constrained_rows;
+ for (std::map<unsigned int,double>::const_iterator
+ dof = block_boundary_values[block_m].begin();
+ dof != block_boundary_values[block_m].end();
+ ++dof)
+ if ((dof->first >= local_range.first) &&
+ (dof->first < local_range.second))
+ constrained_rows.push_back (dof->first);
+
+ for (unsigned int block_n=0; block_n<n_blocks; ++block_n)
+ if (block_m != block_n)
+ matrix.block(block_m,block_n).clear_rows(constrained_rows);
+ }
}
}
}
void
apply_boundary_values (const std::map<unsigned int,double> &boundary_values,
- TrilinosWrappers::SparseMatrix &matrix,
- TrilinosWrappers::Vector &solution,
- TrilinosWrappers::Vector &right_hand_side,
- const bool eliminate_columns)
+ TrilinosWrappers::SparseMatrix &matrix,
+ TrilinosWrappers::Vector &solution,
+ TrilinosWrappers::Vector &right_hand_side,
+ const bool eliminate_columns)
{
- // simply redirect to the generic function
- // used for both trilinos matrix types
+ // simply redirect to the generic function
+ // used for both trilinos matrix types
internal::TrilinosWrappers::apply_boundary_values (boundary_values, matrix, solution,
- right_hand_side, eliminate_columns);
+ right_hand_side, eliminate_columns);
}
void
apply_boundary_values (const std::map<unsigned int,double> &boundary_values,
- TrilinosWrappers::SparseMatrix &matrix,
- TrilinosWrappers::MPI::Vector &solution,
- TrilinosWrappers::MPI::Vector &right_hand_side,
- const bool eliminate_columns)
+ TrilinosWrappers::SparseMatrix &matrix,
+ TrilinosWrappers::MPI::Vector &solution,
+ TrilinosWrappers::MPI::Vector &right_hand_side,
+ const bool eliminate_columns)
{
- // simply redirect to the generic function
- // used for both trilinos matrix types
+ // simply redirect to the generic function
+ // used for both trilinos matrix types
internal::TrilinosWrappers::apply_boundary_values (boundary_values, matrix, solution,
- right_hand_side, eliminate_columns);
+ right_hand_side, eliminate_columns);
}
void
apply_boundary_values (const std::map<unsigned int,double> &boundary_values,
- TrilinosWrappers::BlockSparseMatrix &matrix,
- TrilinosWrappers::BlockVector &solution,
- TrilinosWrappers::BlockVector &right_hand_side,
- const bool eliminate_columns)
+ TrilinosWrappers::BlockSparseMatrix &matrix,
+ TrilinosWrappers::BlockVector &solution,
+ TrilinosWrappers::BlockVector &right_hand_side,
+ const bool eliminate_columns)
{
internal::TrilinosWrappers::apply_block_boundary_values (boundary_values, matrix,
- solution, right_hand_side,
- eliminate_columns);
+ solution, right_hand_side,
+ eliminate_columns);
}
void
apply_boundary_values (const std::map<unsigned int,double> &boundary_values,
- TrilinosWrappers::BlockSparseMatrix &matrix,
- TrilinosWrappers::MPI::BlockVector &solution,
- TrilinosWrappers::MPI::BlockVector &right_hand_side,
- const bool eliminate_columns)
+ TrilinosWrappers::BlockSparseMatrix &matrix,
+ TrilinosWrappers::MPI::BlockVector &solution,
+ TrilinosWrappers::MPI::BlockVector &right_hand_side,
+ const bool eliminate_columns)
{
internal::TrilinosWrappers::apply_block_boundary_values (boundary_values, matrix,
- solution, right_hand_side,
- eliminate_columns);
+ solution, right_hand_side,
+ eliminate_columns);
}
#endif
void
local_apply_boundary_values (const std::map<unsigned int,double> &boundary_values,
- const std::vector<unsigned int> &local_dof_indices,
- FullMatrix<double> &local_matrix,
- Vector<double> &local_rhs,
- const bool eliminate_columns)
+ const std::vector<unsigned int> &local_dof_indices,
+ FullMatrix<double> &local_matrix,
+ Vector<double> &local_rhs,
+ const bool eliminate_columns)
{
Assert (local_dof_indices.size() == local_matrix.m(),
- ExcDimensionMismatch(local_dof_indices.size(),
- local_matrix.m()));
+ ExcDimensionMismatch(local_dof_indices.size(),
+ local_matrix.m()));
Assert (local_dof_indices.size() == local_matrix.n(),
- ExcDimensionMismatch(local_dof_indices.size(),
- local_matrix.n()));
+ ExcDimensionMismatch(local_dof_indices.size(),
+ local_matrix.n()));
Assert (local_dof_indices.size() == local_rhs.size(),
- ExcDimensionMismatch(local_dof_indices.size(),
- local_rhs.size()));
+ ExcDimensionMismatch(local_dof_indices.size(),
+ local_rhs.size()));
- // if there is nothing to do, then exit
- // right away
+ // if there is nothing to do, then exit
+ // right away
if (boundary_values.size() == 0)
return;
- // otherwise traverse all the dofs used in
- // the local matrices and vectors and see
- // what's there to do
-
- // if we need to treat an entry, then we
- // set the diagonal entry to its absolute
- // value. if it is zero, we used to set it
- // to one, which is a really terrible
- // choice that can lead to hours of
- // searching for bugs in programs (I
- // experienced this :-( ) if the matrix
- // entries are otherwise very large. this
- // is so since iterative solvers would
- // simply not correct boundary nodes for
- // their correct values since the residual
- // contributions of their rows of the
- // linear system is almost zero if the
- // diagonal entry is one. thus, set it to
- // the average absolute value of the
- // nonzero diagonal elements.
- //
- // we only compute this value lazily the
- // first time we need it.
+ // otherwise traverse all the dofs used in
+ // the local matrices and vectors and see
+ // what's there to do
+
+ // if we need to treat an entry, then we
+ // set the diagonal entry to its absolute
+ // value. if it is zero, we used to set it
+ // to one, which is a really terrible
+ // choice that can lead to hours of
+ // searching for bugs in programs (I
+ // experienced this :-( ) if the matrix
+ // entries are otherwise very large. this
+ // is so since iterative solvers would
+ // simply not correct boundary nodes for
+ // their correct values since the residual
+ // contributions of their rows of the
+ // linear system is almost zero if the
+ // diagonal entry is one. thus, set it to
+ // the average absolute value of the
+ // nonzero diagonal elements.
+ //
+ // we only compute this value lazily the
+ // first time we need it.
double average_diagonal = 0;
const unsigned int n_local_dofs = local_dof_indices.size();
for (unsigned int i=0; i<n_local_dofs; ++i)
{
- const std::map<unsigned int, double>::const_iterator
- boundary_value = boundary_values.find (local_dof_indices[i]);
- if (boundary_value != boundary_values.end())
- {
- // remove this row, except for the
- // diagonal element
- for (unsigned j=0; j<n_local_dofs; ++j)
- if (i != j)
- local_matrix(i,j) = 0;
-
- // replace diagonal entry by its
- // absolute value to make sure that
- // everything remains positive, or
- // by the average diagonal value if
- // zero
- if (local_matrix(i,i) == 0.)
- {
- // if average diagonal hasn't
- // yet been computed, do so now
- if (average_diagonal == 0.)
- {
- unsigned int nonzero_diagonals = 0;
- for (unsigned int k=0; k<n_local_dofs; ++k)
- if (local_matrix(k,k) != 0.)
- {
- average_diagonal += std::fabs(local_matrix(k,k));
- ++nonzero_diagonals;
- }
- if (nonzero_diagonals != 0)
- average_diagonal /= nonzero_diagonals;
- else
- average_diagonal = 0;
- }
-
- // only if all diagonal entries
- // are zero, then resort to the
- // last measure: choose one
- if (average_diagonal == 0.)
- average_diagonal = 1.;
-
- local_matrix(i,i) = average_diagonal;
- }
- else
- local_matrix(i,i) = std::fabs(local_matrix(i,i));
-
- // and replace rhs entry by correct
- // value
- local_rhs(i) = local_matrix(i,i) * boundary_value->second;
-
- // finally do the elimination step
- // if requested
- if (eliminate_columns == true)
- {
- for (unsigned int row=0; row<n_local_dofs; ++row)
- if (row != i)
- {
- local_rhs(row) -= local_matrix(row,i) * boundary_value->second;
- local_matrix(row,i) = 0;
- }
- }
- }
+ const std::map<unsigned int, double>::const_iterator
+ boundary_value = boundary_values.find (local_dof_indices[i]);
+ if (boundary_value != boundary_values.end())
+ {
+ // remove this row, except for the
+ // diagonal element
+ for (unsigned j=0; j<n_local_dofs; ++j)
+ if (i != j)
+ local_matrix(i,j) = 0;
+
+ // replace diagonal entry by its
+ // absolute value to make sure that
+ // everything remains positive, or
+ // by the average diagonal value if
+ // zero
+ if (local_matrix(i,i) == 0.)
+ {
+ // if average diagonal hasn't
+ // yet been computed, do so now
+ if (average_diagonal == 0.)
+ {
+ unsigned int nonzero_diagonals = 0;
+ for (unsigned int k=0; k<n_local_dofs; ++k)
+ if (local_matrix(k,k) != 0.)
+ {
+ average_diagonal += std::fabs(local_matrix(k,k));
+ ++nonzero_diagonals;
+ }
+ if (nonzero_diagonals != 0)
+ average_diagonal /= nonzero_diagonals;
+ else
+ average_diagonal = 0;
+ }
+
+ // only if all diagonal entries
+ // are zero, then resort to the
+ // last measure: choose one
+ if (average_diagonal == 0.)
+ average_diagonal = 1.;
+
+ local_matrix(i,i) = average_diagonal;
+ }
+ else
+ local_matrix(i,i) = std::fabs(local_matrix(i,i));
+
+ // and replace rhs entry by correct
+ // value
+ local_rhs(i) = local_matrix(i,i) * boundary_value->second;
+
+ // finally do the elimination step
+ // if requested
+ if (eliminate_columns == true)
+ {
+ for (unsigned int row=0; row<n_local_dofs; ++row)
+ if (row != i)
+ {
+ local_rhs(row) -= local_matrix(row,i) * boundary_value->second;
+ local_matrix(row,i) = 0;
+ }
+ }
+ }
}
}
}
template
void
apply_boundary_values<double> (const std::map<unsigned int,double> &boundary_values,
- SparseMatrix<double> &matrix,
- Vector<double> &solution,
- Vector<double> &right_hand_side,
- const bool eliminate_columns);
+ SparseMatrix<double> &matrix,
+ Vector<double> &solution,
+ Vector<double> &right_hand_side,
+ const bool eliminate_columns);
template
void
apply_boundary_values<float> (const std::map<unsigned int,double> &boundary_values,
- SparseMatrix<float> &matrix,
- Vector<float> &solution,
- Vector<float> &right_hand_side,
- const bool eliminate_columns);
+ SparseMatrix<float> &matrix,
+ Vector<float> &solution,
+ Vector<float> &right_hand_side,
+ const bool eliminate_columns);
template
void
apply_boundary_values<double> (const std::map<unsigned int,double> &boundary_values,
- BlockSparseMatrix<double> &matrix,
- BlockVector<double> &solution,
- BlockVector<double> &right_hand_side,
- const bool eliminate_columns);
+ BlockSparseMatrix<double> &matrix,
+ BlockVector<double> &solution,
+ BlockVector<double> &right_hand_side,
+ const bool eliminate_columns);
template
void
apply_boundary_values<float> (const std::map<unsigned int,double> &boundary_values,
- BlockSparseMatrix<float> &matrix,
- BlockVector<float> &solution,
- BlockVector<float> &right_hand_side,
- const bool eliminate_columns);
+ BlockSparseMatrix<float> &matrix,
+ BlockVector<float> &solution,
+ BlockVector<float> &right_hand_side,
+ const bool eliminate_columns);
}
DEAL_II_NAMESPACE_CLOSE
//---------------------------------------------------------------------------
// $Id$
//
-// Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 by the deal.II authors
+// Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
R[i].reinit(bi);
for (unsigned int i=0;i<M1.size();++i)
M1[i].matrix.reinit(bi.block_size(M1[i].row),
- bi.block_size(M1[i].column));
+ bi.block_size(M1[i].column));
for (unsigned int i=0;i<M2.size();++i)
M2[i].matrix.reinit(bi.block_size(M2[i].row),
- bi.block_size(M2[i].column));
+ bi.block_size(M2[i].column));
quadrature_data.reset_values();
}
LocalResults<number>::memory_consumption () const
{
std::size_t mem = sizeof(*this)
- + MemoryConsumption::memory_consumption(J)
- + MemoryConsumption::memory_consumption(R)
- + MemoryConsumption::memory_consumption(M1)
- + MemoryConsumption::memory_consumption(M2)
- + MemoryConsumption::memory_consumption(quadrature_data);
+ + MemoryConsumption::memory_consumption(J)
+ + MemoryConsumption::memory_consumption(R)
+ + MemoryConsumption::memory_consumption(M1)
+ + MemoryConsumption::memory_consumption(M2)
+ + MemoryConsumption::memory_consumption(quadrature_data);
return mem;
}
// $Id$
// Version: $Name$
//
-// Copyright (C) 2009, 2010, 2011 by the deal.II authors
+// Copyright (C) 2009, 2010, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
// $Id$
// Version: $Name$
//
-// Copyright (C) 2009, 2010 by the deal.II authors
+// Copyright (C) 2009, 2010, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
// $Id$
// Version: $Name$
//
-// Copyright (C) 2010 by the deal.II authors
+// Copyright (C) 2010, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
// $Id$
// Version: $Name$
//
-// Copyright (C) 2009, 2010 by Michael Rapson and the deal.II authors
+// Copyright (C) 2009, 2010, 2012 by Michael Rapson and the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
template <int dim>
PointGeometryData<dim>
::PointGeometryData (const std::vector <Point <dim> > &new_locations,
- const std::vector <int> &new_sol_indices)
+ const std::vector <int> &new_sol_indices)
{
locations = new_locations;
solution_indices = new_sol_indices;
template <int dim>
PointValueHistory<dim>
::PointValueHistory (const unsigned int n_independent_variables) :
- n_dofs (0),
- n_indep (n_independent_variables)
+ n_dofs (0),
+ n_indep (n_independent_variables)
{
closed = false;
cleared = false;
- // make a vector for keys
+ // make a vector for keys
dataset_key = std::vector <double> (); // initialize the std::vector
- // make a vector of independent values
+ // make a vector of independent values
independent_values
= std::vector<std::vector <double> > (n_indep, std::vector <double> (0));
}
template <int dim>
PointValueHistory<dim>::PointValueHistory (const DoFHandler<dim> & dof_handler,
- const unsigned int n_independent_variables) :
- dof_handler (&dof_handler),
- n_dofs (dof_handler.n_dofs ()),
- n_indep (n_independent_variables)
+ const unsigned int n_independent_variables) :
+ dof_handler (&dof_handler),
+ n_dofs (dof_handler.n_dofs ()),
+ n_indep (n_independent_variables)
{
closed = false;
cleared = false;
- // make a vector to store keys
+ // make a vector to store keys
dataset_key = std::vector <double> (); // initialize the std::vector
- // make a vector for the independent values
+ // make a vector for the independent values
independent_values
= std::vector<std::vector <double> > (n_indep, std::vector <double> (0));
}
void PointValueHistory<dim>
::add_point (const Point <dim> & location)
{
- // can't be closed to add additional points
- // or vectors
+ // can't be closed to add additional points
+ // or vectors
AssertThrow (!closed, ExcInvalidState ());
AssertThrow (!cleared, ExcInvalidState ());
AssertThrow (n_dofs != 0, ExcDoFHandlerRequired ());
AssertThrow (n_dofs == dof_handler->n_dofs (),
- ExcDoFHandlerChanged (n_dofs, dof_handler->n_dofs ()));
+ ExcDoFHandlerChanged (n_dofs, dof_handler->n_dofs ()));
- // Implementation assumes that support
- // points locations are dofs locations
+ // Implementation assumes that support
+ // points locations are dofs locations
AssertThrow (dof_handler->get_fe ().has_support_points (), ExcNotImplemented ());
- // FEValues object to extract quadrature
- // points from
+ // FEValues object to extract quadrature
+ // points from
std::vector <Point <dim> >
unit_support_points = dof_handler->get_fe ().get_unit_support_points ();
- // While in general quadrature points seems
- // to refer to Gauss quadrature points, in
- // this case the quadrature points are
- // forced to be the support points of the
- // FE.
+ // While in general quadrature points seems
+ // to refer to Gauss quadrature points, in
+ // this case the quadrature points are
+ // forced to be the support points of the
+ // FE.
Quadrature<dim>
support_point_quadrature (dof_handler->get_fe ().get_unit_support_points ());
FEValues<dim> fe_values (dof_handler->get_fe (),
- support_point_quadrature,
- update_quadrature_points);
+ support_point_quadrature,
+ update_quadrature_points);
unsigned int n_support_points
= dof_handler->get_fe ().get_unit_support_points ().size ();
unsigned int n_components
= dof_handler->get_fe ().n_components ();
- // set up a loop over all the cells in the
- // DoFHandler
+ // set up a loop over all the cells in the
+ // DoFHandler
typename DoFHandler<dim>::active_cell_iterator
cell = dof_handler->begin_active ();
typename DoFHandler<dim>::active_cell_iterator
endc = dof_handler->end ();
- // default values to be replaced as closer
- // points are found however they need to be
- // consistent in case they are actually
- // chosen
+ // default values to be replaced as closer
+ // points are found however they need to be
+ // consistent in case they are actually
+ // chosen
typename DoFHandler<dim>::active_cell_iterator current_cell = cell;
std::vector <unsigned int> current_fe_index (n_components, 0); // need one index per component
fe_values.reinit (cell);
for (unsigned int support_point = 0;
support_point < n_support_points; support_point++)
{
- // setup valid data in the empty
- // vectors
+ // setup valid data in the empty
+ // vectors
unsigned int component
- = dof_handler->get_fe ().system_to_component_index (support_point).first;
+ = dof_handler->get_fe ().system_to_component_index (support_point).first;
current_points [component] = fe_values.quadrature_point (support_point);
current_fe_index [component] = support_point;
}
- // check each cell to find a suitable
- // support points
+ // check each cell to find a suitable
+ // support points
for (; cell != endc; cell++)
{
fe_values.reinit (cell);
for (unsigned int support_point = 0;
- support_point < n_support_points; support_point++)
+ support_point < n_support_points; support_point++)
{
unsigned int component
- = dof_handler->get_fe ().system_to_component_index (support_point).first;
+ = dof_handler->get_fe ().system_to_component_index (support_point).first;
Point<dim> test_point
- = fe_values.quadrature_point (support_point);
+ = fe_values.quadrature_point (support_point);
if (location.distance (test_point) <
- location.distance (current_points [component]))
+ location.distance (current_points [component]))
{
- // save the data
+ // save the data
current_points [component] = test_point;
current_cell = cell;
current_fe_index [component] = support_point;
local_dof_indices (dof_handler->get_fe ().dofs_per_cell);
std::vector <int> new_solution_indices;
current_cell->get_dof_indices (local_dof_indices);
- // there is an implicit assumption here
- // that all the closest support point to
- // the requested point for all finite
- // element components lie in the same cell.
- // this could possibly be violated if
- // components use different fe orders,
- // requested points are on the edge or
- // vertex of a cell and we are unlucky with
- // floating point rounding. Worst case
- // scenario however is that the point
- // selected isn't the closest possible, it
- // will still lie within one cell distance.
- // calling
- // GridTools::find_active_cell_around_point
- // to obtain a cell to search may be an
- // option for these methods, but currently
- // the GridTools method does not cater for
- // a vector of points, and does not seem to
- // be intrinsicly faster than this method.
+ // there is an implicit assumption here
+ // that all the closest support point to
+ // the requested point for all finite
+ // element components lie in the same cell.
+ // this could possibly be violated if
+ // components use different fe orders,
+ // requested points are on the edge or
+ // vertex of a cell and we are unlucky with
+ // floating point rounding. Worst case
+ // scenario however is that the point
+ // selected isn't the closest possible, it
+ // will still lie within one cell distance.
+ // calling
+ // GridTools::find_active_cell_around_point
+ // to obtain a cell to search may be an
+ // option for these methods, but currently
+ // the GridTools method does not cater for
+ // a vector of points, and does not seem to
+ // be intrinsicly faster than this method.
for (unsigned int component = 0;
component < dof_handler->get_fe ().n_components (); component++)
{
new_solution_indices
- .push_back (local_dof_indices[current_fe_index [component]]);
+ .push_back (local_dof_indices[current_fe_index [component]]);
}
internal::PointValueHistory::PointGeometryData<dim>
data_store_begin = data_store.begin ();
for (; data_store_begin != data_store.end (); data_store_begin++)
{
- // add an extra row to each vector
- // entry
+ // add an extra row to each vector
+ // entry
for (unsigned int component = 0;
- component < dof_handler->get_fe ().n_components (); component++)
+ component < dof_handler->get_fe ().n_components (); component++)
{
data_store_begin->second.push_back (std::vector<double> (0));
}
void PointValueHistory<dim>
::add_points (const std::vector <Point <dim> > & locations)
{
- // This algorithm adds points in the same
- // order as they appear in the vector
- // locations and users may depend on this
- // so do not change order added!
+ // This algorithm adds points in the same
+ // order as they appear in the vector
+ // locations and users may depend on this
+ // so do not change order added!
- // can't be closed to add additional points or vectors
+ // can't be closed to add additional points or vectors
AssertThrow (!closed, ExcInvalidState ());
AssertThrow (!cleared, ExcInvalidState ());
AssertThrow (n_dofs != 0, ExcDoFHandlerRequired ());
AssertThrow (n_dofs == dof_handler->n_dofs (), ExcDoFHandlerChanged (n_dofs, dof_handler->n_dofs ()));
- // Implementation assumes that support
- // points locations are dofs locations
+ // Implementation assumes that support
+ // points locations are dofs locations
AssertThrow (dof_handler->get_fe ().has_support_points (), ExcNotImplemented ());
- // FEValues object to extract quadrature
- // points from
+ // FEValues object to extract quadrature
+ // points from
std::vector <Point <dim> > unit_support_points = dof_handler->get_fe ().get_unit_support_points ();
- // While in general quadrature points seems
- // to refer to Gauss quadrature points, in
- // this case the quadrature points are
- // forced to be the support points of the
- // FE.
+ // While in general quadrature points seems
+ // to refer to Gauss quadrature points, in
+ // this case the quadrature points are
+ // forced to be the support points of the
+ // FE.
Quadrature<dim> support_point_quadrature (dof_handler->get_fe ().get_unit_support_points ());
FEValues<dim> fe_values (dof_handler->get_fe (), support_point_quadrature, update_quadrature_points);
unsigned int n_support_points = dof_handler->get_fe ().get_unit_support_points ().size ();
unsigned int n_components = dof_handler->get_fe ().n_components ();
- // set up a loop over all the cells in the
- // DoFHandler
+ // set up a loop over all the cells in the
+ // DoFHandler
typename DoFHandler<dim>::active_cell_iterator cell = dof_handler->begin_active ();
typename DoFHandler<dim>::active_cell_iterator endc = dof_handler->end ();
- // default values to be replaced as closer
- // points are found however they need to be
- // consistent in case they are actually
- // chosen vector <vector>s defined where
- // previously single vectors were used
+ // default values to be replaced as closer
+ // points are found however they need to be
+ // consistent in case they are actually
+ // chosen vector <vector>s defined where
+ // previously single vectors were used
- // need to store one value per point per component
+ // need to store one value per point per component
std::vector <typename DoFHandler<dim>::active_cell_iterator > current_cell (locations.size (), cell);
fe_values.reinit (cell);
std::vector <unsigned int> temp_fe_index (n_components, 0);
for (unsigned int support_point = 0; support_point < n_support_points; support_point++)
{
- // setup valid data in the empty
- // vectors
+ // setup valid data in the empty
+ // vectors
unsigned int component = dof_handler->get_fe ().system_to_component_index (support_point).first;
temp_points [component] = fe_values.quadrature_point (support_point);
temp_fe_index [component] = support_point;
std::vector <std::vector <Point <dim> > > current_points (locations.size (), temp_points); // give a valid start point
std::vector <std::vector <unsigned int> > current_fe_index (locations.size (), temp_fe_index);
- // check each cell to find suitable support
- // points
+ // check each cell to find suitable support
+ // points
for (; cell != endc; cell++)
{
fe_values.reinit (cell);
{
if (locations[point].distance (test_point) < locations[point].distance (current_points[point][component]))
{
- // save the data
+ // save the data
current_points[point][component] = test_point;
current_cell[point] = cell;
current_fe_index[point][component] = support_point;
point_geometry_data.push_back (new_point_geometry_data);
std::map <std::string, std::vector <std::vector <double> > >::iterator
- data_store_begin = data_store.begin ();
+ data_store_begin = data_store.begin ();
for (; data_store_begin != data_store.end (); data_store_begin++)
{
- // add an extra row to each vector
- // entry
+ // add an extra row to each vector
+ // entry
for (unsigned int component = 0; component < dof_handler->get_fe ().n_components (); component++)
{
data_store_begin->second.push_back (std::vector<double> (0));
void PointValueHistory<dim>
::add_field_name (const std::string &vector_name)
{
- // can't be closed to add additional points
- // or vectors
+ // can't be closed to add additional points
+ // or vectors
AssertThrow (!closed, ExcInvalidState ());
AssertThrow (n_dofs != 0, ExcDoFHandlerRequired ());
AssertThrow (!cleared, ExcInvalidState ());
AssertThrow (n_dofs == dof_handler->n_dofs (), ExcDoFHandlerChanged (n_dofs, dof_handler->n_dofs ()));
- // make and add a new vector
- // point_geometry_data.size() long
+ // make and add a new vector
+ // point_geometry_data.size() long
pair_data.first = vector_name;
int n_datastreams = point_geometry_data.size () * (dof_handler->get_fe ().n_components ()); // each point has n_components sub parts
std::vector < std::vector <double> > vector_size (n_datastreams,
void PointValueHistory<dim>
::evaluate_field (const std::string &vector_name, const VECTOR & solution)
{
- // must be closed to add data to internal
- // members.
+ // must be closed to add data to internal
+ // members.
Assert (closed, ExcInvalidState ());
Assert (!cleared, ExcInvalidState ());
Assert (n_dofs != 0, ExcDoFHandlerRequired ());
typename std::vector <internal::PointValueHistory::PointGeometryData <dim> >::iterator node = point_geometry_data.begin ();
for (unsigned int data_store_index = 0; node != point_geometry_data.end (); node++, data_store_index++)
{
- // step through each node, to access
- // the Solution_index and the vector
- // index
+ // step through each node, to access
+ // the Solution_index and the vector
+ // index
for (unsigned int component = 0; component < dof_handler->get_fe ().n_components (); component++)
{
unsigned int solution_index = node->solution_indices[component];
void PointValueHistory<dim>
::start_new_dataset (double key)
{
- // must be closed to add data to internal
- // members.
+ // must be closed to add data to internal
+ // members.
Assert (closed, ExcInvalidState ());
Assert (!cleared, ExcInvalidState ());
Assert (deep_check (false), ExcDataLostSync ());
void PointValueHistory<dim>
::push_back_independent (const std::vector <double> &indep_values)
{
- // must be closed to add data to internal
- // members.
+ // must be closed to add data to internal
+ // members.
Assert (closed, ExcInvalidState ());
Assert (!cleared, ExcInvalidState ());
Assert (indep_values.size () == n_indep, ExcDimensionMismatch (indep_values.size (), n_indep));
AssertThrow (!cleared, ExcInvalidState ());
AssertThrow (deep_check (true), ExcDataLostSync ());
- // write inputs to a file
+ // write inputs to a file
if (n_indep != 0)
{
std::string filename = base_name + "_indep.gpl";
to_gnuplot << "# Data independent of mesh location\n";
- // write column headings
+ // write column headings
to_gnuplot << "# <Key> ";
for (unsigned int component = 0; component < n_indep; component++)
}
to_gnuplot << "\n";
- // write general data stored
+ // write general data stored
for (unsigned int key = 0; key < dataset_key.size (); key++)
{
to_gnuplot << dataset_key[key];
- // write points to a file
+ // write points to a file
if (n_dofs != 0)
{
AssertThrow (n_dofs != 0, ExcDoFHandlerRequired ());
typename std::vector <internal::PointValueHistory::PointGeometryData <dim> >::iterator node = point_geometry_data.begin ();
for (unsigned int data_store_index = 0; node != point_geometry_data.end (); node++, data_store_index++)
{
- // for each point, open a file to
- // be written to
+ // for each point, open a file to
+ // be written to
std::string filename = base_name + "_" + Utilities::int_to_string (data_store_index, 2) + ".gpl"; // store by order pushed back
- // due to
- // Utilities::int_to_string(data_store_index,
- // 2) call, can handle up to 100
- // points
+ // due to
+ // Utilities::int_to_string(data_store_index,
+ // 2) call, can handle up to 100
+ // points
std::ofstream to_gnuplot (filename.c_str ());
- // put helpful info about the
- // support point into the file as
- // comments
+ // put helpful info about the
+ // support point into the file as
+ // comments
to_gnuplot << "# DoF_index : Location (for each component)\n";
for (unsigned int component = 0; component < n_components; component++)
{
}
to_gnuplot << "\n";
- // write column headings
+ // write column headings
std::map <std::string, std::vector <std::vector <double> > >::iterator
- data_store_begin = data_store.begin ();
+ data_store_begin = data_store.begin ();
to_gnuplot << "# <Key> ";
for (unsigned int component = 0; component < n_indep; component++)
}
to_gnuplot << "\n";
- // write data stored for the node
+ // write data stored for the node
for (unsigned int key = 0; key < dataset_key.size (); key++)
{
std::map <std::string, std::vector <std::vector <double> > >::iterator
- data_store_begin = data_store.begin ();
+ data_store_begin = data_store.begin ();
to_gnuplot << dataset_key[key];
for (unsigned int component = 0; component < n_indep; component++)
Vector<double> PointValueHistory<dim>
::mark_locations ()
{
- // a method to put a one at each point on
- // the grid where a location is defined
+ // a method to put a one at each point on
+ // the grid where a location is defined
AssertThrow (n_dofs != 0, ExcDoFHandlerRequired ());
AssertThrow (!cleared, ExcInvalidState ());
AssertThrow (n_dofs == dof_handler->n_dofs (), ExcDoFHandlerChanged (n_dofs, dof_handler->n_dofs ()));
else
{
if (!cleared)
- {
- out << "# DoF_index : Location (for each component)\n";
- for (; node != point_geometry_data.end (); node++)
- {
- for (unsigned int component = 0; component < dof_handler->get_fe ().n_components (); component++)
- {
- out << node->solution_indices[component] << " : " << node->locations [component] << "\n";
- }
- out << "\n";
- }
- }
+ {
+ out << "# DoF_index : Location (for each component)\n";
+ for (; node != point_geometry_data.end (); node++)
+ {
+ for (unsigned int component = 0; component < dof_handler->get_fe ().n_components (); component++)
+ {
+ out << node->solution_indices[component] << " : " << node->locations [component] << "\n";
+ }
+ out << "\n";
+ }
+ }
else
- {
+ {
out << "#Cannot access DoF_indices once cleared\n";
- }
+ }
}
out << "\n";
bool PointValueHistory<dim>
::deep_check (bool strict)
{
- // test ways that it can fail, if control
- // reaches last statement return true
+ // test ways that it can fail, if control
+ // reaches last statement return true
if (strict)
{
if (n_indep != 0)
}
}
std::map <std::string, std::vector <std::vector <double> > >::iterator
- data_store_begin = data_store.begin ();
+ data_store_begin = data_store.begin ();
if (n_dofs != 0)
{
for (; data_store_begin != data_store.end (); data_store_begin++)
{
if ((data_store_begin->second)[0].size () != dataset_key.size ())
return false;
- // this loop only tests one
- // member for each name,
- // i.e. checks the user it will
- // not catch internal errors
- // which do not update all
- // fields for a name.
+ // this loop only tests one
+ // member for each name,
+ // i.e. checks the user it will
+ // not catch internal errors
+ // which do not update all
+ // fields for a name.
}
}
return true;
if (n_dofs != 0)
{
std::map <std::string, std::vector <std::vector <double> > >::iterator
- data_store_begin = data_store.begin ();
+ data_store_begin = data_store.begin ();
for (; data_store_begin != data_store.end (); data_store_begin++)
{
if (std::abs ((int) (data_store_begin->second)[0].size () - (int) dataset_key.size ()) >= 2)
return false;
- // this loop only tests one member
- // for each name, i.e. checks the
- // user it will not catch internal
- // errors which do not update all
- // fields for a name.
+ // this loop only tests one member
+ // for each name, i.e. checks the
+ // user it will not catch internal
+ // errors which do not update all
+ // fields for a name.
}
}
return true;
// $Id$
// Version: $Name$
//
-// Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2008, 2009, 2010, 2011 by the deal.II authors
+// Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2008, 2009, 2010, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
template<int dim, typename VECTOR, class DH>
SolutionTransfer<dim, VECTOR, DH>::SolutionTransfer(const DH &dof)
- :
- dof_handler(&dof, typeid(*this).name()),
- n_dofs_old(0),
- prepared_for(none)
+ :
+ dof_handler(&dof, typeid(*this).name()),
+ n_dofs_old(0),
+ prepared_for(none)
{}
{
Assert(prepared_for!=pure_refinement, ExcAlreadyPrepForRef());
Assert(prepared_for!=coarsening_and_refinement,
- ExcAlreadyPrepForCoarseAndRef());
+ ExcAlreadyPrepForCoarseAndRef());
clear();
const unsigned int n_active_cells = dof_handler->get_tria().n_active_cells();
n_dofs_old=dof_handler->n_dofs();
- // efficient reallocation of indices_on_cell
+ // efficient reallocation of indices_on_cell
std::vector<std::vector<unsigned int> > (n_active_cells)
.swap(indices_on_cell);
typename DH::active_cell_iterator cell = dof_handler->begin_active(),
- endc = dof_handler->end();
+ endc = dof_handler->end();
for (unsigned int i=0; cell!=endc; ++cell, ++i)
{
indices_on_cell[i].resize(cell->get_fe().dofs_per_cell);
- // on each cell store the indices of the
- // dofs. after refining we get the values
- // on the children by taking these
- // indices, getting the respective values
- // out of the data vectors and prolonging
- // them to the children
+ // on each cell store the indices of the
+ // dofs. after refining we get the values
+ // on the children by taking these
+ // indices, getting the respective values
+ // out of the data vectors and prolonging
+ // them to the children
cell->get_dof_indices(indices_on_cell[i]);
cell_map[std::make_pair(cell->level(),cell->index())].indices_ptr=&indices_on_cell[i];
}
template<int dim, typename VECTOR, class DH>
void
SolutionTransfer<dim, VECTOR, DH>::refine_interpolate(const VECTOR &in,
- VECTOR &out) const
+ VECTOR &out) const
{
Assert(prepared_for==pure_refinement, ExcNotPrepared());
Assert(in.size()==n_dofs_old, ExcDimensionMismatch(in.size(),n_dofs_old));
Assert(out.size()==dof_handler->n_dofs(),
- ExcDimensionMismatch(out.size(),dof_handler->n_dofs()));
+ ExcDimensionMismatch(out.size(),dof_handler->n_dofs()));
Assert(&in != &out,
ExcMessage ("Vectors cannot be used as input and output"
" at the same time!"));
Vector<typename VECTOR::value_type> local_values(0);
typename DH::cell_iterator cell = dof_handler->begin(),
- endc = dof_handler->end();
+ endc = dof_handler->end();
typename std::map<std::pair<unsigned int, unsigned int>, Pointerstruct>::const_iterator
pointerstruct,
pointerstruct=cell_map.find(std::make_pair(cell->level(),cell->index()));
if (pointerstruct!=cell_map_end)
- // this cell was refined or not
- // touched at all, so we can get
- // the new values by just setting
- // or interpolating to the children,
- // which is both done by one
- // function
- {
- const unsigned int dofs_per_cell=cell->get_fe().dofs_per_cell;
- local_values.reinit(dofs_per_cell, true); // fast reinit, i.e. the
- // entries are not set to 0.
- // make sure that the size of the
- // stored indices is the same as
- // dofs_per_cell. this is kind of a
- // test if we use the same fe in the
- // hp case. to really do that test we
- // would have to store the fe_index
- // of all cells
- Assert(dofs_per_cell==(*pointerstruct->second.indices_ptr).size(),
- ExcNumberOfDoFsPerCellHasChanged());
- for (unsigned int i=0; i<dofs_per_cell; ++i)
- local_values(i)=in((*pointerstruct->second.indices_ptr)[i]);
- cell->set_dof_values_by_interpolation(local_values, out);
- }
+ // this cell was refined or not
+ // touched at all, so we can get
+ // the new values by just setting
+ // or interpolating to the children,
+ // which is both done by one
+ // function
+ {
+ const unsigned int dofs_per_cell=cell->get_fe().dofs_per_cell;
+ local_values.reinit(dofs_per_cell, true); // fast reinit, i.e. the
+ // entries are not set to 0.
+ // make sure that the size of the
+ // stored indices is the same as
+ // dofs_per_cell. this is kind of a
+ // test if we use the same fe in the
+ // hp case. to really do that test we
+ // would have to store the fe_index
+ // of all cells
+ Assert(dofs_per_cell==(*pointerstruct->second.indices_ptr).size(),
+ ExcNumberOfDoFsPerCellHasChanged());
+ for (unsigned int i=0; i<dofs_per_cell; ++i)
+ local_values(i)=in((*pointerstruct->second.indices_ptr)[i]);
+ cell->set_dof_values_by_interpolation(local_values, out);
+ }
}
}
{
template <typename DH>
void extract_interpolation_matrices (const DH&,
- Table<2,FullMatrix<double> > &)
+ Table<2,FullMatrix<double> > &)
{}
template <int dim, int spacedim>
void extract_interpolation_matrices (const dealii::hp::DoFHandler<dim,spacedim> &dof,
- Table<2,FullMatrix<double> > &matrices)
+ Table<2,FullMatrix<double> > &matrices)
{
const dealii::hp::FECollection<dim,spacedim> &fe = dof.get_fe();
matrices.reinit (fe.size(), fe.size());
for (unsigned int i=0; i<fe.size(); ++i)
for (unsigned int j=0; j<fe.size(); ++j)
- if (i != j)
- {
- matrices(i,j).reinit (fe[i].dofs_per_cell, fe[j].dofs_per_cell);
- fe[i].get_interpolation_matrix (fe[j], matrices(i,j));
- }
+ if (i != j)
+ {
+ matrices(i,j).reinit (fe[i].dofs_per_cell, fe[j].dofs_per_cell);
+ fe[i].get_interpolation_matrix (fe[j], matrices(i,j));
+ }
}
template <int dim, int spacedim>
void restriction_additive (const FiniteElement<dim,spacedim> &,
- std::vector<std::vector<bool> > &)
+ std::vector<std::vector<bool> > &)
{}
template <int dim, int spacedim>
void restriction_additive (const dealii::hp::FECollection<dim,spacedim> &fe,
- std::vector<std::vector<bool> > &restriction_is_additive)
+ std::vector<std::vector<bool> > &restriction_is_additive)
{
restriction_is_additive.resize (fe.size());
for (unsigned int f=0; f<fe.size(); ++f)
{
- restriction_is_additive[f].resize (fe[f].dofs_per_cell);
- for (unsigned int i=0; i<fe[f].dofs_per_cell; ++i)
- restriction_is_additive[f][i] = fe[f].restriction_is_additive(i);
+ restriction_is_additive[f].resize (fe[f].dofs_per_cell);
+ for (unsigned int i=0; i<fe[f].dofs_per_cell; ++i)
+ restriction_is_additive[f][i] = fe[f].restriction_is_additive(i);
}
}
}
{
Assert(prepared_for!=pure_refinement, ExcAlreadyPrepForRef());
Assert(!prepared_for!=coarsening_and_refinement,
- ExcAlreadyPrepForCoarseAndRef());
+ ExcAlreadyPrepForCoarseAndRef());
const unsigned int in_size=all_in.size();
Assert(in_size!=0, ExcNoInVectorsGiven());
for (unsigned int i=0; i<in_size; ++i)
{
Assert(all_in[i].size()==n_dofs_old,
- ExcDimensionMismatch(all_in[i].size(),n_dofs_old));
+ ExcDimensionMismatch(all_in[i].size(),n_dofs_old));
}
- // first count the number
- // of cells that'll be coarsened
- // and that'll stay or be refined
+ // first count the number
+ // of cells that'll be coarsened
+ // and that'll stay or be refined
unsigned int n_cells_to_coarsen=0;
unsigned int n_cells_to_stay_or_refine=0;
typename DH::active_cell_iterator
for (; act_cell!=endc; ++act_cell)
{
if (act_cell->coarsen_flag_set())
- ++n_cells_to_coarsen;
+ ++n_cells_to_coarsen;
else
- ++n_cells_to_stay_or_refine;
+ ++n_cells_to_stay_or_refine;
}
Assert((n_cells_to_coarsen+n_cells_to_stay_or_refine)==n_active_cells,
- ExcInternalError());
+ ExcInternalError());
unsigned int n_coarsen_fathers=0;
typename DH::cell_iterator
if (n_cells_to_coarsen)
Assert(n_cells_to_coarsen>=2*n_coarsen_fathers, ExcInternalError());
- // allocate the needed memory. initialize
+ // allocate the needed memory. initialize
// the following arrays in an efficient
// way, without copying much
std::vector<std::vector<unsigned int> >
internal::restriction_additive (dof_handler->get_fe(), restriction_is_additive);
Vector<typename VECTOR::value_type> tmp, tmp2;
- // we need counters for
- // the 'to_stay_or_refine' cells 'n_sr' and
- // the 'coarsen_fathers' cells 'n_cf',
+ // we need counters for
+ // the 'to_stay_or_refine' cells 'n_sr' and
+ // the 'coarsen_fathers' cells 'n_cf',
unsigned int n_sr=0, n_cf=0;
cell = dof_handler->begin();
for (; cell!=endc; ++cell)
{
if (cell->active() && !cell->coarsen_flag_set())
- {
- const unsigned int dofs_per_cell=cell->get_fe().dofs_per_cell;
- indices_on_cell[n_sr].resize(dofs_per_cell);
- // cell will not be coarsened,
- // so we get away by storing the
- // dof indices and later
- // interpolating to the children
- cell->get_dof_indices(indices_on_cell[n_sr]);
- cell_map[std::make_pair(cell->level(), cell->index())]
- = Pointerstruct(&indices_on_cell[n_sr],cell->active_fe_index());
- ++n_sr;
- }
+ {
+ const unsigned int dofs_per_cell=cell->get_fe().dofs_per_cell;
+ indices_on_cell[n_sr].resize(dofs_per_cell);
+ // cell will not be coarsened,
+ // so we get away by storing the
+ // dof indices and later
+ // interpolating to the children
+ cell->get_dof_indices(indices_on_cell[n_sr]);
+ cell_map[std::make_pair(cell->level(), cell->index())]
+ = Pointerstruct(&indices_on_cell[n_sr],cell->active_fe_index());
+ ++n_sr;
+ }
else if (cell->has_children() && cell->child(0)->coarsen_flag_set())
- {
- // note that if one child has the
- // coarsen flag, then all should
- // have if Tria::prepare_* has
- // worked correctly
- for (unsigned int i=1; i<cell->n_children(); ++i)
- Assert(cell->child(i)->coarsen_flag_set(),
- ExcTriaPrepCoarseningNotCalledBefore());
- const unsigned int dofs_per_cell=cell->get_fe().dofs_per_cell;
-
- std::vector<Vector<typename VECTOR::value_type> >(in_size,
- Vector<typename VECTOR::value_type>(dofs_per_cell))
- .swap(dof_values_on_cell[n_cf]);
-
- unsigned int fe_index = cell->active_fe_index();
- unsigned int most_general_child = 0;
- bool different_elements = false;
- for (unsigned int child=0; child<cell->n_children(); ++child)
- {
- if (cell->child(child)->active_fe_index() != fe_index)
- different_elements = true;
- // take FE index from the child with most
- // degrees of freedom locally
- if (cell->child(child)->get_fe().dofs_per_cell >
- cell->child(most_general_child)->get_fe().dofs_per_cell)
- most_general_child = child;
- }
- if (different_elements == true)
- fe_index = cell->child(most_general_child)->active_fe_index();
-
- for (unsigned int j=0; j<in_size; ++j)
- {
- // store the data of each of
- // the input vectors
- if (different_elements == false)
- cell->get_interpolated_dof_values(all_in[j],
- dof_values_on_cell[n_cf][j]);
- else
- {
- // if we have different elements, first
- // interpolate the children's contribution to
- // the most general FE on the child
- // level. Then we manually write the
- // interpolation operation to the coarser
- // level
- dof_values_on_cell[n_cf][j].reinit (cell->child(most_general_child)->get_fe().dofs_per_cell);
- const unsigned int fe_ind_general =
- cell->child(most_general_child)->active_fe_index();
- for (unsigned int child=0; child<cell->n_children(); ++child)
- {
- tmp.reinit (cell->child(child)->get_fe().dofs_per_cell,
- true);
- cell->child(child)->get_dof_values (all_in[j],
- tmp);
- const unsigned int child_ind =
- cell->child(child)->active_fe_index();
- if (child_ind != fe_ind_general)
- {
- tmp2.reinit (cell->child(most_general_child)->get_fe().dofs_per_cell,
- true);
- interpolation_hp (fe_ind_general, child_ind).vmult (tmp2, tmp);
- }
- else
- tmp2.swap (tmp);
-
- // now do the interpolation operation
- const unsigned int dofs_per_cell = tmp2.size();
- tmp.reinit (dofs_per_cell, true);
- cell->child(most_general_child)->get_fe().
- get_restriction_matrix(child, cell->refinement_case()).vmult (tmp, tmp2);
- for (unsigned int i=0; i<dofs_per_cell; ++i)
- if (restriction_is_additive[fe_ind_general][i])
- dof_values_on_cell[n_cf][j](i) += tmp(i);
- else
- if (tmp(i) != zero_val)
- dof_values_on_cell[n_cf][j](i) = tmp(i);
- }
- }
- }
- cell_map[std::make_pair(cell->level(), cell->index())]
- = Pointerstruct(&dof_values_on_cell[n_cf], fe_index);
- ++n_cf;
- }
+ {
+ // note that if one child has the
+ // coarsen flag, then all should
+ // have if Tria::prepare_* has
+ // worked correctly
+ for (unsigned int i=1; i<cell->n_children(); ++i)
+ Assert(cell->child(i)->coarsen_flag_set(),
+ ExcTriaPrepCoarseningNotCalledBefore());
+ const unsigned int dofs_per_cell=cell->get_fe().dofs_per_cell;
+
+ std::vector<Vector<typename VECTOR::value_type> >(in_size,
+ Vector<typename VECTOR::value_type>(dofs_per_cell))
+ .swap(dof_values_on_cell[n_cf]);
+
+ unsigned int fe_index = cell->active_fe_index();
+ unsigned int most_general_child = 0;
+ bool different_elements = false;
+ for (unsigned int child=0; child<cell->n_children(); ++child)
+ {
+ if (cell->child(child)->active_fe_index() != fe_index)
+ different_elements = true;
+ // take FE index from the child with most
+ // degrees of freedom locally
+ if (cell->child(child)->get_fe().dofs_per_cell >
+ cell->child(most_general_child)->get_fe().dofs_per_cell)
+ most_general_child = child;
+ }
+ if (different_elements == true)
+ fe_index = cell->child(most_general_child)->active_fe_index();
+
+ for (unsigned int j=0; j<in_size; ++j)
+ {
+ // store the data of each of
+ // the input vectors
+ if (different_elements == false)
+ cell->get_interpolated_dof_values(all_in[j],
+ dof_values_on_cell[n_cf][j]);
+ else
+ {
+ // if we have different elements, first
+ // interpolate the children's contribution to
+ // the most general FE on the child
+ // level. Then we manually write the
+ // interpolation operation to the coarser
+ // level
+ dof_values_on_cell[n_cf][j].reinit (cell->child(most_general_child)->get_fe().dofs_per_cell);
+ const unsigned int fe_ind_general =
+ cell->child(most_general_child)->active_fe_index();
+ for (unsigned int child=0; child<cell->n_children(); ++child)
+ {
+ tmp.reinit (cell->child(child)->get_fe().dofs_per_cell,
+ true);
+ cell->child(child)->get_dof_values (all_in[j],
+ tmp);
+ const unsigned int child_ind =
+ cell->child(child)->active_fe_index();
+ if (child_ind != fe_ind_general)
+ {
+ tmp2.reinit (cell->child(most_general_child)->get_fe().dofs_per_cell,
+ true);
+ interpolation_hp (fe_ind_general, child_ind).vmult (tmp2, tmp);
+ }
+ else
+ tmp2.swap (tmp);
+
+ // now do the interpolation operation
+ const unsigned int dofs_per_cell = tmp2.size();
+ tmp.reinit (dofs_per_cell, true);
+ cell->child(most_general_child)->get_fe().
+ get_restriction_matrix(child, cell->refinement_case()).vmult (tmp, tmp2);
+ for (unsigned int i=0; i<dofs_per_cell; ++i)
+ if (restriction_is_additive[fe_ind_general][i])
+ dof_values_on_cell[n_cf][j](i) += tmp(i);
+ else
+ if (tmp(i) != zero_val)
+ dof_values_on_cell[n_cf][j](i) = tmp(i);
+ }
+ }
+ }
+ cell_map[std::make_pair(cell->level(), cell->index())]
+ = Pointerstruct(&dof_values_on_cell[n_cf], fe_index);
+ ++n_cf;
+ }
}
Assert(n_sr==n_cells_to_stay_or_refine, ExcInternalError());
Assert(n_cf==n_coarsen_fathers, ExcInternalError());
template<int dim, typename VECTOR, class DH>
void SolutionTransfer<dim, VECTOR, DH>::
interpolate (const std::vector<VECTOR> &all_in,
- std::vector<VECTOR> &all_out) const
+ std::vector<VECTOR> &all_out) const
{
Assert(prepared_for==coarsening_and_refinement, ExcNotPrepared());
const unsigned int size=all_in.size();
Assert(all_out.size()==size, ExcDimensionMismatch(all_out.size(), size));
for (unsigned int i=0; i<size; ++i)
Assert (all_in[i].size() == n_dofs_old,
- ExcDimensionMismatch(all_in[i].size(), n_dofs_old));
+ ExcDimensionMismatch(all_in[i].size(), n_dofs_old));
for (unsigned int i=0; i<all_out.size(); ++i)
Assert (all_out[i].size() == dof_handler->n_dofs(),
- ExcDimensionMismatch(all_out[i].size(), dof_handler->n_dofs()));
+ ExcDimensionMismatch(all_out[i].size(), dof_handler->n_dofs()));
for (unsigned int i=0; i<size; ++i)
for (unsigned int j=0; j<size; ++j)
Assert(&all_in[i] != &all_out[j],
Vector<typename VECTOR::value_type> tmp, tmp2;
typename DH::cell_iterator cell = dof_handler->begin(),
- endc = dof_handler->end();
+ endc = dof_handler->end();
for (; cell!=endc; ++cell)
{
pointerstruct=cell_map.find(std::make_pair(cell->level(),cell->index()));
if (pointerstruct!=cell_map_end)
- {
- const std::vector<unsigned int> * const indexptr
- =pointerstruct->second.indices_ptr;
-
- const std::vector<Vector<typename VECTOR::value_type> > * const valuesptr
- =pointerstruct->second.dof_values_ptr;
-
- const unsigned int dofs_per_cell=cell->get_fe().dofs_per_cell;
-
- // cell stayed or is
- // refined
- if (indexptr)
- {
- Assert (valuesptr == 0,
- ExcInternalError());
-
- // get the values of
- // each of the input
- // data vectors on this
- // cell and prolong it
- // to its children
- unsigned int in_size = indexptr->size();
- local_values.reinit(dofs_per_cell, true);
- for (unsigned int j=0; j<size; ++j)
- {
- // check the FE index of the new element. if
- // we have children and not all of the
- // children have the same FE index, need to
- // manually implement
- // set_dof_values_by_interpolation
- unsigned int new_fe_index = cell->active_fe_index();
- bool different_elements = false;
- if (cell->has_children())
- {
- new_fe_index = cell->child(0)->active_fe_index();
- for (unsigned int child=1; child<cell->n_children(); ++child)
- if (cell->child(child)->active_fe_index() != new_fe_index)
- {
- different_elements = true;
- break;
- }
- }
- if (different_elements == true ||
- new_fe_index != pointerstruct->second.active_fe_index)
- {
- const unsigned int old_index =
- pointerstruct->second.active_fe_index;
- tmp.reinit (in_size, true);
- for (unsigned int i=0; i<in_size; ++i)
- tmp(i)=all_in[j]((*indexptr)[i]);
- if (different_elements == false)
- {
- AssertDimension (tmp.size(),
- interpolation_hp(new_fe_index,old_index).n());
- local_values.reinit (cell->has_children() ?
- cell->child(0)->get_fe().dofs_per_cell
- : cell->get_fe().dofs_per_cell, true);
- AssertDimension (local_values.size(),
- interpolation_hp(new_fe_index,old_index).m());
- // simple case where all children have the
- // same FE index: just interpolate to their FE
- // first and then use the standard routines
- interpolation_hp(new_fe_index,old_index).vmult (local_values, tmp);
- }
-
- if (cell->has_children() == false)
- cell->set_dof_values (local_values, all_out[j]);
- else
- for (unsigned int child=0; child<cell->n_children(); ++child)
- {
- if (different_elements == true)
- {
- const unsigned int c_index =
- cell->child(child)->active_fe_index();
- if (c_index != old_index)
- {
- AssertDimension (tmp.size(),
- interpolation_hp(c_index,old_index).n());
- local_values.reinit(cell->child(child)->get_fe().dofs_per_cell, true);
- AssertDimension (local_values.size(),
- interpolation_hp(c_index,old_index).m());
- interpolation_hp(c_index,old_index).vmult (local_values, tmp);
- }
- else
- local_values = tmp;
- }
- tmp2.reinit (cell->child(child)->get_fe().dofs_per_cell, true);
- cell->child(child)->get_fe().get_prolongation_matrix(child, cell->refinement_case())
- .vmult (tmp2, local_values);
- cell->child(child)->set_dof_values(tmp2,all_out[j]);
- }
- }
- else
- {
- AssertDimension (dofs_per_cell, indexptr->size());
- for (unsigned int i=0; i<dofs_per_cell; ++i)
- local_values(i)=all_in[j]((*indexptr)[i]);
- cell->set_dof_values_by_interpolation(local_values,
- all_out[j]);
- }
- }
- }
- // children of cell were
- // deleted
- else if (valuesptr)
- {
- Assert (!cell->has_children(), ExcInternalError());
- Assert (indexptr == 0,
- ExcInternalError());
- dofs.resize(dofs_per_cell);
- // get the local
- // indices
- cell->get_dof_indices(dofs);
-
- // distribute the
- // stored data to the
- // new vectors
- for (unsigned int j=0; j<size; ++j)
- {
- // make sure that the size of
- // the stored indices is the
- // same as
- // dofs_per_cell. this is
- // kind of a test if we use
- // the same fe in the hp
- // case. to really do that
- // test we would have to
- // store the fe_index of all
- // cells
- const Vector<typename VECTOR::value_type>* data = 0;
- const unsigned int active_fe_index = cell->active_fe_index();
- if (active_fe_index != pointerstruct->second.active_fe_index)
- {
- const unsigned int old_index = pointerstruct->second.active_fe_index;
- tmp.reinit (dofs_per_cell, true);
- AssertDimension ((*valuesptr)[j].size(),
- interpolation_hp(active_fe_index,old_index).n());
- AssertDimension (tmp.size(),
- interpolation_hp(active_fe_index,old_index).m());
- interpolation_hp(active_fe_index,old_index).vmult (tmp, (*valuesptr)[j]);
- data = &tmp;
- }
- else
- data = &(*valuesptr)[j];
-
-
- for (unsigned int i=0; i<dofs_per_cell; ++i)
- all_out[j](dofs[i])=(*data)(i);
- }
- }
- // undefined status
- else
- Assert(false, ExcInternalError());
- }
+ {
+ const std::vector<unsigned int> * const indexptr
+ =pointerstruct->second.indices_ptr;
+
+ const std::vector<Vector<typename VECTOR::value_type> > * const valuesptr
+ =pointerstruct->second.dof_values_ptr;
+
+ const unsigned int dofs_per_cell=cell->get_fe().dofs_per_cell;
+
+ // cell stayed or is
+ // refined
+ if (indexptr)
+ {
+ Assert (valuesptr == 0,
+ ExcInternalError());
+
+ // get the values of
+ // each of the input
+ // data vectors on this
+ // cell and prolong it
+ // to its children
+ unsigned int in_size = indexptr->size();
+ local_values.reinit(dofs_per_cell, true);
+ for (unsigned int j=0; j<size; ++j)
+ {
+ // check the FE index of the new element. if
+ // we have children and not all of the
+ // children have the same FE index, need to
+ // manually implement
+ // set_dof_values_by_interpolation
+ unsigned int new_fe_index = cell->active_fe_index();
+ bool different_elements = false;
+ if (cell->has_children())
+ {
+ new_fe_index = cell->child(0)->active_fe_index();
+ for (unsigned int child=1; child<cell->n_children(); ++child)
+ if (cell->child(child)->active_fe_index() != new_fe_index)
+ {
+ different_elements = true;
+ break;
+ }
+ }
+ if (different_elements == true ||
+ new_fe_index != pointerstruct->second.active_fe_index)
+ {
+ const unsigned int old_index =
+ pointerstruct->second.active_fe_index;
+ tmp.reinit (in_size, true);
+ for (unsigned int i=0; i<in_size; ++i)
+ tmp(i)=all_in[j]((*indexptr)[i]);
+ if (different_elements == false)
+ {
+ AssertDimension (tmp.size(),
+ interpolation_hp(new_fe_index,old_index).n());
+ local_values.reinit (cell->has_children() ?
+ cell->child(0)->get_fe().dofs_per_cell
+ : cell->get_fe().dofs_per_cell, true);
+ AssertDimension (local_values.size(),
+ interpolation_hp(new_fe_index,old_index).m());
+ // simple case where all children have the
+ // same FE index: just interpolate to their FE
+ // first and then use the standard routines
+ interpolation_hp(new_fe_index,old_index).vmult (local_values, tmp);
+ }
+
+ if (cell->has_children() == false)
+ cell->set_dof_values (local_values, all_out[j]);
+ else
+ for (unsigned int child=0; child<cell->n_children(); ++child)
+ {
+ if (different_elements == true)
+ {
+ const unsigned int c_index =
+ cell->child(child)->active_fe_index();
+ if (c_index != old_index)
+ {
+ AssertDimension (tmp.size(),
+ interpolation_hp(c_index,old_index).n());
+ local_values.reinit(cell->child(child)->get_fe().dofs_per_cell, true);
+ AssertDimension (local_values.size(),
+ interpolation_hp(c_index,old_index).m());
+ interpolation_hp(c_index,old_index).vmult (local_values, tmp);
+ }
+ else
+ local_values = tmp;
+ }
+ tmp2.reinit (cell->child(child)->get_fe().dofs_per_cell, true);
+ cell->child(child)->get_fe().get_prolongation_matrix(child, cell->refinement_case())
+ .vmult (tmp2, local_values);
+ cell->child(child)->set_dof_values(tmp2,all_out[j]);
+ }
+ }
+ else
+ {
+ AssertDimension (dofs_per_cell, indexptr->size());
+ for (unsigned int i=0; i<dofs_per_cell; ++i)
+ local_values(i)=all_in[j]((*indexptr)[i]);
+ cell->set_dof_values_by_interpolation(local_values,
+ all_out[j]);
+ }
+ }
+ }
+ // children of cell were
+ // deleted
+ else if (valuesptr)
+ {
+ Assert (!cell->has_children(), ExcInternalError());
+ Assert (indexptr == 0,
+ ExcInternalError());
+ dofs.resize(dofs_per_cell);
+ // get the local
+ // indices
+ cell->get_dof_indices(dofs);
+
+ // distribute the
+ // stored data to the
+ // new vectors
+ for (unsigned int j=0; j<size; ++j)
+ {
+ // make sure that the size of
+ // the stored indices is the
+ // same as
+ // dofs_per_cell. this is
+ // kind of a test if we use
+ // the same fe in the hp
+ // case. to really do that
+ // test we would have to
+ // store the fe_index of all
+ // cells
+ const Vector<typename VECTOR::value_type>* data = 0;
+ const unsigned int active_fe_index = cell->active_fe_index();
+ if (active_fe_index != pointerstruct->second.active_fe_index)
+ {
+ const unsigned int old_index = pointerstruct->second.active_fe_index;
+ tmp.reinit (dofs_per_cell, true);
+ AssertDimension ((*valuesptr)[j].size(),
+ interpolation_hp(active_fe_index,old_index).n());
+ AssertDimension (tmp.size(),
+ interpolation_hp(active_fe_index,old_index).m());
+ interpolation_hp(active_fe_index,old_index).vmult (tmp, (*valuesptr)[j]);
+ data = &tmp;
+ }
+ else
+ data = &(*valuesptr)[j];
+
+
+ for (unsigned int i=0; i<dofs_per_cell; ++i)
+ all_out[j](dofs[i])=(*data)(i);
+ }
+ }
+ // undefined status
+ else
+ Assert(false, ExcInternalError());
+ }
}
}
template<int dim, typename VECTOR, class DH>
void SolutionTransfer<dim, VECTOR, DH>::interpolate(const VECTOR &in,
- VECTOR &out) const
+ VECTOR &out) const
{
Assert (in.size()==n_dofs_old,
- ExcDimensionMismatch(in.size(), n_dofs_old));
+ ExcDimensionMismatch(in.size(), n_dofs_old));
Assert (out.size()==dof_handler->n_dofs(),
- ExcDimensionMismatch(out.size(), dof_handler->n_dofs()));
+ ExcDimensionMismatch(out.size(), dof_handler->n_dofs()));
std::vector<VECTOR> all_in(1);
all_in[0] = in;
std::vector<VECTOR> all_out(1);
all_out[0] = out;
interpolate(all_in,
- all_out);
+ all_out);
out=all_out[0];
}
std::size_t
SolutionTransfer<dim, VECTOR, DH>::memory_consumption () const
{
- // at the moment we do not include the memory
- // consumption of the cell_map as we have no
- // real idea about memory consumption of a
- // std::map
+ // at the moment we do not include the memory
+ // consumption of the cell_map as we have no
+ // real idea about memory consumption of a
+ // std::map
return (MemoryConsumption::memory_consumption (dof_handler) +
- MemoryConsumption::memory_consumption (n_dofs_old) +
- sizeof (prepared_for) +
- MemoryConsumption::memory_consumption (indices_on_cell) +
- MemoryConsumption::memory_consumption (dof_values_on_cell));
+ MemoryConsumption::memory_consumption (n_dofs_old) +
+ sizeof (prepared_for) +
+ MemoryConsumption::memory_consumption (indices_on_cell) +
+ MemoryConsumption::memory_consumption (dof_values_on_cell));
}
// $Id$
// Version: $Name$
//
-// Copyright (C) 1999, 2000, 2001, 2002, 2003, 2005, 2006, 2008, 2009, 2010, 2011 by the deal.II authors
+// Copyright (C) 1999, 2000, 2001, 2002, 2003, 2005, 2006, 2008, 2009, 2010, 2011, 2012 by the deal.II authors
//
// This file is subject to QPL and may not be distributed
// without copyright and license information. Please refer
DEAL_II_NAMESPACE_OPEN
TimeDependent::TimeSteppingData::TimeSteppingData (const unsigned int look_ahead,
- const unsigned int look_back)
- :
- look_ahead (look_ahead),
- look_back (look_back)
+ const unsigned int look_back)
+ :
+ look_ahead (look_ahead),
+ look_back (look_back)
{}
TimeDependent::TimeDependent (const TimeSteppingData &data_primal,
- const TimeSteppingData &data_dual,
- const TimeSteppingData &data_postprocess):
- sweep_no (numbers::invalid_unsigned_int),
- timestepping_data_primal (data_primal),
- timestepping_data_dual (data_dual),
- timestepping_data_postprocess (data_postprocess)
+ const TimeSteppingData &data_dual,
+ const TimeSteppingData &data_postprocess):
+ sweep_no (numbers::invalid_unsigned_int),
+ timestepping_data_primal (data_primal),
+ timestepping_data_dual (data_dual),
+ timestepping_data_postprocess (data_postprocess)
{}
void
TimeDependent::insert_timestep (const TimeStepBase *position,
- TimeStepBase *new_timestep)
+ TimeStepBase *new_timestep)
{
Assert ((std::find(timesteps.begin(), timesteps.end(), position) != timesteps.end()) ||
- (position == 0),
- ExcInvalidPosition());
- // first insert the new time step
- // into the doubly linked list
- // of timesteps
+ (position == 0),
+ ExcInvalidPosition());
+ // first insert the new time step
+ // into the doubly linked list
+ // of timesteps
if (position == 0)
{
- // at the end
+ // at the end
new_timestep->set_next_timestep (0);
if (timesteps.size() > 0)
- {
- timesteps.back()->set_next_timestep (new_timestep);
- new_timestep->set_previous_timestep (timesteps.back());
- }
+ {
+ timesteps.back()->set_next_timestep (new_timestep);
+ new_timestep->set_previous_timestep (timesteps.back());
+ }
else
- new_timestep->set_previous_timestep (0);
+ new_timestep->set_previous_timestep (0);
}
else
if (position == timesteps[0])
{
- // at the beginning
- new_timestep->set_previous_timestep (0);
- if (timesteps.size() > 0)
- {
- timesteps[0]->set_previous_timestep (new_timestep);
- new_timestep->set_next_timestep (timesteps[0]);
- }
- else
- new_timestep->set_next_timestep (0);
+ // at the beginning
+ new_timestep->set_previous_timestep (0);
+ if (timesteps.size() > 0)
+ {
+ timesteps[0]->set_previous_timestep (new_timestep);
+ new_timestep->set_next_timestep (timesteps[0]);
+ }
+ else
+ new_timestep->set_next_timestep (0);
}
else
{
- // inner time step
- std::vector<SmartPointer<TimeStepBase,TimeDependent> >::iterator insert_position
- = std::find(timesteps.begin(), timesteps.end(), position);
-
- (*(insert_position-1))->set_next_timestep (new_timestep);
- new_timestep->set_previous_timestep (*(insert_position-1));
- new_timestep->set_next_timestep (*insert_position);
- (*insert_position)->set_previous_timestep (new_timestep);
+ // inner time step
+ std::vector<SmartPointer<TimeStepBase,TimeDependent> >::iterator insert_position
+ = std::find(timesteps.begin(), timesteps.end(), position);
+
+ (*(insert_position-1))->set_next_timestep (new_timestep);
+ new_timestep->set_previous_timestep (*(insert_position-1));
+ new_timestep->set_next_timestep (*insert_position);
+ (*insert_position)->set_previous_timestep (new_timestep);
};
- // finally enter it into the
- // array
+ // finally enter it into the
+ // array
timesteps.insert ((position == 0 ?
- timesteps.end() :
- std::find(timesteps.begin(), timesteps.end(), position)),
- new_timestep);
+ timesteps.end() :
+ std::find(timesteps.begin(), timesteps.end(), position)),
+ new_timestep);
}
void TimeDependent::delete_timestep (const unsigned int position)
{
Assert (position<timesteps.size(),
- ExcInvalidPosition());
+ ExcInvalidPosition());
- // Remember time step object for
- // later deletion and unlock
- // SmartPointer
+ // Remember time step object for
+ // later deletion and unlock
+ // SmartPointer
TimeStepBase* t = timesteps[position];
timesteps[position] = 0;
- // Now delete unsubscribed object
+ // Now delete unsubscribed object
delete t;
timesteps.erase (timesteps.begin() + position);
- // reset "next" pointer of previous
- // time step if possible
- //
- // note that if now position==size,
- // then we deleted the last time step
+ // reset "next" pointer of previous
+ // time step if possible
+ //
+ // note that if now position==size,
+ // then we deleted the last time step
if (position != 0)
timesteps[position-1]->set_next_timestep ((position<timesteps.size()) ?
- timesteps[position] :
- /*null*/SmartPointer<TimeStepBase,TimeDependent>());
+ timesteps[position] :
+ /*null*/SmartPointer<TimeStepBase,TimeDependent>());
- // same for "previous" pointer of next
- // time step
+ // same for "previous" pointer of next
+ // time step
if (position<timesteps.size())
timesteps[position]->set_previous_timestep ((position!=0) ?
- timesteps[position-1] :
- /*null*/SmartPointer<TimeStepBase,TimeDependent>());
+ timesteps[position-1] :
+ /*null*/SmartPointer<TimeStepBase,TimeDependent>());
}
TimeDependent::solve_primal_problem ()
{
do_loop (std::mem_fun(&TimeStepBase::init_for_primal_problem),
- std::mem_fun(&TimeStepBase::solve_primal_problem),
- timestepping_data_primal,
- forward);
+ std::mem_fun(&TimeStepBase::solve_primal_problem),
+ timestepping_data_primal,
+ forward);
}
TimeDependent::solve_dual_problem ()
{
do_loop (std::mem_fun(&TimeStepBase::init_for_dual_problem),
- std::mem_fun(&TimeStepBase::solve_dual_problem),
- timestepping_data_dual,
- backward);
+ std::mem_fun(&TimeStepBase::solve_dual_problem),
+ timestepping_data_dual,
+ backward);
}
TimeDependent::postprocess ()
{
do_loop (std::mem_fun(&TimeStepBase::init_for_postprocessing),
- std::mem_fun(&TimeStepBase::postprocess_timestep),
- timestepping_data_postprocess,
- forward);
+ std::mem_fun(&TimeStepBase::postprocess_timestep),
+ timestepping_data_postprocess,
+ forward);
}
{
sweep_no = s;
- // reset the number each
- // time step has, since some time
- // steps might have been added since
- // the last time we visited them
- //
- // also set the sweep we will
- // process in the sequel
+ // reset the number each
+ // time step has, since some time
+ // steps might have been added since
+ // the last time we visited them
+ //
+ // also set the sweep we will
+ // process in the sequel
for (unsigned int step=0; step<timesteps.size(); ++step)
{
timesteps[step]->set_timestep_no (step);
= &TimeDependent::end_sweep;
for (unsigned int i=0; i<n_threads; ++i)
threads += Threads::new_thread (p, *this, i*stride,
- (i == n_threads-1 ?
- timesteps.size() :
- (i+1)*stride));
+ (i == n_threads-1 ?
+ timesteps.size() :
+ (i+1)*stride));
threads.join_all();
}
else
void TimeDependent::end_sweep (const unsigned int begin,
- const unsigned int end)
+ const unsigned int end)
{
for (unsigned int step=begin; step<end; ++step)
timesteps[step]->end_sweep ();
TimeDependent::memory_consumption () const
{
std::size_t mem = (MemoryConsumption::memory_consumption (timesteps) +
- MemoryConsumption::memory_consumption (sweep_no) +
- sizeof(timestepping_data_primal) +
- sizeof(timestepping_data_dual) +
- sizeof(timestepping_data_postprocess));
+ MemoryConsumption::memory_consumption (sweep_no) +
+ sizeof(timestepping_data_primal) +
+ sizeof(timestepping_data_dual) +
+ sizeof(timestepping_data_postprocess));
for (unsigned int i=0; i<timesteps.size(); ++i)
mem += MemoryConsumption::memory_consumption (*timesteps[i]);
TimeStepBase::TimeStepBase (const double time) :
- previous_timestep(0),
- next_timestep (0),
- sweep_no (numbers::invalid_unsigned_int),
- timestep_no (numbers::invalid_unsigned_int),
- time (time)
+ previous_timestep(0),
+ next_timestep (0),
+ sweep_no (numbers::invalid_unsigned_int),
+ timestep_no (numbers::invalid_unsigned_int),
+ time (time)
{}
std::size_t
TimeStepBase::memory_consumption () const
{
- // only simple data types
+ // only simple data types
return sizeof(*this);
}
template <int dim>
TimeStepBase_Tria<dim>::TimeStepBase_Tria() :
- TimeStepBase (0),
- tria (0, typeid(*this).name()),
- coarse_grid (0, typeid(*this).name()),
+ TimeStepBase (0),
+ tria (0, typeid(*this).name()),
+ coarse_grid (0, typeid(*this).name()),
flags (),
- refinement_flags(0)
+ refinement_flags(0)
{
Assert (false, ExcPureFunctionCalled());
}
template <int dim>
TimeStepBase_Tria<dim>::TimeStepBase_Tria (const double time,
- const Triangulation<dim> &coarse_grid,
- const Flags &flags,
- const RefinementFlags &refinement_flags) :
- TimeStepBase (time),
- tria(0, typeid(*this).name()),
- coarse_grid (&coarse_grid, typeid(*this).name()),
- flags (flags),
- refinement_flags (refinement_flags)
+ const Triangulation<dim> &coarse_grid,
+ const Flags &flags,
+ const RefinementFlags &refinement_flags) :
+ TimeStepBase (time),
+ tria(0, typeid(*this).name()),
+ coarse_grid (&coarse_grid, typeid(*this).name()),
+ flags (flags),
+ refinement_flags (refinement_flags)
{}
Assert (tria!=0, ExcInternalError());
if (flags.delete_and_rebuild_tria)
- {
- Triangulation<dim>* t = tria;
- tria = 0;
- delete t;
- }
+ {
+ Triangulation<dim>* t = tria;
+ tria = 0;
+ delete t;
+ }
}
TimeStepBase::sleep (sleep_level);
template <int dim>
void TimeStepBase_Tria<dim>::save_refine_flags ()
{
- // for any of the non-initial grids
- // store the refinement flags
+ // for any of the non-initial grids
+ // store the refinement flags
refine_flags.push_back (std::vector<bool>());
coarsen_flags.push_back (std::vector<bool>());
tria->save_refine_flags (refine_flags.back());
{
Assert (tria == 0, ExcGridNotDeleted());
Assert (refine_flags.size() == coarsen_flags.size(),
- ExcInternalError());
+ ExcInternalError());
- // create a virgin triangulation and
- // set it to a copy of the coarse grid
+ // create a virgin triangulation and
+ // set it to a copy of the coarse grid
tria = new Triangulation<dim> ();
tria->copy_triangulation (*coarse_grid);
- // for each of the previous refinement
- // sweeps
+ // for each of the previous refinement
+ // sweeps
for (unsigned int previous_sweep=0; previous_sweep<refine_flags.size();
++previous_sweep)
{
- // get flags
+ // get flags
tria->load_refine_flags (refine_flags[previous_sweep]);
tria->load_coarsen_flags (coarsen_flags[previous_sweep]);
- // limit refinement depth if the user
- // desired so
+ // limit refinement depth if the user
+ // desired so
// if (flags.max_refinement_level != 0)
-// {
-// typename Triangulation<dim>::active_cell_iterator cell, endc;
-// for (cell = tria->begin_active(),
-// endc = tria->end();
-// cell!=endc; ++cell)
-// if (static_cast<unsigned int>(cell->level()) >=
-// flags.max_refinement_level)
-// cell->clear_refine_flag();
-// };
+// {
+// typename Triangulation<dim>::active_cell_iterator cell, endc;
+// for (cell = tria->begin_active(),
+// endc = tria->end();
+// cell!=endc; ++cell)
+// if (static_cast<unsigned int>(cell->level()) >=
+// flags.max_refinement_level)
+// cell->clear_refine_flag();
+// };
tria->execute_coarsening_and_refinement ();
};
template <int dim>
void
mirror_refinement_flags (const typename Triangulation<dim>::cell_iterator &new_cell,
- const typename Triangulation<dim>::cell_iterator &old_cell)
+ const typename Triangulation<dim>::cell_iterator &old_cell)
{
- // mirror the refinement
- // flags from the present time level to
- // the previous if the dual problem was
- // used for the refinement, since the
- // error is computed on a time-space cell
- //
- // we don't mirror the coarsening flags
- // since we want stronger refinement. if
- // this was the wrong decision, the error
- // on the child cells of the previous
- // time slab will indicate coarsening
- // in the next iteration, so this is not
- // so dangerous here.
- //
- // also, we only have to check whether
- // the present cell flagged for
- // refinement and the previous one is on
- // the same level and also active. If it
- // already has children, then there is
- // no problem at all, if it is on a lower
- // level than the present one, then it
- // will be refined below anyway.
+ // mirror the refinement
+ // flags from the present time level to
+ // the previous if the dual problem was
+ // used for the refinement, since the
+ // error is computed on a time-space cell
+ //
+ // we don't mirror the coarsening flags
+ // since we want stronger refinement. if
+ // this was the wrong decision, the error
+ // on the child cells of the previous
+ // time slab will indicate coarsening
+ // in the next iteration, so this is not
+ // so dangerous here.
+ //
+ // also, we only have to check whether
+ // the present cell flagged for
+ // refinement and the previous one is on
+ // the same level and also active. If it
+ // already has children, then there is
+ // no problem at all, if it is on a lower
+ // level than the present one, then it
+ // will be refined below anyway.
if (new_cell->active())
{
- if (new_cell->refine_flag_set() && old_cell->active())
- {
- if (old_cell->coarsen_flag_set())
- old_cell->clear_coarsen_flag();
+ if (new_cell->refine_flag_set() && old_cell->active())
+ {
+ if (old_cell->coarsen_flag_set())
+ old_cell->clear_coarsen_flag();
- old_cell->set_refine_flag();
- };
+ old_cell->set_refine_flag();
+ };
- return;
+ return;
};
if (old_cell->has_children() && new_cell->has_children())
{
- Assert(old_cell->n_children()==new_cell->n_children(), ExcNotImplemented());
- for (unsigned int c=0; c<new_cell->n_children(); ++c)
- dealii::mirror_refinement_flags<dim> (new_cell->child(c), old_cell->child(c));
+ Assert(old_cell->n_children()==new_cell->n_children(), ExcNotImplemented());
+ for (unsigned int c=0; c<new_cell->n_children(); ++c)
+ dealii::mirror_refinement_flags<dim> (new_cell->child(c), old_cell->child(c));
}
}
template <int dim>
bool
adapt_grid_cells (const typename Triangulation<dim>::cell_iterator &cell1,
- const typename Triangulation<dim>::cell_iterator &cell2)
+ const typename Triangulation<dim>::cell_iterator &cell2)
{
if (cell2->has_children() && cell1->has_children())
{
- bool grids_changed = false;
+ bool grids_changed = false;
- Assert(cell2->n_children()==cell1->n_children(), ExcNotImplemented());
- for (unsigned int c=0; c<cell1->n_children(); ++c)
- grids_changed |= dealii::adapt_grid_cells<dim> (cell1->child(c),
- cell2->child(c));
- return grids_changed;
+ Assert(cell2->n_children()==cell1->n_children(), ExcNotImplemented());
+ for (unsigned int c=0; c<cell1->n_children(); ++c)
+ grids_changed |= dealii::adapt_grid_cells<dim> (cell1->child(c),
+ cell2->child(c));
+ return grids_changed;
};
if (!cell1->has_children() && !cell2->has_children())
- // none of the two have children, so
- // make sure that not one is flagged
- // for refinement and the other for
- // coarsening
+ // none of the two have children, so
+ // make sure that not one is flagged
+ // for refinement and the other for
+ // coarsening
{
- if (cell1->refine_flag_set() && cell2->coarsen_flag_set())
- {
- cell2->clear_coarsen_flag();
- return true;
- }
- else
- if (cell1->coarsen_flag_set() && cell2->refine_flag_set())
- {
- cell1->clear_coarsen_flag();
- return true;
- };
-
- return false;
+ if (cell1->refine_flag_set() && cell2->coarsen_flag_set())
+ {
+ cell2->clear_coarsen_flag();
+ return true;
+ }
+ else
+ if (cell1->coarsen_flag_set() && cell2->refine_flag_set())
+ {
+ cell1->clear_coarsen_flag();
+ return true;
+ };
+
+ return false;
};
if (cell1->has_children() && !cell2->has_children())
- // cell1 has children, cell2 has not
- // -> cell2 needs to be refined if any
- // of cell1's children is flagged
- // for refinement. None of them should
- // be refined further, since then in the
- // last round something must have gone
- // wrong
- //
- // if cell2 was flagged for coarsening,
- // we need to clear that flag in any
- // case. The only exception would be
- // if all children of cell1 were
- // flagged for coarsening, but rules
- // for coarsening are so complicated
- // that we will not attempt to cover
- // them. Rather accept one cell which
- // is not coarsened...
+ // cell1 has children, cell2 has not
+ // -> cell2 needs to be refined if any
+ // of cell1's children is flagged
+ // for refinement. None of them should
+ // be refined further, since then in the
+ // last round something must have gone
+ // wrong
+ //
+ // if cell2 was flagged for coarsening,
+ // we need to clear that flag in any
+ // case. The only exception would be
+ // if all children of cell1 were
+ // flagged for coarsening, but rules
+ // for coarsening are so complicated
+ // that we will not attempt to cover
+ // them. Rather accept one cell which
+ // is not coarsened...
{
- bool changed_grid = false;
- if (cell2->coarsen_flag_set())
- {
- cell2->clear_coarsen_flag();
- changed_grid = true;
- };
-
- if (!cell2->refine_flag_set())
- for (unsigned int c=0; c<cell1->n_children(); ++c)
- if (cell1->child(c)->refine_flag_set() ||
- cell1->child(c)->has_children())
- {
- cell2->set_refine_flag();
- changed_grid = true;
- break;
- };
- return changed_grid;
+ bool changed_grid = false;
+ if (cell2->coarsen_flag_set())
+ {
+ cell2->clear_coarsen_flag();
+ changed_grid = true;
+ };
+
+ if (!cell2->refine_flag_set())
+ for (unsigned int c=0; c<cell1->n_children(); ++c)
+ if (cell1->child(c)->refine_flag_set() ||
+ cell1->child(c)->has_children())
+ {
+ cell2->set_refine_flag();
+ changed_grid = true;
+ break;
+ };
+ return changed_grid;
};
if (!cell1->has_children() && cell2->has_children())
- // same thing, other way round...
+ // same thing, other way round...
{
- bool changed_grid = false;
- if (cell1->coarsen_flag_set())
- {
- cell1->clear_coarsen_flag();
- changed_grid = true;
- };
-
- if (!cell1->refine_flag_set())
- for (unsigned int c=0; c<cell2->n_children(); ++c)
- if (cell2->child(c)->refine_flag_set() ||
- cell2->child(c)->has_children())
- {
- cell1->set_refine_flag();
- changed_grid = true;
- break;
- };
- return changed_grid;
+ bool changed_grid = false;
+ if (cell1->coarsen_flag_set())
+ {
+ cell1->clear_coarsen_flag();
+ changed_grid = true;
+ };
+
+ if (!cell1->refine_flag_set())
+ for (unsigned int c=0; c<cell2->n_children(); ++c)
+ if (cell2->child(c)->refine_flag_set() ||
+ cell2->child(c)->has_children())
+ {
+ cell1->set_refine_flag();
+ changed_grid = true;
+ break;
+ };
+ return changed_grid;
};
Assert (false, ExcInternalError());
template <int dim>
bool
adapt_grids (Triangulation<dim> &tria1,
- Triangulation<dim> &tria2)
+ Triangulation<dim> &tria2)
{
bool grids_changed = false;
typename Triangulation<dim>::cell_iterator cell1 = tria1.begin(),
- cell2 = tria2.begin();
+ cell2 = tria2.begin();
typename Triangulation<dim>::cell_iterator endc;
endc = (tria1.n_levels() == 1 ?
- typename Triangulation<dim>::cell_iterator(tria1.end()) :
- tria1.begin(1));
+ typename Triangulation<dim>::cell_iterator(tria1.end()) :
+ tria1.begin(1));
for (; cell1!=endc; ++cell1, ++cell2)
grids_changed |= dealii::adapt_grid_cells<dim> (cell1, cell2);
Vector<float> criteria;
get_tria_refinement_criteria (criteria);
- // copy the following two values since
- // we may need modified values in the
- // process of this function
+ // copy the following two values since
+ // we may need modified values in the
+ // process of this function
double refinement_threshold = refinement_data.refinement_threshold,
- coarsening_threshold = refinement_data.coarsening_threshold;
-
- // prepare an array where the criteria
- // are stored in a sorted fashion
- // we need this if cell number correction
- // is switched on.
- // the criteria are sorted in ascending
- // order
- // only fill it when needed
+ coarsening_threshold = refinement_data.coarsening_threshold;
+
+ // prepare an array where the criteria
+ // are stored in a sorted fashion
+ // we need this if cell number correction
+ // is switched on.
+ // the criteria are sorted in ascending
+ // order
+ // only fill it when needed
Vector<float> sorted_criteria;
- // two pointers into this array denoting
- // the position where the two thresholds
- // are assumed
+ // two pointers into this array denoting
+ // the position where the two thresholds
+ // are assumed
Vector<float>::const_iterator p_refinement_threshold=0,
- p_coarsening_threshold=0;
-
-
- // if we are to do some cell number
- // correction steps, we have to find out
- // which further cells (beyond
- // refinement_threshold) to refine in case
- // we need more cells, and which cells
- // to not refine in case we need less cells
- // (or even to coarsen, if necessary). to
- // this end, we first define pointers into
- // a sorted array of criteria pointing
- // to the thresholds of refinement or
- // coarsening; moving these pointers amounts
- // to changing the threshold such that the
- // number of cells flagged for refinement
- // or coarsening would be changed by one
+ p_coarsening_threshold=0;
+
+
+ // if we are to do some cell number
+ // correction steps, we have to find out
+ // which further cells (beyond
+ // refinement_threshold) to refine in case
+ // we need more cells, and which cells
+ // to not refine in case we need less cells
+ // (or even to coarsen, if necessary). to
+ // this end, we first define pointers into
+ // a sorted array of criteria pointing
+ // to the thresholds of refinement or
+ // coarsening; moving these pointers amounts
+ // to changing the threshold such that the
+ // number of cells flagged for refinement
+ // or coarsening would be changed by one
if ((timestep_no != 0) &&
(sweep_no>=refinement_flags.first_sweep_with_correction) &&
(refinement_flags.cell_number_correction_steps > 0))
{
sorted_criteria = criteria;
std::sort (sorted_criteria.begin(),
- sorted_criteria.end());
+ sorted_criteria.end());
p_refinement_threshold = Utilities::lower_bound (sorted_criteria.begin(),
- sorted_criteria.end(),
- static_cast<float>(refinement_threshold));
+ sorted_criteria.end(),
+ static_cast<float>(refinement_threshold));
p_coarsening_threshold = std::upper_bound (sorted_criteria.begin(),
- sorted_criteria.end(),
- static_cast<float>(coarsening_threshold));
+ sorted_criteria.end(),
+ static_cast<float>(coarsening_threshold));
};
- // actually flag cells the first time
+ // actually flag cells the first time
GridRefinement::refine (*tria, criteria, refinement_threshold);
GridRefinement::coarsen (*tria, criteria, coarsening_threshold);
- // store this number for the following
- // since its computation is rather
- // expensive and since it doesn't change
+ // store this number for the following
+ // since its computation is rather
+ // expensive and since it doesn't change
const unsigned int n_active_cells = tria->n_active_cells ();
- // if not on first time level: try to
- // adjust the number of resulting
- // cells to those on the previous
- // time level. Only do the cell number
- // correction for higher sweeps and if
- // there are sufficiently many cells
- // already to avoid "grid stall" i.e.
- // that the grid's evolution is hindered
- // by the correction (this usually
- // happens if there are very few cells,
- // since then the number of cells touched
- // by the correction step may exceed the
- // number of cells which are flagged for
- // refinement; in this case it often
- // happens that the number of cells
- // does not grow between sweeps, which
- // clearly is not the wanted behaviour)
- //
- // however, if we do not do anything, we
- // can get into trouble somewhen later.
- // therefore, we also use the correction
- // step for the first sweep or if the
- // number of cells is between 100 and 300
- // (unlike in the first version of the
- // algorithm), but relax the conditions
- // for the correction to allow deviations
- // which are three times as high than
- // allowed (sweep==1 || cell number<200)
- // or twice as high (sweep==2 ||
- // cell number<300). Also, since
- // refinement never does any harm other
- // than increased work, we allow for
- // arbitrary growth of cell number if
- // the estimated cell number is below
- // 200.
- //
- // repeat this loop several times since
- // the first estimate may not be totally
- // correct
+ // if not on first time level: try to
+ // adjust the number of resulting
+ // cells to those on the previous
+ // time level. Only do the cell number
+ // correction for higher sweeps and if
+ // there are sufficiently many cells
+ // already to avoid "grid stall" i.e.
+ // that the grid's evolution is hindered
+ // by the correction (this usually
+ // happens if there are very few cells,
+ // since then the number of cells touched
+ // by the correction step may exceed the
+ // number of cells which are flagged for
+ // refinement; in this case it often
+ // happens that the number of cells
+ // does not grow between sweeps, which
+ // clearly is not the wanted behaviour)
+ //
+ // however, if we do not do anything, we
+ // can get into trouble somewhen later.
+ // therefore, we also use the correction
+ // step for the first sweep or if the
+ // number of cells is between 100 and 300
+ // (unlike in the first version of the
+ // algorithm), but relax the conditions
+ // for the correction to allow deviations
+ // which are three times as high than
+ // allowed (sweep==1 || cell number<200)
+ // or twice as high (sweep==2 ||
+ // cell number<300). Also, since
+ // refinement never does any harm other
+ // than increased work, we allow for
+ // arbitrary growth of cell number if
+ // the estimated cell number is below
+ // 200.
+ //
+ // repeat this loop several times since
+ // the first estimate may not be totally
+ // correct
if ((timestep_no != 0) && (sweep_no>=refinement_flags.first_sweep_with_correction))
for (unsigned int loop=0;
- loop<refinement_flags.cell_number_correction_steps; ++loop)
+ loop<refinement_flags.cell_number_correction_steps; ++loop)
{
- Triangulation<dim> *previous_tria
- = dynamic_cast<const TimeStepBase_Tria<dim>*>(previous_timestep)->tria;
-
- // do one adaption step if desired
- // (there are more coming below then
- // also)
- if (refinement_flags.adapt_grids)
- dealii::adapt_grids<dim> (*previous_tria, *tria);
-
- // perform flagging of cells
- // needed to regularize the
- // triangulation
- tria->prepare_coarsening_and_refinement ();
- previous_tria->prepare_coarsening_and_refinement ();
-
-
- // now count the number of elements
- // which will result on the previous
- // grid after it will be refined. The
- // number which will really result
- // should be approximately that that we
- // compute here, since we already
- // performed most of the prepare*
- // steps for the previous grid
- //
- // use a double value since for each
- // four cells (in 2D) that we flagged
- // for coarsening we result in one
- // new. but since we loop over flagged
- // cells, we have to subtract 3/4 of
- // a cell for each flagged cell
- Assert(!tria->get_anisotropic_refinement_flag(), ExcNotImplemented());
- Assert(!previous_tria->get_anisotropic_refinement_flag(), ExcNotImplemented());
- double previous_cells = previous_tria->n_active_cells();
- typename Triangulation<dim>::active_cell_iterator cell, endc;
- cell = previous_tria->begin_active();
- endc = previous_tria->end();
- for (; cell!=endc; ++cell)
- if (cell->refine_flag_set())
- previous_cells += (GeometryInfo<dim>::max_children_per_cell-1);
- else
- if (cell->coarsen_flag_set())
- previous_cells -= (GeometryInfo<dim>::max_children_per_cell-1) /
- GeometryInfo<dim>::max_children_per_cell;
-
- // @p{previous_cells} now gives the
- // number of cells which would result
- // from the flags on the previous grid
- // if we refined it now. However, some
- // more flags will be set when we adapt
- // the previous grid with this one
- // after the flags have been set for
- // this time level; on the other hand,
- // we don't account for this, since the
- // number of cells on this time level
- // will be changed afterwards by the
- // same way, when it is adapted to the
- // next time level
-
- // now estimate the number of cells which
- // will result on this level
- double estimated_cells = n_active_cells;
- cell = tria->begin_active();
- endc = tria->end();
- for (; cell!=endc; ++cell)
- if (cell->refine_flag_set())
- estimated_cells += (GeometryInfo<dim>::max_children_per_cell-1);
- else
- if (cell->coarsen_flag_set())
- estimated_cells -= (GeometryInfo<dim>::max_children_per_cell-1) /
- GeometryInfo<dim>::max_children_per_cell;
-
- // calculate the allowed delta in
- // cell numbers; be more lenient
- // if there are few cells
- double delta_up = refinement_flags.cell_number_corridor_top,
- delta_down = refinement_flags.cell_number_corridor_bottom;
-
- const std::vector<std::pair<unsigned int,double> > &relaxations
- = (sweep_no >= refinement_flags.correction_relaxations.size() ?
- refinement_flags.correction_relaxations.back() :
- refinement_flags.correction_relaxations[sweep_no]);
- for (unsigned int r=0; r!=relaxations.size(); ++r)
- if (n_active_cells < relaxations[r].first)
- {
- delta_up *= relaxations[r].second;
- delta_down *= relaxations[r].second;
- break;
- };
-
- // now, if the number of estimated
- // cells exceeds the number of cells
- // on the old time level by more than
- // delta: cut the top threshold
- //
- // note that for each cell that
- // we unflag we have to diminish the
- // estimated number of cells by
- // @p{children_per_cell}.
- if (estimated_cells > previous_cells*(1.+delta_up))
- {
- // only limit the cell number
- // if there will not be less
- // than some number of cells
- //
- // also note that when using the
- // dual estimator, the initial
- // time level is not refined
- // on its own, so we may not
- // limit the number of the second
- // time level on the basis of
- // the initial one; since for
- // the dual estimator, we
- // mirror the refinement
- // flags, the initial level
- // will be passively refined
- // later on.
- if (estimated_cells>refinement_flags.min_cells_for_correction)
- {
- // number of cells by which the
- // new grid is to be diminished
- double delta_cells = estimated_cells -
- previous_cells*(1.+delta_up);
-
- // if we need to reduce the
- // number of cells, we need
- // to raise the thresholds,
- // i.e. move ahead in the
- // sorted array, since this
- // is sorted in ascending
- // order. do so by removing
- // cells tagged for refinement
-
- for (unsigned int i=0; i<delta_cells;
- i += GeometryInfo<dim>::max_children_per_cell-1)
- if (p_refinement_threshold != sorted_criteria.end())
- ++p_refinement_threshold;
- else
- break;
- }
- else
- // too many cells, but we
- // won't do anything about
- // that
- break;
- }
- else
- // likewise: if the estimated number
- // of cells is less than 90 per cent
- // of those at the previous time level:
- // raise threshold by refining
- // additional cells. if we start to
- // run into the area of cells
- // which are to be coarsened, we
- // raise the limit for these too
- if (estimated_cells < previous_cells*(1.-delta_down))
- {
- // number of cells by which the
- // new grid is to be enlarged
- double delta_cells = previous_cells*(1.-delta_down)-estimated_cells;
- // heuristics: usually, if we
- // add @p{delta_cells} to the
- // present state, we end up
- // with much more than only
- // (1-delta_down)*prev_cells
- // because of the effect of
- // regularization and because
- // of adaption to the
- // following grid. Therefore,
- // if we are not in the last
- // correction loop, we try not
- // to add as many cells as seem
- // necessary at first and hope
- // to get closer to the limit
- // this way. Only in the last
- // loop do we have to take the
- // full number to guarantee the
- // wanted result.
- //
- // The value 0.9 is taken from
- // practice, as the additional
- // number of cells introduced
- // by regularization is
- // approximately 10 per cent
- // of the flagged cells.
- if (loop != refinement_flags.cell_number_correction_steps-1)
- delta_cells *= 0.9;
-
- // if more cells need to be
- // refined, we need to lower
- // the thresholds, i.e. to
- // move to the beginning
- // of sorted_criteria, which is
- // sorted in ascending order
- for (unsigned int i=0; i<delta_cells;
- i += (GeometryInfo<dim>::max_children_per_cell-1))
- if (p_refinement_threshold != p_coarsening_threshold)
- --refinement_threshold;
- else
- if (p_coarsening_threshold != sorted_criteria.begin())
- --p_coarsening_threshold, --p_refinement_threshold;
- else
- break;
- }
- else
- // estimated cell number is ok,
- // stop correction steps
- break;
-
- if (p_refinement_threshold == sorted_criteria.end())
- {
- Assert (p_coarsening_threshold != p_refinement_threshold,
- ExcInternalError());
- --p_refinement_threshold;
- };
-
- coarsening_threshold = *p_coarsening_threshold;
- refinement_threshold = *p_refinement_threshold;
-
- if (coarsening_threshold>=refinement_threshold)
- coarsening_threshold = 0.999*refinement_threshold;
-
- // now that we have re-adjusted
- // thresholds: clear all refine and
- // coarsening flags and do it all
- // over again
- cell = tria->begin_active();
- endc = tria->end();
- for (; cell!=endc; ++cell)
- {
- cell->clear_refine_flag ();
- cell->clear_coarsen_flag ();
- };
-
-
- // flag cells finally
- GridRefinement::refine (*tria, criteria, refinement_threshold);
- GridRefinement::coarsen (*tria, criteria, coarsening_threshold);
+ Triangulation<dim> *previous_tria
+ = dynamic_cast<const TimeStepBase_Tria<dim>*>(previous_timestep)->tria;
+
+ // do one adaption step if desired
+ // (there are more coming below then
+ // also)
+ if (refinement_flags.adapt_grids)
+ dealii::adapt_grids<dim> (*previous_tria, *tria);
+
+ // perform flagging of cells
+ // needed to regularize the
+ // triangulation
+ tria->prepare_coarsening_and_refinement ();
+ previous_tria->prepare_coarsening_and_refinement ();
+
+
+ // now count the number of elements
+ // which will result on the previous
+ // grid after it will be refined. The
+ // number which will really result
+ // should be approximately that that we
+ // compute here, since we already
+ // performed most of the prepare*
+ // steps for the previous grid
+ //
+ // use a double value since for each
+ // four cells (in 2D) that we flagged
+ // for coarsening we result in one
+ // new. but since we loop over flagged
+ // cells, we have to subtract 3/4 of
+ // a cell for each flagged cell
+ Assert(!tria->get_anisotropic_refinement_flag(), ExcNotImplemented());
+ Assert(!previous_tria->get_anisotropic_refinement_flag(), ExcNotImplemented());
+ double previous_cells = previous_tria->n_active_cells();
+ typename Triangulation<dim>::active_cell_iterator cell, endc;
+ cell = previous_tria->begin_active();
+ endc = previous_tria->end();
+ for (; cell!=endc; ++cell)
+ if (cell->refine_flag_set())
+ previous_cells += (GeometryInfo<dim>::max_children_per_cell-1);
+ else
+ if (cell->coarsen_flag_set())
+ previous_cells -= (GeometryInfo<dim>::max_children_per_cell-1) /
+ GeometryInfo<dim>::max_children_per_cell;
+
+ // @p{previous_cells} now gives the
+ // number of cells which would result
+ // from the flags on the previous grid
+ // if we refined it now. However, some
+ // more flags will be set when we adapt
+ // the previous grid with this one
+ // after the flags have been set for
+ // this time level; on the other hand,
+ // we don't account for this, since the
+ // number of cells on this time level
+ // will be changed afterwards by the
+ // same way, when it is adapted to the
+ // next time level
+
+ // now estimate the number of cells which
+ // will result on this level
+ double estimated_cells = n_active_cells;
+ cell = tria->begin_active();
+ endc = tria->end();
+ for (; cell!=endc; ++cell)
+ if (cell->refine_flag_set())
+ estimated_cells += (GeometryInfo<dim>::max_children_per_cell-1);
+ else
+ if (cell->coarsen_flag_set())
+ estimated_cells -= (GeometryInfo<dim>::max_children_per_cell-1) /
+ GeometryInfo<dim>::max_children_per_cell;
+
+ // calculate the allowed delta in
+ // cell numbers; be more lenient
+ // if there are few cells
+ double delta_up = refinement_flags.cell_number_corridor_top,
+ delta_down = refinement_flags.cell_number_corridor_bottom;
+
+ const std::vector<std::pair<unsigned int,double> > &relaxations
+ = (sweep_no >= refinement_flags.correction_relaxations.size() ?
+ refinement_flags.correction_relaxations.back() :
+ refinement_flags.correction_relaxations[sweep_no]);
+ for (unsigned int r=0; r!=relaxations.size(); ++r)
+ if (n_active_cells < relaxations[r].first)
+ {
+ delta_up *= relaxations[r].second;
+ delta_down *= relaxations[r].second;
+ break;
+ };
+
+ // now, if the number of estimated
+ // cells exceeds the number of cells
+ // on the old time level by more than
+ // delta: cut the top threshold
+ //
+ // note that for each cell that
+ // we unflag we have to diminish the
+ // estimated number of cells by
+ // @p{children_per_cell}.
+ if (estimated_cells > previous_cells*(1.+delta_up))
+ {
+ // only limit the cell number
+ // if there will not be less
+ // than some number of cells
+ //
+ // also note that when using the
+ // dual estimator, the initial
+ // time level is not refined
+ // on its own, so we may not
+ // limit the number of the second
+ // time level on the basis of
+ // the initial one; since for
+ // the dual estimator, we
+ // mirror the refinement
+ // flags, the initial level
+ // will be passively refined
+ // later on.
+ if (estimated_cells>refinement_flags.min_cells_for_correction)
+ {
+ // number of cells by which the
+ // new grid is to be diminished
+ double delta_cells = estimated_cells -
+ previous_cells*(1.+delta_up);
+
+ // if we need to reduce the
+ // number of cells, we need
+ // to raise the thresholds,
+ // i.e. move ahead in the
+ // sorted array, since this
+ // is sorted in ascending
+ // order. do so by removing
+ // cells tagged for refinement
+
+ for (unsigned int i=0; i<delta_cells;
+ i += GeometryInfo<dim>::max_children_per_cell-1)
+ if (p_refinement_threshold != sorted_criteria.end())
+ ++p_refinement_threshold;
+ else
+ break;
+ }
+ else
+ // too many cells, but we
+ // won't do anything about
+ // that
+ break;
+ }
+ else
+ // likewise: if the estimated number
+ // of cells is less than 90 per cent
+ // of those at the previous time level:
+ // raise threshold by refining
+ // additional cells. if we start to
+ // run into the area of cells
+ // which are to be coarsened, we
+ // raise the limit for these too
+ if (estimated_cells < previous_cells*(1.-delta_down))
+ {
+ // number of cells by which the
+ // new grid is to be enlarged
+ double delta_cells = previous_cells*(1.-delta_down)-estimated_cells;
+ // heuristics: usually, if we
+ // add @p{delta_cells} to the
+ // present state, we end up
+ // with much more than only
+ // (1-delta_down)*prev_cells
+ // because of the effect of
+ // regularization and because
+ // of adaption to the
+ // following grid. Therefore,
+ // if we are not in the last
+ // correction loop, we try not
+ // to add as many cells as seem
+ // necessary at first and hope
+ // to get closer to the limit
+ // this way. Only in the last
+ // loop do we have to take the
+ // full number to guarantee the
+ // wanted result.
+ //
+ // The value 0.9 is taken from
+ // practice, as the additional
+ // number of cells introduced
+ // by regularization is
+ // approximately 10 per cent
+ // of the flagged cells.
+ if (loop != refinement_flags.cell_number_correction_steps-1)
+ delta_cells *= 0.9;
+
+ // if more cells need to be
+ // refined, we need to lower
+ // the thresholds, i.e. to
+ // move to the beginning
+ // of sorted_criteria, which is
+ // sorted in ascending order
+ for (unsigned int i=0; i<delta_cells;
+ i += (GeometryInfo<dim>::max_children_per_cell-1))
+ if (p_refinement_threshold != p_coarsening_threshold)
+ --refinement_threshold;
+ else
+ if (p_coarsening_threshold != sorted_criteria.begin())
+ --p_coarsening_threshold, --p_refinement_threshold;
+ else
+ break;
+ }
+ else
+ // estimated cell number is ok,
+ // stop correction steps
+ break;
+
+ if (p_refinement_threshold == sorted_criteria.end())
+ {
+ Assert (p_coarsening_threshold != p_refinement_threshold,
+ ExcInternalError());
+ --p_refinement_threshold;
+ };
+
+ coarsening_threshold = *p_coarsening_threshold;
+ refinement_threshold = *p_refinement_threshold;
+
+ if (coarsening_threshold>=refinement_threshold)
+ coarsening_threshold = 0.999*refinement_threshold;
+
+ // now that we have re-adjusted
+ // thresholds: clear all refine and
+ // coarsening flags and do it all
+ // over again
+ cell = tria->begin_active();
+ endc = tria->end();
+ for (; cell!=endc; ++cell)
+ {
+ cell->clear_refine_flag ();
+ cell->clear_coarsen_flag ();
+ };
+
+
+ // flag cells finally
+ GridRefinement::refine (*tria, criteria, refinement_threshold);
+ GridRefinement::coarsen (*tria, criteria, coarsening_threshold);
};
- // if step number is greater than
- // one: adapt this and the previous
- // grid to each other. Don't do so
- // for the initial grid because
- // it is always taken to be the first
- // grid and needs therefore no
- // treatment of its own.
+ // if step number is greater than
+ // one: adapt this and the previous
+ // grid to each other. Don't do so
+ // for the initial grid because
+ // it is always taken to be the first
+ // grid and needs therefore no
+ // treatment of its own.
if ((timestep_no >= 1) && (refinement_flags.adapt_grids))
{
Triangulation<dim> *previous_tria
- = dynamic_cast<const TimeStepBase_Tria<dim>*>(previous_timestep)->tria;
-
-
- // if we used the dual estimator, we
- // computed the error information on
- // a time slab, rather than on a level
- // of its own. we then mirror the
- // refinement flags we determined for
- // the present level to the previous
- // one
- //
- // do this mirroring only, if cell number
- // adjustment is on, since otherwise
- // strange things may happen
+ = dynamic_cast<const TimeStepBase_Tria<dim>*>(previous_timestep)->tria;
+
+
+ // if we used the dual estimator, we
+ // computed the error information on
+ // a time slab, rather than on a level
+ // of its own. we then mirror the
+ // refinement flags we determined for
+ // the present level to the previous
+ // one
+ //
+ // do this mirroring only, if cell number
+ // adjustment is on, since otherwise
+ // strange things may happen
if (refinement_flags.mirror_flags_to_previous_grid)
- {
- dealii::adapt_grids<dim> (*previous_tria, *tria);
+ {
+ dealii::adapt_grids<dim> (*previous_tria, *tria);
- typename Triangulation<dim>::cell_iterator old_cell, new_cell, endc;
- old_cell = previous_tria->begin(0);
- new_cell = tria->begin(0);
- endc = tria->end(0);
- for (; new_cell!=endc; ++new_cell, ++old_cell)
- dealii::mirror_refinement_flags<dim> (new_cell, old_cell);
- };
+ typename Triangulation<dim>::cell_iterator old_cell, new_cell, endc;
+ old_cell = previous_tria->begin(0);
+ new_cell = tria->begin(0);
+ endc = tria->end(0);
+ for (; new_cell!=endc; ++new_cell, ++old_cell)
+ dealii::mirror_refinement_flags<dim> (new_cell, old_cell);
+ };
tria->prepare_coarsening_and_refinement ();
previous_tria->prepare_coarsening_and_refinement ();
- // adapt present and previous grids
- // to each other: flag additional
- // cells to avoid the previous grid
- // to have cells refined twice more
- // than the present one and vica versa.
+ // adapt present and previous grids
+ // to each other: flag additional
+ // cells to avoid the previous grid
+ // to have cells refined twice more
+ // than the present one and vica versa.
dealii::adapt_grids<dim> (*previous_tria, *tria);
};
}
TimeStepBase_Tria<dim>::memory_consumption () const
{
return (TimeStepBase::memory_consumption () +
- sizeof(tria) +
- MemoryConsumption::memory_consumption (coarse_grid) +
- sizeof(flags) + sizeof(refinement_flags) +
- MemoryConsumption::memory_consumption (refine_flags) +
- MemoryConsumption::memory_consumption (coarsen_flags));
+ sizeof(tria) +
+ MemoryConsumption::memory_consumption (coarse_grid) +
+ sizeof(flags) + sizeof(refinement_flags) +
+ MemoryConsumption::memory_consumption (refine_flags) +
+ MemoryConsumption::memory_consumption (coarsen_flags));
}
template <int dim>
TimeStepBase_Tria_Flags::Flags<dim>::Flags ()
- :
- delete_and_rebuild_tria (false),
- wakeup_level_to_build_grid (0),
- sleep_level_to_delete_grid (0)
+ :
+ delete_and_rebuild_tria (false),
+ wakeup_level_to_build_grid (0),
+ sleep_level_to_delete_grid (0)
{
Assert (false, ExcInternalError());
}
template <int dim>
TimeStepBase_Tria_Flags::Flags<dim>::Flags (const bool delete_and_rebuild_tria,
- const unsigned int wakeup_level_to_build_grid,
- const unsigned int sleep_level_to_delete_grid):
- delete_and_rebuild_tria (delete_and_rebuild_tria),
- wakeup_level_to_build_grid (wakeup_level_to_build_grid),
- sleep_level_to_delete_grid (sleep_level_to_delete_grid)
+ const unsigned int wakeup_level_to_build_grid,
+ const unsigned int sleep_level_to_delete_grid):
+ delete_and_rebuild_tria (delete_and_rebuild_tria),
+ wakeup_level_to_build_grid (wakeup_level_to_build_grid),
+ sleep_level_to_delete_grid (sleep_level_to_delete_grid)
{
// Assert (!delete_and_rebuild_tria || (wakeup_level_to_build_grid>=1),
-// ExcInvalidParameter(wakeup_level_to_build_grid));
+// ExcInvalidParameter(wakeup_level_to_build_grid));
// Assert (!delete_and_rebuild_tria || (sleep_level_to_delete_grid>=1),
-// ExcInvalidParameter(sleep_level_to_delete_grid));
+// ExcInvalidParameter(sleep_level_to_delete_grid));
}
TimeStepBase_Tria_Flags::RefinementFlags<dim>::default_correction_relaxations
(1, // one element, denoting the first and all subsequent sweeps
std::vector<std::pair<unsigned int,double> >(1, // one element, denoting the upper bound
- // for the following
- // relaxation
- std::make_pair (0U, 0.)));
+ // for the following
+ // relaxation
+ std::make_pair (0U, 0.)));
template <int dim>
TimeStepBase_Tria_Flags::RefinementFlags<dim>::
RefinementFlags (const unsigned int max_refinement_level,
- const unsigned int first_sweep_with_correction,
- const unsigned int min_cells_for_correction,
- const double cell_number_corridor_top,
- const double cell_number_corridor_bottom,
- const CorrectionRelaxations &correction_relaxations,
- const unsigned int cell_number_correction_steps,
- const bool mirror_flags_to_previous_grid,
- const bool adapt_grids) :
- max_refinement_level(max_refinement_level),
- first_sweep_with_correction (first_sweep_with_correction),
- min_cells_for_correction(min_cells_for_correction),
- cell_number_corridor_top(cell_number_corridor_top),
- cell_number_corridor_bottom(cell_number_corridor_bottom),
- correction_relaxations (correction_relaxations.size() != 0 ?
- correction_relaxations :
- default_correction_relaxations),
- cell_number_correction_steps(cell_number_correction_steps),
- mirror_flags_to_previous_grid(mirror_flags_to_previous_grid),
- adapt_grids(adapt_grids)
+ const unsigned int first_sweep_with_correction,
+ const unsigned int min_cells_for_correction,
+ const double cell_number_corridor_top,
+ const double cell_number_corridor_bottom,
+ const CorrectionRelaxations &correction_relaxations,
+ const unsigned int cell_number_correction_steps,
+ const bool mirror_flags_to_previous_grid,
+ const bool adapt_grids) :
+ max_refinement_level(max_refinement_level),
+ first_sweep_with_correction (first_sweep_with_correction),
+ min_cells_for_correction(min_cells_for_correction),
+ cell_number_corridor_top(cell_number_corridor_top),
+ cell_number_corridor_bottom(cell_number_corridor_bottom),
+ correction_relaxations (correction_relaxations.size() != 0 ?
+ correction_relaxations :
+ default_correction_relaxations),
+ cell_number_correction_steps(cell_number_correction_steps),
+ mirror_flags_to_previous_grid(mirror_flags_to_previous_grid),
+ adapt_grids(adapt_grids)
{
Assert (cell_number_corridor_top>=0, ExcInvalidValue (cell_number_corridor_top));
Assert (cell_number_corridor_bottom>=0, ExcInvalidValue (cell_number_corridor_bottom));
template <int dim>
TimeStepBase_Tria_Flags::RefinementData<dim>::
RefinementData (const double _refinement_threshold,
- const double _coarsening_threshold) :
- refinement_threshold(_refinement_threshold),
- // in some rare cases it may happen that
- // both thresholds are the same (e.g. if
- // there are many cells with the same
- // error indicator). That would mean that
- // all cells will be flagged for
- // refinement or coarsening, but some will
- // be flagged for both, namely those for
- // which the indicator equals the
- // thresholds. This is forbidden, however.
- //
- // In some rare cases with very few cells
- // we also could get integer round off
- // errors and get problems with
- // the top and bottom fractions.
- //
- // In these case we arbitrarily reduce the
- // bottom threshold by one permille below
- // the top threshold
- coarsening_threshold((_coarsening_threshold == _refinement_threshold ?
- _coarsening_threshold :
- 0.999*_coarsening_threshold))
+ const double _coarsening_threshold) :
+ refinement_threshold(_refinement_threshold),
+ // in some rare cases it may happen that
+ // both thresholds are the same (e.g. if
+ // there are many cells with the same
+ // error indicator). That would mean that
+ // all cells will be flagged for
+ // refinement or coarsening, but some will
+ // be flagged for both, namely those for
+ // which the indicator equals the
+ // thresholds. This is forbidden, however.
+ //
+ // In some rare cases with very few cells
+ // we also could get integer round off
+ // errors and get problems with
+ // the top and bottom fractions.
+ //
+ // In these case we arbitrarily reduce the
+ // bottom threshold by one permille below
+ // the top threshold
+ coarsening_threshold((_coarsening_threshold == _refinement_threshold ?
+ _coarsening_threshold :
+ 0.999*_coarsening_threshold))
{
Assert (refinement_threshold >= 0, ExcInvalidValue(refinement_threshold));
Assert (coarsening_threshold >= 0, ExcInvalidValue(coarsening_threshold));
- // allow both thresholds to be zero,
- // since this is needed in case all indicators
- // are zero
+ // allow both thresholds to be zero,
+ // since this is needed in case all indicators
+ // are zero
Assert ((coarsening_threshold < refinement_threshold) ||
- ((coarsening_threshold == 0) && (refinement_threshold == 0)),
- ExcInvalidValue (coarsening_threshold));
+ ((coarsening_threshold == 0) && (refinement_threshold == 0)),
+ ExcInvalidValue (coarsening_threshold));
}
void
subtract_mean_value(Vector<double> &v,
- const std::vector<bool> &p_select)
+ const std::vector<bool> &p_select)
{
const unsigned int n = v.size();
Assert(n == p_select.size(),
- ExcDimensionMismatch(n, p_select.size()));
+ ExcDimensionMismatch(n, p_select.size()));
double s = 0;
unsigned int counter = 0;
for (unsigned int i=0; i<n; ++i)
if (p_select[i])
- {
- s += v(i);
- ++counter;
- }
+ {
+ s += v(i);
+ ++counter;
+ }
Assert (counter > 0, ExcNoComponentSelected());
s /= counter;
for (unsigned int i=0; i<n; ++i)
if (p_select[i])
- v(i) -= s;
+ v(i) -= s;
}
}