15 #include "../general/osockstream.hpp" 31 int new_nodes_ordering)
37 int fes_ordering =
space->GetOrdering(),
38 ncomp =
space->GetVDim();
41 const int pnt_cnt = field0.
Size() / ncomp;
45 for (
int i = 0; i < ncomp; i++)
49 new_field_temp.
MakeRef(new_field, i*pnt_cnt, pnt_cnt);
53 new_field_temp.
SetSize(pnt_cnt);
54 for (
int j = 0; j < pnt_cnt; j++)
56 new_field_temp(j) = new_field(i + j*ncomp);
59 ComputeAtNewPositionScalar(new_nodes, new_field_temp);
62 for (
int j = 0; j < pnt_cnt; j++)
64 new_field(i + j*ncomp) = new_field_temp(j);
73 void AdvectorCG::ComputeAtNewPositionScalar(
const Vector &new_nodes,
81 MFEM_VERIFY(m != NULL,
"No mesh has been given to the AdaptivityEvaluator.");
86 double minv = new_field.
Min(), maxv = new_field.
Max();
110 MFEM_VERIFY(oper != NULL,
111 "No FE space has been given to the AdaptivityEvaluator.");
112 ode_solver.
Init(*oper);
116 for (
int i = 0; i < m->
GetNE(); i++)
121 const int s = new_field.
Size();
124 for (
int i = 0; i <
s; i++)
131 v_max = std::max(v_max,
vel);
137 double v_loc = v_max, h_loc = h_min;
138 MPI_Allreduce(&v_loc, &v_max, 1, MPI_DOUBLE, MPI_MAX,
pfes->
GetComm());
139 MPI_Allreduce(&h_loc, &h_min, 1, MPI_DOUBLE, MPI_MIN,
pfes->
GetComm());
153 v_max = std::sqrt(v_max);
154 double dt = dt_scale * h_min / v_max;
157 bool last_step =
false;
158 for (
int ti = 1; !last_step; ti++)
165 ode_solver.
Step(new_field,
t, dt);
168 double glob_minv = minv,
173 MPI_Allreduce(&minv, &glob_minv, 1, MPI_DOUBLE, MPI_MIN,
pfes->
GetComm());
174 MPI_Allreduce(&maxv, &glob_maxv, 1, MPI_DOUBLE, MPI_MAX,
pfes->
GetComm());
180 for (
int i = 0; i <
s; i++)
182 if (new_field(i) < glob_minv) { new_field(i) = glob_minv; }
183 if (new_field(i) > glob_maxv) { new_field(i) = glob_maxv; }
198 x0(x_start), x_now(*fes.
GetMesh()->GetNodes()),
199 u(
vel), u_coeff(&
u), M(&fes), K(&fes), al(al)
222 K.BilinearForm::operator=(0.0);
226 M.BilinearForm::operator=(0.0);
247 lin_solver.
Mult(rhs, di_dt);
259 x0(x_start), x_now(*pfes.
GetMesh()->GetNodes()),
260 u(
vel), u_coeff(&
u), M(&pfes), K(&pfes), al(al)
291 K.BilinearForm::operator=(0.0);
295 M.BilinearForm::operator=(0.0);
319 lin_solver.SetOperator(*Mop);
320 lin_solver.SetRelTol(1e-8);
321 lin_solver.SetAbsTol(0.0);
322 lin_solver.SetMaxIter(100);
323 lin_solver.SetPrintLevel(0);
324 lin_solver.Mult(*RHS, X);
332 #ifdef MFEM_USE_GSLIB 343 const double rel_bbox_el = 0.1;
344 const double newton_tol = 1.0e-12;
345 const int npts_at_once = 256;
364 finder->
Setup(*m, rel_bbox_el, newton_tol, npts_at_once);
367 field0_gf = init_field;
372 int new_nodes_ordering)
374 finder->
Interpolate(new_nodes, field0_gf, new_field, new_nodes_ordering);
383 double energy_in = 0.0;
386 MFEM_VERIFY(!(
parallel && p_nlf == NULL),
"Invalid Operator subclass.");
395 MFEM_VERIFY(!(serial && nlf == NULL),
"Invalid Operator subclass.");
408 if (!cP) { x_out_loc = x; }
409 else { cP->
Mult(x, x_out_loc); }
421 double avg_err, max_err;
427 mfem::out <<
"TMOPNewtonSolver converged " 428 "based on the surface fitting error.\n";
438 const bool untangling = (min_detT_in <= 0.0) ? true :
false;
439 const double untangle_factor = 1.5;
444 MFEM_VERIFY(
min_det_ptr != NULL,
" Initial mesh was valid, but" 445 " intermediate mesh is invalid. Contact TMOP Developers.");
449 const bool have_b = (
b.Size() ==
Height());
452 bool x_out_ok =
false;
453 double energy_out = 0.0, min_detT_out;
454 const double norm_in =
Norm(
r);
456 const double detJ_factor = (
solver_type == 1) ? 0.25 : 0.5;
463 for (
int i = 0; i < 12; i++)
466 add(x, -scale,
c, x_out);
470 if (!cP) { x_out_loc = x_out; }
471 else { cP->
Mult(x_out, x_out_loc); }
479 if (untangling ==
false && min_detT_out < 0.0)
484 mfem::out <<
"Scale = " << scale <<
" Neg det(J) found.\n";
486 scale *= detJ_factor;
continue;
488 if (untangling ==
true && min_detT_out < *
min_det_ptr)
493 mfem::out <<
"Scale = " << scale <<
" Neg det(J) decreased.\n";
495 scale *= detJ_factor;
continue;
501 if (untangling) { x_out_ok =
true;
break; }
516 if (energy_out > energy_in + 0.2*fabs(energy_in) ||
517 std::isnan(energy_out) != 0)
521 mfem::out <<
"Scale = " << scale <<
" Increasing energy: " 522 << energy_in <<
" --> " << energy_out <<
'\n';
524 scale *= 0.5;
continue;
529 if (have_b) {
r -=
b; }
530 double norm_out =
Norm(
r);
532 if (norm_out > 1.2*norm_in)
536 mfem::out <<
"Scale = " << scale <<
" Norm increased: " 537 << norm_in <<
" --> " << norm_out <<
'\n';
539 scale *= 0.5;
continue;
541 else { x_out_ok =
true;
break; }
547 if (min_detT_out > 0.0)
552 {
mfem::out <<
"The mesh has been untangled at the used points!\n"; }
554 else { *
min_det_ptr = untangle_factor * min_detT_out; }
563 << min_detT_in <<
" -> " << min_detT_out
564 <<
" with " << scale <<
" scaling.\n";
569 << energy_in <<
" --> " << energy_out <<
" or " 570 << (energy_in - energy_out) / energy_in * 100.0
571 <<
"% with " << scale <<
" scaling.\n";
575 if (x_out_ok ==
false) { scale = 0.0; }
589 for (
int i = 0; i < integs.
Size(); i++)
600 for (
int j = 0; j < ati.
Size(); j++)
602 ati[j]->UpdateSurfaceFittingWeight(factor);
617 for (
int i = 0; i < integs.
Size(); i++)
629 for (
int j = 0; j < ati.
Size(); j++)
631 weight = ati[j]->GetSurfaceFittingWeight();
639 double &err_max)
const 648 double err_avg_loc, err_max_loc;
649 for (
int i = 0; i < integs.
Size(); i++)
657 err_avg = std::fmax(err_avg_loc, err_avg);
658 err_max = std::fmax(err_max_loc, err_max);
665 for (
int j = 0; j < ati.
Size(); j++)
667 if (ati[j]->IsSurfaceFittingEnabled())
669 ati[j]->GetSurfaceFittingErrors(err_avg_loc, err_max_loc);
670 err_avg = std::fmax(err_avg_loc, err_avg);
671 err_max = std::fmax(err_max_loc, err_max);
688 for (
int i = 0; i < integs.
Size(); i++)
700 for (
int j = 0; j < ati.
Size(); j++)
702 dtc = ati[j]->GetDiscreteAdaptTC();
716 for (
int i = 0; i < integs.
Size(); i++)
733 for (
int j = 0; j < ati.
Size(); j++)
735 ati[j]->UpdateAfterMeshPositionChange(x_loc, pfesc->
GetOrdering());
736 ati[j]->ComputeFDh(x_loc, *pfesc);
739 ati[j]->ComputeUntangleMetricQuantiles(x_loc, *pfesc);
761 for (
int i = 0; i < integs.
Size(); i++)
778 for (
int j = 0; j < ati.
Size(); j++)
780 ati[j]->UpdateAfterMeshPositionChange(x_loc, fesc->
GetOrdering());
781 ati[j]->ComputeFDh(x_loc, *fesc);
784 ati[j]->ComputeUntangleMetricQuantiles(x_loc, *fesc);
798 double surf_fit_err_max = -10;
799 double surf_fit_err_avg = -10;
808 mfem::out <<
"Avg/Max surface fitting error: " <<
809 surf_fit_err_avg <<
" " <<
810 surf_fit_err_max <<
"\n";
811 mfem::out <<
"Min/Max surface fitting weight: " <<
812 weights.
Min() <<
" " << weights.
Max() <<
"\n";
819 if (rel_change_surf_fit_err < 1.e-2)
830 int x_ordering)
const 832 const bool update_flag =
true;
856 for (
int i = 0; i < NE; i++)
867 for (
int j = 0; j < nsp; j++)
871 min_detJ = std::min(min_detJ, Jpr.
Det());
880 double min_detT_all = min_detJ;
885 MPI_Allreduce(&min_detJ, &min_detT_all, 1, MPI_DOUBLE, MPI_MIN,
886 p_nlf->ParFESpace()->GetComm());
891 min_detT_all /= Wideal.
Det();
901 char *title,
int position)
910 sock.
open(
"localhost", 19916);
911 sock <<
"solution\n";
917 sock <<
"window_title '"<< title <<
"'\n" 918 <<
"window_geometry " 919 << position <<
" " << 0 <<
" " << 600 <<
" " << 600 <<
"\n" 929 char *title,
int position)
936 sock <<
"solution\n";
940 sock <<
"window_title '"<< title <<
"'\n" 941 <<
"window_geometry " 942 << position <<
" " << 0 <<
" " << 600 <<
" " << 600 <<
"\n" VectorGridFunctionCoefficient u_coeff
void vis_tmop_metric_p(int order, TMOP_QualityMetric &qm, const TargetConstructor &tc, ParMesh &pmesh, char *title, int position)
void ComputeUntangleMetricQuantiles(const Vector &x, const FiniteElementSpace &fes)
virtual void Interpolate(const GridFunction &field_in, Vector &field_out)
T Min() const
Find the minimal element in the array, using the comparison operator < for class T.
virtual void Mult(const Vector &x, Vector &y) const
Matrix vector multiplication.
Conjugate gradient method.
int GetNPoints() const
Returns the number of the points in the integration rule.
AssemblyLevel
Enumeration defining the assembly level for bilinear and nonlinear form classes derived from Operator...
Class for an integration rule - an Array of IntegrationPoint.
virtual const Operator * GetProlongationMatrix() const
The returned Operator is owned by the FiniteElementSpace.
Class for grid function - Vector with associated FE space.
Data type for scaled Jacobi-type smoother of sparse matrix.
virtual void ComputeAtNewPosition(const Vector &new_nodes, Vector &new_field, int new_nodes_ordering=Ordering::byNODES)
double GetSurfaceFittingWeight()
Get the surface fitting weight.
double surf_fit_err_avg_prvs
virtual void Mult(const Vector &ind, Vector &di_dt) const
Perform the action of the operator: y = k = f(x, t), where k solves the algebraic equation F(x...
void GetSurfaceFittingWeight(Array< double > &weights) const
Get the surface fitting weight for all the TMOP integrators.
double ComputeMinDet(const Vector &x_loc, const FiniteElementSpace &fes) const
void SaveAsOne(const char *fname, int precision=16) const
double surf_fit_max_threshold
void SetSize(int s)
Resize the vector to size s.
void InterpolateTMOP_QualityMetric(TMOP_QualityMetric &metric, const TargetConstructor &tc, const Mesh &mesh, GridFunction &metric_gf)
Interpolates the metric's values at the nodes of metric_gf.
Base abstract class for first order time dependent operators.
bool summary
A summary of the solver process will be reported after the last iteration to mfem::out.
const Array< TMOP_Integrator * > & GetTMOPIntegrators() const
bool first_and_last
Information about the first and last iteration will be printed to mfem::out.
Pointer to an Operator of a specified type.
DiscreteAdaptTC * GetDiscreteAdaptTC() const
virtual void Mult(const Vector &b, Vector &x) const
Operator application: y=A(x).
int Size() const
Returns the size of the vector.
T Max() const
Find the maximal element in the array, using the comparison operator < for class T.
ParFiniteElementSpace * pfes
Data type dense matrix using column-major storage.
void GetSurfaceFittingErrors(double &err_avg, double &err_max)
double MinDetJpr_2D(const FiniteElementSpace *, const Vector &) const
double * Data() const
Returns the matrix data array.
void Init(TimeDependentOperator &f_) override
Associate a TimeDependentOperator with the ODE solver.
bool IsSurfaceFittingEnabled()
virtual void Mult(const Vector &x, Vector &y) const =0
Operator application: y=A(x).
Abstract parallel finite element space.
void vis_tmop_metric_s(int order, TMOP_QualityMetric &qm, const TargetConstructor &tc, Mesh &mesh, char *title, int position)
void UpdateGradientTargetSpecification(const Vector &x, double dx, bool use_flag=false, int x_ordering=Ordering::byNODES)
void GetSubVector(const Array< int > &dofs, Vector &elemvect) const
Extract entries listed in dofs to the output Vector elemvect.
void UpdateSurfaceFittingWeight(double factor)
Update the surface fitting weight as surf_fit_coeff *= factor;.
bool UsesTensorBasis(const FiniteElementSpace &fes)
Return true if the mesh contains only one topology and the elements are tensor elements.
void add(const Vector &v1, const Vector &v2, Vector &v)
virtual const FiniteElement * GetFE(int i) const
Returns pointer to the FiniteElement in the FiniteElementCollection associated with i'th element in t...
int GetNumGeometries(int dim) const
Return the number of geometries of the given dimension present in the mesh.
virtual void ComputeAtNewPosition(const Vector &new_nodes, Vector &new_field, int new_nodes_ordering=Ordering::byNODES)
double Norm(const Vector &x) const
Geometry::Type GetGeomType() const
Returns the Geometry::Type of the reference element.
Abstract class for local mesh quality metrics in the target-matrix optimization paradigm (TMOP) by P...
IntegrationPoint & IntPoint(int i)
Returns a reference to the i-th integration point.
virtual void SetPrintLevel(int print_lvl)
Legacy method to set the level of verbosity of the solver output.
double f(const Vector &xvec)
double GetElementSize(ElementTransformation *T, int type=0)
int Append(const T &el)
Append element 'el' to array, resize if necessary.
const FiniteElementCollection * FEColl() const
void UpdateAfterMeshPositionChange(const Vector &new_x, int new_x_ordering=Ordering::byNODES)
Jacobi smoothing for a given bilinear form (no matrix necessary).
static MemoryType GetDeviceMemoryType()
Get the current Device MemoryType. This is the MemoryType used by most MFEM classes when allocating m...
virtual double ComputeScalingFactor(const Vector &x, const Vector &b) const
ParMesh * GetParMesh() const
void SetMaxIter(int max_it)
void Setup(Mesh &m, const double bb_t=0.1, const double newt_tol=1.0e-12, const int npt_max=256)
Performs a single remap advection step in serial.
const SparseMatrix * GetConformingProlongation() const
The returned SparseMatrix is owned by the FiniteElementSpace.
virtual void Mult(const Vector &ind, Vector &di_dt) const
Perform the action of the operator: y = k = f(x, t), where k solves the algebraic equation F(x...
Parallel smoothers in hypre.
FiniteElementSpace * FESpace()
int GetNE() const
Returns number of elements in the mesh.
bool compute_metric_quantile_flag
DofTransformation * GetElementVDofs(int i, Array< int > &vdofs) const
Returns indexes of degrees of freedom in array dofs for i'th element.
Wrapper for hypre's parallel vector class.
Mesh * GetMesh() const
Returns the mesh.
void SetAbsTol(double atol)
virtual void ProcessNewState(const Vector &x) const
PrintLevel print_options
Output behavior for the iterative solver.
void SetRelTol(double rtol)
ComplexDenseMatrix * MultAtB(const ComplexDenseMatrix &A, const ComplexDenseMatrix &B)
Multiply the complex conjugate transpose of a matrix A with a matrix B. A^H*B.
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
OutStream out(std::cout)
Global stream used by the library for standard output. Initially it uses the same std::streambuf as s...
void subtract(const Vector &x, const Vector &y, Vector &z)
MemoryType
Memory types supported by MFEM.
double Min() const
Returns the minimal element of the vector.
Performs a single remap advection step in parallel.
bool update_surf_fit_coeff
void SetSize(int nsize)
Change the logical size of the array, keep existing entries.
double MinDetJpr_3D(const FiniteElementSpace *, const Vector &) const
void PrintAsOne(std::ostream &out=mfem::out) const
int GetDof() const
Returns the number of degrees of freedom in the finite element.
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows().
double Max() const
Returns the maximal element of the vector.
void ResetUpdateFlags()
Used in combination with the Update methods to avoid extra computations.
const IntegrationRule & GetIntegrationRule(const FiniteElement &el) const
virtual double GetTime() const
Read the currently set time.
int GetNE() const
Returns number of elements.
virtual const Operator * GetProlongationMatrix() const
The returned Operator is owned by the FiniteElementSpace.
void ComputeFDh(const Vector &x, const FiniteElementSpace &fes)
Determines the perturbation, h, for FD-based approximation.
void UpdateHessianTargetSpecification(const Vector &x, double dx, bool use_flag=false, int x_ordering=Ordering::byNODES)
Ordering::Type GetOrdering() const
Return the ordering method.
void vel(const Vector &x, double t, Vector &u)
virtual void SetInitialField(const Vector &init_nodes, const Vector &init_field)
VectorGridFunctionCoefficient u_coeff
SerialAdvectorCGOper(const Vector &x_start, GridFunction &vel, FiniteElementSpace &fes, AssemblyLevel al=AssemblyLevel::LEGACY)
int GetVSize() const
Return the number of vector dofs, i.e. GetNDofs() x GetVDim().
double infinity()
Define a shortcut for std::numeric_limits<double>::infinity()
const DenseMatrix & GetGeomToPerfGeomJac(int GeomType) const
virtual void SetSpace(FiniteElementSpace *f)
Associate a new FiniteElementSpace with the GridFunction.
int open(const char hostname[], int port)
Open the socket stream on 'port' at 'hostname'.
int Size() const
Return the logical size of the array.
virtual void SetOperator(const Operator &op)
Also calls SetOperator for the preconditioner if there is one.
virtual void GetSurfaceFittingError(double &err_avg, double &err_max) const
ParAdvectorCGOper(const Vector &x_start, GridFunction &vel, ParFiniteElementSpace &pfes, AssemblyLevel al=AssemblyLevel::LEGACY, MemoryType mt=MemoryType::DEFAULT)
FindPointsGSLIB can robustly evaluate a GridFunction on an arbitrary collection of points...
virtual void Print(std::ostream &os=mfem::out) const
void MakeRef(Vector &base, int offset, int size)
Reset the Vector to be a reference to a sub-vector of base.
virtual void SetPreconditioner(Solver &pr)
This should be called before SetOperator.
void Step(Vector &x, double &t, double &dt) override
Perform a time step from time t [in] to time t [out] based on the requested step size dt [in]...
void UpdateTargetSpecification(const Vector &new_x, bool use_flag=false, int new_x_ordering=Ordering::byNODES)
void GetNodes(Vector &node_coord) const
bool iterations
Detailed information about each iteration will be reported to mfem::out.
double u(const Vector &xvec)
void SetNodes(const Vector &node_coord)
Updates the vertex/node locations. Invokes NodesUpdated().
Class for parallel grid function.
Base class representing target-matrix construction algorithms for mesh optimization via the target-ma...
virtual void Save(std::ostream &out) const
Save the GridFunction to an output stream.
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const =0
Evaluate the gradients of all shape functions of a scalar finite element in reference space at the gi...
Class for parallel meshes.
virtual double * HostReadWrite()
Shortcut for mfem::ReadWrite(vec.GetMemory(), vec.Size(), false).
void UpdateSurfaceFittingWeight(double factor) const
Update surface fitting weight as surf_fit_weight *= factor.
void Reset(OpType *A, bool own_A=true)
Reset the OperatorHandle to the given OpType pointer, A.
virtual void SetInitialField(const Vector &init_nodes, const Vector &init_field)
Arbitrary order "L2-conforming" discontinuous finite elements.
void NodesUpdated()
This function should be called after the mesh node coordinates have been updated externally, e.g. by modifying the internal nodal GridFunction returned by GetNodes().
A TMOP integrator class based on any given TMOP_QualityMetric and TargetConstructor.
void UpdateDiscreteTC(const TMOP_Integrator &ti, const Vector &x_new, int x_ordering=Ordering::byNODES) const